btm_inq.c 111 KB

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