btm_inq.cc 96 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589
  1. /******************************************************************************
  2. *
  3. * Copyright 1999-2014 Broadcom Corporation
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at:
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. ******************************************************************************/
  18. /******************************************************************************
  19. *
  20. * This file contains functions that handle inquiries. These include
  21. * setting discoverable mode, controlling the mode of the Baseband, and
  22. * maintaining a small database of inquiry responses, with API for people
  23. * to browse it.
  24. *
  25. ******************************************************************************/
  26. #include <log/log.h>
  27. #include <stddef.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include "common/time_util.h"
  32. #include "device/include/controller.h"
  33. #include "osi/include/osi.h"
  34. #include "advertise_data_parser.h"
  35. #include "bt_common.h"
  36. #include "bt_types.h"
  37. #include "btm_api.h"
  38. #include "btm_int.h"
  39. #include "btu.h"
  40. #include "hcidefs.h"
  41. #include "hcimsgs.h"
  42. using bluetooth::Uuid;
  43. /* 3 second timeout waiting for responses */
  44. #define BTM_INQ_REPLY_TIMEOUT_MS (3 * 1000)
  45. /* TRUE to enable DEBUG traces for btm_inq */
  46. #ifndef BTM_INQ_DEBUG
  47. #define BTM_INQ_DEBUG FALSE
  48. #endif
  49. /******************************************************************************/
  50. /* L O C A L D A T A D E F I N I T I O N S */
  51. /******************************************************************************/
  52. static const LAP general_inq_lap = {0x9e, 0x8b, 0x33};
  53. static const LAP limited_inq_lap = {0x9e, 0x8b, 0x00};
  54. const uint16_t BTM_EIR_UUID_LKUP_TBL[BTM_EIR_MAX_SERVICES] = {
  55. UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER,
  56. /* UUID_SERVCLASS_BROWSE_GROUP_DESCRIPTOR, */
  57. /* UUID_SERVCLASS_PUBLIC_BROWSE_GROUP, */
  58. UUID_SERVCLASS_SERIAL_PORT, UUID_SERVCLASS_LAN_ACCESS_USING_PPP,
  59. UUID_SERVCLASS_DIALUP_NETWORKING, UUID_SERVCLASS_IRMC_SYNC,
  60. UUID_SERVCLASS_OBEX_OBJECT_PUSH, UUID_SERVCLASS_OBEX_FILE_TRANSFER,
  61. UUID_SERVCLASS_IRMC_SYNC_COMMAND, UUID_SERVCLASS_HEADSET,
  62. UUID_SERVCLASS_CORDLESS_TELEPHONY, UUID_SERVCLASS_AUDIO_SOURCE,
  63. UUID_SERVCLASS_AUDIO_SINK, UUID_SERVCLASS_AV_REM_CTRL_TARGET,
  64. /* UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION, */
  65. UUID_SERVCLASS_AV_REMOTE_CONTROL,
  66. /* UUID_SERVCLASS_VIDEO_CONFERENCING, */
  67. UUID_SERVCLASS_INTERCOM, UUID_SERVCLASS_FAX,
  68. UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY,
  69. /* UUID_SERVCLASS_WAP, */
  70. /* UUID_SERVCLASS_WAP_CLIENT, */
  71. UUID_SERVCLASS_PANU, UUID_SERVCLASS_NAP, UUID_SERVCLASS_GN,
  72. UUID_SERVCLASS_DIRECT_PRINTING,
  73. /* UUID_SERVCLASS_REFERENCE_PRINTING, */
  74. UUID_SERVCLASS_IMAGING, UUID_SERVCLASS_IMAGING_RESPONDER,
  75. UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE, UUID_SERVCLASS_IMAGING_REF_OBJECTS,
  76. UUID_SERVCLASS_HF_HANDSFREE, UUID_SERVCLASS_AG_HANDSFREE,
  77. UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE,
  78. /* UUID_SERVCLASS_REFLECTED_UI, */
  79. UUID_SERVCLASS_BASIC_PRINTING, UUID_SERVCLASS_PRINTING_STATUS,
  80. UUID_SERVCLASS_HUMAN_INTERFACE, UUID_SERVCLASS_CABLE_REPLACEMENT,
  81. UUID_SERVCLASS_HCRP_PRINT, UUID_SERVCLASS_HCRP_SCAN,
  82. /* UUID_SERVCLASS_COMMON_ISDN_ACCESS, */
  83. /* UUID_SERVCLASS_VIDEO_CONFERENCING_GW, */
  84. /* UUID_SERVCLASS_UDI_MT, */
  85. /* UUID_SERVCLASS_UDI_TA, */
  86. /* UUID_SERVCLASS_VCP, */
  87. UUID_SERVCLASS_SAP, UUID_SERVCLASS_PBAP_PCE, UUID_SERVCLASS_PBAP_PSE,
  88. UUID_SERVCLASS_PHONE_ACCESS, UUID_SERVCLASS_HEADSET_HS,
  89. UUID_SERVCLASS_PNP_INFORMATION,
  90. /* UUID_SERVCLASS_GENERIC_NETWORKING, */
  91. /* UUID_SERVCLASS_GENERIC_FILETRANSFER, */
  92. /* UUID_SERVCLASS_GENERIC_AUDIO, */
  93. /* UUID_SERVCLASS_GENERIC_TELEPHONY, */
  94. /* UUID_SERVCLASS_UPNP_SERVICE, */
  95. /* UUID_SERVCLASS_UPNP_IP_SERVICE, */
  96. /* UUID_SERVCLASS_ESDP_UPNP_IP_PAN, */
  97. /* UUID_SERVCLASS_ESDP_UPNP_IP_LAP, */
  98. /* UUID_SERVCLASS_ESDP_UPNP_IP_L2CAP, */
  99. UUID_SERVCLASS_VIDEO_SOURCE, UUID_SERVCLASS_VIDEO_SINK,
  100. /* UUID_SERVCLASS_VIDEO_DISTRIBUTION */
  101. UUID_SERVCLASS_MESSAGE_ACCESS, UUID_SERVCLASS_MESSAGE_NOTIFICATION,
  102. UUID_SERVCLASS_HDP_SOURCE, UUID_SERVCLASS_HDP_SINK};
  103. /******************************************************************************/
  104. /* L O C A L F U N C T I O N P R O T O T Y P E S */
  105. /******************************************************************************/
  106. static void btm_initiate_inquiry(tBTM_INQUIRY_VAR_ST* p_inq);
  107. static tBTM_STATUS btm_set_inq_event_filter(uint8_t filter_cond_type,
  108. tBTM_INQ_FILT_COND* p_filt_cond);
  109. static void btm_clr_inq_result_flt(void);
  110. static uint8_t btm_convert_uuid_to_eir_service(uint16_t uuid16);
  111. static void btm_set_eir_uuid(uint8_t* p_eir, tBTM_INQ_RESULTS* p_results);
  112. static const uint8_t* btm_eir_get_uuid_list(uint8_t* p_eir, size_t eir_len,
  113. uint8_t uuid_size,
  114. uint8_t* p_num_uuid,
  115. uint8_t* p_uuid_list_type);
  116. /*******************************************************************************
  117. *
  118. * Function BTM_SetDiscoverability
  119. *
  120. * Description This function is called to set the device into or out of
  121. * discoverable mode. Discoverable mode means inquiry
  122. * scans are enabled. If a value of '0' is entered for window
  123. * or interval, the default values are used.
  124. *
  125. * Returns BTM_SUCCESS if successful
  126. * BTM_BUSY if a setting of the filter is already in progress
  127. * BTM_NO_RESOURCES if couldn't get a memory pool buffer
  128. * BTM_ILLEGAL_VALUE if a bad parameter was detected
  129. * BTM_WRONG_MODE if the device is not up.
  130. *
  131. ******************************************************************************/
  132. tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode, uint16_t window,
  133. uint16_t interval) {
  134. uint8_t scan_mode = 0;
  135. uint16_t service_class;
  136. uint8_t* p_cod;
  137. uint8_t major, minor;
  138. DEV_CLASS cod;
  139. LAP temp_lap[2];
  140. bool is_limited;
  141. bool cod_limited;
  142. BTM_TRACE_API("BTM_SetDiscoverability");
  143. if (controller_get_interface()->supports_ble()) {
  144. if (btm_ble_set_discoverability((uint16_t)(inq_mode)) == BTM_SUCCESS) {
  145. btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_BLE_DISCOVERABLE_MASK);
  146. btm_cb.btm_inq_vars.discoverable_mode |=
  147. (inq_mode & BTM_BLE_DISCOVERABLE_MASK);
  148. }
  149. }
  150. inq_mode &= ~BTM_BLE_DISCOVERABLE_MASK;
  151. /*** Check mode parameter ***/
  152. if (inq_mode > BTM_MAX_DISCOVERABLE) return (BTM_ILLEGAL_VALUE);
  153. /* Make sure the controller is active */
  154. if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET);
  155. /* If the window and/or interval is '0', set to default values */
  156. if (!window) window = BTM_DEFAULT_DISC_WINDOW;
  157. if (!interval) interval = BTM_DEFAULT_DISC_INTERVAL;
  158. BTM_TRACE_API(
  159. "BTM_SetDiscoverability: mode %d [NonDisc-0, Lim-1, Gen-2], window "
  160. "0x%04x, interval 0x%04x",
  161. inq_mode, window, interval);
  162. /*** Check for valid window and interval parameters ***/
  163. /*** Only check window and duration if mode is connectable ***/
  164. if (inq_mode != BTM_NON_DISCOVERABLE) {
  165. /* window must be less than or equal to interval */
  166. if (window < HCI_MIN_INQUIRYSCAN_WINDOW ||
  167. window > HCI_MAX_INQUIRYSCAN_WINDOW ||
  168. interval < HCI_MIN_INQUIRYSCAN_INTERVAL ||
  169. interval > HCI_MAX_INQUIRYSCAN_INTERVAL || window > interval) {
  170. return (BTM_ILLEGAL_VALUE);
  171. }
  172. }
  173. /* Set the IAC if needed */
  174. if (inq_mode != BTM_NON_DISCOVERABLE) {
  175. if (inq_mode & BTM_LIMITED_DISCOVERABLE) {
  176. /* Use the GIAC and LIAC codes for limited discoverable mode */
  177. memcpy(temp_lap[0], limited_inq_lap, LAP_LEN);
  178. memcpy(temp_lap[1], general_inq_lap, LAP_LEN);
  179. btsnd_hcic_write_cur_iac_lap(2, (LAP * const)temp_lap);
  180. } else {
  181. btsnd_hcic_write_cur_iac_lap(1, (LAP * const) & general_inq_lap);
  182. }
  183. scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
  184. }
  185. /* Send down the inquiry scan window and period if changed */
  186. if ((window != btm_cb.btm_inq_vars.inq_scan_window) ||
  187. (interval != btm_cb.btm_inq_vars.inq_scan_period)) {
  188. btsnd_hcic_write_inqscan_cfg(interval, window);
  189. btm_cb.btm_inq_vars.inq_scan_window = window;
  190. btm_cb.btm_inq_vars.inq_scan_period = interval;
  191. }
  192. if (btm_cb.btm_inq_vars.connectable_mode & BTM_CONNECTABLE_MASK)
  193. scan_mode |= HCI_PAGE_SCAN_ENABLED;
  194. btsnd_hcic_write_scan_enable(scan_mode);
  195. btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_DISCOVERABLE_MASK);
  196. btm_cb.btm_inq_vars.discoverable_mode |= inq_mode;
  197. /* Change the service class bit if mode has changed */
  198. p_cod = BTM_ReadDeviceClass();
  199. BTM_COD_SERVICE_CLASS(service_class, p_cod);
  200. is_limited = (inq_mode & BTM_LIMITED_DISCOVERABLE) ? true : false;
  201. cod_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false;
  202. if (is_limited ^ cod_limited) {
  203. BTM_COD_MINOR_CLASS(minor, p_cod);
  204. BTM_COD_MAJOR_CLASS(major, p_cod);
  205. if (is_limited)
  206. service_class |= BTM_COD_SERVICE_LMTD_DISCOVER;
  207. else
  208. service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER;
  209. FIELDS_TO_COD(cod, minor, major, service_class);
  210. (void)BTM_SetDeviceClass(cod);
  211. }
  212. return (BTM_SUCCESS);
  213. }
  214. /*******************************************************************************
  215. *
  216. * Function BTM_SetInquiryScanType
  217. *
  218. * Description This function is called to set the iquiry scan-type to
  219. * standard or interlaced.
  220. *
  221. * Returns BTM_SUCCESS if successful
  222. * BTM_MODE_UNSUPPORTED if not a 1.2 device
  223. * BTM_WRONG_MODE if the device is not up.
  224. *
  225. ******************************************************************************/
  226. tBTM_STATUS BTM_SetInquiryScanType(uint16_t scan_type) {
  227. BTM_TRACE_API("BTM_SetInquiryScanType");
  228. if (scan_type != BTM_SCAN_TYPE_STANDARD &&
  229. scan_type != BTM_SCAN_TYPE_INTERLACED)
  230. return (BTM_ILLEGAL_VALUE);
  231. /* whatever app wants if device is not 1.2 scan type should be STANDARD */
  232. if (!controller_get_interface()->supports_interlaced_inquiry_scan())
  233. return (BTM_MODE_UNSUPPORTED);
  234. /* Check for scan type if configuration has been changed */
  235. if (scan_type != btm_cb.btm_inq_vars.inq_scan_type) {
  236. if (BTM_IsDeviceUp()) {
  237. btsnd_hcic_write_inqscan_type((uint8_t)scan_type);
  238. btm_cb.btm_inq_vars.inq_scan_type = scan_type;
  239. } else
  240. return (BTM_WRONG_MODE);
  241. }
  242. return (BTM_SUCCESS);
  243. }
  244. /*******************************************************************************
  245. *
  246. * Function BTM_SetPageScanType
  247. *
  248. * Description This function is called to set the page scan-type to
  249. * standard or interlaced.
  250. *
  251. * Returns BTM_SUCCESS if successful
  252. * BTM_MODE_UNSUPPORTED if not a 1.2 device
  253. * BTM_WRONG_MODE if the device is not up.
  254. *
  255. ******************************************************************************/
  256. tBTM_STATUS BTM_SetPageScanType(uint16_t scan_type) {
  257. BTM_TRACE_API("BTM_SetPageScanType");
  258. if (scan_type != BTM_SCAN_TYPE_STANDARD &&
  259. scan_type != BTM_SCAN_TYPE_INTERLACED)
  260. return (BTM_ILLEGAL_VALUE);
  261. /* whatever app wants if device is not 1.2 scan type should be STANDARD */
  262. if (!controller_get_interface()->supports_interlaced_inquiry_scan())
  263. return (BTM_MODE_UNSUPPORTED);
  264. /* Check for scan type if configuration has been changed */
  265. if (scan_type != btm_cb.btm_inq_vars.page_scan_type) {
  266. if (BTM_IsDeviceUp()) {
  267. btsnd_hcic_write_pagescan_type((uint8_t)scan_type);
  268. btm_cb.btm_inq_vars.page_scan_type = scan_type;
  269. } else
  270. return (BTM_WRONG_MODE);
  271. }
  272. return (BTM_SUCCESS);
  273. }
  274. /*******************************************************************************
  275. *
  276. * Function BTM_SetInquiryMode
  277. *
  278. * Description This function is called to set standard or with RSSI
  279. * mode of the inquiry for local device.
  280. *
  281. * Output Params: mode - standard, with RSSI, extended
  282. *
  283. * Returns BTM_SUCCESS if successful
  284. * BTM_NO_RESOURCES if couldn't get a memory pool buffer
  285. * BTM_ILLEGAL_VALUE if a bad parameter was detected
  286. * BTM_WRONG_MODE if the device is not up.
  287. *
  288. ******************************************************************************/
  289. tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) {
  290. const controller_t* controller = controller_get_interface();
  291. BTM_TRACE_API("BTM_SetInquiryMode");
  292. if (mode == BTM_INQ_RESULT_STANDARD) {
  293. /* mandatory mode */
  294. } else if (mode == BTM_INQ_RESULT_WITH_RSSI) {
  295. if (!controller->supports_rssi_with_inquiry_results())
  296. return (BTM_MODE_UNSUPPORTED);
  297. } else if (mode == BTM_INQ_RESULT_EXTENDED) {
  298. if (!controller->supports_extended_inquiry_response())
  299. return (BTM_MODE_UNSUPPORTED);
  300. } else
  301. return (BTM_ILLEGAL_VALUE);
  302. if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
  303. btsnd_hcic_write_inquiry_mode(mode);
  304. return (BTM_SUCCESS);
  305. }
  306. /*******************************************************************************
  307. *
  308. * Function BTM_ReadDiscoverability
  309. *
  310. * Description This function is called to read the current discoverability
  311. * mode of the device.
  312. *
  313. * Output Params: p_window - current inquiry scan duration
  314. * p_interval - current inquiry scan interval
  315. *
  316. * Returns BTM_NON_DISCOVERABLE, BTM_LIMITED_DISCOVERABLE, or
  317. * BTM_GENERAL_DISCOVERABLE
  318. *
  319. ******************************************************************************/
  320. uint16_t BTM_ReadDiscoverability(uint16_t* p_window, uint16_t* p_interval) {
  321. BTM_TRACE_API("BTM_ReadDiscoverability");
  322. if (p_window) *p_window = btm_cb.btm_inq_vars.inq_scan_window;
  323. if (p_interval) *p_interval = btm_cb.btm_inq_vars.inq_scan_period;
  324. return (btm_cb.btm_inq_vars.discoverable_mode);
  325. }
  326. /*******************************************************************************
  327. *
  328. * Function BTM_SetPeriodicInquiryMode
  329. *
  330. * Description This function is called to set the device periodic inquiry
  331. * mode. If the duration is zero, the periodic inquiry mode is
  332. * cancelled.
  333. *
  334. * Note: We currently do not allow concurrent inquiry and
  335. * periodic inquiry.
  336. *
  337. * Parameters: p_inqparms - pointer to the inquiry information
  338. * mode - GENERAL or LIMITED inquiry
  339. * duration - length in 1.28 sec intervals (If '0', the
  340. * inquiry is CANCELLED)
  341. * max_resps - maximum amount of devices to search for
  342. * before ending the inquiry
  343. * filter_cond_type - BTM_CLR_INQUIRY_FILTER,
  344. * BTM_FILTER_COND_DEVICE_CLASS, or
  345. * BTM_FILTER_COND_BD_ADDR
  346. * filter_cond - value for the filter (based on
  347. * filter_cond_type)
  348. *
  349. * max_delay - maximum amount of time between successive
  350. * inquiries
  351. * min_delay - minimum amount of time between successive
  352. * inquiries
  353. * p_results_cb - callback returning pointer to results
  354. * (tBTM_INQ_RESULTS)
  355. *
  356. * Returns BTM_CMD_STARTED if successfully started
  357. * BTM_ILLEGAL_VALUE if a bad parameter is detected
  358. * BTM_NO_RESOURCES if could not allocate a message buffer
  359. * BTM_SUCCESS - if cancelling the periodic inquiry
  360. * BTM_BUSY - if an inquiry is already active
  361. * BTM_WRONG_MODE if the device is not up.
  362. *
  363. ******************************************************************************/
  364. tBTM_STATUS BTM_SetPeriodicInquiryMode(tBTM_INQ_PARMS* p_inqparms,
  365. uint16_t max_delay, uint16_t min_delay,
  366. tBTM_INQ_RESULTS_CB* p_results_cb) {
  367. tBTM_STATUS status;
  368. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  369. BTM_TRACE_API(
  370. "BTM_SetPeriodicInquiryMode: mode: %d, dur: %d, rsps: %d, flt: %d, min: "
  371. "%d, max: %d",
  372. p_inqparms->mode, p_inqparms->duration, p_inqparms->max_resps,
  373. p_inqparms->filter_cond_type, min_delay, max_delay);
  374. /*** Make sure the device is ready ***/
  375. if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
  376. /* Only one active inquiry is allowed in this implementation.
  377. Also do not allow an inquiry if the inquiry filter is being updated */
  378. if (p_inq->inq_active || p_inq->inqfilt_active) return (BTM_BUSY);
  379. /* If illegal parameters return false */
  380. if (p_inqparms->mode != BTM_GENERAL_INQUIRY &&
  381. p_inqparms->mode != BTM_LIMITED_INQUIRY)
  382. return (BTM_ILLEGAL_VALUE);
  383. /* Verify the parameters for this command */
  384. if (p_inqparms->duration < BTM_MIN_INQUIRY_LEN ||
  385. p_inqparms->duration > BTM_MAX_INQUIRY_LENGTH ||
  386. min_delay <= p_inqparms->duration ||
  387. min_delay < BTM_PER_INQ_MIN_MIN_PERIOD ||
  388. min_delay > BTM_PER_INQ_MAX_MIN_PERIOD || max_delay <= min_delay ||
  389. max_delay < BTM_PER_INQ_MIN_MAX_PERIOD)
  390. /* max_delay > BTM_PER_INQ_MAX_MAX_PERIOD)*/
  391. /* BTM_PER_INQ_MAX_MAX_PERIOD set to 1's in all bits. Condition resulting in
  392. false always*/
  393. {
  394. return (BTM_ILLEGAL_VALUE);
  395. }
  396. /* Save the inquiry parameters to be used upon the completion of
  397. * setting/clearing the inquiry filter */
  398. p_inq->inqparms = *p_inqparms;
  399. p_inq->per_min_delay = min_delay;
  400. p_inq->per_max_delay = max_delay;
  401. p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
  402. p_inq->p_inq_results_cb = p_results_cb;
  403. p_inq->inq_active = (uint8_t)(
  404. (p_inqparms->mode == BTM_LIMITED_INQUIRY)
  405. ? (BTM_LIMITED_INQUIRY_ACTIVE | BTM_PERIODIC_INQUIRY_ACTIVE)
  406. : (BTM_GENERAL_INQUIRY_ACTIVE | BTM_PERIODIC_INQUIRY_ACTIVE));
  407. /* If a filter is specified, then save it for later and clear the current
  408. filter.
  409. The setting of the filter is done upon completion of clearing of the
  410. previous
  411. filter.
  412. */
  413. if (p_inqparms->filter_cond_type != BTM_CLR_INQUIRY_FILTER) {
  414. p_inq->state = BTM_INQ_CLR_FILT_STATE;
  415. p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;
  416. } else /* The filter is not being used so simply clear it; the inquiry can
  417. start after this operation */
  418. p_inq->state = BTM_INQ_SET_FILT_STATE;
  419. /* Before beginning the inquiry the current filter must be cleared, so
  420. * initiate the command */
  421. status = btm_set_inq_event_filter(p_inqparms->filter_cond_type,
  422. &p_inqparms->filter_cond);
  423. if (status != BTM_CMD_STARTED) {
  424. /* If set filter command is not succesful reset the state */
  425. p_inq->p_inq_results_cb = NULL;
  426. p_inq->state = BTM_INQ_INACTIVE_STATE;
  427. }
  428. return (status);
  429. }
  430. /*******************************************************************************
  431. *
  432. * Function BTM_CancelPeriodicInquiry
  433. *
  434. * Description This function cancels a periodic inquiry
  435. *
  436. * Returns
  437. * BTM_NO_RESOURCES if could not allocate a message buffer
  438. * BTM_SUCCESS - if cancelling the periodic inquiry
  439. * BTM_WRONG_MODE if the device is not up.
  440. *
  441. ******************************************************************************/
  442. tBTM_STATUS BTM_CancelPeriodicInquiry(void) {
  443. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  444. tBTM_STATUS status = BTM_SUCCESS;
  445. BTM_TRACE_API("BTM_CancelPeriodicInquiry called");
  446. /*** Make sure the device is ready ***/
  447. if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
  448. /* Only cancel if one is active */
  449. if (btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) {
  450. btm_cb.btm_inq_vars.inq_active = BTM_INQUIRY_INACTIVE;
  451. btm_cb.btm_inq_vars.p_inq_results_cb = NULL;
  452. btsnd_hcic_exit_per_inq();
  453. /* If the event filter is in progress, mark it so that the processing of the
  454. return
  455. event will be ignored */
  456. if (p_inq->inqfilt_active) p_inq->pending_filt_complete_event++;
  457. p_inq->inqfilt_active = false;
  458. p_inq->inq_counter++;
  459. }
  460. return (status);
  461. }
  462. /*******************************************************************************
  463. *
  464. * Function BTM_SetConnectability
  465. *
  466. * Description This function is called to set the device into or out of
  467. * connectable mode. Discoverable mode means page scans are
  468. * enabled.
  469. *
  470. * Returns BTM_SUCCESS if successful
  471. * BTM_ILLEGAL_VALUE if a bad parameter is detected
  472. * BTM_NO_RESOURCES if could not allocate a message buffer
  473. * BTM_WRONG_MODE if the device is not up.
  474. *
  475. ******************************************************************************/
  476. tBTM_STATUS BTM_SetConnectability(uint16_t page_mode, uint16_t window,
  477. uint16_t interval) {
  478. uint8_t scan_mode = 0;
  479. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  480. BTM_TRACE_API("BTM_SetConnectability");
  481. if (controller_get_interface()->supports_ble()) {
  482. if (btm_ble_set_connectability(page_mode) != BTM_SUCCESS) {
  483. return BTM_NO_RESOURCES;
  484. }
  485. p_inq->connectable_mode &= (~BTM_BLE_CONNECTABLE_MASK);
  486. p_inq->connectable_mode |= (page_mode & BTM_BLE_CONNECTABLE_MASK);
  487. }
  488. page_mode &= ~BTM_BLE_CONNECTABLE_MASK;
  489. /*** Check mode parameter ***/
  490. if (page_mode != BTM_NON_CONNECTABLE && page_mode != BTM_CONNECTABLE)
  491. return (BTM_ILLEGAL_VALUE);
  492. /* Make sure the controller is active */
  493. if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET);
  494. /* If the window and/or interval is '0', set to default values */
  495. if (!window) window = BTM_DEFAULT_CONN_WINDOW;
  496. if (!interval) interval = BTM_DEFAULT_CONN_INTERVAL;
  497. BTM_TRACE_API(
  498. "BTM_SetConnectability: mode %d [NonConn-0, Conn-1], window 0x%04x, "
  499. "interval 0x%04x",
  500. page_mode, window, interval);
  501. /*** Check for valid window and interval parameters ***/
  502. /*** Only check window and duration if mode is connectable ***/
  503. if (page_mode == BTM_CONNECTABLE) {
  504. /* window must be less than or equal to interval */
  505. if (window < HCI_MIN_PAGESCAN_WINDOW || window > HCI_MAX_PAGESCAN_WINDOW ||
  506. interval < HCI_MIN_PAGESCAN_INTERVAL ||
  507. interval > HCI_MAX_PAGESCAN_INTERVAL || window > interval) {
  508. return (BTM_ILLEGAL_VALUE);
  509. }
  510. scan_mode |= HCI_PAGE_SCAN_ENABLED;
  511. }
  512. if ((window != p_inq->page_scan_window) ||
  513. (interval != p_inq->page_scan_period)) {
  514. p_inq->page_scan_window = window;
  515. p_inq->page_scan_period = interval;
  516. btsnd_hcic_write_pagescan_cfg(interval, window);
  517. }
  518. /* Keep the inquiry scan as previouosly set */
  519. if (p_inq->discoverable_mode & BTM_DISCOVERABLE_MASK)
  520. scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
  521. btsnd_hcic_write_scan_enable(scan_mode);
  522. p_inq->connectable_mode &= (~BTM_CONNECTABLE_MASK);
  523. p_inq->connectable_mode |= page_mode;
  524. return (BTM_SUCCESS);
  525. }
  526. /*******************************************************************************
  527. *
  528. * Function BTM_ReadConnectability
  529. *
  530. * Description This function is called to read the current discoverability
  531. * mode of the device.
  532. * Output Params p_window - current page scan duration
  533. * p_interval - current time between page scans
  534. *
  535. * Returns BTM_NON_CONNECTABLE or BTM_CONNECTABLE
  536. *
  537. ******************************************************************************/
  538. uint16_t BTM_ReadConnectability(uint16_t* p_window, uint16_t* p_interval) {
  539. BTM_TRACE_API("BTM_ReadConnectability");
  540. if (p_window) *p_window = btm_cb.btm_inq_vars.page_scan_window;
  541. if (p_interval) *p_interval = btm_cb.btm_inq_vars.page_scan_period;
  542. return (btm_cb.btm_inq_vars.connectable_mode);
  543. }
  544. /*******************************************************************************
  545. *
  546. * Function BTM_IsInquiryActive
  547. *
  548. * Description This function returns a bit mask of the current inquiry
  549. * state
  550. *
  551. * Returns BTM_INQUIRY_INACTIVE if inactive (0)
  552. * BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active
  553. * BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active
  554. * BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active
  555. *
  556. ******************************************************************************/
  557. uint16_t BTM_IsInquiryActive(void) {
  558. BTM_TRACE_API("BTM_IsInquiryActive");
  559. return (btm_cb.btm_inq_vars.inq_active);
  560. }
  561. /*******************************************************************************
  562. *
  563. * Function BTM_CancelInquiry
  564. *
  565. * Description This function cancels an inquiry if active
  566. *
  567. * Returns BTM_SUCCESS if successful
  568. * BTM_NO_RESOURCES if could not allocate a message buffer
  569. * BTM_WRONG_MODE if the device is not up.
  570. *
  571. ******************************************************************************/
  572. tBTM_STATUS BTM_CancelInquiry(void) {
  573. tBTM_STATUS status = BTM_SUCCESS;
  574. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  575. BTM_TRACE_API("BTM_CancelInquiry called");
  576. /*** Make sure the device is ready ***/
  577. if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
  578. /* Only cancel if not in periodic mode, otherwise the caller should call
  579. * BTM_CancelPeriodicMode */
  580. if ((p_inq->inq_active & BTM_INQUIRY_ACTIVE_MASK) != 0 &&
  581. (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))) {
  582. p_inq->inq_active = BTM_INQUIRY_INACTIVE;
  583. p_inq->state = BTM_INQ_INACTIVE_STATE;
  584. p_inq->p_inq_results_cb = NULL; /* Do not notify caller anymore */
  585. p_inq->p_inq_cmpl_cb = NULL; /* Do not notify caller anymore */
  586. /* If the event filter is in progress, mark it so that the processing of the
  587. return
  588. event will be ignored */
  589. if (p_inq->inqfilt_active) {
  590. p_inq->inqfilt_active = false;
  591. p_inq->pending_filt_complete_event++;
  592. }
  593. /* Initiate the cancel inquiry */
  594. else {
  595. if ((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0) {
  596. btsnd_hcic_inq_cancel();
  597. }
  598. if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
  599. btm_ble_stop_inquiry();
  600. }
  601. /* Do not send the BUSY_LEVEL event yet. Wait for the cancel_complete event
  602. * and then send the BUSY_LEVEL event
  603. * btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
  604. */
  605. p_inq->inq_counter++;
  606. btm_clr_inq_result_flt();
  607. }
  608. return (status);
  609. }
  610. /*******************************************************************************
  611. *
  612. * Function BTM_StartInquiry
  613. *
  614. * Description This function is called to start an inquiry.
  615. *
  616. * Parameters: p_inqparms - pointer to the inquiry information
  617. * mode - GENERAL or LIMITED inquiry, BR/LE bit mask
  618. * seperately
  619. * duration - length in 1.28 sec intervals (If '0', the
  620. * inquiry is CANCELLED)
  621. * max_resps - maximum amount of devices to search for
  622. * before ending the inquiry
  623. * filter_cond_type - BTM_CLR_INQUIRY_FILTER,
  624. * BTM_FILTER_COND_DEVICE_CLASS, or
  625. * BTM_FILTER_COND_BD_ADDR
  626. * filter_cond - value for the filter (based on
  627. * filter_cond_type)
  628. *
  629. * p_results_cb - Pointer to the callback routine which gets
  630. * called upon receipt of an inquiry result. If
  631. * this field is NULL, the application is not
  632. * notified.
  633. *
  634. * p_cmpl_cb - Pointer to the callback routine which gets
  635. * called upon completion. If this field is
  636. * NULL, the application is not notified when
  637. * completed.
  638. * Returns tBTM_STATUS
  639. * BTM_CMD_STARTED if successfully initiated
  640. * BTM_BUSY if already in progress
  641. * BTM_ILLEGAL_VALUE if parameter(s) are out of range
  642. * BTM_NO_RESOURCES if could not allocate resources to start
  643. * the command
  644. * BTM_WRONG_MODE if the device is not up.
  645. *
  646. ******************************************************************************/
  647. tBTM_STATUS BTM_StartInquiry(tBTM_INQ_PARMS* p_inqparms,
  648. tBTM_INQ_RESULTS_CB* p_results_cb,
  649. tBTM_CMPL_CB* p_cmpl_cb) {
  650. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  651. BTM_TRACE_API("BTM_StartInquiry: mode: %d, dur: %d, rsps: %d, flt: %d",
  652. p_inqparms->mode, p_inqparms->duration, p_inqparms->max_resps,
  653. p_inqparms->filter_cond_type);
  654. /* Only one active inquiry is allowed in this implementation.
  655. Also do not allow an inquiry if the inquiry filter is being updated */
  656. if (p_inq->inq_active || p_inq->inqfilt_active) {
  657. /*check if LE observe is already running*/
  658. if (p_inq->scan_type == INQ_LE_OBSERVE &&
  659. p_inq->p_inq_ble_results_cb != nullptr) {
  660. BTM_TRACE_API("BTM_StartInquiry: LE observe in progress");
  661. p_inq->scan_type = INQ_GENERAL;
  662. p_inq->inq_active = BTM_INQUIRY_INACTIVE;
  663. btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
  664. btm_send_hci_scan_enable(BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
  665. } else {
  666. LOG(ERROR) << __func__ << ": BTM_BUSY";
  667. return (BTM_BUSY);
  668. }
  669. } else {
  670. p_inq->scan_type = INQ_GENERAL;
  671. }
  672. /*** Make sure the device is ready ***/
  673. if (!BTM_IsDeviceUp()) {
  674. LOG(ERROR) << __func__ << ": adapter is not up";
  675. return BTM_WRONG_MODE;
  676. }
  677. if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) != BTM_GENERAL_INQUIRY &&
  678. (p_inqparms->mode & BTM_BR_INQUIRY_MASK) != BTM_LIMITED_INQUIRY &&
  679. (p_inqparms->mode & BTM_BLE_INQUIRY_MASK) != BTM_BLE_GENERAL_INQUIRY &&
  680. (p_inqparms->mode & BTM_BLE_INQUIRY_MASK) != BTM_BLE_LIMITED_INQUIRY) {
  681. LOG(ERROR) << __func__ << ": illegal inquiry mode "
  682. << std::to_string(p_inqparms->mode);
  683. return (BTM_ILLEGAL_VALUE);
  684. }
  685. /* Save the inquiry parameters to be used upon the completion of
  686. * setting/clearing the inquiry filter */
  687. p_inq->inqparms = *p_inqparms;
  688. /* Initialize the inquiry variables */
  689. p_inq->state = BTM_INQ_ACTIVE_STATE;
  690. p_inq->p_inq_cmpl_cb = p_cmpl_cb;
  691. p_inq->p_inq_results_cb = p_results_cb;
  692. p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
  693. p_inq->inq_active = p_inqparms->mode;
  694. BTM_TRACE_DEBUG("BTM_StartInquiry: p_inq->inq_active = 0x%02x",
  695. p_inq->inq_active);
  696. tBTM_STATUS status = BTM_CMD_STARTED;
  697. /* start LE inquiry here if requested */
  698. if ((p_inqparms->mode & BTM_BLE_INQUIRY_MASK)) {
  699. if (!controller_get_interface()->supports_ble()) {
  700. LOG(ERROR) << __func__ << ": trying to do LE scan on a non-LE adapter";
  701. p_inq->inqparms.mode &= ~BTM_BLE_INQUIRY_MASK;
  702. status = BTM_ILLEGAL_VALUE;
  703. } else {
  704. /* BLE for now does not support filter condition for inquiry */
  705. status = btm_ble_start_inquiry(
  706. (uint8_t)(p_inqparms->mode & BTM_BLE_INQUIRY_MASK),
  707. p_inqparms->duration);
  708. if (status != BTM_CMD_STARTED) {
  709. LOG(ERROR) << __func__ << ": Error Starting LE Inquiry";
  710. p_inq->inqparms.mode &= ~BTM_BLE_INQUIRY_MASK;
  711. }
  712. }
  713. p_inqparms->mode &= ~BTM_BLE_INQUIRY_MASK;
  714. BTM_TRACE_DEBUG("BTM_StartInquiry: mode = %02x", p_inqparms->mode);
  715. }
  716. /* we're done with this routine if BR/EDR inquiry is not desired. */
  717. if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) == BTM_INQUIRY_NONE) {
  718. return status;
  719. }
  720. /* BR/EDR inquiry portion */
  721. /* If a filter is specified, then save it for later and clear the current
  722. filter.
  723. The setting of the filter is done upon completion of clearing of the
  724. previous
  725. filter.
  726. */
  727. switch (p_inqparms->filter_cond_type) {
  728. case BTM_CLR_INQUIRY_FILTER:
  729. p_inq->state = BTM_INQ_SET_FILT_STATE;
  730. break;
  731. case BTM_FILTER_COND_DEVICE_CLASS:
  732. case BTM_FILTER_COND_BD_ADDR:
  733. /* The filter is not being used so simply clear it;
  734. the inquiry can start after this operation */
  735. p_inq->state = BTM_INQ_CLR_FILT_STATE;
  736. p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;
  737. /* =============>>>> adding LE filtering here ????? */
  738. break;
  739. default:
  740. LOG(ERROR) << __func__ << ": invalid filter condition type "
  741. << std::to_string(p_inqparms->filter_cond_type);
  742. return (BTM_ILLEGAL_VALUE);
  743. }
  744. /* Before beginning the inquiry the current filter must be cleared, so
  745. * initiate the command */
  746. status = btm_set_inq_event_filter(p_inqparms->filter_cond_type,
  747. &p_inqparms->filter_cond);
  748. if (status != BTM_CMD_STARTED) {
  749. LOG(ERROR) << __func__ << ": failed to set inquiry event filter";
  750. p_inq->state = BTM_INQ_INACTIVE_STATE;
  751. }
  752. return (status);
  753. }
  754. /*******************************************************************************
  755. *
  756. * Function BTM_ReadRemoteDeviceName
  757. *
  758. * Description This function initiates a remote device HCI command to the
  759. * controller and calls the callback when the process has
  760. * completed.
  761. *
  762. * Input Params: remote_bda - device address of name to retrieve
  763. * p_cb - callback function called when
  764. * BTM_CMD_STARTED is returned.
  765. * A pointer to tBTM_REMOTE_DEV_NAME is
  766. * passed to the callback.
  767. *
  768. * Returns
  769. * BTM_CMD_STARTED is returned if the request was successfully
  770. * sent to HCI.
  771. * BTM_BUSY if already in progress
  772. * BTM_UNKNOWN_ADDR if device address is bad
  773. * BTM_NO_RESOURCES if could not allocate resources to start
  774. * the command
  775. * BTM_WRONG_MODE if the device is not up.
  776. *
  777. ******************************************************************************/
  778. tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
  779. tBTM_CMPL_CB* p_cb,
  780. tBT_TRANSPORT transport) {
  781. VLOG(1) << __func__ << ": bd addr " << remote_bda;
  782. /* Use LE transport when LE is the only available option */
  783. if (transport == BT_TRANSPORT_LE) {
  784. return btm_ble_read_remote_name(remote_bda, p_cb);
  785. }
  786. /* Use classic transport for BR/EDR and Dual Mode devices */
  787. return btm_initiate_rem_name(remote_bda, BTM_RMT_NAME_EXT,
  788. BTM_EXT_RMT_NAME_TIMEOUT_MS, p_cb);
  789. }
  790. /*******************************************************************************
  791. *
  792. * Function BTM_CancelRemoteDeviceName
  793. *
  794. * Description This function initiates the cancel request for the specified
  795. * remote device.
  796. *
  797. * Input Params: None
  798. *
  799. * Returns
  800. * BTM_CMD_STARTED is returned if the request was successfully
  801. * sent to HCI.
  802. * BTM_NO_RESOURCES if could not allocate resources to start
  803. * the command
  804. * BTM_WRONG_MODE if there is not an active remote name
  805. * request.
  806. *
  807. ******************************************************************************/
  808. tBTM_STATUS BTM_CancelRemoteDeviceName(void) {
  809. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  810. BTM_TRACE_API("BTM_CancelRemoteDeviceName()");
  811. /* Make sure there is not already one in progress */
  812. if (p_inq->remname_active) {
  813. if (BTM_UseLeLink(p_inq->remname_bda)) {
  814. if (btm_ble_cancel_remote_name(p_inq->remname_bda))
  815. return (BTM_CMD_STARTED);
  816. else
  817. return (BTM_UNKNOWN_ADDR);
  818. } else
  819. btsnd_hcic_rmt_name_req_cancel(p_inq->remname_bda);
  820. return (BTM_CMD_STARTED);
  821. } else
  822. return (BTM_WRONG_MODE);
  823. }
  824. /*******************************************************************************
  825. *
  826. * Function BTM_InqDbRead
  827. *
  828. * Description This function looks through the inquiry database for a match
  829. * based on Bluetooth Device Address. This is the application's
  830. * interface to get the inquiry details of a specific BD
  831. * address.
  832. *
  833. * Returns pointer to entry, or NULL if not found
  834. *
  835. ******************************************************************************/
  836. tBTM_INQ_INFO* BTM_InqDbRead(const RawAddress& p_bda) {
  837. VLOG(1) << __func__ << ": bd addr " << p_bda;
  838. tINQ_DB_ENT* p_ent = btm_inq_db_find(p_bda);
  839. if (!p_ent) return NULL;
  840. return &p_ent->inq_info;
  841. }
  842. /*******************************************************************************
  843. *
  844. * Function BTM_InqDbFirst
  845. *
  846. * Description This function looks through the inquiry database for the
  847. * first used entry, and returns that. This is used in
  848. * conjunction with
  849. * BTM_InqDbNext by applications as a way to walk through the
  850. * inquiry database.
  851. *
  852. * Returns pointer to first in-use entry, or NULL if DB is empty
  853. *
  854. ******************************************************************************/
  855. tBTM_INQ_INFO* BTM_InqDbFirst(void) {
  856. uint16_t xx;
  857. tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
  858. for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
  859. if (p_ent->in_use) return (&p_ent->inq_info);
  860. }
  861. /* If here, no used entry found */
  862. return ((tBTM_INQ_INFO*)NULL);
  863. }
  864. /*******************************************************************************
  865. *
  866. * Function BTM_InqDbNext
  867. *
  868. * Description This function looks through the inquiry database for the
  869. * next used entry, and returns that. If the input parameter
  870. * is NULL, the first entry is returned.
  871. *
  872. * Returns pointer to next in-use entry, or NULL if no more found.
  873. *
  874. ******************************************************************************/
  875. tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) {
  876. tINQ_DB_ENT* p_ent;
  877. uint16_t inx;
  878. if (p_cur) {
  879. p_ent = (tINQ_DB_ENT*)((uint8_t*)p_cur - offsetof(tINQ_DB_ENT, inq_info));
  880. inx = (uint16_t)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
  881. for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE;
  882. inx++, p_ent++) {
  883. if (p_ent->in_use) return (&p_ent->inq_info);
  884. }
  885. /* If here, more entries found */
  886. return ((tBTM_INQ_INFO*)NULL);
  887. } else
  888. return (BTM_InqDbFirst());
  889. }
  890. /*******************************************************************************
  891. *
  892. * Function BTM_ClearInqDb
  893. *
  894. * Description This function is called to clear out a device or all devices
  895. * from the inquiry database.
  896. *
  897. * Parameter p_bda - (input) BD_ADDR -> Address of device to clear
  898. * (NULL clears all entries)
  899. *
  900. * Returns BTM_BUSY if an inquiry, get remote name, or event filter
  901. * is active, otherwise BTM_SUCCESS
  902. *
  903. ******************************************************************************/
  904. tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda) {
  905. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  906. /* If an inquiry or remote name is in progress return busy */
  907. if (p_inq->inq_active != BTM_INQUIRY_INACTIVE || p_inq->inqfilt_active)
  908. return (BTM_BUSY);
  909. btm_clr_inq_db(p_bda);
  910. return (BTM_SUCCESS);
  911. }
  912. /*******************************************************************************
  913. *
  914. * Function BTM_ReadInquiryRspTxPower
  915. *
  916. * Description This command will read the inquiry Transmit Power level used
  917. * to transmit the FHS and EIR data packets. This can be used
  918. * directly in the Tx Power Level EIR data type.
  919. *
  920. * Returns BTM_SUCCESS if successful
  921. *
  922. ******************************************************************************/
  923. tBTM_STATUS BTM_ReadInquiryRspTxPower(tBTM_CMPL_CB* p_cb) {
  924. if (btm_cb.devcb.p_inq_tx_power_cmpl_cb) return (BTM_BUSY);
  925. btm_cb.devcb.p_inq_tx_power_cmpl_cb = p_cb;
  926. alarm_set_on_mloop(btm_cb.devcb.read_inq_tx_power_timer,
  927. BTM_INQ_REPLY_TIMEOUT_MS, btm_read_inq_tx_power_timeout,
  928. NULL);
  929. btsnd_hcic_read_inq_tx_power();
  930. return (BTM_CMD_STARTED);
  931. }
  932. /*******************************************************************************
  933. *******************************************************************************
  934. * **
  935. * BTM Internal Inquiry Functions **
  936. * **
  937. *******************************************************************************
  938. ******************************************************************************/
  939. /*******************************************************************************
  940. *
  941. * Function btm_inq_db_reset
  942. *
  943. * Description This function is called at at reset to clear the inquiry
  944. * database & pending callback.
  945. *
  946. * Returns void
  947. *
  948. ******************************************************************************/
  949. void btm_inq_db_reset(void) {
  950. tBTM_REMOTE_DEV_NAME rem_name;
  951. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  952. uint8_t num_responses;
  953. uint8_t temp_inq_active;
  954. tBTM_STATUS status;
  955. /* If an inquiry or periodic inquiry is active, reset the mode to inactive */
  956. if (p_inq->inq_active != BTM_INQUIRY_INACTIVE) {
  957. temp_inq_active = p_inq->inq_active; /* Save so state can change BEFORE
  958. callback is called */
  959. p_inq->inq_active = BTM_INQUIRY_INACTIVE;
  960. /* If not a periodic inquiry, the complete callback must be called to notify
  961. * caller */
  962. if (temp_inq_active == BTM_LIMITED_INQUIRY_ACTIVE ||
  963. temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE) {
  964. if (p_inq->p_inq_cmpl_cb) {
  965. num_responses = 0;
  966. (*p_inq->p_inq_cmpl_cb)(&num_responses);
  967. }
  968. }
  969. }
  970. /* Cancel a remote name request if active, and notify the caller (if waiting)
  971. */
  972. if (p_inq->remname_active) {
  973. alarm_cancel(p_inq->remote_name_timer);
  974. p_inq->remname_active = false;
  975. p_inq->remname_bda = RawAddress::kEmpty;
  976. if (p_inq->p_remname_cmpl_cb) {
  977. rem_name.status = BTM_DEV_RESET;
  978. (*p_inq->p_remname_cmpl_cb)(&rem_name);
  979. p_inq->p_remname_cmpl_cb = NULL;
  980. }
  981. }
  982. /* Cancel an inquiry filter request if active, and notify the caller (if
  983. * waiting) */
  984. if (p_inq->inqfilt_active) {
  985. p_inq->inqfilt_active = false;
  986. if (p_inq->p_inqfilter_cmpl_cb) {
  987. status = BTM_DEV_RESET;
  988. (*p_inq->p_inqfilter_cmpl_cb)(&status);
  989. }
  990. }
  991. p_inq->state = BTM_INQ_INACTIVE_STATE;
  992. p_inq->pending_filt_complete_event = 0;
  993. p_inq->p_inq_results_cb = NULL;
  994. btm_clr_inq_db(NULL); /* Clear out all the entries in the database */
  995. btm_clr_inq_result_flt();
  996. p_inq->discoverable_mode = BTM_NON_DISCOVERABLE;
  997. p_inq->connectable_mode = BTM_NON_CONNECTABLE;
  998. p_inq->page_scan_type = BTM_SCAN_TYPE_STANDARD;
  999. p_inq->inq_scan_type = BTM_SCAN_TYPE_STANDARD;
  1000. p_inq->discoverable_mode |= BTM_BLE_NON_DISCOVERABLE;
  1001. p_inq->connectable_mode |= BTM_BLE_NON_CONNECTABLE;
  1002. return;
  1003. }
  1004. /*******************************************************************************
  1005. *
  1006. * Function btm_inq_db_init
  1007. *
  1008. * Description This function is called at startup to initialize the inquiry
  1009. * database.
  1010. *
  1011. * Returns void
  1012. *
  1013. ******************************************************************************/
  1014. void btm_inq_db_init(void) {
  1015. alarm_free(btm_cb.btm_inq_vars.remote_name_timer);
  1016. btm_cb.btm_inq_vars.remote_name_timer =
  1017. alarm_new("btm_inq.remote_name_timer");
  1018. btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
  1019. }
  1020. /*******************************************************************************
  1021. *
  1022. * Function btm_inq_stop_on_ssp
  1023. *
  1024. * Description This function is called on incoming SSP
  1025. *
  1026. * Returns void
  1027. *
  1028. ******************************************************************************/
  1029. void btm_inq_stop_on_ssp(void) {
  1030. uint8_t normal_active =
  1031. (BTM_GENERAL_INQUIRY_ACTIVE | BTM_LIMITED_INQUIRY_ACTIVE);
  1032. #if (BTM_INQ_DEBUG == TRUE)
  1033. BTM_TRACE_DEBUG(
  1034. "btm_inq_stop_on_ssp: no_inc_ssp=%d inq_active:0x%x state:%d "
  1035. "inqfilt_active:%d",
  1036. btm_cb.btm_inq_vars.no_inc_ssp, btm_cb.btm_inq_vars.inq_active,
  1037. btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
  1038. #endif
  1039. if (btm_cb.btm_inq_vars.no_inc_ssp) {
  1040. if (btm_cb.btm_inq_vars.state == BTM_INQ_ACTIVE_STATE) {
  1041. if (btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) {
  1042. BTM_CancelPeriodicInquiry();
  1043. } else if (btm_cb.btm_inq_vars.inq_active & normal_active) {
  1044. /* can not call BTM_CancelInquiry() here. We need to report inquiry
  1045. * complete evt */
  1046. btsnd_hcic_inq_cancel();
  1047. }
  1048. }
  1049. /* do not allow inquiry to start */
  1050. btm_cb.btm_inq_vars.inq_active |= BTM_SSP_INQUIRY_ACTIVE;
  1051. }
  1052. }
  1053. /*******************************************************************************
  1054. *
  1055. * Function btm_inq_clear_ssp
  1056. *
  1057. * Description This function is called when pairing_state becomes idle
  1058. *
  1059. * Returns void
  1060. *
  1061. ******************************************************************************/
  1062. void btm_inq_clear_ssp(void) {
  1063. btm_cb.btm_inq_vars.inq_active &= ~BTM_SSP_INQUIRY_ACTIVE;
  1064. }
  1065. /*******************************************************************************
  1066. *
  1067. * Function btm_clr_inq_db
  1068. *
  1069. * Description This function is called to clear out a device or all devices
  1070. * from the inquiry database.
  1071. *
  1072. * Parameter p_bda - (input) BD_ADDR -> Address of device to clear
  1073. * (NULL clears all entries)
  1074. *
  1075. * Returns void
  1076. *
  1077. ******************************************************************************/
  1078. void btm_clr_inq_db(const RawAddress* p_bda) {
  1079. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  1080. tINQ_DB_ENT* p_ent = p_inq->inq_db;
  1081. uint16_t xx;
  1082. #if (BTM_INQ_DEBUG == TRUE)
  1083. BTM_TRACE_DEBUG("btm_clr_inq_db: inq_active:0x%x state:%d",
  1084. btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
  1085. #endif
  1086. for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
  1087. if (p_ent->in_use) {
  1088. /* If this is the specified BD_ADDR or clearing all devices */
  1089. if (p_bda == NULL || (p_ent->inq_info.results.remote_bd_addr == *p_bda)) {
  1090. p_ent->in_use = false;
  1091. }
  1092. }
  1093. }
  1094. #if (BTM_INQ_DEBUG == TRUE)
  1095. BTM_TRACE_DEBUG("inq_active:0x%x state:%d", btm_cb.btm_inq_vars.inq_active,
  1096. btm_cb.btm_inq_vars.state);
  1097. #endif
  1098. }
  1099. /*******************************************************************************
  1100. *
  1101. * Function btm_clr_inq_result_flt
  1102. *
  1103. * Description This function looks through the bdaddr database for a match
  1104. * based on Bluetooth Device Address
  1105. *
  1106. * Returns true if found, else false (new entry)
  1107. *
  1108. ******************************************************************************/
  1109. static void btm_clr_inq_result_flt(void) {
  1110. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  1111. osi_free_and_reset((void**)&p_inq->p_bd_db);
  1112. p_inq->num_bd_entries = 0;
  1113. p_inq->max_bd_entries = 0;
  1114. }
  1115. /*******************************************************************************
  1116. *
  1117. * Function btm_inq_find_bdaddr
  1118. *
  1119. * Description This function looks through the bdaddr database for a match
  1120. * based on Bluetooth Device Address
  1121. *
  1122. * Returns true if found, else false (new entry)
  1123. *
  1124. ******************************************************************************/
  1125. bool btm_inq_find_bdaddr(const RawAddress& p_bda) {
  1126. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  1127. tINQ_BDADDR* p_db = &p_inq->p_bd_db[0];
  1128. uint16_t xx;
  1129. /* Don't bother searching, database doesn't exist or periodic mode */
  1130. if ((p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) || !p_db)
  1131. return (false);
  1132. for (xx = 0; xx < p_inq->num_bd_entries; xx++, p_db++) {
  1133. if (p_db->bd_addr == p_bda && p_db->inq_count == p_inq->inq_counter)
  1134. return (true);
  1135. }
  1136. if (xx < p_inq->max_bd_entries) {
  1137. p_db->inq_count = p_inq->inq_counter;
  1138. p_db->bd_addr = p_bda;
  1139. p_inq->num_bd_entries++;
  1140. }
  1141. /* If here, New Entry */
  1142. return (false);
  1143. }
  1144. /*******************************************************************************
  1145. *
  1146. * Function btm_inq_db_find
  1147. *
  1148. * Description This function looks through the inquiry database for a match
  1149. * based on Bluetooth Device Address
  1150. *
  1151. * Returns pointer to entry, or NULL if not found
  1152. *
  1153. ******************************************************************************/
  1154. tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda) {
  1155. uint16_t xx;
  1156. tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
  1157. for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
  1158. if (p_ent->in_use && p_ent->inq_info.results.remote_bd_addr == p_bda)
  1159. return (p_ent);
  1160. }
  1161. /* If here, not found */
  1162. return (NULL);
  1163. }
  1164. /*******************************************************************************
  1165. *
  1166. * Function btm_inq_db_new
  1167. *
  1168. * Description This function looks through the inquiry database for an
  1169. * unused entry. If no entry is free, it allocates the oldest
  1170. * entry.
  1171. *
  1172. * Returns pointer to entry
  1173. *
  1174. ******************************************************************************/
  1175. tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda) {
  1176. uint16_t xx;
  1177. tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
  1178. tINQ_DB_ENT* p_old = btm_cb.btm_inq_vars.inq_db;
  1179. uint64_t ot = UINT64_MAX;
  1180. for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
  1181. if (!p_ent->in_use) {
  1182. memset(p_ent, 0, sizeof(tINQ_DB_ENT));
  1183. p_ent->inq_info.results.remote_bd_addr = p_bda;
  1184. p_ent->in_use = true;
  1185. return (p_ent);
  1186. }
  1187. if (p_ent->time_of_resp < ot) {
  1188. p_old = p_ent;
  1189. ot = p_ent->time_of_resp;
  1190. }
  1191. }
  1192. /* If here, no free entry found. Return the oldest. */
  1193. memset(p_old, 0, sizeof(tINQ_DB_ENT));
  1194. p_old->inq_info.results.remote_bd_addr = p_bda;
  1195. p_old->in_use = true;
  1196. return (p_old);
  1197. }
  1198. /*******************************************************************************
  1199. *
  1200. * Function btm_set_inq_event_filter
  1201. *
  1202. * Description This function is called to set the inquiry event filter.
  1203. * It is called by either internally, or by the external API
  1204. * function (BTM_SetInqEventFilter). It is used internally as
  1205. * part of the inquiry processing.
  1206. *
  1207. * Input Params:
  1208. * filter_cond_type - this is the type of inquiry filter to
  1209. * apply:
  1210. * BTM_FILTER_COND_DEVICE_CLASS,
  1211. * BTM_FILTER_COND_BD_ADDR, or
  1212. * BTM_CLR_INQUIRY_FILTER
  1213. *
  1214. * p_filt_cond - this is either a BD_ADDR or DEV_CLASS
  1215. * depending on the filter_cond_type
  1216. * (See section 4.7.3 of Core Spec 1.0b).
  1217. *
  1218. * Returns BTM_CMD_STARTED if successfully initiated
  1219. * BTM_NO_RESOURCES if couldn't get a memory pool buffer
  1220. * BTM_ILLEGAL_VALUE if a bad parameter was detected
  1221. *
  1222. ******************************************************************************/
  1223. static tBTM_STATUS btm_set_inq_event_filter(uint8_t filter_cond_type,
  1224. tBTM_INQ_FILT_COND* p_filt_cond) {
  1225. uint8_t condition_length = DEV_CLASS_LEN * 2;
  1226. uint8_t condition_buf[DEV_CLASS_LEN * 2];
  1227. uint8_t* p_cond = condition_buf; /* points to the condition to pass to HCI */
  1228. #if (BTM_INQ_DEBUG == TRUE)
  1229. BTM_TRACE_DEBUG(
  1230. "btm_set_inq_event_filter: filter type %d [Clear-0, COD-1, BDADDR-2]",
  1231. filter_cond_type);
  1232. VLOG(2) << "condition " << p_filt_cond->bdaddr_cond;
  1233. #endif
  1234. /* Load the correct filter condition to pass to the lower layer */
  1235. switch (filter_cond_type) {
  1236. case BTM_FILTER_COND_DEVICE_CLASS:
  1237. /* copy the device class and device class fields into contiguous memory to
  1238. * send to HCI */
  1239. memcpy(condition_buf, p_filt_cond->cod_cond.dev_class, DEV_CLASS_LEN);
  1240. memcpy(&condition_buf[DEV_CLASS_LEN],
  1241. p_filt_cond->cod_cond.dev_class_mask, DEV_CLASS_LEN);
  1242. /* condition length should already be set as the default */
  1243. break;
  1244. case BTM_FILTER_COND_BD_ADDR:
  1245. p_cond = (uint8_t*)&p_filt_cond->bdaddr_cond;
  1246. /* condition length should already be set as the default */
  1247. break;
  1248. case BTM_CLR_INQUIRY_FILTER:
  1249. condition_length = 0;
  1250. break;
  1251. default:
  1252. return (BTM_ILLEGAL_VALUE); /* Bad parameter was passed in */
  1253. }
  1254. btm_cb.btm_inq_vars.inqfilt_active = true;
  1255. /* Filter the inquiry results for the specified condition type and value */
  1256. btsnd_hcic_set_event_filter(HCI_FILTER_INQUIRY_RESULT, filter_cond_type,
  1257. p_cond, condition_length);
  1258. return (BTM_CMD_STARTED);
  1259. }
  1260. /*******************************************************************************
  1261. *
  1262. * Function btm_event_filter_complete
  1263. *
  1264. * Description This function is called when a set event filter has
  1265. * completed.
  1266. * Note: This routine currently only handles inquiry filters.
  1267. * Connection filters are ignored for now.
  1268. *
  1269. * Returns void
  1270. *
  1271. ******************************************************************************/
  1272. void btm_event_filter_complete(uint8_t* p) {
  1273. uint8_t hci_status;
  1274. tBTM_STATUS status;
  1275. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  1276. tBTM_CMPL_CB* p_cb = p_inq->p_inqfilter_cmpl_cb;
  1277. #if (BTM_INQ_DEBUG == TRUE)
  1278. BTM_TRACE_DEBUG(
  1279. "btm_event_filter_complete: inq_active:0x%x state:%d inqfilt_active:%d",
  1280. btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
  1281. btm_cb.btm_inq_vars.inqfilt_active);
  1282. #endif
  1283. /* If the filter complete event is from an old or cancelled request, ignore it
  1284. */
  1285. if (p_inq->pending_filt_complete_event) {
  1286. p_inq->pending_filt_complete_event--;
  1287. return;
  1288. }
  1289. /* Only process the inquiry filter; Ignore the connection filter until it
  1290. is used by the upper layers */
  1291. if (p_inq->inqfilt_active) {
  1292. /* Extract the returned status from the buffer */
  1293. STREAM_TO_UINT8(hci_status, p);
  1294. if (hci_status != HCI_SUCCESS) {
  1295. /* If standalone operation, return the error status; if embedded in the
  1296. * inquiry, continue the inquiry */
  1297. BTM_TRACE_WARNING(
  1298. "BTM Warning: Set Event Filter Failed (HCI returned 0x%x)",
  1299. hci_status);
  1300. status = BTM_ERR_PROCESSING;
  1301. } else
  1302. status = BTM_SUCCESS;
  1303. /* If the set filter was initiated externally (via BTM_SetInqEventFilter),
  1304. call the
  1305. callback function to notify the initiator that it has completed */
  1306. if (p_inq->state == BTM_INQ_INACTIVE_STATE) {
  1307. p_inq->inqfilt_active = false;
  1308. if (p_cb) (*p_cb)(&status);
  1309. } else /* An inquiry is active (the set filter command was internally
  1310. generated),
  1311. process the next state of the process (Set a new filter or start
  1312. the inquiry). */
  1313. {
  1314. if (status != BTM_SUCCESS) {
  1315. /* Process the inquiry complete (Error Status) */
  1316. btm_process_inq_complete(
  1317. BTM_ERR_PROCESSING,
  1318. (uint8_t)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
  1319. /* btm_process_inq_complete() does not restore the following settings on
  1320. * periodic inquiry */
  1321. p_inq->inqfilt_active = false;
  1322. p_inq->inq_active = BTM_INQUIRY_INACTIVE;
  1323. p_inq->state = BTM_INQ_INACTIVE_STATE;
  1324. return;
  1325. }
  1326. /* Check to see if a new filter needs to be set up */
  1327. if (p_inq->state == BTM_INQ_CLR_FILT_STATE) {
  1328. status = btm_set_inq_event_filter(p_inq->inqparms.filter_cond_type,
  1329. &p_inq->inqparms.filter_cond);
  1330. if (status == BTM_CMD_STARTED) {
  1331. p_inq->state = BTM_INQ_SET_FILT_STATE;
  1332. } else /* Error setting the filter: Call the initiator's callback
  1333. function to indicate a failure */
  1334. {
  1335. p_inq->inqfilt_active = false;
  1336. /* Process the inquiry complete (Error Status) */
  1337. btm_process_inq_complete(
  1338. BTM_ERR_PROCESSING,
  1339. (uint8_t)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
  1340. }
  1341. } else /* Initiate the Inquiry or Periodic Inquiry */
  1342. {
  1343. p_inq->state = BTM_INQ_ACTIVE_STATE;
  1344. p_inq->inqfilt_active = false;
  1345. btm_initiate_inquiry(p_inq);
  1346. }
  1347. }
  1348. }
  1349. }
  1350. /*******************************************************************************
  1351. *
  1352. * Function btm_initiate_inquiry
  1353. *
  1354. * Description This function is called to start an inquiry or periodic
  1355. * inquiry upon completion of the setting and/or clearing of
  1356. * the inquiry filter.
  1357. *
  1358. * Inputs: p_inq (btm_cb.btm_inq_vars) - pointer to saved inquiry
  1359. * information
  1360. * mode - GENERAL or LIMITED inquiry
  1361. * duration - length in 1.28 sec intervals
  1362. * (If '0', the inquiry is CANCELLED)
  1363. * max_resps - maximum amount of devices to search for
  1364. * before ending the inquiry
  1365. * filter_cond_type - BTM_CLR_INQUIRY_FILTER,
  1366. * BTM_FILTER_COND_DEVICE_CLASS, or
  1367. * BTM_FILTER_COND_BD_ADDR
  1368. * filter_cond - value for the filter
  1369. * (based on filter_cond_type)
  1370. *
  1371. * Returns If an error occurs the initiator's callback is called with
  1372. * the error status.
  1373. *
  1374. ******************************************************************************/
  1375. static void btm_initiate_inquiry(tBTM_INQUIRY_VAR_ST* p_inq) {
  1376. const LAP* lap;
  1377. tBTM_INQ_PARMS* p_inqparms = &p_inq->inqparms;
  1378. #if (BTM_INQ_DEBUG == TRUE)
  1379. BTM_TRACE_DEBUG(
  1380. "btm_initiate_inquiry: inq_active:0x%x state:%d inqfilt_active:%d",
  1381. btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
  1382. btm_cb.btm_inq_vars.inqfilt_active);
  1383. #endif
  1384. btm_acl_update_busy_level(BTM_BLI_INQ_EVT);
  1385. if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE) {
  1386. btm_process_inq_complete(BTM_NO_RESOURCES,
  1387. (uint8_t)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
  1388. return;
  1389. }
  1390. /* Make sure the number of responses doesn't overflow the database
  1391. * configuration */
  1392. p_inqparms->max_resps = (uint8_t)((p_inqparms->max_resps <= BTM_INQ_DB_SIZE)
  1393. ? p_inqparms->max_resps
  1394. : BTM_INQ_DB_SIZE);
  1395. lap = (p_inq->inq_active & BTM_LIMITED_INQUIRY_ACTIVE) ? &limited_inq_lap
  1396. : &general_inq_lap;
  1397. if (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) {
  1398. btsnd_hcic_per_inq_mode(p_inq->per_max_delay, p_inq->per_min_delay, *lap,
  1399. p_inqparms->duration, p_inqparms->max_resps);
  1400. } else {
  1401. btm_clr_inq_result_flt();
  1402. /* Allocate memory to hold bd_addrs responding */
  1403. p_inq->p_bd_db = (tINQ_BDADDR*)osi_calloc(BT_DEFAULT_BUFFER_SIZE);
  1404. p_inq->max_bd_entries =
  1405. (uint16_t)(BT_DEFAULT_BUFFER_SIZE / sizeof(tINQ_BDADDR));
  1406. btsnd_hcic_inquiry(*lap, p_inqparms->duration, 0);
  1407. }
  1408. }
  1409. /*******************************************************************************
  1410. *
  1411. * Function btm_process_inq_results
  1412. *
  1413. * Description This function is called when inquiry results are received
  1414. * from the device. It updates the inquiry database. If the
  1415. * inquiry database is full, the oldest entry is discarded.
  1416. *
  1417. * Parameters inq_res_mode - BTM_INQ_RESULT_STANDARD
  1418. * BTM_INQ_RESULT_WITH_RSSI
  1419. * BTM_INQ_RESULT_EXTENDED
  1420. *
  1421. * Returns void
  1422. *
  1423. ******************************************************************************/
  1424. void btm_process_inq_results(uint8_t* p, uint8_t hci_evt_len,
  1425. uint8_t inq_res_mode) {
  1426. uint8_t num_resp, xx;
  1427. RawAddress bda;
  1428. tINQ_DB_ENT* p_i;
  1429. tBTM_INQ_RESULTS* p_cur = NULL;
  1430. bool is_new = true;
  1431. bool update = false;
  1432. int8_t i_rssi;
  1433. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  1434. tBTM_INQ_RESULTS_CB* p_inq_results_cb = p_inq->p_inq_results_cb;
  1435. uint8_t page_scan_rep_mode = 0;
  1436. uint8_t page_scan_per_mode = 0;
  1437. uint8_t page_scan_mode = 0;
  1438. uint8_t rssi = 0;
  1439. DEV_CLASS dc;
  1440. uint16_t clock_offset;
  1441. uint8_t* p_eir_data = NULL;
  1442. #if (BTM_INQ_DEBUG == TRUE)
  1443. BTM_TRACE_DEBUG(
  1444. "btm_process_inq_results inq_active:0x%x state:%d inqfilt_active:%d",
  1445. btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
  1446. btm_cb.btm_inq_vars.inqfilt_active);
  1447. #endif
  1448. /* Only process the results if the BR inquiry is still active */
  1449. if (!(p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK)) return;
  1450. STREAM_TO_UINT8(num_resp, p);
  1451. if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
  1452. if (num_resp > 1) {
  1453. BTM_TRACE_ERROR("btm_process_inq_results() extended results (%d) > 1",
  1454. num_resp);
  1455. return;
  1456. }
  1457. constexpr uint16_t extended_inquiry_result_size = 254;
  1458. if (hci_evt_len - 1 != extended_inquiry_result_size) {
  1459. android_errorWriteLog(0x534e4554, "141620271");
  1460. BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
  1461. num_resp, hci_evt_len);
  1462. return;
  1463. }
  1464. } else if (inq_res_mode == BTM_INQ_RESULT_STANDARD ||
  1465. inq_res_mode == BTM_INQ_RESULT_WITH_RSSI) {
  1466. constexpr uint16_t inquiry_result_size = 14;
  1467. if (hci_evt_len < num_resp * inquiry_result_size) {
  1468. android_errorWriteLog(0x534e4554, "141620271");
  1469. BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
  1470. num_resp, hci_evt_len);
  1471. return;
  1472. }
  1473. }
  1474. for (xx = 0; xx < num_resp; xx++) {
  1475. update = false;
  1476. /* Extract inquiry results */
  1477. STREAM_TO_BDADDR(bda, p);
  1478. STREAM_TO_UINT8(page_scan_rep_mode, p);
  1479. STREAM_TO_UINT8(page_scan_per_mode, p);
  1480. if (inq_res_mode == BTM_INQ_RESULT_STANDARD) {
  1481. STREAM_TO_UINT8(page_scan_mode, p);
  1482. }
  1483. STREAM_TO_DEVCLASS(dc, p);
  1484. STREAM_TO_UINT16(clock_offset, p);
  1485. if (inq_res_mode != BTM_INQ_RESULT_STANDARD) {
  1486. STREAM_TO_UINT8(rssi, p);
  1487. }
  1488. p_i = btm_inq_db_find(bda);
  1489. /* Only process the num_resp is smaller than max_resps.
  1490. If results are queued to BTU task while canceling inquiry,
  1491. or when more than one result is in this response, > max_resp
  1492. responses could be processed which can confuse some apps
  1493. */
  1494. if (p_inq->inqparms.max_resps &&
  1495. p_inq->inq_cmpl_info.num_resp >= p_inq->inqparms.max_resps
  1496. /* new device response */
  1497. &&
  1498. (p_i == NULL ||
  1499. /* exisiting device with BR/EDR info */
  1500. (p_i &&
  1501. (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0))) {
  1502. /* BTM_TRACE_WARNING("INQ RES: Extra Response Received...ignoring"); */
  1503. return;
  1504. }
  1505. /* Check if this address has already been processed for this inquiry */
  1506. if (btm_inq_find_bdaddr(bda)) {
  1507. /* BTM_TRACE_DEBUG("BDA seen before [%02x%02x %02x%02x %02x%02x]",
  1508. bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);*/
  1509. /* By default suppose no update needed */
  1510. i_rssi = (int8_t)rssi;
  1511. /* If this new RSSI is higher than the last one */
  1512. if (p_inq->inqparms.report_dup && (rssi != 0) && p_i &&
  1513. (i_rssi > p_i->inq_info.results.rssi ||
  1514. p_i->inq_info.results.rssi == 0
  1515. /* BR/EDR inquiry information update */
  1516. ||
  1517. (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)) {
  1518. p_cur = &p_i->inq_info.results;
  1519. BTM_TRACE_DEBUG("update RSSI new:%d, old:%d", i_rssi, p_cur->rssi);
  1520. p_cur->rssi = i_rssi;
  1521. update = true;
  1522. }
  1523. /* If we received a second Extended Inq Event for an already */
  1524. /* discovered device, this is because for the first one EIR was not
  1525. received */
  1526. else if ((inq_res_mode == BTM_INQ_RESULT_EXTENDED) && (p_i)) {
  1527. p_cur = &p_i->inq_info.results;
  1528. update = true;
  1529. }
  1530. /* If no update needed continue with next response (if any) */
  1531. else
  1532. continue;
  1533. }
  1534. /* If existing entry, use that, else get a new one (possibly reusing the
  1535. * oldest) */
  1536. if (p_i == NULL) {
  1537. p_i = btm_inq_db_new(bda);
  1538. is_new = true;
  1539. }
  1540. /* If an entry for the device already exists, overwrite it ONLY if it is
  1541. from
  1542. a previous inquiry. (Ignore it if it is a duplicate response from the
  1543. same
  1544. inquiry.
  1545. */
  1546. else if (p_i->inq_count == p_inq->inq_counter &&
  1547. (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR))
  1548. is_new = false;
  1549. /* keep updating RSSI to have latest value */
  1550. if (inq_res_mode != BTM_INQ_RESULT_STANDARD)
  1551. p_i->inq_info.results.rssi = (int8_t)rssi;
  1552. else
  1553. p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI;
  1554. if (is_new) {
  1555. /* Save the info */
  1556. p_cur = &p_i->inq_info.results;
  1557. p_cur->page_scan_rep_mode = page_scan_rep_mode;
  1558. p_cur->page_scan_per_mode = page_scan_per_mode;
  1559. p_cur->page_scan_mode = page_scan_mode;
  1560. p_cur->dev_class[0] = dc[0];
  1561. p_cur->dev_class[1] = dc[1];
  1562. p_cur->dev_class[2] = dc[2];
  1563. p_cur->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
  1564. p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms();
  1565. if (p_i->inq_count != p_inq->inq_counter)
  1566. p_inq->inq_cmpl_info.num_resp++; /* A new response was found */
  1567. p_cur->inq_result_type = BTM_INQ_RESULT_BR;
  1568. if (p_i->inq_count != p_inq->inq_counter) {
  1569. p_cur->device_type = BT_DEVICE_TYPE_BREDR;
  1570. p_i->scan_rsp = false;
  1571. } else
  1572. p_cur->device_type |= BT_DEVICE_TYPE_BREDR;
  1573. p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */
  1574. /* If the number of responses found and not unlimited, issue a cancel
  1575. * inquiry */
  1576. if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) &&
  1577. p_inq->inqparms.max_resps &&
  1578. p_inq->inq_cmpl_info.num_resp == p_inq->inqparms.max_resps &&
  1579. /* BLE scanning is active and received adv */
  1580. ((((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) &&
  1581. p_cur->device_type == BT_DEVICE_TYPE_DUMO && p_i->scan_rsp) ||
  1582. (p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) == 0)) {
  1583. /* BTM_TRACE_DEBUG("BTMINQ: Found devices, cancelling
  1584. * inquiry..."); */
  1585. btsnd_hcic_inq_cancel();
  1586. if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
  1587. btm_ble_stop_inquiry();
  1588. btm_acl_update_busy_level(BTM_BLI_INQ_DONE_EVT);
  1589. }
  1590. /* Initialize flag to false. This flag is set/used by application */
  1591. p_i->inq_info.appl_knows_rem_name = false;
  1592. }
  1593. if (is_new || update) {
  1594. if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
  1595. memset(p_cur->eir_uuid, 0,
  1596. BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS / 8));
  1597. /* set bit map of UUID list from received EIR */
  1598. btm_set_eir_uuid(p, p_cur);
  1599. p_eir_data = p;
  1600. } else
  1601. p_eir_data = NULL;
  1602. /* If a callback is registered, call it with the results */
  1603. if (p_inq_results_cb)
  1604. (p_inq_results_cb)((tBTM_INQ_RESULTS*)p_cur, p_eir_data,
  1605. HCI_EXT_INQ_RESPONSE_LEN);
  1606. }
  1607. }
  1608. }
  1609. /*******************************************************************************
  1610. *
  1611. * Function btm_sort_inq_result
  1612. *
  1613. * Description This function is called when inquiry complete is received
  1614. * from the device to sort inquiry results based on rssi.
  1615. *
  1616. * Returns void
  1617. *
  1618. ******************************************************************************/
  1619. void btm_sort_inq_result(void) {
  1620. uint8_t xx, yy, num_resp;
  1621. tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
  1622. tINQ_DB_ENT* p_next = btm_cb.btm_inq_vars.inq_db + 1;
  1623. int size;
  1624. tINQ_DB_ENT* p_tmp = (tINQ_DB_ENT*)osi_malloc(sizeof(tINQ_DB_ENT));
  1625. num_resp = (btm_cb.btm_inq_vars.inq_cmpl_info.num_resp < BTM_INQ_DB_SIZE)
  1626. ? btm_cb.btm_inq_vars.inq_cmpl_info.num_resp
  1627. : BTM_INQ_DB_SIZE;
  1628. size = sizeof(tINQ_DB_ENT);
  1629. for (xx = 0; xx < num_resp - 1; xx++, p_ent++) {
  1630. for (yy = xx + 1, p_next = p_ent + 1; yy < num_resp; yy++, p_next++) {
  1631. if (p_ent->inq_info.results.rssi < p_next->inq_info.results.rssi) {
  1632. memcpy(p_tmp, p_next, size);
  1633. memcpy(p_next, p_ent, size);
  1634. memcpy(p_ent, p_tmp, size);
  1635. }
  1636. }
  1637. }
  1638. osi_free(p_tmp);
  1639. }
  1640. /*******************************************************************************
  1641. *
  1642. * Function btm_process_inq_complete
  1643. *
  1644. * Description This function is called when inquiry complete is received
  1645. * from the device. Call the callback if not in periodic
  1646. * inquiry mode AND it is not NULL
  1647. * (The caller wants the event).
  1648. *
  1649. * The callback pass back the status and the number of
  1650. * responses
  1651. *
  1652. * Returns void
  1653. *
  1654. ******************************************************************************/
  1655. void btm_process_inq_complete(uint8_t status, uint8_t mode) {
  1656. tBTM_CMPL_CB* p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb;
  1657. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  1658. p_inq->inqparms.mode &= ~(mode);
  1659. if (p_inq->scan_type == INQ_LE_OBSERVE && !p_inq->inq_active) {
  1660. /*end of LE observe*/
  1661. p_inq->p_inq_ble_results_cb = NULL;
  1662. p_inq->p_inq_ble_cmpl_cb = NULL;
  1663. p_inq->scan_type = INQ_NONE;
  1664. }
  1665. #if (BTM_INQ_DEBUG == TRUE)
  1666. BTM_TRACE_DEBUG(
  1667. "btm_process_inq_complete inq_active:0x%x state:%d inqfilt_active:%d",
  1668. btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
  1669. btm_cb.btm_inq_vars.inqfilt_active);
  1670. #endif
  1671. btm_acl_update_busy_level(BTM_BLI_INQ_DONE_EVT);
  1672. /* Ignore any stray or late complete messages if the inquiry is not active */
  1673. if (p_inq->inq_active) {
  1674. p_inq->inq_cmpl_info.status = (tBTM_STATUS)(
  1675. (status == HCI_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING);
  1676. /* Notify caller that the inquiry has completed; (periodic inquiries do not
  1677. * send completion events */
  1678. if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) &&
  1679. p_inq->inqparms.mode == 0) {
  1680. btm_clear_all_pending_le_entry();
  1681. p_inq->state = BTM_INQ_INACTIVE_STATE;
  1682. /* Increment so the start of a next inquiry has a new count */
  1683. p_inq->inq_counter++;
  1684. btm_clr_inq_result_flt();
  1685. if ((p_inq->inq_cmpl_info.status == BTM_SUCCESS) &&
  1686. controller_get_interface()->supports_rssi_with_inquiry_results()) {
  1687. btm_sort_inq_result();
  1688. }
  1689. /* Clear the results callback if set */
  1690. p_inq->p_inq_results_cb = NULL;
  1691. p_inq->inq_active = BTM_INQUIRY_INACTIVE;
  1692. p_inq->p_inq_cmpl_cb = NULL;
  1693. /* If we have a callback registered for inquiry complete, call it */
  1694. BTM_TRACE_DEBUG("BTM Inq Compl Callback: status 0x%02x, num results %d",
  1695. p_inq->inq_cmpl_info.status,
  1696. p_inq->inq_cmpl_info.num_resp);
  1697. if (p_inq_cb) (p_inq_cb)((tBTM_INQUIRY_CMPL*)&p_inq->inq_cmpl_info);
  1698. }
  1699. }
  1700. if (p_inq->inqparms.mode == 0 &&
  1701. p_inq->scan_type == INQ_GENERAL) // this inquiry is complete
  1702. {
  1703. p_inq->scan_type = INQ_NONE;
  1704. /* check if the LE observe is pending */
  1705. if (p_inq->p_inq_ble_results_cb != NULL) {
  1706. BTM_TRACE_DEBUG("BTM Inq Compl: resuming a pending LE scan");
  1707. BTM_BleObserve(1, 0, p_inq->p_inq_ble_results_cb,
  1708. p_inq->p_inq_ble_cmpl_cb);
  1709. }
  1710. }
  1711. #if (BTM_INQ_DEBUG == TRUE)
  1712. BTM_TRACE_DEBUG("inq_active:0x%x state:%d inqfilt_active:%d",
  1713. btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
  1714. btm_cb.btm_inq_vars.inqfilt_active);
  1715. #endif
  1716. }
  1717. /*******************************************************************************
  1718. *
  1719. * Function btm_process_cancel_complete
  1720. *
  1721. * Description This function is called when inquiry cancel complete is
  1722. * received from the device. This function will also call the
  1723. * btm_process_inq_complete. This function is needed to
  1724. * differentiate a cancel_cmpl_evt from the inq_cmpl_evt.
  1725. *
  1726. * Returns void
  1727. *
  1728. ******************************************************************************/
  1729. void btm_process_cancel_complete(uint8_t status, uint8_t mode) {
  1730. btm_acl_update_busy_level(BTM_BLI_INQ_CANCEL_EVT);
  1731. btm_process_inq_complete(status, mode);
  1732. }
  1733. /*******************************************************************************
  1734. *
  1735. * Function btm_initiate_rem_name
  1736. *
  1737. * Description This function looks initiates a remote name request. It is
  1738. * called either by GAP or by the API call
  1739. * BTM_ReadRemoteDeviceName.
  1740. *
  1741. * Input Params: p_cb - callback function called when
  1742. * BTM_CMD_STARTED is returned.
  1743. * A pointer to tBTM_REMOTE_DEV_NAME is
  1744. * passed to the callback.
  1745. *
  1746. * Returns
  1747. * BTM_CMD_STARTED is returned if the request was sent to HCI.
  1748. * BTM_BUSY if already in progress
  1749. * BTM_NO_RESOURCES if could not allocate resources to start
  1750. * the command
  1751. * BTM_WRONG_MODE if the device is not up.
  1752. *
  1753. ******************************************************************************/
  1754. tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
  1755. uint64_t timeout_ms, tBTM_CMPL_CB* p_cb) {
  1756. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  1757. /*** Make sure the device is ready ***/
  1758. if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
  1759. if (origin == BTM_RMT_NAME_SEC) {
  1760. btsnd_hcic_rmt_name_req(remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
  1761. HCI_MANDATARY_PAGE_SCAN_MODE, 0);
  1762. return BTM_CMD_STARTED;
  1763. }
  1764. /* Make sure there are no two remote name requests from external API in
  1765. progress */
  1766. else if (origin == BTM_RMT_NAME_EXT) {
  1767. if (p_inq->remname_active) {
  1768. return (BTM_BUSY);
  1769. } else {
  1770. /* If there is no remote name request running,call the callback function
  1771. * and start timer */
  1772. p_inq->p_remname_cmpl_cb = p_cb;
  1773. p_inq->remname_bda = remote_bda;
  1774. alarm_set_on_mloop(p_inq->remote_name_timer, timeout_ms,
  1775. btm_inq_remote_name_timer_timeout, NULL);
  1776. /* If the database entry exists for the device, use its clock offset */
  1777. tINQ_DB_ENT* p_i = btm_inq_db_find(remote_bda);
  1778. if (p_i) {
  1779. tBTM_INQ_INFO* p_cur = &p_i->inq_info;
  1780. btsnd_hcic_rmt_name_req(
  1781. remote_bda, p_cur->results.page_scan_rep_mode,
  1782. p_cur->results.page_scan_mode,
  1783. (uint16_t)(p_cur->results.clock_offset | BTM_CLOCK_OFFSET_VALID));
  1784. } else {
  1785. /* Otherwise use defaults and mark the clock offset as invalid */
  1786. btsnd_hcic_rmt_name_req(remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
  1787. HCI_MANDATARY_PAGE_SCAN_MODE, 0);
  1788. }
  1789. p_inq->remname_active = true;
  1790. return BTM_CMD_STARTED;
  1791. }
  1792. } else {
  1793. return BTM_ILLEGAL_VALUE;
  1794. }
  1795. }
  1796. /*******************************************************************************
  1797. *
  1798. * Function btm_process_remote_name
  1799. *
  1800. * Description This function is called when a remote name is received from
  1801. * the device. If remote names are cached, it updates the
  1802. * inquiry database.
  1803. *
  1804. * Returns void
  1805. *
  1806. ******************************************************************************/
  1807. void btm_process_remote_name(const RawAddress* bda, BD_NAME bdn,
  1808. uint16_t evt_len, uint8_t hci_status) {
  1809. tBTM_REMOTE_DEV_NAME rem_name;
  1810. tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
  1811. tBTM_CMPL_CB* p_cb = p_inq->p_remname_cmpl_cb;
  1812. uint8_t* p_n1;
  1813. uint16_t temp_evt_len;
  1814. if (bda) {
  1815. VLOG(2) << "BDA " << *bda;
  1816. }
  1817. VLOG(2) << "Inquire BDA " << p_inq->remname_bda;
  1818. /* If the inquire BDA and remote DBA are the same, then stop the timer and set
  1819. * the active to false */
  1820. if ((p_inq->remname_active) && (!bda || (*bda == p_inq->remname_bda))) {
  1821. if (BTM_UseLeLink(p_inq->remname_bda)) {
  1822. if (hci_status == HCI_ERR_UNSPECIFIED)
  1823. btm_ble_cancel_remote_name(p_inq->remname_bda);
  1824. }
  1825. alarm_cancel(p_inq->remote_name_timer);
  1826. p_inq->remname_active = false;
  1827. /* Clean up and return the status if the command was not successful */
  1828. /* Note: If part of the inquiry, the name is not stored, and the */
  1829. /* inquiry complete callback is called. */
  1830. if (hci_status == HCI_SUCCESS) {
  1831. /* Copy the name from the data stream into the return structure */
  1832. /* Note that even if it is not being returned, it is used as a */
  1833. /* temporary buffer. */
  1834. p_n1 = (uint8_t*)rem_name.remote_bd_name;
  1835. rem_name.length = (evt_len < BD_NAME_LEN) ? evt_len : BD_NAME_LEN;
  1836. rem_name.remote_bd_name[rem_name.length] = 0;
  1837. rem_name.status = BTM_SUCCESS;
  1838. temp_evt_len = rem_name.length;
  1839. while (temp_evt_len > 0) {
  1840. *p_n1++ = *bdn++;
  1841. temp_evt_len--;
  1842. }
  1843. rem_name.remote_bd_name[rem_name.length] = 0;
  1844. }
  1845. /* If processing a stand alone remote name then report the error in the
  1846. callback */
  1847. else {
  1848. rem_name.status = BTM_BAD_VALUE_RET;
  1849. rem_name.length = 0;
  1850. rem_name.remote_bd_name[0] = 0;
  1851. }
  1852. /* Reset the remote BAD to zero and call callback if possible */
  1853. p_inq->remname_bda = RawAddress::kEmpty;
  1854. p_inq->p_remname_cmpl_cb = NULL;
  1855. if (p_cb) (p_cb)(&rem_name);
  1856. }
  1857. }
  1858. void btm_inq_remote_name_timer_timeout(UNUSED_ATTR void* data) {
  1859. btm_inq_rmt_name_failed();
  1860. }
  1861. /*******************************************************************************
  1862. *
  1863. * Function btm_inq_rmt_name_failed
  1864. *
  1865. * Description This function is if timeout expires while getting remote
  1866. * name. This is done for devices that incorrectly do not
  1867. * report operation failure
  1868. *
  1869. * Returns void
  1870. *
  1871. ******************************************************************************/
  1872. void btm_inq_rmt_name_failed(void) {
  1873. BTM_TRACE_ERROR("btm_inq_rmt_name_failed() remname_active=%d",
  1874. btm_cb.btm_inq_vars.remname_active);
  1875. if (btm_cb.btm_inq_vars.remname_active)
  1876. btm_process_remote_name(&btm_cb.btm_inq_vars.remname_bda, NULL, 0,
  1877. HCI_ERR_UNSPECIFIED);
  1878. else
  1879. btm_process_remote_name(NULL, NULL, 0, HCI_ERR_UNSPECIFIED);
  1880. btm_sec_rmt_name_request_complete(NULL, NULL, HCI_ERR_UNSPECIFIED);
  1881. }
  1882. /*******************************************************************************
  1883. *
  1884. * Function btm_read_inq_tx_power_timeout
  1885. *
  1886. * Description Callback when reading the inquiry tx power times out.
  1887. *
  1888. * Returns void
  1889. *
  1890. ******************************************************************************/
  1891. void btm_read_inq_tx_power_timeout(UNUSED_ATTR void* data) {
  1892. tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_inq_tx_power_cmpl_cb;
  1893. btm_cb.devcb.p_inq_tx_power_cmpl_cb = NULL;
  1894. if (p_cb) (*p_cb)((void*)NULL);
  1895. }
  1896. /*******************************************************************************
  1897. *
  1898. * Function btm_read_inq_tx_power_complete
  1899. *
  1900. * Description read inquiry tx power level complete callback function.
  1901. *
  1902. * Returns void
  1903. *
  1904. ******************************************************************************/
  1905. void btm_read_inq_tx_power_complete(uint8_t* p) {
  1906. tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_inq_tx_power_cmpl_cb;
  1907. tBTM_INQ_TXPWR_RESULT result;
  1908. BTM_TRACE_DEBUG("%s", __func__);
  1909. alarm_cancel(btm_cb.devcb.read_inq_tx_power_timer);
  1910. btm_cb.devcb.p_inq_tx_power_cmpl_cb = NULL;
  1911. /* If there was a registered callback, call it */
  1912. if (p_cb) {
  1913. STREAM_TO_UINT8(result.hci_status, p);
  1914. if (result.hci_status == HCI_SUCCESS) {
  1915. result.status = BTM_SUCCESS;
  1916. STREAM_TO_UINT8(result.tx_power, p);
  1917. BTM_TRACE_EVENT(
  1918. "BTM INQ TX POWER Complete: tx_power %d, hci status 0x%02x",
  1919. result.tx_power, result.hci_status);
  1920. } else {
  1921. result.status = BTM_ERR_PROCESSING;
  1922. }
  1923. (*p_cb)(&result);
  1924. }
  1925. }
  1926. /*******************************************************************************
  1927. *
  1928. * Function BTM_WriteEIR
  1929. *
  1930. * Description This function is called to write EIR data to controller.
  1931. *
  1932. * Parameters p_buff - allocated HCI command buffer including extended
  1933. * inquriry response
  1934. *
  1935. * Returns BTM_SUCCESS - if successful
  1936. * BTM_MODE_UNSUPPORTED - if local device cannot support it
  1937. *
  1938. ******************************************************************************/
  1939. tBTM_STATUS BTM_WriteEIR(BT_HDR* p_buff) {
  1940. if (controller_get_interface()->supports_extended_inquiry_response()) {
  1941. BTM_TRACE_API("Write Extended Inquiry Response to controller");
  1942. btsnd_hcic_write_ext_inquiry_response(p_buff, BTM_EIR_DEFAULT_FEC_REQUIRED);
  1943. return BTM_SUCCESS;
  1944. } else {
  1945. osi_free(p_buff);
  1946. return BTM_MODE_UNSUPPORTED;
  1947. }
  1948. }
  1949. /*******************************************************************************
  1950. *
  1951. * Function btm_convert_uuid_to_eir_service
  1952. *
  1953. * Description This function is called to get the bit position of UUID.
  1954. *
  1955. * Parameters uuid16 - UUID 16-bit
  1956. *
  1957. * Returns BTM EIR service ID if found
  1958. * BTM_EIR_MAX_SERVICES - if not found
  1959. *
  1960. ******************************************************************************/
  1961. static uint8_t btm_convert_uuid_to_eir_service(uint16_t uuid16) {
  1962. uint8_t xx;
  1963. for (xx = 0; xx < BTM_EIR_MAX_SERVICES; xx++) {
  1964. if (uuid16 == BTM_EIR_UUID_LKUP_TBL[xx]) {
  1965. return xx;
  1966. }
  1967. }
  1968. return BTM_EIR_MAX_SERVICES;
  1969. }
  1970. /*******************************************************************************
  1971. *
  1972. * Function BTM_HasEirService
  1973. *
  1974. * Description This function is called to know if UUID in bit map of UUID.
  1975. *
  1976. * Parameters p_eir_uuid - bit map of UUID list
  1977. * uuid16 - UUID 16-bit
  1978. *
  1979. * Returns true - if found
  1980. * false - if not found
  1981. *
  1982. ******************************************************************************/
  1983. bool BTM_HasEirService(const uint32_t* p_eir_uuid, uint16_t uuid16) {
  1984. uint8_t service_id;
  1985. service_id = btm_convert_uuid_to_eir_service(uuid16);
  1986. if (service_id < BTM_EIR_MAX_SERVICES)
  1987. return (BTM_EIR_HAS_SERVICE(p_eir_uuid, service_id));
  1988. else
  1989. return (false);
  1990. }
  1991. /*******************************************************************************
  1992. *
  1993. * Function BTM_HasInquiryEirService
  1994. *
  1995. * Description This function is called to know if UUID in bit map of UUID
  1996. * list.
  1997. *
  1998. * Parameters p_results - inquiry results
  1999. * uuid16 - UUID 16-bit
  2000. *
  2001. * Returns BTM_EIR_FOUND - if found
  2002. * BTM_EIR_NOT_FOUND - if not found and it is complete list
  2003. * BTM_EIR_UNKNOWN - if not found and it is not complete list
  2004. *
  2005. ******************************************************************************/
  2006. tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService(tBTM_INQ_RESULTS* p_results,
  2007. uint16_t uuid16) {
  2008. if (BTM_HasEirService(p_results->eir_uuid, uuid16)) {
  2009. return BTM_EIR_FOUND;
  2010. } else if (p_results->eir_complete_list) {
  2011. return BTM_EIR_NOT_FOUND;
  2012. } else
  2013. return BTM_EIR_UNKNOWN;
  2014. }
  2015. /*******************************************************************************
  2016. *
  2017. * Function BTM_AddEirService
  2018. *
  2019. * Description This function is called to add a service in bit map of UUID
  2020. * list.
  2021. *
  2022. * Parameters p_eir_uuid - bit mask of UUID list for EIR
  2023. * uuid16 - UUID 16-bit
  2024. *
  2025. * Returns None
  2026. *
  2027. ******************************************************************************/
  2028. void BTM_AddEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
  2029. uint8_t service_id;
  2030. service_id = btm_convert_uuid_to_eir_service(uuid16);
  2031. if (service_id < BTM_EIR_MAX_SERVICES)
  2032. BTM_EIR_SET_SERVICE(p_eir_uuid, service_id);
  2033. }
  2034. /*******************************************************************************
  2035. *
  2036. * Function BTM_RemoveEirService
  2037. *
  2038. * Description This function is called to remove a service in bit map of
  2039. * UUID list.
  2040. *
  2041. * Parameters p_eir_uuid - bit mask of UUID list for EIR
  2042. * uuid16 - UUID 16-bit
  2043. *
  2044. * Returns None
  2045. *
  2046. ******************************************************************************/
  2047. void BTM_RemoveEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
  2048. uint8_t service_id;
  2049. service_id = btm_convert_uuid_to_eir_service(uuid16);
  2050. if (service_id < BTM_EIR_MAX_SERVICES)
  2051. BTM_EIR_CLR_SERVICE(p_eir_uuid, service_id);
  2052. }
  2053. /*******************************************************************************
  2054. *
  2055. * Function BTM_GetEirSupportedServices
  2056. *
  2057. * Description This function is called to get UUID list from bit map of
  2058. * UUID list.
  2059. *
  2060. * Parameters p_eir_uuid - bit mask of UUID list for EIR
  2061. * p - reference of current pointer of EIR
  2062. * max_num_uuid16 - max number of UUID can be written in EIR
  2063. * num_uuid16 - number of UUID have been written in EIR
  2064. *
  2065. * Returns BTM_EIR_MORE_16BITS_UUID_TYPE, if it has more than max
  2066. * BTM_EIR_COMPLETE_16BITS_UUID_TYPE, otherwise
  2067. *
  2068. ******************************************************************************/
  2069. uint8_t BTM_GetEirSupportedServices(uint32_t* p_eir_uuid, uint8_t** p,
  2070. uint8_t max_num_uuid16,
  2071. uint8_t* p_num_uuid16) {
  2072. uint8_t service_index;
  2073. *p_num_uuid16 = 0;
  2074. for (service_index = 0; service_index < BTM_EIR_MAX_SERVICES;
  2075. service_index++) {
  2076. if (BTM_EIR_HAS_SERVICE(p_eir_uuid, service_index)) {
  2077. if (*p_num_uuid16 < max_num_uuid16) {
  2078. UINT16_TO_STREAM(*p, BTM_EIR_UUID_LKUP_TBL[service_index]);
  2079. (*p_num_uuid16)++;
  2080. }
  2081. /* if max number of UUIDs are stored and found one more */
  2082. else {
  2083. return BTM_EIR_MORE_16BITS_UUID_TYPE;
  2084. }
  2085. }
  2086. }
  2087. return BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
  2088. }
  2089. /*******************************************************************************
  2090. *
  2091. * Function BTM_GetEirUuidList
  2092. *
  2093. * Description This function parses EIR and returns UUID list.
  2094. *
  2095. * Parameters p_eir - EIR
  2096. * eir_len - EIR len
  2097. * uuid_size - Uuid::kNumBytes16, Uuid::kNumBytes32,
  2098. * Uuid::kNumBytes128
  2099. * p_num_uuid - return number of UUID in found list
  2100. * p_uuid_list - return UUID list
  2101. * max_num_uuid - maximum number of UUID to be returned
  2102. *
  2103. * Returns 0 - if not found
  2104. * BTM_EIR_COMPLETE_16BITS_UUID_TYPE
  2105. * BTM_EIR_MORE_16BITS_UUID_TYPE
  2106. * BTM_EIR_COMPLETE_32BITS_UUID_TYPE
  2107. * BTM_EIR_MORE_32BITS_UUID_TYPE
  2108. * BTM_EIR_COMPLETE_128BITS_UUID_TYPE
  2109. * BTM_EIR_MORE_128BITS_UUID_TYPE
  2110. *
  2111. ******************************************************************************/
  2112. uint8_t BTM_GetEirUuidList(uint8_t* p_eir, size_t eir_len, uint8_t uuid_size,
  2113. uint8_t* p_num_uuid, uint8_t* p_uuid_list,
  2114. uint8_t max_num_uuid) {
  2115. const uint8_t* p_uuid_data;
  2116. uint8_t type;
  2117. uint8_t yy, xx;
  2118. uint16_t* p_uuid16 = (uint16_t*)p_uuid_list;
  2119. uint32_t* p_uuid32 = (uint32_t*)p_uuid_list;
  2120. char buff[Uuid::kNumBytes128 * 2 + 1];
  2121. p_uuid_data =
  2122. btm_eir_get_uuid_list(p_eir, eir_len, uuid_size, p_num_uuid, &type);
  2123. if (p_uuid_data == NULL) {
  2124. return 0x00;
  2125. }
  2126. if (*p_num_uuid > max_num_uuid) {
  2127. BTM_TRACE_WARNING("%s: number of uuid in EIR = %d, size of uuid list = %d",
  2128. __func__, *p_num_uuid, max_num_uuid);
  2129. *p_num_uuid = max_num_uuid;
  2130. }
  2131. BTM_TRACE_DEBUG("%s: type = %02X, number of uuid = %d", __func__, type,
  2132. *p_num_uuid);
  2133. if (uuid_size == Uuid::kNumBytes16) {
  2134. for (yy = 0; yy < *p_num_uuid; yy++) {
  2135. STREAM_TO_UINT16(*(p_uuid16 + yy), p_uuid_data);
  2136. BTM_TRACE_DEBUG(" 0x%04X", *(p_uuid16 + yy));
  2137. }
  2138. } else if (uuid_size == Uuid::kNumBytes32) {
  2139. for (yy = 0; yy < *p_num_uuid; yy++) {
  2140. STREAM_TO_UINT32(*(p_uuid32 + yy), p_uuid_data);
  2141. BTM_TRACE_DEBUG(" 0x%08X", *(p_uuid32 + yy));
  2142. }
  2143. } else if (uuid_size == Uuid::kNumBytes128) {
  2144. for (yy = 0; yy < *p_num_uuid; yy++) {
  2145. STREAM_TO_ARRAY16(p_uuid_list + yy * Uuid::kNumBytes128, p_uuid_data);
  2146. for (xx = 0; xx < Uuid::kNumBytes128; xx++)
  2147. snprintf(buff + xx * 2, sizeof(buff) - xx * 2, "%02X",
  2148. *(p_uuid_list + yy * Uuid::kNumBytes128 + xx));
  2149. BTM_TRACE_DEBUG(" 0x%s", buff);
  2150. }
  2151. }
  2152. return type;
  2153. }
  2154. /*******************************************************************************
  2155. *
  2156. * Function btm_eir_get_uuid_list
  2157. *
  2158. * Description This function searches UUID list in EIR.
  2159. *
  2160. * Parameters p_eir - address of EIR
  2161. * eir_len - EIR length
  2162. * uuid_size - size of UUID to find
  2163. * p_num_uuid - number of UUIDs found
  2164. * p_uuid_list_type - EIR data type
  2165. *
  2166. * Returns NULL - if UUID list with uuid_size is not found
  2167. * beginning of UUID list in EIR - otherwise
  2168. *
  2169. ******************************************************************************/
  2170. static const uint8_t* btm_eir_get_uuid_list(uint8_t* p_eir, size_t eir_len,
  2171. uint8_t uuid_size,
  2172. uint8_t* p_num_uuid,
  2173. uint8_t* p_uuid_list_type) {
  2174. const uint8_t* p_uuid_data;
  2175. uint8_t complete_type, more_type;
  2176. uint8_t uuid_len;
  2177. switch (uuid_size) {
  2178. case Uuid::kNumBytes16:
  2179. complete_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
  2180. more_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
  2181. break;
  2182. case Uuid::kNumBytes32:
  2183. complete_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
  2184. more_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
  2185. break;
  2186. case Uuid::kNumBytes128:
  2187. complete_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
  2188. more_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
  2189. break;
  2190. default:
  2191. *p_num_uuid = 0;
  2192. return NULL;
  2193. break;
  2194. }
  2195. p_uuid_data = AdvertiseDataParser::GetFieldByType(p_eir, eir_len,
  2196. complete_type, &uuid_len);
  2197. if (p_uuid_data == NULL) {
  2198. p_uuid_data = AdvertiseDataParser::GetFieldByType(p_eir, eir_len, more_type,
  2199. &uuid_len);
  2200. *p_uuid_list_type = more_type;
  2201. } else {
  2202. *p_uuid_list_type = complete_type;
  2203. }
  2204. *p_num_uuid = uuid_len / uuid_size;
  2205. return p_uuid_data;
  2206. }
  2207. /*******************************************************************************
  2208. *
  2209. * Function btm_convert_uuid_to_uuid16
  2210. *
  2211. * Description This function converts UUID to UUID 16-bit.
  2212. *
  2213. * Parameters p_uuid - address of UUID
  2214. * uuid_size - size of UUID
  2215. *
  2216. * Returns 0 - if UUID cannot be converted to UUID 16-bit
  2217. * UUID 16-bit - otherwise
  2218. *
  2219. ******************************************************************************/
  2220. static uint16_t btm_convert_uuid_to_uuid16(const uint8_t* p_uuid,
  2221. uint8_t uuid_size) {
  2222. static const uint8_t base_uuid[Uuid::kNumBytes128] = {
  2223. 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
  2224. 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  2225. uint16_t uuid16 = 0;
  2226. uint32_t uuid32;
  2227. bool is_base_uuid;
  2228. uint8_t xx;
  2229. switch (uuid_size) {
  2230. case Uuid::kNumBytes16:
  2231. STREAM_TO_UINT16(uuid16, p_uuid);
  2232. break;
  2233. case Uuid::kNumBytes32:
  2234. STREAM_TO_UINT32(uuid32, p_uuid);
  2235. if (uuid32 < 0x10000) uuid16 = (uint16_t)uuid32;
  2236. break;
  2237. case Uuid::kNumBytes128:
  2238. /* See if we can compress his UUID down to 16 or 32bit UUIDs */
  2239. is_base_uuid = true;
  2240. for (xx = 0; xx < Uuid::kNumBytes128 - 4; xx++) {
  2241. if (p_uuid[xx] != base_uuid[xx]) {
  2242. is_base_uuid = false;
  2243. break;
  2244. }
  2245. }
  2246. if (is_base_uuid) {
  2247. if ((p_uuid[Uuid::kNumBytes128 - 1] == 0) &&
  2248. (p_uuid[Uuid::kNumBytes128 - 2] == 0)) {
  2249. p_uuid += (Uuid::kNumBytes128 - 4);
  2250. STREAM_TO_UINT16(uuid16, p_uuid);
  2251. }
  2252. }
  2253. break;
  2254. default:
  2255. BTM_TRACE_WARNING("btm_convert_uuid_to_uuid16 invalid uuid size");
  2256. break;
  2257. }
  2258. return (uuid16);
  2259. }
  2260. /*******************************************************************************
  2261. *
  2262. * Function btm_set_eir_uuid
  2263. *
  2264. * Description This function is called to store received UUID into inquiry
  2265. * result.
  2266. *
  2267. * Parameters p_eir - pointer of EIR significant part
  2268. * p_results - pointer of inquiry result
  2269. *
  2270. * Returns None
  2271. *
  2272. ******************************************************************************/
  2273. void btm_set_eir_uuid(uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) {
  2274. const uint8_t* p_uuid_data;
  2275. uint8_t num_uuid;
  2276. uint16_t uuid16;
  2277. uint8_t yy;
  2278. uint8_t type = BTM_EIR_MORE_16BITS_UUID_TYPE;
  2279. p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
  2280. Uuid::kNumBytes16, &num_uuid, &type);
  2281. if (type == BTM_EIR_COMPLETE_16BITS_UUID_TYPE) {
  2282. p_results->eir_complete_list = true;
  2283. } else {
  2284. p_results->eir_complete_list = false;
  2285. }
  2286. BTM_TRACE_API("btm_set_eir_uuid eir_complete_list=0x%02X",
  2287. p_results->eir_complete_list);
  2288. if (p_uuid_data) {
  2289. for (yy = 0; yy < num_uuid; yy++) {
  2290. STREAM_TO_UINT16(uuid16, p_uuid_data);
  2291. BTM_AddEirService(p_results->eir_uuid, uuid16);
  2292. }
  2293. }
  2294. p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
  2295. Uuid::kNumBytes32, &num_uuid, &type);
  2296. if (p_uuid_data) {
  2297. for (yy = 0; yy < num_uuid; yy++) {
  2298. uuid16 = btm_convert_uuid_to_uuid16(p_uuid_data, Uuid::kNumBytes32);
  2299. p_uuid_data += Uuid::kNumBytes32;
  2300. if (uuid16) BTM_AddEirService(p_results->eir_uuid, uuid16);
  2301. }
  2302. }
  2303. p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
  2304. Uuid::kNumBytes128, &num_uuid, &type);
  2305. if (p_uuid_data) {
  2306. for (yy = 0; yy < num_uuid; yy++) {
  2307. uuid16 = btm_convert_uuid_to_uuid16(p_uuid_data, Uuid::kNumBytes128);
  2308. p_uuid_data += Uuid::kNumBytes128;
  2309. if (uuid16) BTM_AddEirService(p_results->eir_uuid, uuid16);
  2310. }
  2311. }
  2312. }