btm_sco.c 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2000-2012 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 SCO connections. This includes
  21. * operations such as connect, disconnect, change supported packet types.
  22. *
  23. ******************************************************************************/
  24. #include <string.h>
  25. #include "stack/bt_types.h"
  26. #include "common/bt_target.h"
  27. #include "stack/bt_types.h"
  28. #include "stack/hcimsgs.h"
  29. #include "stack/btu.h"
  30. #include "stack/btm_api.h"
  31. #include "osi/allocator.h"
  32. #include "btm_int.h"
  33. #include "stack/hcidefs.h"
  34. //#include "bt_utils.h"
  35. #if BTM_SCO_INCLUDED == TRUE
  36. /********************************************************************************/
  37. /* L O C A L D A T A D E F I N I T I O N S */
  38. /********************************************************************************/
  39. #define SCO_ST_UNUSED 0
  40. #define SCO_ST_LISTENING 1
  41. #define SCO_ST_W4_CONN_RSP 2
  42. #define SCO_ST_CONNECTING 3
  43. #define SCO_ST_CONNECTED 4
  44. #define SCO_ST_DISCONNECTING 5
  45. #define SCO_ST_PEND_UNPARK 6
  46. #define SCO_ST_PEND_ROLECHANGE 7
  47. /********************************************************************************/
  48. /* L O C A L F U N C T I O N P R O T O T Y P E S */
  49. /********************************************************************************/
  50. static const tBTM_ESCO_PARAMS btm_esco_defaults = {
  51. BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */
  52. BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */
  53. 0x000a, /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */
  54. 0x0060, /* Inp Linear, Air CVSD, 2s Comp, 16bit */
  55. (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */
  56. BTM_SCO_PKT_TYPES_MASK_HV2 +
  57. BTM_SCO_PKT_TYPES_MASK_HV3 +
  58. BTM_SCO_PKT_TYPES_MASK_EV3 +
  59. BTM_SCO_PKT_TYPES_MASK_EV4 +
  60. BTM_SCO_PKT_TYPES_MASK_EV5),
  61. BTM_ESCO_RETRANS_POWER /* Retransmission Effort (Power) */
  62. };
  63. /*******************************************************************************
  64. **
  65. ** Function btm_sco_flush_sco_data
  66. **
  67. ** Description This function is called to flush the SCO data for this channel.
  68. **
  69. ** Returns void
  70. **
  71. *******************************************************************************/
  72. void btm_sco_flush_sco_data(UINT16 sco_inx)
  73. {
  74. #if BTM_SCO_HCI_INCLUDED == TRUE
  75. #if (BTM_MAX_SCO_LINKS>0)
  76. tSCO_CONN *p ;
  77. BT_HDR *p_buf;
  78. if (sco_inx < BTM_MAX_SCO_LINKS) {
  79. p = &btm_cb.sco_cb.sco_db[sco_inx];
  80. while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p->xmit_data_q, 0)) != NULL) {
  81. osi_free(p_buf);
  82. }
  83. }
  84. #else
  85. UNUSED(sco_inx);
  86. #endif
  87. #else
  88. UNUSED(sco_inx);
  89. #endif
  90. }
  91. /*******************************************************************************
  92. **
  93. ** Function btm_sco_init
  94. **
  95. ** Description This function is called at BTM startup to initialize
  96. **
  97. ** Returns void
  98. **
  99. *******************************************************************************/
  100. void btm_sco_init (void)
  101. {
  102. #if 0 /* cleared in btm_init; put back in if called from anywhere else! */
  103. memset (&btm_cb.sco_cb, 0, sizeof(tSCO_CB));
  104. #endif
  105. #if (BTM_SCO_HCI_INCLUDED == TRUE)
  106. for (int i = 0; i < BTM_MAX_SCO_LINKS; i++) {
  107. btm_cb.sco_cb.sco_db[i].xmit_data_q = fixed_queue_new(QUEUE_SIZE_MAX);
  108. }
  109. #endif
  110. /* Initialize nonzero defaults */
  111. btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
  112. btm_cb.sco_cb.def_esco_parms = btm_esco_defaults; /* Initialize with defaults */
  113. btm_cb.sco_cb.desired_sco_mode = BTM_DEFAULT_SCO_MODE;
  114. }
  115. /*******************************************************************************
  116. **
  117. ** Function btm_esco_conn_rsp
  118. **
  119. ** Description This function is called upon receipt of an (e)SCO connection
  120. ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
  121. ** the request. Parameters used to negotiate eSCO links.
  122. ** If p_parms is NULL, then default values are used.
  123. ** If the link type of the incoming request is SCO, then only
  124. ** the tx_bw, max_latency, content format, and packet_types are
  125. ** valid. The hci_status parameter should be
  126. ** ([0x0] to accept, [0x0d..0x0f] to reject)
  127. **
  128. ** Returns void
  129. **
  130. *******************************************************************************/
  131. static void btm_esco_conn_rsp (UINT16 sco_inx, UINT8 hci_status, BD_ADDR bda,
  132. tBTM_ESCO_PARAMS *p_parms)
  133. {
  134. #if (BTM_MAX_SCO_LINKS>0)
  135. tSCO_CONN *p_sco = NULL;
  136. tBTM_ESCO_PARAMS *p_setup;
  137. UINT16 temp_pkt_types;
  138. if (sco_inx < BTM_MAX_SCO_LINKS) {
  139. p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
  140. }
  141. /* Reject the connect request if refused by caller or wrong state */
  142. if (hci_status != HCI_SUCCESS || p_sco == NULL) {
  143. if (p_sco) {
  144. p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING
  145. : SCO_ST_UNUSED;
  146. }
  147. if (!btm_cb.sco_cb.esco_supported) {
  148. if (!btsnd_hcic_reject_conn (bda, hci_status)) {
  149. BTM_TRACE_ERROR("Could not reject (e)SCO conn: No Buffer!!!");
  150. }
  151. } else {
  152. if (!btsnd_hcic_reject_esco_conn (bda, hci_status)) {
  153. BTM_TRACE_ERROR("Could not reject (e)SCO conn: No Buffer!!!");
  154. }
  155. }
  156. } else { /* Connection is being accepted */
  157. p_sco->state = SCO_ST_CONNECTING;
  158. p_setup = &p_sco->esco.setup;
  159. /* If parameters not specified use the default */
  160. if (p_parms) {
  161. *p_setup = *p_parms;
  162. } else { /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
  163. *p_setup = btm_cb.sco_cb.def_esco_parms;
  164. }
  165. temp_pkt_types = (p_setup->packet_types &
  166. BTM_SCO_SUPPORTED_PKTS_MASK &
  167. btm_cb.btm_sco_pkt_types_supported);
  168. /* Make sure at least one eSCO packet type is sent, else might confuse peer */
  169. /* Taking this out to confirm with BQB tests
  170. ** Real application would like to include this though, as many devices
  171. ** do not retry with SCO only if an eSCO connection fails.
  172. if (!(temp_pkt_types & BTM_ESCO_LINK_ONLY_MASK))
  173. {
  174. temp_pkt_types |= BTM_SCO_PKT_TYPES_MASK_EV3;
  175. }
  176. */
  177. /* If SCO request, remove eSCO packet types (conformance) */
  178. if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO) {
  179. temp_pkt_types &= BTM_SCO_LINK_ONLY_MASK;
  180. temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
  181. } else {
  182. /* OR in any exception packet types */
  183. temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
  184. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
  185. }
  186. if (btsnd_hcic_accept_esco_conn (bda, p_setup->tx_bw, p_setup->rx_bw,
  187. p_setup->max_latency, p_setup->voice_contfmt,
  188. p_setup->retrans_effort, temp_pkt_types)) {
  189. p_setup->packet_types = temp_pkt_types;
  190. } else {
  191. BTM_TRACE_ERROR("Could not accept SCO conn: No Buffer!!!");
  192. }
  193. }
  194. #endif
  195. }
  196. #if BTM_SCO_HCI_INCLUDED == TRUE
  197. void btm_sco_process_num_bufs (UINT16 num_lm_sco_bufs)
  198. {
  199. BTM_TRACE_DEBUG("%s, %d", __FUNCTION__, num_lm_sco_bufs);
  200. btm_cb.sco_cb.num_lm_sco_bufs = btm_cb.sco_cb.xmit_window_size = num_lm_sco_bufs;
  201. }
  202. /*******************************************************************************
  203. **
  204. ** Function BTM_ConfigScoPath
  205. **
  206. ** Description This function enable/disable SCO over HCI and registers SCO
  207. ** data callback if SCO over HCI is enabled.
  208. **
  209. ** Parameter path: SCO or HCI
  210. ** p_sco_data_cb: callback function or SCO data if path is set
  211. ** to transport.
  212. ** p_pcm_param: pointer to the PCM interface parameter. If a NULL
  213. ** pointer is used, PCM parameter maintained in
  214. ** the control block will be used; otherwise update
  215. ** control block value.
  216. ** err_data_rpt: Lisbon feature to enable the erronous data report
  217. ** or not.
  218. **
  219. ** Returns BTM_SUCCESS if the successful.
  220. ** BTM_NO_RESOURCES: no rsource to start the command.
  221. ** BTM_ILLEGAL_VALUE: invalid callback function pointer.
  222. ** BTM_CMD_STARTED :Command sent. Waiting for command cmpl event.
  223. **
  224. **
  225. *******************************************************************************/
  226. //extern
  227. tBTM_STATUS BTM_ConfigScoPath (tBTM_SCO_ROUTE_TYPE path,
  228. tBTM_SCO_DATA_CB *p_sco_data_cb,
  229. tBTM_SCO_PCM_PARAM *p_pcm_param,
  230. BOOLEAN err_data_rpt)
  231. {
  232. UNUSED(err_data_rpt);
  233. UNUSED(p_pcm_param);
  234. btm_cb.sco_cb.sco_path = path;
  235. if (path == BTM_SCO_ROUTE_PCM) {
  236. return BTM_SUCCESS;
  237. } else if (path == BTM_SCO_ROUTE_HCI) {
  238. if (p_sco_data_cb) {
  239. btm_cb.sco_cb.p_data_cb = p_sco_data_cb;
  240. }
  241. }
  242. return BTM_SUCCESS;
  243. }
  244. static void hci_sco_data_to_lower(BT_HDR *p_buf)
  245. {
  246. p_buf->event = BT_EVT_TO_LM_HCI_SCO;
  247. if (p_buf->offset == 0) {
  248. BTM_TRACE_ERROR("offset cannot be 0");
  249. osi_free(p_buf);
  250. }
  251. bte_main_hci_send(p_buf, (UINT16)(BT_EVT_TO_LM_HCI_SCO | LOCAL_BLE_CONTROLLER_ID));
  252. }
  253. /*******************************************************************************
  254. **
  255. ** Function btm_sco_check_send_pkts
  256. **
  257. ** Description This function is called to check if it can send packets
  258. ** to the Host Controller.
  259. **
  260. ** Returns void
  261. **
  262. *******************************************************************************/
  263. void btm_sco_check_send_pkts (UINT16 sco_inx)
  264. {
  265. tSCO_CB *p_cb = &btm_cb.sco_cb;
  266. tSCO_CONN *p_ccb = &p_cb->sco_db[sco_inx];
  267. /* If there is data to send, send it now */
  268. BT_HDR *p_buf;
  269. while (p_cb->xmit_window_size != 0)
  270. {
  271. if ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->xmit_data_q, 0)) == NULL) {
  272. break;
  273. }
  274. #if BTM_SCO_HCI_DEBUG
  275. BTM_TRACE_DEBUG("btm: [%d] buf in xmit_data_q",
  276. fixed_queue_length(p_ccb->xmit_data_q) + 1);
  277. #endif
  278. /* Don't go negative */
  279. p_cb->xmit_window_size -= 1;
  280. p_ccb->sent_not_acked += 1;
  281. // HCI_SCO_DATA_TO_LOWER(p_buf);
  282. hci_sco_data_to_lower(p_buf);
  283. }
  284. }
  285. void btm_sco_process_num_completed_pkts (UINT8 *p)
  286. {
  287. UINT8 num_handles, xx;
  288. UINT16 handle;
  289. UINT16 num_sent;
  290. UINT16 sco_inx;
  291. tSCO_CB *p_cb = &btm_cb.sco_cb;
  292. tSCO_CONN * p_ccb;
  293. STREAM_TO_UINT8 (num_handles, p);
  294. for (xx = 0; xx < num_handles; xx++) {
  295. STREAM_TO_UINT16 (handle, p);
  296. STREAM_TO_UINT16 (num_sent, p);
  297. if ((sco_inx = btm_find_scb_by_handle(handle)) == BTM_MAX_SCO_LINKS) {
  298. continue;
  299. }
  300. BTM_TRACE_DEBUG("%s, %d, %u", __FUNCTION__, handle, p_cb->xmit_window_size); //debug
  301. p_ccb = &p_cb->sco_db[sco_inx];
  302. p_ccb->sent_not_acked -= num_sent;
  303. // don't go negative
  304. if (p_ccb->sent_not_acked < 0) {
  305. BTM_TRACE_WARNING("SCO: un-acked underf: %u", p_ccb->sent_not_acked);
  306. p_ccb->sent_not_acked = 0;
  307. }
  308. p_cb->xmit_window_size += num_sent;
  309. if (p_cb->xmit_window_size > p_cb->num_lm_sco_bufs) {
  310. BTM_TRACE_WARNING("SCO xwind: %d, max %d", p_cb->xmit_window_size, p_cb->num_lm_sco_bufs);
  311. p_cb->xmit_window_size = p_cb->num_lm_sco_bufs;
  312. }
  313. btm_sco_check_send_pkts (sco_inx);
  314. }
  315. return;
  316. }
  317. #endif /* BTM_SCO_HCI_INCLUDED == TRUE */
  318. /*******************************************************************************
  319. **
  320. ** Function btm_route_sco_data
  321. **
  322. ** Description Route received SCO data.
  323. **
  324. ** Returns void
  325. **
  326. *******************************************************************************/
  327. void btm_route_sco_data(BT_HDR *p_msg)
  328. {
  329. #if BTM_SCO_HCI_INCLUDED == TRUE
  330. UINT16 sco_inx, handle;
  331. UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset;
  332. UINT8 pkt_size = 0;
  333. UINT8 pkt_status = 0;
  334. /* Extract Packet_Status_Flag and handle */
  335. STREAM_TO_UINT16 (handle, p);
  336. pkt_status = HCID_GET_EVENT(handle);
  337. handle = HCID_GET_HANDLE (handle);
  338. STREAM_TO_UINT8 (pkt_size, p);
  339. UNUSED(pkt_size);
  340. if ((sco_inx = btm_find_scb_by_handle(handle)) != BTM_MAX_SCO_LINKS ) {
  341. /* send data callback */
  342. if (!btm_cb.sco_cb.p_data_cb )
  343. /* if no data callback registered, just free the buffer */
  344. {
  345. osi_free (p_msg);
  346. } else {
  347. (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg, (tBTM_SCO_DATA_FLAG) pkt_status);
  348. }
  349. } else { /* no mapping handle SCO connection is active, free the buffer */
  350. osi_free (p_msg);
  351. }
  352. BTM_TRACE_DEBUG ("SCO: hdl %x, len %d, pkt_sz %d\n", handle, p_msg->len, pkt_size);
  353. #else
  354. osi_free(p_msg);
  355. #endif
  356. }
  357. /*******************************************************************************
  358. **
  359. ** Function BTM_WriteScoData
  360. **
  361. ** Description This function write SCO data to a specified instance. The data
  362. ** to be written p_buf needs to carry an offset of
  363. ** HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not
  364. ** exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is set
  365. ** to 60 and is configurable. Data longer than the maximum bytes
  366. ** will be truncated.
  367. **
  368. ** Returns BTM_SUCCESS: data write is successful
  369. ** BTM_ILLEGAL_VALUE: SCO data contains illegal offset value.
  370. ** BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO packet
  371. ** size.
  372. ** BTM_NO_RESOURCES: no resources.
  373. ** BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is not
  374. ** routed via HCI.
  375. ** BTM_ERR_PROCESSING: transmit queue overflow
  376. **
  377. **
  378. *******************************************************************************/
  379. tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf)
  380. {
  381. APPL_TRACE_DEBUG("%s", __FUNCTION__);
  382. #if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTM_MAX_SCO_LINKS>0)
  383. tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
  384. UINT8 *p;
  385. tBTM_STATUS status = BTM_SUCCESS;
  386. if (sco_inx < BTM_MAX_SCO_LINKS && btm_cb.sco_cb.p_data_cb &&
  387. p_ccb->state == SCO_ST_CONNECTED) {
  388. /* Ensure we have enough space in the buffer for the SCO and HCI headers */
  389. if (p_buf->offset < HCI_SCO_PREAMBLE_SIZE) {
  390. BTM_TRACE_ERROR ("BTM SCO - cannot send buffer, offset: %d", p_buf->offset);
  391. status = BTM_ILLEGAL_VALUE;
  392. } else { /* write HCI header */
  393. /* Step back 3 bytes to add the headers */
  394. p_buf->offset -= HCI_SCO_PREAMBLE_SIZE;
  395. /* Set the pointer to the beginning of the data */
  396. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  397. /* add HCI handle */
  398. UINT16_TO_STREAM (p, p_ccb->hci_handle);
  399. /* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max,
  400. and set warning status */
  401. if (p_buf->len > BTM_SCO_DATA_SIZE_MAX) {
  402. BTM_TRACE_WARNING ("BTM SCO hdl %x, bad len %u", p_ccb->hci_handle, p_buf->len);
  403. p_buf->len = BTM_SCO_DATA_SIZE_MAX;
  404. status = BTM_SCO_BAD_LENGTH;
  405. }
  406. UINT8_TO_STREAM (p, (UINT8)p_buf->len);
  407. p_buf->len += HCI_SCO_PREAMBLE_SIZE;
  408. if (fixed_queue_length(p_ccb->xmit_data_q) < BTM_SCO_XMIT_QUEUE_THRS) {
  409. if (fixed_queue_length(p_ccb->xmit_data_q) >= BTM_SCO_XMIT_QUEUE_HIGH_WM) {
  410. status = BTM_NO_RESOURCES;
  411. }
  412. fixed_queue_enqueue(p_ccb->xmit_data_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
  413. btm_sco_check_send_pkts (sco_inx);
  414. } else {
  415. BTM_TRACE_WARNING ("SCO xmit Q overflow, pkt dropped");
  416. status = BTM_ERR_PROCESSING;
  417. }
  418. }
  419. } else {
  420. BTM_TRACE_WARNING ("BTM_WriteScoData, invalid sco index: %d at state [%d]",
  421. sco_inx, btm_cb.sco_cb.sco_db[sco_inx].state);
  422. status = BTM_UNKNOWN_ADDR;
  423. }
  424. if (status != BTM_SUCCESS && status!= BTM_NO_RESOURCES) {
  425. BTM_TRACE_WARNING ("stat %d", status);
  426. osi_free(p_buf);
  427. }
  428. return (status);
  429. #else
  430. UNUSED(sco_inx);
  431. UNUSED(p_buf);
  432. return (BTM_NO_RESOURCES);
  433. #endif
  434. }
  435. #if (BTM_MAX_SCO_LINKS>0)
  436. /*******************************************************************************
  437. **
  438. ** Function btm_send_connect_request
  439. **
  440. ** Description This function is called to respond to SCO connect indications
  441. **
  442. ** Returns void
  443. **
  444. *******************************************************************************/
  445. static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle,
  446. tBTM_ESCO_PARAMS *p_setup)
  447. {
  448. UINT16 temp_pkt_types;
  449. UINT8 xx;
  450. tACL_CONN *p_acl;
  451. /* Send connect request depending on version of spec */
  452. if (!btm_cb.sco_cb.esco_supported) {
  453. if (!btsnd_hcic_add_SCO_conn (acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types))) {
  454. return (BTM_NO_RESOURCES);
  455. }
  456. } else {
  457. temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
  458. btm_cb.btm_sco_pkt_types_supported);
  459. /* OR in any exception packet types */
  460. temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
  461. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
  462. /* Finally, remove EDR eSCO if the remote device doesn't support it */
  463. /* UPF25: Only SCO was brought up in this case */
  464. btm_handle_to_acl_index(acl_handle);
  465. if ((xx = btm_handle_to_acl_index(acl_handle)) < MAX_L2CAP_LINKS) {
  466. p_acl = &btm_cb.acl_db[xx];
  467. if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
  468. BTM_TRACE_WARNING("BTM Remote does not support 2-EDR eSCO");
  469. temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 |
  470. HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5);
  471. }
  472. if (!HCI_EDR_ESCO_3MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
  473. BTM_TRACE_WARNING("BTM Remote does not support 3-EDR eSCO");
  474. temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 |
  475. HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5);
  476. }
  477. /* Check to see if BR/EDR Secure Connections is being used
  478. ** If so, we cannot use SCO-only packet types (HFP 1.7)
  479. */
  480. if (BTM_BothEndsSupportSecureConnections(p_acl->remote_addr)) {
  481. temp_pkt_types &= ~(BTM_SCO_PKT_TYPE_MASK);
  482. BTM_TRACE_DEBUG("%s: SCO Conn: pkt_types after removing SCO (0x%04x)", __FUNCTION__,
  483. temp_pkt_types);
  484. /* Return error if no packet types left */
  485. if (temp_pkt_types == 0) {
  486. BTM_TRACE_ERROR("%s: SCO Conn (BR/EDR SC): No packet types available",__FUNCTION__);
  487. return (BTM_WRONG_MODE);
  488. }
  489. } else {
  490. BTM_TRACE_DEBUG("%s: SCO Conn(BR/EDR SC):local or peer does not support BR/EDR SC",__FUNCTION__);
  491. }
  492. }
  493. BTM_TRACE_API("txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
  494. p_setup->tx_bw, p_setup->rx_bw,
  495. p_setup->max_latency, p_setup->voice_contfmt,
  496. p_setup->retrans_effort, temp_pkt_types);
  497. if (!btsnd_hcic_setup_esco_conn(acl_handle,
  498. p_setup->tx_bw,
  499. p_setup->rx_bw,
  500. p_setup->max_latency,
  501. p_setup->voice_contfmt,
  502. p_setup->retrans_effort,
  503. temp_pkt_types)) {
  504. return (BTM_NO_RESOURCES);
  505. } else {
  506. p_setup->packet_types = temp_pkt_types;
  507. }
  508. }
  509. return (BTM_CMD_STARTED);
  510. }
  511. #endif
  512. /*******************************************************************************
  513. **
  514. ** Function btm_set_sco_ind_cback
  515. **
  516. ** Description This function is called to register for TCS SCO connect
  517. ** indications.
  518. **
  519. ** Returns void
  520. **
  521. *******************************************************************************/
  522. void btm_set_sco_ind_cback( tBTM_SCO_IND_CBACK *sco_ind_cb )
  523. {
  524. btm_cb.sco_cb.app_sco_ind_cb = sco_ind_cb;
  525. }
  526. /*******************************************************************************
  527. **
  528. ** Function btm_accept_sco_link
  529. **
  530. ** Description This function is called to respond to TCS SCO connect
  531. ** indications
  532. **
  533. ** Returns void
  534. **
  535. *******************************************************************************/
  536. void btm_accept_sco_link(UINT16 sco_inx, tBTM_ESCO_PARAMS *p_setup,
  537. tBTM_SCO_CB *p_conn_cb, tBTM_SCO_CB *p_disc_cb)
  538. {
  539. #if (BTM_MAX_SCO_LINKS>0)
  540. tSCO_CONN *p_sco;
  541. if (sco_inx >= BTM_MAX_SCO_LINKS) {
  542. BTM_TRACE_ERROR("btm_accept_sco_link: Invalid sco_inx(%d)", sco_inx);
  543. return;
  544. }
  545. /* Link role is ignored in for this message */
  546. p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
  547. p_sco->p_conn_cb = p_conn_cb;
  548. p_sco->p_disc_cb = p_disc_cb;
  549. p_sco->esco.data.link_type = BTM_LINK_TYPE_ESCO; /* Accept with all supported types */
  550. BTM_TRACE_DEBUG("TCS accept SCO: Packet Types 0x%04x", p_setup->packet_types);
  551. btm_esco_conn_rsp(sco_inx, HCI_SUCCESS, p_sco->esco.data.bd_addr, p_setup);
  552. #else
  553. btm_reject_sco_link(sco_inx);
  554. #endif
  555. }
  556. /*******************************************************************************
  557. **
  558. ** Function btm_reject_sco_link
  559. **
  560. ** Description This function is called to respond to SCO connect indications
  561. **
  562. ** Returns void
  563. **
  564. *******************************************************************************/
  565. void btm_reject_sco_link( UINT16 sco_inx )
  566. {
  567. btm_esco_conn_rsp(sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
  568. btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, NULL);
  569. }
  570. /*******************************************************************************
  571. **
  572. ** Function BTM_CreateSco
  573. **
  574. ** Description This function is called to create an SCO connection. If the
  575. ** "is_orig" flag is TRUE, the connection will be originated,
  576. ** otherwise BTM will wait for the other side to connect.
  577. **
  578. ** NOTE: If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
  579. ** parameter the default packet types is used.
  580. **
  581. ** Returns BTM_UNKNOWN_ADDR if the ACL connection is not up
  582. ** BTM_BUSY if another SCO being set up to
  583. ** the same BD address
  584. ** BTM_NO_RESOURCES if the max SCO limit has been reached
  585. ** BTM_CMD_STARTED if the connection establishment is started.
  586. ** In this case, "*p_sco_inx" is filled in
  587. ** with the sco index used for the connection.
  588. **
  589. *******************************************************************************/
  590. tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types,
  591. UINT16 *p_sco_inx, tBTM_SCO_CB *p_conn_cb,
  592. tBTM_SCO_CB *p_disc_cb)
  593. {
  594. #if (BTM_MAX_SCO_LINKS > 0)
  595. tBTM_ESCO_PARAMS *p_setup;
  596. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  597. UINT16 xx;
  598. UINT16 acl_handle = 0;
  599. UINT16 temp_pkt_types;
  600. tACL_CONN *p_acl;
  601. #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
  602. tBTM_PM_MODE md;
  603. tBTM_PM_PWR_MD pm;
  604. #else // BTM_SCO_WAKE_PARKED_LINK
  605. UINT8 mode;
  606. #endif // BTM_SCO_WAKE_PARKED_LINK
  607. *p_sco_inx = BTM_INVALID_SCO_INDEX;
  608. /* If originating, ensure that there is an ACL connection to the BD Address */
  609. if (is_orig) {
  610. if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda, BT_TRANSPORT_BR_EDR)) == 0xFFFF)) {
  611. return (BTM_UNKNOWN_ADDR);
  612. }
  613. }
  614. if (remote_bda) {
  615. /* If any SCO is being established to the remote BD address, refuse this */
  616. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  617. if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING)
  618. || (p->state == SCO_ST_PEND_UNPARK))
  619. && (!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN))) {
  620. return (BTM_BUSY);
  621. }
  622. }
  623. } else {
  624. /* Support only 1 wildcard BD address at a time */
  625. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  626. if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known)) {
  627. return (BTM_BUSY);
  628. }
  629. }
  630. }
  631. /* Now, try to find an unused control block, and kick off the SCO establishment */
  632. for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  633. if (p->state == SCO_ST_UNUSED) {
  634. if (remote_bda) {
  635. if (is_orig) {
  636. /* can not create SCO link if in park mode */
  637. #if BTM_SCO_WAKE_PARKED_LINK == TRUE
  638. if (BTM_ReadPowerMode(remote_bda, &md) == BTM_SUCCESS) {
  639. if (md == BTM_PM_MD_PARK || md == BTM_PM_MD_SNIFF) {
  640. memset( (void *)&pm, 0, sizeof(pm));
  641. pm.mode = BTM_PM_MD_ACTIVE;
  642. BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm);
  643. p->state = SCO_ST_PEND_UNPARK;
  644. }
  645. }
  646. #else // BTM_SCO_WAKE_PARKED_LINK
  647. if ( (BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_PM_MD_PARK) ) {
  648. return (BTM_WRONG_MODE);
  649. }
  650. #endif // BTM_SCO_WAKE_PARKED_LINK
  651. }
  652. memcpy (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN);
  653. p->rem_bd_known = TRUE;
  654. } else {
  655. p->rem_bd_known = FALSE;
  656. }
  657. /* Link role is ignored in for this message */
  658. if (pkt_types == BTM_IGNORE_SCO_PKT_TYPE) {
  659. pkt_types = btm_cb.sco_cb.def_esco_parms.packet_types;
  660. }
  661. p_setup = &p->esco.setup;
  662. *p_setup = btm_cb.sco_cb.def_esco_parms;
  663. p_setup->packet_types = (btm_cb.sco_cb.desired_sco_mode == BTM_LINK_TYPE_SCO)
  664. ? (pkt_types & BTM_SCO_LINK_ONLY_MASK) : pkt_types;
  665. temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
  666. btm_cb.btm_sco_pkt_types_supported);
  667. /* OR in any exception packet types */
  668. if (btm_cb.sco_cb.desired_sco_mode == HCI_LINK_TYPE_ESCO) {
  669. temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
  670. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
  671. } else { /* Only using SCO packet types; turn off EDR also */
  672. temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
  673. }
  674. p_setup->packet_types = temp_pkt_types;
  675. p->p_conn_cb = p_conn_cb;
  676. p->p_disc_cb = p_disc_cb;
  677. p->hci_handle = BTM_INVALID_HCI_HANDLE;
  678. p->is_orig = is_orig;
  679. if ( p->state != SCO_ST_PEND_UNPARK ) {
  680. if (is_orig) {
  681. /* If role change is in progress, do not proceed with SCO setup
  682. * Wait till role change is complete */
  683. p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
  684. if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE) {
  685. BTM_TRACE_API("Role Change is in progress for ACL handle 0x%04x", acl_handle);
  686. p->state = SCO_ST_PEND_ROLECHANGE;
  687. }
  688. }
  689. }
  690. if ( p->state != SCO_ST_PEND_UNPARK && p->state != SCO_ST_PEND_ROLECHANGE ) {
  691. if (is_orig) {
  692. BTM_TRACE_API("BTM_CreateSco -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d",
  693. acl_handle, btm_cb.sco_cb.desired_sco_mode);
  694. if ((btm_send_connect_request(acl_handle, p_setup)) != BTM_CMD_STARTED) {
  695. return (BTM_NO_RESOURCES);
  696. }
  697. p->state = SCO_ST_CONNECTING;
  698. } else {
  699. p->state = SCO_ST_LISTENING;
  700. }
  701. }
  702. *p_sco_inx = xx;
  703. return (BTM_CMD_STARTED);
  704. }
  705. }
  706. #endif
  707. /* If here, all SCO blocks in use */
  708. return (BTM_NO_RESOURCES);
  709. }
  710. #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
  711. /*******************************************************************************
  712. **
  713. ** Function btm_sco_chk_pend_unpark
  714. **
  715. ** Description This function is called by BTIF when there is a mode change
  716. ** event to see if there are SCO commands waiting for the unpark.
  717. **
  718. ** Returns void
  719. **
  720. *******************************************************************************/
  721. void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle)
  722. {
  723. #if (BTM_MAX_SCO_LINKS>0)
  724. UINT16 xx;
  725. UINT16 acl_handle;
  726. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  727. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  728. if ((p->state == SCO_ST_PEND_UNPARK) &&
  729. ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
  730. {
  731. BTM_TRACE_API("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x",
  732. acl_handle, btm_cb.sco_cb.desired_sco_mode, hci_status);
  733. if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED) {
  734. p->state = SCO_ST_CONNECTING;
  735. }
  736. }
  737. }
  738. #endif // BTM_MAX_SCO_LINKS
  739. }
  740. #endif // BTM_SCO_WAKE_PARKED_LINK
  741. /*******************************************************************************
  742. **
  743. ** Function btm_sco_chk_pend_rolechange
  744. **
  745. ** Description This function is called by BTIF when there is a role change
  746. ** event to see if there are SCO commands waiting for the role change.
  747. **
  748. ** Returns void
  749. **
  750. *******************************************************************************/
  751. void btm_sco_chk_pend_rolechange (UINT16 hci_handle)
  752. {
  753. #if (BTM_MAX_SCO_LINKS>0)
  754. UINT16 xx;
  755. UINT16 acl_handle;
  756. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  757. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  758. if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
  759. ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
  760. {
  761. BTM_TRACE_API("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle);
  762. if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED) {
  763. p->state = SCO_ST_CONNECTING;
  764. }
  765. }
  766. }
  767. #endif
  768. }
  769. /*******************************************************************************
  770. **
  771. ** Function btm_sco_conn_req
  772. **
  773. ** Description This function is called by BTIF when an SCO connection
  774. ** request is received from a remote.
  775. **
  776. ** Returns void
  777. **
  778. *******************************************************************************/
  779. void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type)
  780. {
  781. #if (BTM_MAX_SCO_LINKS>0)
  782. tSCO_CB *p_sco = &btm_cb.sco_cb;
  783. tSCO_CONN *p = &p_sco->sco_db[0];
  784. UINT16 xx;
  785. tBTM_ESCO_CONN_REQ_EVT_DATA evt_data;
  786. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  787. /*
  788. * If the sco state is in the SCO_ST_CONNECTING state, we still need
  789. * to return accept sco to avoid race conditon for sco creation
  790. */
  791. int rem_bd_matches = p->rem_bd_known &&
  792. !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
  793. if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
  794. ((p->state == SCO_ST_LISTENING) && (rem_bd_matches || !p->rem_bd_known))) {
  795. /* If this guy was a wildcard, he is not one any more */
  796. p->rem_bd_known = TRUE;
  797. p->esco.data.link_type = link_type;
  798. p->state = SCO_ST_W4_CONN_RSP;
  799. memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
  800. /* If no callback, auto-accept the connection if packet types match */
  801. if (!p->esco.p_esco_cback) {
  802. /* If requesting eSCO reject if default parameters are SCO only */
  803. if ((link_type == BTM_LINK_TYPE_ESCO
  804. && !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK)
  805. && ((p_sco->def_esco_parms.packet_types & BTM_SCO_EXCEPTION_PKTS_MASK)
  806. == BTM_SCO_EXCEPTION_PKTS_MASK))
  807. /* Reject request if SCO is desired but no SCO packets delected */
  808. || (link_type == BTM_LINK_TYPE_SCO
  809. && !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK))) {
  810. btm_esco_conn_rsp(xx, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
  811. } else { /* Accept the request */
  812. btm_esco_conn_rsp(xx, HCI_SUCCESS, bda, NULL);
  813. }
  814. } else { /* Notify upper layer of connect indication */
  815. memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN);
  816. memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
  817. evt_data.link_type = link_type;
  818. evt_data.sco_inx = xx;
  819. p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, (tBTM_ESCO_EVT_DATA *)&evt_data);
  820. }
  821. return;
  822. }
  823. }
  824. /* TCS usage */
  825. if (btm_cb.sco_cb.app_sco_ind_cb) {
  826. /* Now, try to find an unused control block */
  827. for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  828. if (p->state == SCO_ST_UNUSED) {
  829. p->is_orig = FALSE;
  830. p->state = SCO_ST_LISTENING;
  831. p->esco.data.link_type = link_type;
  832. memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
  833. p->rem_bd_known = TRUE;
  834. break;
  835. }
  836. }
  837. if ( xx < BTM_MAX_SCO_LINKS) {
  838. btm_cb.sco_cb.app_sco_ind_cb(xx);
  839. return;
  840. }
  841. }
  842. #endif
  843. /* If here, no one wants the SCO connection. Reject it */
  844. BTM_TRACE_WARNING("btm_sco_conn_req: No one wants this SCO connection; rejecting it");
  845. btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
  846. }
  847. /*******************************************************************************
  848. **
  849. ** Function btm_sco_connected
  850. **
  851. ** Description This function is called by BTIF when an (e)SCO connection
  852. ** is connected.
  853. **
  854. ** Returns void
  855. **
  856. *******************************************************************************/
  857. void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle,
  858. tBTM_ESCO_DATA *p_esco_data)
  859. {
  860. #if (BTM_MAX_SCO_LINKS>0)
  861. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  862. UINT16 xx;
  863. BOOLEAN spt = FALSE;
  864. tBTM_CHG_ESCO_PARAMS parms;
  865. #endif
  866. btm_cb.sco_cb.sco_disc_reason = hci_status;
  867. BTM_TRACE_ERROR("%s, handle %x", __FUNCTION__, hci_handle);
  868. #if (BTM_MAX_SCO_LINKS>0)
  869. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  870. if (((p->state == SCO_ST_CONNECTING) ||
  871. (p->state == SCO_ST_LISTENING) ||
  872. (p->state == SCO_ST_W4_CONN_RSP))
  873. && (p->rem_bd_known)
  874. && (!bda || !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN))) {
  875. if (hci_status != HCI_SUCCESS) {
  876. /* Report the error if originator, otherwise remain in Listen mode */
  877. if (p->is_orig) {
  878. /* If role switch is pending, we need try again after role switch is complete */
  879. if (hci_status == HCI_ERR_ROLE_SWITCH_PENDING) {
  880. BTM_TRACE_API("Role Change pending for HCI handle 0x%04x", hci_handle);
  881. p->state = SCO_ST_PEND_ROLECHANGE;
  882. }
  883. /* avoid calling disconnect callback because of sco creation race */
  884. else if (hci_status != HCI_ERR_LMP_ERR_TRANS_COLLISION) {
  885. p->state = SCO_ST_UNUSED;
  886. (*p->p_disc_cb)(xx);
  887. }
  888. } else {
  889. /* Notify the upper layer that incoming sco connection has failed. */
  890. if (p->state == SCO_ST_CONNECTING) {
  891. p->state = SCO_ST_UNUSED;
  892. (*p->p_disc_cb)(xx);
  893. } else {
  894. p->state = SCO_ST_LISTENING;
  895. }
  896. }
  897. return;
  898. }
  899. if (p->state == SCO_ST_LISTENING) {
  900. spt = TRUE;
  901. }
  902. #if BTM_SCO_HCI_INCLUDED == TRUE
  903. p->sent_not_acked = 0;
  904. #endif
  905. p->state = SCO_ST_CONNECTED;
  906. p->hci_handle = hci_handle;
  907. if (!btm_cb.sco_cb.esco_supported) {
  908. p->esco.data.link_type = BTM_LINK_TYPE_SCO;
  909. if (spt) {
  910. parms.packet_types = p->esco.setup.packet_types;
  911. /* Keep the other parameters the same for SCO */
  912. parms.max_latency = p->esco.setup.max_latency;
  913. parms.retrans_effort = p->esco.setup.retrans_effort;
  914. BTM_ChangeEScoLinkParms(xx, &parms);
  915. }
  916. } else {
  917. if (p_esco_data) {
  918. p->esco.data = *p_esco_data;
  919. }
  920. }
  921. (*p->p_conn_cb)(xx);
  922. return;
  923. }
  924. }
  925. #endif
  926. }
  927. /*******************************************************************************
  928. **
  929. ** Function btm_find_scb_by_handle
  930. **
  931. ** Description Look through all active SCO connection for a match based on the
  932. ** HCI handle.
  933. **
  934. ** Returns index to matched SCO connection CB, or BTM_MAX_SCO_LINKS if
  935. ** no match.
  936. **
  937. *******************************************************************************/
  938. UINT16 btm_find_scb_by_handle (UINT16 handle)
  939. {
  940. int xx;
  941. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  942. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  943. if ((p->state == SCO_ST_CONNECTED) && (p->hci_handle == handle)) {
  944. return (xx);
  945. }
  946. }
  947. /* If here, no match found */
  948. return (xx);
  949. }
  950. /*******************************************************************************
  951. **
  952. ** Function BTM_RemoveSco
  953. **
  954. ** Description This function is called to remove a specific SCO connection.
  955. **
  956. ** Returns status of the operation
  957. **
  958. *******************************************************************************/
  959. tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx)
  960. {
  961. #if (BTM_MAX_SCO_LINKS>0)
  962. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
  963. UINT16 tempstate;
  964. /* Validity check */
  965. if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED)) {
  966. return (BTM_UNKNOWN_ADDR);
  967. }
  968. /* If no HCI handle, simply drop the connection and return */
  969. if (p->hci_handle == BTM_INVALID_HCI_HANDLE || p->state == SCO_ST_PEND_UNPARK) {
  970. p->hci_handle = BTM_INVALID_HCI_HANDLE;
  971. p->state = SCO_ST_UNUSED;
  972. p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
  973. return (BTM_SUCCESS);
  974. }
  975. tempstate = p->state;
  976. p->state = SCO_ST_DISCONNECTING;
  977. if (!btsnd_hcic_disconnect (p->hci_handle, HCI_ERR_PEER_USER)) {
  978. p->state = tempstate;
  979. return (BTM_NO_RESOURCES);
  980. }
  981. return (BTM_CMD_STARTED);
  982. #else
  983. return (BTM_NO_RESOURCES);
  984. #endif
  985. }
  986. /*******************************************************************************
  987. **
  988. ** Function btm_remove_sco_links
  989. **
  990. ** Description This function is called to remove all sco links for an ACL link.
  991. **
  992. ** Returns void
  993. **
  994. *******************************************************************************/
  995. void btm_remove_sco_links (BD_ADDR bda)
  996. {
  997. #if (BTM_MAX_SCO_LINKS>0)
  998. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  999. UINT16 xx;
  1000. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1001. if (p->rem_bd_known && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN))) {
  1002. BTM_RemoveSco(xx);
  1003. }
  1004. }
  1005. #endif
  1006. }
  1007. /*******************************************************************************
  1008. **
  1009. ** Function btm_sco_removed
  1010. **
  1011. ** Description This function is called by BTIF when an SCO connection
  1012. ** is removed.
  1013. **
  1014. ** Returns void
  1015. **
  1016. *******************************************************************************/
  1017. void btm_sco_removed (UINT16 hci_handle, UINT8 reason)
  1018. {
  1019. #if (BTM_MAX_SCO_LINKS>0)
  1020. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1021. UINT16 xx;
  1022. #endif
  1023. btm_cb.sco_cb.sco_disc_reason = reason;
  1024. #if (BTM_MAX_SCO_LINKS>0)
  1025. p = &btm_cb.sco_cb.sco_db[0];
  1026. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1027. if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle)) {
  1028. btm_sco_flush_sco_data(xx);
  1029. p->state = SCO_ST_UNUSED;
  1030. #if BTM_SCO_HCI_INCLUDED == TRUE
  1031. btm_cb.sco_cb.xmit_window_size += p->sent_not_acked;
  1032. /* avoid overflow */
  1033. if (btm_cb.sco_cb.xmit_window_size > btm_cb.sco_cb.num_lm_sco_bufs) {
  1034. btm_cb.sco_cb.xmit_window_size = btm_cb.sco_cb.num_lm_sco_bufs;
  1035. }
  1036. p->sent_not_acked = 0;
  1037. #endif
  1038. p->hci_handle = BTM_INVALID_HCI_HANDLE;
  1039. p->rem_bd_known = FALSE;
  1040. p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
  1041. (*p->p_disc_cb)(xx);
  1042. return;
  1043. }
  1044. }
  1045. #endif
  1046. }
  1047. /*******************************************************************************
  1048. **
  1049. ** Function btm_sco_acl_removed
  1050. **
  1051. ** Description This function is called when an ACL connection is
  1052. ** removed. If the BD address is NULL, it is assumed that
  1053. ** the local device is down, and all SCO links are removed.
  1054. ** If a specific BD address is passed, only SCO connections
  1055. ** to that BD address are removed.
  1056. **
  1057. ** Returns void
  1058. **
  1059. *******************************************************************************/
  1060. void btm_sco_acl_removed (BD_ADDR bda)
  1061. {
  1062. #if (BTM_MAX_SCO_LINKS>0)
  1063. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1064. UINT16 xx;
  1065. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1066. if (p->state != SCO_ST_UNUSED) {
  1067. if ((!bda) || (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN) && p->rem_bd_known)) {
  1068. btm_sco_flush_sco_data(xx);
  1069. p->state = SCO_ST_UNUSED;
  1070. p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
  1071. (*p->p_disc_cb)(xx);
  1072. }
  1073. }
  1074. }
  1075. #endif
  1076. }
  1077. /*******************************************************************************
  1078. **
  1079. ** Function BTM_SetScoPacketTypes
  1080. **
  1081. ** Description This function is called to set the packet types used for
  1082. ** a specific SCO connection,
  1083. **
  1084. ** Parameters pkt_types - One or more of the following
  1085. ** BTM_SCO_PKT_TYPES_MASK_HV1
  1086. ** BTM_SCO_PKT_TYPES_MASK_HV2
  1087. ** BTM_SCO_PKT_TYPES_MASK_HV3
  1088. ** BTM_SCO_PKT_TYPES_MASK_EV3
  1089. ** BTM_SCO_PKT_TYPES_MASK_EV4
  1090. ** BTM_SCO_PKT_TYPES_MASK_EV5
  1091. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
  1092. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
  1093. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
  1094. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
  1095. **
  1096. ** BTM_SCO_LINK_ALL_MASK - enables all supported types
  1097. **
  1098. ** Returns status of the operation
  1099. **
  1100. *******************************************************************************/
  1101. tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types)
  1102. {
  1103. #if (BTM_MAX_SCO_LINKS>0)
  1104. tBTM_CHG_ESCO_PARAMS parms;
  1105. tSCO_CONN *p;
  1106. /* Validity check */
  1107. if (sco_inx >= BTM_MAX_SCO_LINKS) {
  1108. return (BTM_UNKNOWN_ADDR);
  1109. }
  1110. p = &btm_cb.sco_cb.sco_db[sco_inx];
  1111. parms.packet_types = pkt_types;
  1112. /* Keep the other parameters the same for SCO */
  1113. parms.max_latency = p->esco.setup.max_latency;
  1114. parms.retrans_effort = p->esco.setup.retrans_effort;
  1115. return (BTM_ChangeEScoLinkParms(sco_inx, &parms));
  1116. #else
  1117. return (BTM_UNKNOWN_ADDR);
  1118. #endif
  1119. }
  1120. /*******************************************************************************
  1121. **
  1122. ** Function BTM_ReadScoPacketTypes
  1123. **
  1124. ** Description This function is read the packet types used for a specific
  1125. ** SCO connection.
  1126. **
  1127. ** Returns Packet types supported for the connection
  1128. ** One or more of the following (bitmask):
  1129. ** BTM_SCO_PKT_TYPES_MASK_HV1
  1130. ** BTM_SCO_PKT_TYPES_MASK_HV2
  1131. ** BTM_SCO_PKT_TYPES_MASK_HV3
  1132. ** BTM_SCO_PKT_TYPES_MASK_EV3
  1133. ** BTM_SCO_PKT_TYPES_MASK_EV4
  1134. ** BTM_SCO_PKT_TYPES_MASK_EV5
  1135. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
  1136. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
  1137. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
  1138. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
  1139. **
  1140. *******************************************************************************/
  1141. UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx)
  1142. {
  1143. #if (BTM_MAX_SCO_LINKS>0)
  1144. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
  1145. /* Validity check */
  1146. if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED)) {
  1147. return (p->esco.setup.packet_types);
  1148. } else {
  1149. return (0);
  1150. }
  1151. #else
  1152. return (0);
  1153. #endif
  1154. }
  1155. /*******************************************************************************
  1156. **
  1157. ** Function BTM_ReadScoDiscReason
  1158. **
  1159. ** Description This function is returns the reason why an (e)SCO connection
  1160. ** has been removed. It contains the value until read, or until
  1161. ** another (e)SCO connection has disconnected.
  1162. **
  1163. ** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
  1164. **
  1165. *******************************************************************************/
  1166. UINT16 BTM_ReadScoDiscReason (void)
  1167. {
  1168. UINT16 res = btm_cb.sco_cb.sco_disc_reason;
  1169. btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
  1170. return (res);
  1171. }
  1172. /*******************************************************************************
  1173. **
  1174. ** Function BTM_ReadDeviceScoPacketTypes
  1175. **
  1176. ** Description This function is read the SCO packet types that
  1177. ** the device supports.
  1178. **
  1179. ** Returns Packet types supported by the device.
  1180. ** One or more of the following (bitmask):
  1181. ** BTM_SCO_PKT_TYPES_MASK_HV1
  1182. ** BTM_SCO_PKT_TYPES_MASK_HV2
  1183. ** BTM_SCO_PKT_TYPES_MASK_HV3
  1184. ** BTM_SCO_PKT_TYPES_MASK_EV3
  1185. ** BTM_SCO_PKT_TYPES_MASK_EV4
  1186. ** BTM_SCO_PKT_TYPES_MASK_EV5
  1187. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
  1188. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
  1189. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
  1190. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
  1191. **
  1192. *******************************************************************************/
  1193. UINT16 BTM_ReadDeviceScoPacketTypes (void)
  1194. {
  1195. return (btm_cb.btm_sco_pkt_types_supported);
  1196. }
  1197. /*******************************************************************************
  1198. **
  1199. ** Function BTM_ReadScoHandle
  1200. **
  1201. ** Description This function is used to read the HCI handle used for a specific
  1202. ** SCO connection,
  1203. **
  1204. ** Returns handle for the connection, or 0xFFFF if invalid SCO index.
  1205. **
  1206. *******************************************************************************/
  1207. UINT16 BTM_ReadScoHandle (UINT16 sco_inx)
  1208. {
  1209. #if (BTM_MAX_SCO_LINKS>0)
  1210. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
  1211. /* Validity check */
  1212. if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED)) {
  1213. return (p->hci_handle);
  1214. } else {
  1215. return (BTM_INVALID_HCI_HANDLE);
  1216. }
  1217. #else
  1218. return (BTM_INVALID_HCI_HANDLE);
  1219. #endif
  1220. }
  1221. /*******************************************************************************
  1222. **
  1223. ** Function BTM_ReadScoBdAddr
  1224. **
  1225. ** Description This function is read the remote BD Address for a specific
  1226. ** SCO connection,
  1227. **
  1228. ** Returns pointer to BD address or NULL if not known
  1229. **
  1230. *******************************************************************************/
  1231. UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx)
  1232. {
  1233. #if (BTM_MAX_SCO_LINKS>0)
  1234. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
  1235. /* Validity check */
  1236. if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known)) {
  1237. return (p->esco.data.bd_addr);
  1238. } else {
  1239. return (NULL);
  1240. }
  1241. #else
  1242. return (NULL);
  1243. #endif
  1244. }
  1245. /*******************************************************************************
  1246. **
  1247. ** Function BTM_SetEScoMode
  1248. **
  1249. ** Description This function sets up the negotiated parameters for SCO or
  1250. ** eSCO, and sets as the default mode used for outgoing calls to
  1251. ** BTM_CreateSco. It does not change any currently active (e)SCO links.
  1252. ** Note: Incoming (e)SCO connections will always use packet types
  1253. ** supported by the controller. If eSCO is not desired the
  1254. ** feature should be disabled in the controller's feature mask.
  1255. **
  1256. ** Returns BTM_SUCCESS if the successful.
  1257. ** BTM_BUSY if there are one or more active (e)SCO links.
  1258. **
  1259. *******************************************************************************/
  1260. tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
  1261. {
  1262. tSCO_CB *p_esco = &btm_cb.sco_cb;
  1263. tBTM_ESCO_PARAMS *p_def = &p_esco->def_esco_parms;
  1264. if (p_esco->esco_supported) {
  1265. if (p_parms) {
  1266. if (sco_mode == BTM_LINK_TYPE_ESCO) {
  1267. *p_def = *p_parms; /* Save as the default parameters */
  1268. } else { /* Load only the SCO packet types */
  1269. p_def->packet_types = p_parms->packet_types;
  1270. p_def->tx_bw = BTM_64KBITS_RATE;
  1271. p_def->rx_bw = BTM_64KBITS_RATE;
  1272. p_def->max_latency = 0x000a;
  1273. p_def->voice_contfmt = 0x0060;
  1274. p_def->retrans_effort = 0;
  1275. /* OR in any exception packet types */
  1276. p_def->packet_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
  1277. }
  1278. }
  1279. p_esco->desired_sco_mode = sco_mode;
  1280. BTM_TRACE_API("BTM_SetEScoMode -> mode %d", sco_mode);
  1281. } else {
  1282. p_esco->desired_sco_mode = BTM_LINK_TYPE_SCO;
  1283. p_def->packet_types &= BTM_SCO_LINK_ONLY_MASK;
  1284. p_def->retrans_effort = 0;
  1285. BTM_TRACE_API("BTM_SetEScoMode -> mode SCO (eSCO not supported)");
  1286. }
  1287. BTM_TRACE_DEBUG(" txbw 0x%08x, rxbw 0x%08x, max_lat 0x%04x, voice 0x%04x, pkt 0x%04x, rtx effort 0x%02x",
  1288. p_def->tx_bw, p_def->rx_bw, p_def->max_latency,
  1289. p_def->voice_contfmt, p_def->packet_types,
  1290. p_def->retrans_effort);
  1291. return (BTM_SUCCESS);
  1292. }
  1293. /*******************************************************************************
  1294. **
  1295. ** Function BTM_RegForEScoEvts
  1296. **
  1297. ** Description This function registers a SCO event callback with the
  1298. ** specified instance. It should be used to received
  1299. ** connection indication events and change of link parameter
  1300. ** events.
  1301. **
  1302. ** Returns BTM_SUCCESS if the successful.
  1303. ** BTM_ILLEGAL_VALUE if there is an illegal sco_inx
  1304. ** BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
  1305. ** later or does not support eSCO.
  1306. **
  1307. *******************************************************************************/
  1308. tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback)
  1309. {
  1310. #if (BTM_MAX_SCO_LINKS>0)
  1311. if (!btm_cb.sco_cb.esco_supported) {
  1312. btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
  1313. return (BTM_MODE_UNSUPPORTED);
  1314. }
  1315. if (sco_inx < BTM_MAX_SCO_LINKS &&
  1316. btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED) {
  1317. btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
  1318. return (BTM_SUCCESS);
  1319. }
  1320. return (BTM_ILLEGAL_VALUE);
  1321. #else
  1322. return (BTM_MODE_UNSUPPORTED);
  1323. #endif
  1324. }
  1325. /*******************************************************************************
  1326. **
  1327. ** Function BTM_ReadEScoLinkParms
  1328. **
  1329. ** Description This function returns the current eSCO link parameters for
  1330. ** the specified handle. This can be called anytime a connection
  1331. ** is active, but is typically called after receiving the SCO
  1332. ** opened callback.
  1333. **
  1334. ** Note: If called over a 1.1 controller, only the packet types
  1335. ** field has meaning.
  1336. **
  1337. ** Returns BTM_SUCCESS if returned data is valid connection.
  1338. ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
  1339. **
  1340. *******************************************************************************/
  1341. tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms)
  1342. {
  1343. #if (BTM_MAX_SCO_LINKS>0)
  1344. UINT8 index;
  1345. BTM_TRACE_API("BTM_ReadEScoLinkParms -> sco_inx 0x%04x", sco_inx);
  1346. if (sco_inx < BTM_MAX_SCO_LINKS &&
  1347. btm_cb.sco_cb.sco_db[sco_inx].state >= SCO_ST_CONNECTED) {
  1348. *p_parms = btm_cb.sco_cb.sco_db[sco_inx].esco.data;
  1349. return (BTM_SUCCESS);
  1350. }
  1351. if (sco_inx == BTM_FIRST_ACTIVE_SCO_INDEX) {
  1352. for (index = 0; index < BTM_MAX_SCO_LINKS; index++) {
  1353. if (btm_cb.sco_cb.sco_db[index].state >= SCO_ST_CONNECTED) {
  1354. BTM_TRACE_API("BTM_ReadEScoLinkParms the first active SCO index is %d", index);
  1355. *p_parms = btm_cb.sco_cb.sco_db[index].esco.data;
  1356. return (BTM_SUCCESS);
  1357. }
  1358. }
  1359. }
  1360. #endif
  1361. BTM_TRACE_API("BTM_ReadEScoLinkParms cannot find the SCO index!");
  1362. memset(p_parms, 0, sizeof(tBTM_ESCO_DATA));
  1363. return (BTM_WRONG_MODE);
  1364. }
  1365. /*******************************************************************************
  1366. **
  1367. ** Function BTM_ChangeEScoLinkParms
  1368. **
  1369. ** Description This function requests renegotiation of the parameters on
  1370. ** the current eSCO Link. If any of the changes are accepted
  1371. ** by the controllers, the BTM_ESCO_CHG_EVT event is sent in
  1372. ** the tBTM_ESCO_CBACK function with the current settings of
  1373. ** the link. The callback is registered through the call to
  1374. ** BTM_SetEScoMode.
  1375. **
  1376. ** Note: If called over a SCO link (including 1.1 controller),
  1377. ** a change packet type request is sent out instead.
  1378. **
  1379. ** Returns BTM_CMD_STARTED if command is successfully initiated.
  1380. ** BTM_NO_RESOURCES - not enough resources to initiate command.
  1381. ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
  1382. **
  1383. *******************************************************************************/
  1384. tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms)
  1385. {
  1386. #if (BTM_MAX_SCO_LINKS>0)
  1387. tBTM_ESCO_PARAMS *p_setup;
  1388. tSCO_CONN *p_sco;
  1389. UINT16 temp_pkt_types;
  1390. /* Make sure sco handle is valid and on an active link */
  1391. if (sco_inx >= BTM_MAX_SCO_LINKS ||
  1392. btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED) {
  1393. return (BTM_WRONG_MODE);
  1394. }
  1395. p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
  1396. p_setup = &p_sco->esco.setup;
  1397. /* If SCO connection OR eSCO not supported just send change packet types */
  1398. if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
  1399. !btm_cb.sco_cb.esco_supported) {
  1400. p_setup->packet_types = p_parms->packet_types &
  1401. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
  1402. BTM_TRACE_API("BTM_ChangeEScoLinkParms -> SCO Link for handle 0x%04x, pkt 0x%04x",
  1403. p_sco->hci_handle, p_setup->packet_types);
  1404. if (!btsnd_hcic_change_conn_type (p_sco->hci_handle,
  1405. BTM_ESCO_2_SCO(p_setup->packet_types))) {
  1406. return (BTM_NO_RESOURCES);
  1407. }
  1408. } else {
  1409. temp_pkt_types = (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
  1410. btm_cb.btm_sco_pkt_types_supported);
  1411. /* OR in any exception packet types */
  1412. temp_pkt_types |= ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
  1413. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
  1414. BTM_TRACE_API("BTM_ChangeEScoLinkParms -> eSCO Link for handle 0x%04x", p_sco->hci_handle);
  1415. BTM_TRACE_API(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
  1416. p_setup->tx_bw, p_setup->rx_bw, p_parms->max_latency,
  1417. p_setup->voice_contfmt, p_parms->retrans_effort, temp_pkt_types);
  1418. /* When changing an existing link, only change latency, retrans, and pkts */
  1419. if (!btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->tx_bw,
  1420. p_setup->rx_bw, p_parms->max_latency,
  1421. p_setup->voice_contfmt,
  1422. p_parms->retrans_effort,
  1423. temp_pkt_types)) {
  1424. return (BTM_NO_RESOURCES);
  1425. } else {
  1426. p_parms->packet_types = temp_pkt_types;
  1427. }
  1428. }
  1429. return (BTM_CMD_STARTED);
  1430. #else
  1431. return (BTM_WRONG_MODE);
  1432. #endif
  1433. }
  1434. /*******************************************************************************
  1435. **
  1436. ** Function BTM_EScoConnRsp
  1437. **
  1438. ** Description This function is called upon receipt of an (e)SCO connection
  1439. ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
  1440. ** the request. Parameters used to negotiate eSCO links.
  1441. ** If p_parms is NULL, then values set through BTM_SetEScoMode
  1442. ** are used.
  1443. ** If the link type of the incoming request is SCO, then only
  1444. ** the tx_bw, max_latency, content format, and packet_types are
  1445. ** valid. The hci_status parameter should be
  1446. ** ([0x0] to accept, [0x0d..0x0f] to reject)
  1447. **
  1448. **
  1449. ** Returns void
  1450. **
  1451. *******************************************************************************/
  1452. void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms)
  1453. {
  1454. #if (BTM_MAX_SCO_LINKS>0)
  1455. if (sco_inx < BTM_MAX_SCO_LINKS &&
  1456. btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP) {
  1457. btm_esco_conn_rsp(sco_inx, hci_status,
  1458. btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr,
  1459. p_parms);
  1460. }
  1461. #endif
  1462. }
  1463. /*******************************************************************************
  1464. **
  1465. ** Function btm_read_def_esco_mode
  1466. **
  1467. ** Description This function copies the current default esco settings into
  1468. ** the return buffer.
  1469. **
  1470. ** Returns tBTM_SCO_TYPE
  1471. **
  1472. *******************************************************************************/
  1473. tBTM_SCO_TYPE btm_read_def_esco_mode (tBTM_ESCO_PARAMS *p_parms)
  1474. {
  1475. #if (BTM_MAX_SCO_LINKS>0)
  1476. *p_parms = btm_cb.sco_cb.def_esco_parms;
  1477. return btm_cb.sco_cb.desired_sco_mode;
  1478. #else
  1479. return BTM_LINK_TYPE_SCO;
  1480. #endif
  1481. }
  1482. /*******************************************************************************
  1483. **
  1484. ** Function btm_esco_proc_conn_chg
  1485. **
  1486. ** Description This function is called by BTIF when an SCO connection
  1487. ** is changed.
  1488. **
  1489. ** Returns void
  1490. **
  1491. *******************************************************************************/
  1492. void btm_esco_proc_conn_chg (UINT8 status, UINT16 handle, UINT8 tx_interval,
  1493. UINT8 retrans_window, UINT16 rx_pkt_len,
  1494. UINT16 tx_pkt_len)
  1495. {
  1496. #if (BTM_MAX_SCO_LINKS>0)
  1497. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1498. tBTM_CHG_ESCO_EVT_DATA data;
  1499. UINT16 xx;
  1500. BTM_TRACE_EVENT("btm_esco_proc_conn_chg -> handle 0x%04x, status 0x%02x",
  1501. handle, status);
  1502. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1503. if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle) {
  1504. /* If upper layer wants notification */
  1505. if (p->esco.p_esco_cback) {
  1506. memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN);
  1507. data.hci_status = status;
  1508. data.sco_inx = xx;
  1509. data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len;
  1510. data.tx_pkt_len = p->esco.data.tx_pkt_len = tx_pkt_len;
  1511. data.tx_interval = p->esco.data.tx_interval = tx_interval;
  1512. data.retrans_window = p->esco.data.retrans_window = retrans_window;
  1513. (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT,
  1514. (tBTM_ESCO_EVT_DATA *)&data);
  1515. }
  1516. return;
  1517. }
  1518. }
  1519. #endif
  1520. }
  1521. /*******************************************************************************
  1522. **
  1523. ** Function btm_is_sco_active
  1524. **
  1525. ** Description This function is called to see if a SCO handle is already in
  1526. ** use.
  1527. **
  1528. ** Returns BOOLEAN
  1529. **
  1530. *******************************************************************************/
  1531. BOOLEAN btm_is_sco_active (UINT16 handle)
  1532. {
  1533. #if (BTM_MAX_SCO_LINKS>0)
  1534. UINT16 xx;
  1535. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1536. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1537. if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED) {
  1538. return (TRUE);
  1539. }
  1540. }
  1541. #endif
  1542. return (FALSE);
  1543. }
  1544. /*******************************************************************************
  1545. **
  1546. ** Function BTM_GetNumScoLinks
  1547. **
  1548. ** Description This function returns the number of active sco links.
  1549. **
  1550. ** Returns UINT8
  1551. **
  1552. *******************************************************************************/
  1553. UINT8 BTM_GetNumScoLinks (void)
  1554. {
  1555. #if (BTM_MAX_SCO_LINKS>0)
  1556. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1557. UINT16 xx;
  1558. UINT8 num_scos = 0;
  1559. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1560. switch (p->state) {
  1561. case SCO_ST_W4_CONN_RSP:
  1562. case SCO_ST_CONNECTING:
  1563. case SCO_ST_CONNECTED:
  1564. case SCO_ST_DISCONNECTING:
  1565. case SCO_ST_PEND_UNPARK:
  1566. num_scos++;
  1567. }
  1568. }
  1569. return (num_scos);
  1570. #else
  1571. return (0);
  1572. #endif
  1573. }
  1574. /*******************************************************************************
  1575. **
  1576. ** Function btm_is_sco_active_by_bdaddr
  1577. **
  1578. ** Description This function is called to see if a SCO active to a bd address.
  1579. **
  1580. ** Returns BOOLEAN
  1581. **
  1582. *******************************************************************************/
  1583. BOOLEAN btm_is_sco_active_by_bdaddr (BD_ADDR remote_bda)
  1584. {
  1585. #if (BTM_MAX_SCO_LINKS>0)
  1586. UINT8 xx;
  1587. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1588. /* If any SCO is being established to the remote BD address, refuse this */
  1589. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1590. if ((!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) && (p->state == SCO_ST_CONNECTED)) {
  1591. return (TRUE);
  1592. }
  1593. }
  1594. #endif
  1595. return (FALSE);
  1596. }
  1597. #else /* SCO_EXCLUDED == TRUE (Link in stubs) */
  1598. tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig,
  1599. UINT16 pkt_types, UINT16 *p_sco_inx,
  1600. tBTM_SCO_CB *p_conn_cb,
  1601. tBTM_SCO_CB *p_disc_cb)
  1602. {
  1603. return (BTM_NO_RESOURCES);
  1604. }
  1605. tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx)
  1606. {
  1607. return (BTM_NO_RESOURCES);
  1608. }
  1609. tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types)
  1610. {
  1611. return (BTM_NO_RESOURCES);
  1612. }
  1613. UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx)
  1614. {
  1615. return (0);
  1616. }
  1617. UINT16 BTM_ReadDeviceScoPacketTypes (void)
  1618. {
  1619. return (0);
  1620. }
  1621. UINT16 BTM_ReadScoHandle (UINT16 sco_inx)
  1622. {
  1623. return (BTM_INVALID_HCI_HANDLE);
  1624. }
  1625. UINT8 *BTM_ReadScoBdAddr(UINT16 sco_inx)
  1626. {
  1627. return ((UINT8 *) NULL);
  1628. }
  1629. UINT16 BTM_ReadScoDiscReason (void)
  1630. {
  1631. return (BTM_INVALID_SCO_DISC_REASON);
  1632. }
  1633. tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
  1634. {
  1635. return (BTM_MODE_UNSUPPORTED);
  1636. }
  1637. tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback)
  1638. {
  1639. return (BTM_ILLEGAL_VALUE);
  1640. }
  1641. tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms)
  1642. {
  1643. return (BTM_MODE_UNSUPPORTED);
  1644. }
  1645. tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms)
  1646. {
  1647. return (BTM_MODE_UNSUPPORTED);
  1648. }
  1649. void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms) {}
  1650. UINT8 BTM_GetNumScoLinks (void)
  1651. {
  1652. return (0);
  1653. }
  1654. #endif /* If SCO is being used */