btm_sco.c 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907
  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. /*******************************************************************************
  318. **
  319. ** Function btm_pkt_stat_nums_update
  320. **
  321. ** Description Update the number of received SCO data packet status.
  322. **
  323. ** Returns void
  324. **
  325. *******************************************************************************/
  326. static void btm_pkt_stat_nums_update(uint16_t sco_inx, uint8_t pkt_status)
  327. {
  328. tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
  329. p_ccb->pkt_stat_nums.rx_total++;
  330. if (pkt_status == BTM_SCO_DATA_CORRECT) {
  331. p_ccb->pkt_stat_nums.rx_correct++;
  332. } else if (pkt_status == BTM_SCO_DATA_PAR_ERR) {
  333. p_ccb->pkt_stat_nums.rx_err++;
  334. } else if (pkt_status == BTM_SCO_DATA_NONE) {
  335. p_ccb->pkt_stat_nums.rx_none++;
  336. } else {
  337. p_ccb->pkt_stat_nums.rx_lost++;
  338. }
  339. }
  340. /*******************************************************************************
  341. **
  342. ** Function btm_pkt_stat_send_nums_update
  343. **
  344. ** Description Update the number of send packet status.
  345. **
  346. ** Returns void
  347. **
  348. *******************************************************************************/
  349. static void btm_pkt_stat_send_nums_update(uint16_t sco_inx, uint8_t pkt_status)
  350. {
  351. tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
  352. p_ccb->pkt_stat_nums.tx_total++;
  353. if (pkt_status != BTM_SUCCESS && pkt_status != BTM_NO_RESOURCES && pkt_status != BTM_SCO_BAD_LENGTH) {
  354. p_ccb->pkt_stat_nums.tx_discarded++;
  355. }
  356. }
  357. /*******************************************************************************
  358. **
  359. ** Function btm_pkt_stat_nums_reset
  360. **
  361. ** Description This function is called to reset the number of packet status struct
  362. **
  363. ** Returns void
  364. **
  365. *******************************************************************************/
  366. static void btm_pkt_stat_nums_reset(uint16_t sco_inx)
  367. {
  368. memset(&btm_cb.sco_cb.sco_db[sco_inx].pkt_stat_nums, 0, sizeof(tBTM_SCO_PKT_STAT_NUMS));
  369. }
  370. /*******************************************************************************
  371. **
  372. ** Function BTM_PktStatNumsGet
  373. **
  374. ** Description This function is called to get the number of packet status struct
  375. **
  376. ** Returns void
  377. **
  378. *******************************************************************************/
  379. void BTM_PktStatNumsGet(uint16_t sync_conn_handle, tBTM_SCO_PKT_STAT_NUMS *p_pkt_nums)
  380. {
  381. uint16_t sco_inx = btm_find_scb_by_handle(sync_conn_handle);
  382. if (sco_inx < BTM_MAX_SCO_LINKS) {
  383. memcpy(p_pkt_nums, &btm_cb.sco_cb.sco_db[sco_inx].pkt_stat_nums, sizeof(tBTM_SCO_PKT_STAT_NUMS));
  384. } else {
  385. memset(p_pkt_nums, 0, sizeof(tBTM_SCO_PKT_STAT_NUMS));
  386. }
  387. }
  388. #endif /* BTM_SCO_HCI_INCLUDED == TRUE */
  389. /*******************************************************************************
  390. **
  391. ** Function btm_route_sco_data
  392. **
  393. ** Description Route received SCO data.
  394. **
  395. ** Returns void
  396. **
  397. *******************************************************************************/
  398. void btm_route_sco_data(BT_HDR *p_msg)
  399. {
  400. #if BTM_SCO_HCI_INCLUDED == TRUE
  401. UINT16 sco_inx, handle;
  402. UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset;
  403. UINT8 pkt_size = 0;
  404. UINT8 pkt_status = 0;
  405. /* Extract Packet_Status_Flag and handle */
  406. STREAM_TO_UINT16 (handle, p);
  407. pkt_status = HCID_GET_EVENT(handle);
  408. handle = HCID_GET_HANDLE (handle);
  409. STREAM_TO_UINT8 (pkt_size, p);
  410. UNUSED(pkt_size);
  411. if ((sco_inx = btm_find_scb_by_handle(handle)) != BTM_MAX_SCO_LINKS ) {
  412. /* send data callback */
  413. if (!btm_cb.sco_cb.p_data_cb )
  414. /* if no data callback registered, just free the buffer */
  415. {
  416. osi_free (p_msg);
  417. } else {
  418. btm_pkt_stat_nums_update(sco_inx, pkt_status);
  419. (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg, (tBTM_SCO_DATA_FLAG) pkt_status);
  420. }
  421. } else { /* no mapping handle SCO connection is active, free the buffer */
  422. osi_free (p_msg);
  423. }
  424. BTM_TRACE_DEBUG ("SCO: hdl %x, len %d, pkt_sz %d\n", handle, p_msg->len, pkt_size);
  425. #else
  426. osi_free(p_msg);
  427. #endif
  428. }
  429. /*******************************************************************************
  430. **
  431. ** Function BTM_WriteScoData
  432. **
  433. ** Description This function write SCO data to a specified instance. The data
  434. ** to be written p_buf needs to carry an offset of
  435. ** HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not
  436. ** exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is set
  437. ** to 60 and is configurable. Data longer than the maximum bytes
  438. ** will be truncated.
  439. **
  440. ** Returns BTM_SUCCESS: data write is successful
  441. ** BTM_ILLEGAL_VALUE: SCO data contains illegal offset value.
  442. ** BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO packet
  443. ** size.
  444. ** BTM_NO_RESOURCES: no resources.
  445. ** BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is not
  446. ** routed via HCI.
  447. ** BTM_ERR_PROCESSING: transmit queue overflow
  448. **
  449. **
  450. *******************************************************************************/
  451. tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf)
  452. {
  453. APPL_TRACE_DEBUG("%s", __FUNCTION__);
  454. #if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTM_MAX_SCO_LINKS>0)
  455. tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
  456. UINT8 *p;
  457. tBTM_STATUS status = BTM_SUCCESS;
  458. if (sco_inx < BTM_MAX_SCO_LINKS && btm_cb.sco_cb.p_data_cb &&
  459. p_ccb->state == SCO_ST_CONNECTED) {
  460. /* Ensure we have enough space in the buffer for the SCO and HCI headers */
  461. if (p_buf->offset < HCI_SCO_PREAMBLE_SIZE) {
  462. BTM_TRACE_ERROR ("BTM SCO - cannot send buffer, offset: %d", p_buf->offset);
  463. status = BTM_ILLEGAL_VALUE;
  464. } else { /* write HCI header */
  465. /* Step back 3 bytes to add the headers */
  466. p_buf->offset -= HCI_SCO_PREAMBLE_SIZE;
  467. /* Set the pointer to the beginning of the data */
  468. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  469. /* add HCI handle */
  470. UINT16_TO_STREAM (p, p_ccb->hci_handle);
  471. /* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max,
  472. and set warning status */
  473. if (p_buf->len > BTM_SCO_DATA_SIZE_MAX) {
  474. BTM_TRACE_WARNING ("BTM SCO hdl %x, bad len %u", p_ccb->hci_handle, p_buf->len);
  475. p_buf->len = BTM_SCO_DATA_SIZE_MAX;
  476. status = BTM_SCO_BAD_LENGTH;
  477. }
  478. UINT8_TO_STREAM (p, (UINT8)p_buf->len);
  479. p_buf->len += HCI_SCO_PREAMBLE_SIZE;
  480. if (fixed_queue_length(p_ccb->xmit_data_q) < BTM_SCO_XMIT_QUEUE_THRS) {
  481. if (fixed_queue_length(p_ccb->xmit_data_q) >= BTM_SCO_XMIT_QUEUE_HIGH_WM) {
  482. status = BTM_NO_RESOURCES;
  483. }
  484. fixed_queue_enqueue(p_ccb->xmit_data_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT);
  485. btm_sco_check_send_pkts (sco_inx);
  486. } else {
  487. BTM_TRACE_WARNING ("SCO xmit Q overflow, pkt dropped");
  488. status = BTM_ERR_PROCESSING;
  489. }
  490. }
  491. } else {
  492. BTM_TRACE_WARNING ("BTM_WriteScoData, invalid sco index: %d at state [%d]",
  493. sco_inx, btm_cb.sco_cb.sco_db[sco_inx].state);
  494. status = BTM_UNKNOWN_ADDR;
  495. }
  496. if (status != BTM_SUCCESS && status!= BTM_NO_RESOURCES && status != BTM_SCO_BAD_LENGTH) {
  497. BTM_TRACE_WARNING ("stat %d", status);
  498. osi_free(p_buf);
  499. }
  500. btm_pkt_stat_send_nums_update(sco_inx, status);
  501. return (status);
  502. #else
  503. UNUSED(sco_inx);
  504. UNUSED(p_buf);
  505. return (BTM_NO_RESOURCES);
  506. #endif
  507. }
  508. #if (BTM_MAX_SCO_LINKS>0)
  509. /*******************************************************************************
  510. **
  511. ** Function btm_send_connect_request
  512. **
  513. ** Description This function is called to respond to SCO connect indications
  514. **
  515. ** Returns void
  516. **
  517. *******************************************************************************/
  518. static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle,
  519. tBTM_ESCO_PARAMS *p_setup)
  520. {
  521. UINT16 temp_pkt_types;
  522. tACL_CONN *p_acl;
  523. /* Send connect request depending on version of spec */
  524. if (!btm_cb.sco_cb.esco_supported) {
  525. if (!btsnd_hcic_add_SCO_conn (acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types))) {
  526. return (BTM_NO_RESOURCES);
  527. }
  528. } else {
  529. temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
  530. btm_cb.btm_sco_pkt_types_supported);
  531. /* OR in any exception packet types */
  532. temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
  533. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
  534. /* Finally, remove EDR eSCO if the remote device doesn't support it */
  535. /* UPF25: Only SCO was brought up in this case */
  536. p_acl = btm_handle_to_acl(acl_handle);
  537. if (p_acl) {
  538. if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
  539. BTM_TRACE_WARNING("BTM Remote does not support 2-EDR eSCO");
  540. temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 |
  541. HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5);
  542. }
  543. if (!HCI_EDR_ESCO_3MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0])) {
  544. BTM_TRACE_WARNING("BTM Remote does not support 3-EDR eSCO");
  545. temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 |
  546. HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5);
  547. }
  548. /* Check to see if BR/EDR Secure Connections is being used
  549. ** If so, we cannot use SCO-only packet types (HFP 1.7)
  550. */
  551. if (BTM_BothEndsSupportSecureConnections(p_acl->remote_addr)) {
  552. temp_pkt_types &= ~(BTM_SCO_PKT_TYPE_MASK);
  553. BTM_TRACE_DEBUG("%s: SCO Conn: pkt_types after removing SCO (0x%04x)", __FUNCTION__,
  554. temp_pkt_types);
  555. /* Return error if no packet types left */
  556. if (temp_pkt_types == 0) {
  557. BTM_TRACE_ERROR("%s: SCO Conn (BR/EDR SC): No packet types available",__FUNCTION__);
  558. return (BTM_WRONG_MODE);
  559. }
  560. } else {
  561. BTM_TRACE_DEBUG("%s: SCO Conn(BR/EDR SC):local or peer does not support BR/EDR SC",__FUNCTION__);
  562. }
  563. }
  564. BTM_TRACE_API("txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
  565. p_setup->tx_bw, p_setup->rx_bw,
  566. p_setup->max_latency, p_setup->voice_contfmt,
  567. p_setup->retrans_effort, temp_pkt_types);
  568. if (!btsnd_hcic_setup_esco_conn(acl_handle,
  569. p_setup->tx_bw,
  570. p_setup->rx_bw,
  571. p_setup->max_latency,
  572. p_setup->voice_contfmt,
  573. p_setup->retrans_effort,
  574. temp_pkt_types)) {
  575. return (BTM_NO_RESOURCES);
  576. } else {
  577. p_setup->packet_types = temp_pkt_types;
  578. }
  579. }
  580. return (BTM_CMD_STARTED);
  581. }
  582. #endif
  583. /*******************************************************************************
  584. **
  585. ** Function btm_set_sco_ind_cback
  586. **
  587. ** Description This function is called to register for TCS SCO connect
  588. ** indications.
  589. **
  590. ** Returns void
  591. **
  592. *******************************************************************************/
  593. void btm_set_sco_ind_cback( tBTM_SCO_IND_CBACK *sco_ind_cb )
  594. {
  595. btm_cb.sco_cb.app_sco_ind_cb = sco_ind_cb;
  596. }
  597. /*******************************************************************************
  598. **
  599. ** Function btm_accept_sco_link
  600. **
  601. ** Description This function is called to respond to TCS SCO connect
  602. ** indications
  603. **
  604. ** Returns void
  605. **
  606. *******************************************************************************/
  607. void btm_accept_sco_link(UINT16 sco_inx, tBTM_ESCO_PARAMS *p_setup,
  608. tBTM_SCO_CB *p_conn_cb, tBTM_SCO_CB *p_disc_cb)
  609. {
  610. #if (BTM_MAX_SCO_LINKS>0)
  611. tSCO_CONN *p_sco;
  612. if (sco_inx >= BTM_MAX_SCO_LINKS) {
  613. BTM_TRACE_ERROR("btm_accept_sco_link: Invalid sco_inx(%d)", sco_inx);
  614. return;
  615. }
  616. /* Link role is ignored in for this message */
  617. p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
  618. p_sco->p_conn_cb = p_conn_cb;
  619. p_sco->p_disc_cb = p_disc_cb;
  620. p_sco->esco.data.link_type = BTM_LINK_TYPE_ESCO; /* Accept with all supported types */
  621. BTM_TRACE_DEBUG("TCS accept SCO: Packet Types 0x%04x", p_setup->packet_types);
  622. btm_esco_conn_rsp(sco_inx, HCI_SUCCESS, p_sco->esco.data.bd_addr, p_setup);
  623. #else
  624. btm_reject_sco_link(sco_inx);
  625. #endif
  626. }
  627. /*******************************************************************************
  628. **
  629. ** Function btm_reject_sco_link
  630. **
  631. ** Description This function is called to respond to SCO connect indications
  632. **
  633. ** Returns void
  634. **
  635. *******************************************************************************/
  636. void btm_reject_sco_link( UINT16 sco_inx )
  637. {
  638. btm_esco_conn_rsp(sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
  639. btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, NULL);
  640. }
  641. /*******************************************************************************
  642. **
  643. ** Function BTM_CreateSco
  644. **
  645. ** Description This function is called to create an SCO connection. If the
  646. ** "is_orig" flag is TRUE, the connection will be originated,
  647. ** otherwise BTM will wait for the other side to connect.
  648. **
  649. ** NOTE: If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
  650. ** parameter the default packet types is used.
  651. **
  652. ** Returns BTM_UNKNOWN_ADDR if the ACL connection is not up
  653. ** BTM_BUSY if another SCO being set up to
  654. ** the same BD address
  655. ** BTM_NO_RESOURCES if the max SCO limit has been reached
  656. ** BTM_CMD_STARTED if the connection establishment is started.
  657. ** In this case, "*p_sco_inx" is filled in
  658. ** with the sco index used for the connection.
  659. **
  660. *******************************************************************************/
  661. tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types,
  662. UINT16 *p_sco_inx, tBTM_SCO_CB *p_conn_cb,
  663. tBTM_SCO_CB *p_disc_cb)
  664. {
  665. #if (BTM_MAX_SCO_LINKS > 0)
  666. tBTM_ESCO_PARAMS *p_setup;
  667. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  668. UINT16 xx;
  669. UINT16 acl_handle = 0;
  670. UINT16 temp_pkt_types;
  671. tACL_CONN *p_acl;
  672. #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
  673. tBTM_PM_MODE md;
  674. tBTM_PM_PWR_MD pm;
  675. #else // BTM_SCO_WAKE_PARKED_LINK
  676. UINT8 mode;
  677. #endif // BTM_SCO_WAKE_PARKED_LINK
  678. *p_sco_inx = BTM_INVALID_SCO_INDEX;
  679. /* If originating, ensure that there is an ACL connection to the BD Address */
  680. if (is_orig) {
  681. if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda, BT_TRANSPORT_BR_EDR)) == 0xFFFF)) {
  682. return (BTM_UNKNOWN_ADDR);
  683. }
  684. }
  685. if (remote_bda) {
  686. /* If any SCO is being established to the remote BD address, refuse this */
  687. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  688. if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING)
  689. || (p->state == SCO_ST_PEND_UNPARK))
  690. && (!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN))) {
  691. return (BTM_BUSY);
  692. }
  693. }
  694. } else {
  695. /* Support only 1 wildcard BD address at a time */
  696. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  697. if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known)) {
  698. return (BTM_BUSY);
  699. }
  700. }
  701. }
  702. /* Now, try to find an unused control block, and kick off the SCO establishment */
  703. for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  704. if (p->state == SCO_ST_UNUSED) {
  705. if (remote_bda) {
  706. if (is_orig) {
  707. /* can not create SCO link if in park mode */
  708. #if BTM_SCO_WAKE_PARKED_LINK == TRUE
  709. if (BTM_ReadPowerMode(remote_bda, &md) == BTM_SUCCESS) {
  710. if (md == BTM_PM_MD_PARK || md == BTM_PM_MD_SNIFF) {
  711. memset( (void *)&pm, 0, sizeof(pm));
  712. pm.mode = BTM_PM_MD_ACTIVE;
  713. BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm);
  714. p->state = SCO_ST_PEND_UNPARK;
  715. }
  716. }
  717. #else // BTM_SCO_WAKE_PARKED_LINK
  718. if ( (BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_PM_MD_PARK) ) {
  719. return (BTM_WRONG_MODE);
  720. }
  721. #endif // BTM_SCO_WAKE_PARKED_LINK
  722. }
  723. memcpy (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN);
  724. p->rem_bd_known = TRUE;
  725. } else {
  726. p->rem_bd_known = FALSE;
  727. }
  728. /* Link role is ignored in for this message */
  729. if (pkt_types == BTM_IGNORE_SCO_PKT_TYPE) {
  730. pkt_types = btm_cb.sco_cb.def_esco_parms.packet_types;
  731. }
  732. p_setup = &p->esco.setup;
  733. *p_setup = btm_cb.sco_cb.def_esco_parms;
  734. p_setup->packet_types = (btm_cb.sco_cb.desired_sco_mode == BTM_LINK_TYPE_SCO)
  735. ? (pkt_types & BTM_SCO_LINK_ONLY_MASK) : pkt_types;
  736. temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
  737. btm_cb.btm_sco_pkt_types_supported);
  738. /* OR in any exception packet types */
  739. if (btm_cb.sco_cb.desired_sco_mode == HCI_LINK_TYPE_ESCO) {
  740. temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
  741. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
  742. } else { /* Only using SCO packet types; turn off EDR also */
  743. temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
  744. }
  745. p_setup->packet_types = temp_pkt_types;
  746. p->p_conn_cb = p_conn_cb;
  747. p->p_disc_cb = p_disc_cb;
  748. p->hci_handle = BTM_INVALID_HCI_HANDLE;
  749. p->is_orig = is_orig;
  750. if ( p->state != SCO_ST_PEND_UNPARK ) {
  751. if (is_orig) {
  752. /* If role change is in progress, do not proceed with SCO setup
  753. * Wait till role change is complete */
  754. p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
  755. if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE) {
  756. BTM_TRACE_API("Role Change is in progress for ACL handle 0x%04x", acl_handle);
  757. p->state = SCO_ST_PEND_ROLECHANGE;
  758. }
  759. }
  760. }
  761. if ( p->state != SCO_ST_PEND_UNPARK && p->state != SCO_ST_PEND_ROLECHANGE ) {
  762. if (is_orig) {
  763. BTM_TRACE_API("BTM_CreateSco -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d",
  764. acl_handle, btm_cb.sco_cb.desired_sco_mode);
  765. if ((btm_send_connect_request(acl_handle, p_setup)) != BTM_CMD_STARTED) {
  766. return (BTM_NO_RESOURCES);
  767. }
  768. p->state = SCO_ST_CONNECTING;
  769. } else {
  770. p->state = SCO_ST_LISTENING;
  771. }
  772. }
  773. *p_sco_inx = xx;
  774. return (BTM_CMD_STARTED);
  775. }
  776. }
  777. #endif
  778. /* If here, all SCO blocks in use */
  779. return (BTM_NO_RESOURCES);
  780. }
  781. #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
  782. /*******************************************************************************
  783. **
  784. ** Function btm_sco_chk_pend_unpark
  785. **
  786. ** Description This function is called by BTIF when there is a mode change
  787. ** event to see if there are SCO commands waiting for the unpark.
  788. **
  789. ** Returns void
  790. **
  791. *******************************************************************************/
  792. void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle)
  793. {
  794. #if (BTM_MAX_SCO_LINKS>0)
  795. UINT16 xx;
  796. UINT16 acl_handle;
  797. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  798. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  799. if ((p->state == SCO_ST_PEND_UNPARK) &&
  800. ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
  801. {
  802. BTM_TRACE_API("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x",
  803. acl_handle, btm_cb.sco_cb.desired_sco_mode, hci_status);
  804. if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED) {
  805. p->state = SCO_ST_CONNECTING;
  806. }
  807. }
  808. }
  809. #endif // BTM_MAX_SCO_LINKS
  810. }
  811. #endif // BTM_SCO_WAKE_PARKED_LINK
  812. /*******************************************************************************
  813. **
  814. ** Function btm_sco_chk_pend_rolechange
  815. **
  816. ** Description This function is called by BTIF when there is a role change
  817. ** event to see if there are SCO commands waiting for the role change.
  818. **
  819. ** Returns void
  820. **
  821. *******************************************************************************/
  822. void btm_sco_chk_pend_rolechange (UINT16 hci_handle)
  823. {
  824. #if (BTM_MAX_SCO_LINKS>0)
  825. UINT16 xx;
  826. UINT16 acl_handle;
  827. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  828. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  829. if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
  830. ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
  831. {
  832. BTM_TRACE_API("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle);
  833. if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED) {
  834. p->state = SCO_ST_CONNECTING;
  835. }
  836. }
  837. }
  838. #endif
  839. }
  840. /*******************************************************************************
  841. **
  842. ** Function btm_sco_conn_req
  843. **
  844. ** Description This function is called by BTIF when an SCO connection
  845. ** request is received from a remote.
  846. **
  847. ** Returns void
  848. **
  849. *******************************************************************************/
  850. void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type)
  851. {
  852. #if (BTM_MAX_SCO_LINKS>0)
  853. tSCO_CB *p_sco = &btm_cb.sco_cb;
  854. tSCO_CONN *p = &p_sco->sco_db[0];
  855. UINT16 xx;
  856. tBTM_ESCO_CONN_REQ_EVT_DATA evt_data;
  857. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  858. /*
  859. * If the sco state is in the SCO_ST_CONNECTING state, we still need
  860. * to return accept sco to avoid race conditon for sco creation
  861. */
  862. int rem_bd_matches = p->rem_bd_known &&
  863. !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
  864. if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
  865. ((p->state == SCO_ST_LISTENING) && (rem_bd_matches || !p->rem_bd_known))) {
  866. /* If this guy was a wildcard, he is not one any more */
  867. p->rem_bd_known = TRUE;
  868. p->esco.data.link_type = link_type;
  869. p->state = SCO_ST_W4_CONN_RSP;
  870. memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
  871. /* If no callback, auto-accept the connection if packet types match */
  872. if (!p->esco.p_esco_cback) {
  873. /* If requesting eSCO reject if default parameters are SCO only */
  874. if ((link_type == BTM_LINK_TYPE_ESCO
  875. && !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK)
  876. && ((p_sco->def_esco_parms.packet_types & BTM_SCO_EXCEPTION_PKTS_MASK)
  877. == BTM_SCO_EXCEPTION_PKTS_MASK))
  878. /* Reject request if SCO is desired but no SCO packets delected */
  879. || (link_type == BTM_LINK_TYPE_SCO
  880. && !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK))) {
  881. btm_esco_conn_rsp(xx, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
  882. } else { /* Accept the request */
  883. btm_esco_conn_rsp(xx, HCI_SUCCESS, bda, NULL);
  884. }
  885. } else { /* Notify upper layer of connect indication */
  886. memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN);
  887. memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
  888. evt_data.link_type = link_type;
  889. evt_data.sco_inx = xx;
  890. p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, (tBTM_ESCO_EVT_DATA *)&evt_data);
  891. }
  892. return;
  893. }
  894. }
  895. /* TCS usage */
  896. if (btm_cb.sco_cb.app_sco_ind_cb) {
  897. /* Now, try to find an unused control block */
  898. for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  899. if (p->state == SCO_ST_UNUSED) {
  900. p->is_orig = FALSE;
  901. p->state = SCO_ST_LISTENING;
  902. p->esco.data.link_type = link_type;
  903. memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
  904. p->rem_bd_known = TRUE;
  905. break;
  906. }
  907. }
  908. if ( xx < BTM_MAX_SCO_LINKS) {
  909. btm_cb.sco_cb.app_sco_ind_cb(xx);
  910. return;
  911. }
  912. }
  913. #endif
  914. /* If here, no one wants the SCO connection. Reject it */
  915. BTM_TRACE_WARNING("btm_sco_conn_req: No one wants this SCO connection; rejecting it");
  916. btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
  917. }
  918. /*******************************************************************************
  919. **
  920. ** Function btm_sco_connected
  921. **
  922. ** Description This function is called by BTIF when an (e)SCO connection
  923. ** is connected.
  924. **
  925. ** Returns void
  926. **
  927. *******************************************************************************/
  928. void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle,
  929. tBTM_ESCO_DATA *p_esco_data)
  930. {
  931. #if (BTM_MAX_SCO_LINKS>0)
  932. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  933. UINT16 xx;
  934. BOOLEAN spt = FALSE;
  935. tBTM_CHG_ESCO_PARAMS parms;
  936. #endif
  937. btm_cb.sco_cb.sco_disc_reason = hci_status;
  938. BTM_TRACE_API("%s, handle %x", __FUNCTION__, hci_handle);
  939. #if (BTM_MAX_SCO_LINKS>0)
  940. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  941. if (((p->state == SCO_ST_CONNECTING) ||
  942. (p->state == SCO_ST_LISTENING) ||
  943. (p->state == SCO_ST_W4_CONN_RSP))
  944. && (p->rem_bd_known)
  945. && (!bda || !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN))) {
  946. if (hci_status != HCI_SUCCESS) {
  947. /* Report the error if originator, otherwise remain in Listen mode */
  948. if (p->is_orig) {
  949. /* If role switch is pending, we need try again after role switch is complete */
  950. if (hci_status == HCI_ERR_ROLE_SWITCH_PENDING) {
  951. BTM_TRACE_API("Role Change pending for HCI handle 0x%04x", hci_handle);
  952. p->state = SCO_ST_PEND_ROLECHANGE;
  953. }
  954. /* avoid calling disconnect callback because of sco creation race */
  955. else if (hci_status != HCI_ERR_LMP_ERR_TRANS_COLLISION) {
  956. p->state = SCO_ST_UNUSED;
  957. (*p->p_disc_cb)(xx);
  958. }
  959. } else {
  960. /* Notify the upper layer that incoming sco connection has failed. */
  961. if (p->state == SCO_ST_CONNECTING) {
  962. p->state = SCO_ST_UNUSED;
  963. (*p->p_disc_cb)(xx);
  964. } else {
  965. p->state = SCO_ST_LISTENING;
  966. }
  967. }
  968. return;
  969. }
  970. if (p->state == SCO_ST_LISTENING) {
  971. spt = TRUE;
  972. }
  973. #if BTM_SCO_HCI_INCLUDED == TRUE
  974. p->sent_not_acked = 0;
  975. btm_pkt_stat_nums_reset(xx);
  976. #endif
  977. p->state = SCO_ST_CONNECTED;
  978. p->hci_handle = hci_handle;
  979. if (!btm_cb.sco_cb.esco_supported) {
  980. p->esco.data.link_type = BTM_LINK_TYPE_SCO;
  981. if (spt) {
  982. parms.packet_types = p->esco.setup.packet_types;
  983. /* Keep the other parameters the same for SCO */
  984. parms.max_latency = p->esco.setup.max_latency;
  985. parms.retrans_effort = p->esco.setup.retrans_effort;
  986. BTM_ChangeEScoLinkParms(xx, &parms);
  987. }
  988. } else {
  989. if (p_esco_data) {
  990. p->esco.data = *p_esco_data;
  991. }
  992. }
  993. (*p->p_conn_cb)(xx);
  994. return;
  995. }
  996. }
  997. #endif
  998. }
  999. /*******************************************************************************
  1000. **
  1001. ** Function btm_find_scb_by_handle
  1002. **
  1003. ** Description Look through all active SCO connection for a match based on the
  1004. ** HCI handle.
  1005. **
  1006. ** Returns index to matched SCO connection CB, or BTM_MAX_SCO_LINKS if
  1007. ** no match.
  1008. **
  1009. *******************************************************************************/
  1010. UINT16 btm_find_scb_by_handle (UINT16 handle)
  1011. {
  1012. int xx;
  1013. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1014. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1015. if ((p->state == SCO_ST_CONNECTED) && (p->hci_handle == handle)) {
  1016. return (xx);
  1017. }
  1018. }
  1019. /* If here, no match found */
  1020. return (xx);
  1021. }
  1022. /*******************************************************************************
  1023. **
  1024. ** Function BTM_RemoveSco
  1025. **
  1026. ** Description This function is called to remove a specific SCO connection.
  1027. **
  1028. ** Returns status of the operation
  1029. **
  1030. *******************************************************************************/
  1031. tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx)
  1032. {
  1033. #if (BTM_MAX_SCO_LINKS>0)
  1034. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
  1035. UINT16 tempstate;
  1036. /* Validity check */
  1037. if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED)) {
  1038. return (BTM_UNKNOWN_ADDR);
  1039. }
  1040. /* If no HCI handle, simply drop the connection and return */
  1041. if (p->hci_handle == BTM_INVALID_HCI_HANDLE || p->state == SCO_ST_PEND_UNPARK) {
  1042. p->hci_handle = BTM_INVALID_HCI_HANDLE;
  1043. p->state = SCO_ST_UNUSED;
  1044. p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
  1045. return (BTM_SUCCESS);
  1046. }
  1047. tempstate = p->state;
  1048. p->state = SCO_ST_DISCONNECTING;
  1049. if (!btsnd_hcic_disconnect (p->hci_handle, HCI_ERR_PEER_USER)) {
  1050. p->state = tempstate;
  1051. return (BTM_NO_RESOURCES);
  1052. }
  1053. return (BTM_CMD_STARTED);
  1054. #else
  1055. return (BTM_NO_RESOURCES);
  1056. #endif
  1057. }
  1058. /*******************************************************************************
  1059. **
  1060. ** Function btm_remove_sco_links
  1061. **
  1062. ** Description This function is called to remove all sco links for an ACL link.
  1063. **
  1064. ** Returns void
  1065. **
  1066. *******************************************************************************/
  1067. void btm_remove_sco_links (BD_ADDR bda)
  1068. {
  1069. #if (BTM_MAX_SCO_LINKS>0)
  1070. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1071. UINT16 xx;
  1072. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1073. if (p->rem_bd_known && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN))) {
  1074. BTM_RemoveSco(xx);
  1075. }
  1076. }
  1077. #endif
  1078. }
  1079. /*******************************************************************************
  1080. **
  1081. ** Function btm_sco_removed
  1082. **
  1083. ** Description This function is called by BTIF when an SCO connection
  1084. ** is removed.
  1085. **
  1086. ** Returns void
  1087. **
  1088. *******************************************************************************/
  1089. void btm_sco_removed (UINT16 hci_handle, UINT8 reason)
  1090. {
  1091. #if (BTM_MAX_SCO_LINKS>0)
  1092. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1093. UINT16 xx;
  1094. #endif
  1095. btm_cb.sco_cb.sco_disc_reason = reason;
  1096. #if (BTM_MAX_SCO_LINKS>0)
  1097. p = &btm_cb.sco_cb.sco_db[0];
  1098. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1099. if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle)) {
  1100. btm_sco_flush_sco_data(xx);
  1101. p->state = SCO_ST_UNUSED;
  1102. #if BTM_SCO_HCI_INCLUDED == TRUE
  1103. btm_cb.sco_cb.xmit_window_size += p->sent_not_acked;
  1104. /* avoid overflow */
  1105. if (btm_cb.sco_cb.xmit_window_size > btm_cb.sco_cb.num_lm_sco_bufs) {
  1106. btm_cb.sco_cb.xmit_window_size = btm_cb.sco_cb.num_lm_sco_bufs;
  1107. }
  1108. p->sent_not_acked = 0;
  1109. #endif
  1110. p->hci_handle = BTM_INVALID_HCI_HANDLE;
  1111. p->rem_bd_known = FALSE;
  1112. p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
  1113. (*p->p_disc_cb)(xx);
  1114. return;
  1115. }
  1116. }
  1117. #endif
  1118. }
  1119. /*******************************************************************************
  1120. **
  1121. ** Function btm_sco_acl_removed
  1122. **
  1123. ** Description This function is called when an ACL connection is
  1124. ** removed. If the BD address is NULL, it is assumed that
  1125. ** the local device is down, and all SCO links are removed.
  1126. ** If a specific BD address is passed, only SCO connections
  1127. ** to that BD address are removed.
  1128. **
  1129. ** Returns void
  1130. **
  1131. *******************************************************************************/
  1132. void btm_sco_acl_removed (BD_ADDR bda)
  1133. {
  1134. #if (BTM_MAX_SCO_LINKS>0)
  1135. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1136. UINT16 xx;
  1137. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1138. if (p->state != SCO_ST_UNUSED) {
  1139. if ((!bda) || (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN) && p->rem_bd_known)) {
  1140. btm_sco_flush_sco_data(xx);
  1141. p->state = SCO_ST_UNUSED;
  1142. p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
  1143. (*p->p_disc_cb)(xx);
  1144. }
  1145. }
  1146. }
  1147. #endif
  1148. }
  1149. /*******************************************************************************
  1150. **
  1151. ** Function BTM_SetScoPacketTypes
  1152. **
  1153. ** Description This function is called to set the packet types used for
  1154. ** a specific SCO connection,
  1155. **
  1156. ** Parameters pkt_types - One or more of the following
  1157. ** BTM_SCO_PKT_TYPES_MASK_HV1
  1158. ** BTM_SCO_PKT_TYPES_MASK_HV2
  1159. ** BTM_SCO_PKT_TYPES_MASK_HV3
  1160. ** BTM_SCO_PKT_TYPES_MASK_EV3
  1161. ** BTM_SCO_PKT_TYPES_MASK_EV4
  1162. ** BTM_SCO_PKT_TYPES_MASK_EV5
  1163. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
  1164. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
  1165. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
  1166. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
  1167. **
  1168. ** BTM_SCO_LINK_ALL_MASK - enables all supported types
  1169. **
  1170. ** Returns status of the operation
  1171. **
  1172. *******************************************************************************/
  1173. tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types)
  1174. {
  1175. #if (BTM_MAX_SCO_LINKS>0)
  1176. tBTM_CHG_ESCO_PARAMS parms;
  1177. tSCO_CONN *p;
  1178. /* Validity check */
  1179. if (sco_inx >= BTM_MAX_SCO_LINKS) {
  1180. return (BTM_UNKNOWN_ADDR);
  1181. }
  1182. p = &btm_cb.sco_cb.sco_db[sco_inx];
  1183. parms.packet_types = pkt_types;
  1184. /* Keep the other parameters the same for SCO */
  1185. parms.max_latency = p->esco.setup.max_latency;
  1186. parms.retrans_effort = p->esco.setup.retrans_effort;
  1187. return (BTM_ChangeEScoLinkParms(sco_inx, &parms));
  1188. #else
  1189. return (BTM_UNKNOWN_ADDR);
  1190. #endif
  1191. }
  1192. /*******************************************************************************
  1193. **
  1194. ** Function BTM_ReadScoPacketTypes
  1195. **
  1196. ** Description This function is read the packet types used for a specific
  1197. ** SCO connection.
  1198. **
  1199. ** Returns Packet types supported for the connection
  1200. ** One or more of the following (bitmask):
  1201. ** BTM_SCO_PKT_TYPES_MASK_HV1
  1202. ** BTM_SCO_PKT_TYPES_MASK_HV2
  1203. ** BTM_SCO_PKT_TYPES_MASK_HV3
  1204. ** BTM_SCO_PKT_TYPES_MASK_EV3
  1205. ** BTM_SCO_PKT_TYPES_MASK_EV4
  1206. ** BTM_SCO_PKT_TYPES_MASK_EV5
  1207. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
  1208. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
  1209. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
  1210. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
  1211. **
  1212. *******************************************************************************/
  1213. UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx)
  1214. {
  1215. #if (BTM_MAX_SCO_LINKS>0)
  1216. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
  1217. /* Validity check */
  1218. if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED)) {
  1219. return (p->esco.setup.packet_types);
  1220. } else {
  1221. return (0);
  1222. }
  1223. #else
  1224. return (0);
  1225. #endif
  1226. }
  1227. /*******************************************************************************
  1228. **
  1229. ** Function BTM_ReadScoDiscReason
  1230. **
  1231. ** Description This function is returns the reason why an (e)SCO connection
  1232. ** has been removed. It contains the value until read, or until
  1233. ** another (e)SCO connection has disconnected.
  1234. **
  1235. ** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
  1236. **
  1237. *******************************************************************************/
  1238. UINT16 BTM_ReadScoDiscReason (void)
  1239. {
  1240. UINT16 res = btm_cb.sco_cb.sco_disc_reason;
  1241. btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
  1242. return (res);
  1243. }
  1244. /*******************************************************************************
  1245. **
  1246. ** Function BTM_ReadDeviceScoPacketTypes
  1247. **
  1248. ** Description This function is read the SCO packet types that
  1249. ** the device supports.
  1250. **
  1251. ** Returns Packet types supported by the device.
  1252. ** One or more of the following (bitmask):
  1253. ** BTM_SCO_PKT_TYPES_MASK_HV1
  1254. ** BTM_SCO_PKT_TYPES_MASK_HV2
  1255. ** BTM_SCO_PKT_TYPES_MASK_HV3
  1256. ** BTM_SCO_PKT_TYPES_MASK_EV3
  1257. ** BTM_SCO_PKT_TYPES_MASK_EV4
  1258. ** BTM_SCO_PKT_TYPES_MASK_EV5
  1259. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
  1260. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
  1261. ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
  1262. ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
  1263. **
  1264. *******************************************************************************/
  1265. UINT16 BTM_ReadDeviceScoPacketTypes (void)
  1266. {
  1267. return (btm_cb.btm_sco_pkt_types_supported);
  1268. }
  1269. /*******************************************************************************
  1270. **
  1271. ** Function BTM_ReadScoHandle
  1272. **
  1273. ** Description This function is used to read the HCI handle used for a specific
  1274. ** SCO connection,
  1275. **
  1276. ** Returns handle for the connection, or 0xFFFF if invalid SCO index.
  1277. **
  1278. *******************************************************************************/
  1279. UINT16 BTM_ReadScoHandle (UINT16 sco_inx)
  1280. {
  1281. #if (BTM_MAX_SCO_LINKS>0)
  1282. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
  1283. /* Validity check */
  1284. if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED)) {
  1285. return (p->hci_handle);
  1286. } else {
  1287. return (BTM_INVALID_HCI_HANDLE);
  1288. }
  1289. #else
  1290. return (BTM_INVALID_HCI_HANDLE);
  1291. #endif
  1292. }
  1293. /*******************************************************************************
  1294. **
  1295. ** Function BTM_ReadScoBdAddr
  1296. **
  1297. ** Description This function is read the remote BD Address for a specific
  1298. ** SCO connection,
  1299. **
  1300. ** Returns pointer to BD address or NULL if not known
  1301. **
  1302. *******************************************************************************/
  1303. UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx)
  1304. {
  1305. #if (BTM_MAX_SCO_LINKS>0)
  1306. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
  1307. /* Validity check */
  1308. if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known)) {
  1309. return (p->esco.data.bd_addr);
  1310. } else {
  1311. return (NULL);
  1312. }
  1313. #else
  1314. return (NULL);
  1315. #endif
  1316. }
  1317. /*******************************************************************************
  1318. **
  1319. ** Function BTM_SetEScoMode
  1320. **
  1321. ** Description This function sets up the negotiated parameters for SCO or
  1322. ** eSCO, and sets as the default mode used for outgoing calls to
  1323. ** BTM_CreateSco. It does not change any currently active (e)SCO links.
  1324. ** Note: Incoming (e)SCO connections will always use packet types
  1325. ** supported by the controller. If eSCO is not desired the
  1326. ** feature should be disabled in the controller's feature mask.
  1327. **
  1328. ** Returns BTM_SUCCESS if the successful.
  1329. ** BTM_BUSY if there are one or more active (e)SCO links.
  1330. **
  1331. *******************************************************************************/
  1332. tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
  1333. {
  1334. tSCO_CB *p_esco = &btm_cb.sco_cb;
  1335. tBTM_ESCO_PARAMS *p_def = &p_esco->def_esco_parms;
  1336. if (p_esco->esco_supported) {
  1337. if (p_parms) {
  1338. if (sco_mode == BTM_LINK_TYPE_ESCO) {
  1339. *p_def = *p_parms; /* Save as the default parameters */
  1340. } else { /* Load only the SCO packet types */
  1341. p_def->packet_types = p_parms->packet_types;
  1342. p_def->tx_bw = BTM_64KBITS_RATE;
  1343. p_def->rx_bw = BTM_64KBITS_RATE;
  1344. p_def->max_latency = 0x000a;
  1345. p_def->voice_contfmt = 0x0060;
  1346. p_def->retrans_effort = 0;
  1347. /* OR in any exception packet types */
  1348. p_def->packet_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
  1349. }
  1350. }
  1351. p_esco->desired_sco_mode = sco_mode;
  1352. BTM_TRACE_API("BTM_SetEScoMode -> mode %d", sco_mode);
  1353. } else {
  1354. p_esco->desired_sco_mode = BTM_LINK_TYPE_SCO;
  1355. p_def->packet_types &= BTM_SCO_LINK_ONLY_MASK;
  1356. p_def->retrans_effort = 0;
  1357. BTM_TRACE_API("BTM_SetEScoMode -> mode SCO (eSCO not supported)");
  1358. }
  1359. BTM_TRACE_DEBUG(" txbw 0x%08x, rxbw 0x%08x, max_lat 0x%04x, voice 0x%04x, pkt 0x%04x, rtx effort 0x%02x",
  1360. p_def->tx_bw, p_def->rx_bw, p_def->max_latency,
  1361. p_def->voice_contfmt, p_def->packet_types,
  1362. p_def->retrans_effort);
  1363. return (BTM_SUCCESS);
  1364. }
  1365. /*******************************************************************************
  1366. **
  1367. ** Function BTM_RegForEScoEvts
  1368. **
  1369. ** Description This function registers a SCO event callback with the
  1370. ** specified instance. It should be used to received
  1371. ** connection indication events and change of link parameter
  1372. ** events.
  1373. **
  1374. ** Returns BTM_SUCCESS if the successful.
  1375. ** BTM_ILLEGAL_VALUE if there is an illegal sco_inx
  1376. ** BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
  1377. ** later or does not support eSCO.
  1378. **
  1379. *******************************************************************************/
  1380. tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback)
  1381. {
  1382. #if (BTM_MAX_SCO_LINKS>0)
  1383. if (!btm_cb.sco_cb.esco_supported) {
  1384. btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
  1385. return (BTM_MODE_UNSUPPORTED);
  1386. }
  1387. if (sco_inx < BTM_MAX_SCO_LINKS &&
  1388. btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED) {
  1389. btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
  1390. return (BTM_SUCCESS);
  1391. }
  1392. return (BTM_ILLEGAL_VALUE);
  1393. #else
  1394. return (BTM_MODE_UNSUPPORTED);
  1395. #endif
  1396. }
  1397. /*******************************************************************************
  1398. **
  1399. ** Function BTM_ReadEScoLinkParms
  1400. **
  1401. ** Description This function returns the current eSCO link parameters for
  1402. ** the specified handle. This can be called anytime a connection
  1403. ** is active, but is typically called after receiving the SCO
  1404. ** opened callback.
  1405. **
  1406. ** Note: If called over a 1.1 controller, only the packet types
  1407. ** field has meaning.
  1408. **
  1409. ** Returns BTM_SUCCESS if returned data is valid connection.
  1410. ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
  1411. **
  1412. *******************************************************************************/
  1413. tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms)
  1414. {
  1415. #if (BTM_MAX_SCO_LINKS>0)
  1416. UINT8 index;
  1417. BTM_TRACE_API("BTM_ReadEScoLinkParms -> sco_inx 0x%04x", sco_inx);
  1418. if (sco_inx < BTM_MAX_SCO_LINKS &&
  1419. btm_cb.sco_cb.sco_db[sco_inx].state >= SCO_ST_CONNECTED) {
  1420. *p_parms = btm_cb.sco_cb.sco_db[sco_inx].esco.data;
  1421. return (BTM_SUCCESS);
  1422. }
  1423. if (sco_inx == BTM_FIRST_ACTIVE_SCO_INDEX) {
  1424. for (index = 0; index < BTM_MAX_SCO_LINKS; index++) {
  1425. if (btm_cb.sco_cb.sco_db[index].state >= SCO_ST_CONNECTED) {
  1426. BTM_TRACE_API("BTM_ReadEScoLinkParms the first active SCO index is %d", index);
  1427. *p_parms = btm_cb.sco_cb.sco_db[index].esco.data;
  1428. return (BTM_SUCCESS);
  1429. }
  1430. }
  1431. }
  1432. #endif
  1433. BTM_TRACE_API("BTM_ReadEScoLinkParms cannot find the SCO index!");
  1434. memset(p_parms, 0, sizeof(tBTM_ESCO_DATA));
  1435. return (BTM_WRONG_MODE);
  1436. }
  1437. /*******************************************************************************
  1438. **
  1439. ** Function BTM_ChangeEScoLinkParms
  1440. **
  1441. ** Description This function requests renegotiation of the parameters on
  1442. ** the current eSCO Link. If any of the changes are accepted
  1443. ** by the controllers, the BTM_ESCO_CHG_EVT event is sent in
  1444. ** the tBTM_ESCO_CBACK function with the current settings of
  1445. ** the link. The callback is registered through the call to
  1446. ** BTM_SetEScoMode.
  1447. **
  1448. ** Note: If called over a SCO link (including 1.1 controller),
  1449. ** a change packet type request is sent out instead.
  1450. **
  1451. ** Returns BTM_CMD_STARTED if command is successfully initiated.
  1452. ** BTM_NO_RESOURCES - not enough resources to initiate command.
  1453. ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
  1454. **
  1455. *******************************************************************************/
  1456. tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms)
  1457. {
  1458. #if (BTM_MAX_SCO_LINKS>0)
  1459. tBTM_ESCO_PARAMS *p_setup;
  1460. tSCO_CONN *p_sco;
  1461. UINT16 temp_pkt_types;
  1462. /* Make sure sco handle is valid and on an active link */
  1463. if (sco_inx >= BTM_MAX_SCO_LINKS ||
  1464. btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED) {
  1465. return (BTM_WRONG_MODE);
  1466. }
  1467. p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
  1468. p_setup = &p_sco->esco.setup;
  1469. /* If SCO connection OR eSCO not supported just send change packet types */
  1470. if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
  1471. !btm_cb.sco_cb.esco_supported) {
  1472. p_setup->packet_types = p_parms->packet_types &
  1473. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
  1474. BTM_TRACE_API("BTM_ChangeEScoLinkParms -> SCO Link for handle 0x%04x, pkt 0x%04x",
  1475. p_sco->hci_handle, p_setup->packet_types);
  1476. if (!btsnd_hcic_change_conn_type (p_sco->hci_handle,
  1477. BTM_ESCO_2_SCO(p_setup->packet_types))) {
  1478. return (BTM_NO_RESOURCES);
  1479. }
  1480. } else {
  1481. temp_pkt_types = (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
  1482. btm_cb.btm_sco_pkt_types_supported);
  1483. /* OR in any exception packet types */
  1484. temp_pkt_types |= ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
  1485. (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
  1486. BTM_TRACE_API("BTM_ChangeEScoLinkParms -> eSCO Link for handle 0x%04x", p_sco->hci_handle);
  1487. BTM_TRACE_API(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
  1488. p_setup->tx_bw, p_setup->rx_bw, p_parms->max_latency,
  1489. p_setup->voice_contfmt, p_parms->retrans_effort, temp_pkt_types);
  1490. /* When changing an existing link, only change latency, retrans, and pkts */
  1491. if (!btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->tx_bw,
  1492. p_setup->rx_bw, p_parms->max_latency,
  1493. p_setup->voice_contfmt,
  1494. p_parms->retrans_effort,
  1495. temp_pkt_types)) {
  1496. return (BTM_NO_RESOURCES);
  1497. } else {
  1498. p_parms->packet_types = temp_pkt_types;
  1499. }
  1500. }
  1501. return (BTM_CMD_STARTED);
  1502. #else
  1503. return (BTM_WRONG_MODE);
  1504. #endif
  1505. }
  1506. /*******************************************************************************
  1507. **
  1508. ** Function BTM_EScoConnRsp
  1509. **
  1510. ** Description This function is called upon receipt of an (e)SCO connection
  1511. ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
  1512. ** the request. Parameters used to negotiate eSCO links.
  1513. ** If p_parms is NULL, then values set through BTM_SetEScoMode
  1514. ** are used.
  1515. ** If the link type of the incoming request is SCO, then only
  1516. ** the tx_bw, max_latency, content format, and packet_types are
  1517. ** valid. The hci_status parameter should be
  1518. ** ([0x0] to accept, [0x0d..0x0f] to reject)
  1519. **
  1520. **
  1521. ** Returns void
  1522. **
  1523. *******************************************************************************/
  1524. void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms)
  1525. {
  1526. #if (BTM_MAX_SCO_LINKS>0)
  1527. if (sco_inx < BTM_MAX_SCO_LINKS &&
  1528. btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP) {
  1529. btm_esco_conn_rsp(sco_inx, hci_status,
  1530. btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr,
  1531. p_parms);
  1532. }
  1533. #endif
  1534. }
  1535. /*******************************************************************************
  1536. **
  1537. ** Function btm_read_def_esco_mode
  1538. **
  1539. ** Description This function copies the current default esco settings into
  1540. ** the return buffer.
  1541. **
  1542. ** Returns tBTM_SCO_TYPE
  1543. **
  1544. *******************************************************************************/
  1545. tBTM_SCO_TYPE btm_read_def_esco_mode (tBTM_ESCO_PARAMS *p_parms)
  1546. {
  1547. #if (BTM_MAX_SCO_LINKS>0)
  1548. *p_parms = btm_cb.sco_cb.def_esco_parms;
  1549. return btm_cb.sco_cb.desired_sco_mode;
  1550. #else
  1551. return BTM_LINK_TYPE_SCO;
  1552. #endif
  1553. }
  1554. /*******************************************************************************
  1555. **
  1556. ** Function btm_esco_proc_conn_chg
  1557. **
  1558. ** Description This function is called by BTIF when an SCO connection
  1559. ** is changed.
  1560. **
  1561. ** Returns void
  1562. **
  1563. *******************************************************************************/
  1564. void btm_esco_proc_conn_chg (UINT8 status, UINT16 handle, UINT8 tx_interval,
  1565. UINT8 retrans_window, UINT16 rx_pkt_len,
  1566. UINT16 tx_pkt_len)
  1567. {
  1568. #if (BTM_MAX_SCO_LINKS>0)
  1569. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1570. tBTM_CHG_ESCO_EVT_DATA data;
  1571. UINT16 xx;
  1572. BTM_TRACE_EVENT("btm_esco_proc_conn_chg -> handle 0x%04x, status 0x%02x",
  1573. handle, status);
  1574. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1575. if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle) {
  1576. /* If upper layer wants notification */
  1577. if (p->esco.p_esco_cback) {
  1578. memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN);
  1579. data.hci_status = status;
  1580. data.sco_inx = xx;
  1581. data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len;
  1582. data.tx_pkt_len = p->esco.data.tx_pkt_len = tx_pkt_len;
  1583. data.tx_interval = p->esco.data.tx_interval = tx_interval;
  1584. data.retrans_window = p->esco.data.retrans_window = retrans_window;
  1585. (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT,
  1586. (tBTM_ESCO_EVT_DATA *)&data);
  1587. }
  1588. return;
  1589. }
  1590. }
  1591. #endif
  1592. }
  1593. /*******************************************************************************
  1594. **
  1595. ** Function btm_is_sco_active
  1596. **
  1597. ** Description This function is called to see if a SCO handle is already in
  1598. ** use.
  1599. **
  1600. ** Returns BOOLEAN
  1601. **
  1602. *******************************************************************************/
  1603. BOOLEAN btm_is_sco_active (UINT16 handle)
  1604. {
  1605. #if (BTM_MAX_SCO_LINKS>0)
  1606. UINT16 xx;
  1607. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1608. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1609. if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED) {
  1610. return (TRUE);
  1611. }
  1612. }
  1613. #endif
  1614. return (FALSE);
  1615. }
  1616. /*******************************************************************************
  1617. **
  1618. ** Function BTM_GetNumScoLinks
  1619. **
  1620. ** Description This function returns the number of active sco links.
  1621. **
  1622. ** Returns UINT8
  1623. **
  1624. *******************************************************************************/
  1625. UINT8 BTM_GetNumScoLinks (void)
  1626. {
  1627. #if (BTM_MAX_SCO_LINKS>0)
  1628. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1629. UINT16 xx;
  1630. UINT8 num_scos = 0;
  1631. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1632. switch (p->state) {
  1633. case SCO_ST_W4_CONN_RSP:
  1634. case SCO_ST_CONNECTING:
  1635. case SCO_ST_CONNECTED:
  1636. case SCO_ST_DISCONNECTING:
  1637. case SCO_ST_PEND_UNPARK:
  1638. num_scos++;
  1639. }
  1640. }
  1641. return (num_scos);
  1642. #else
  1643. return (0);
  1644. #endif
  1645. }
  1646. /*******************************************************************************
  1647. **
  1648. ** Function btm_is_sco_active_by_bdaddr
  1649. **
  1650. ** Description This function is called to see if a SCO active to a bd address.
  1651. **
  1652. ** Returns BOOLEAN
  1653. **
  1654. *******************************************************************************/
  1655. BOOLEAN btm_is_sco_active_by_bdaddr (BD_ADDR remote_bda)
  1656. {
  1657. #if (BTM_MAX_SCO_LINKS>0)
  1658. UINT8 xx;
  1659. tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
  1660. /* If any SCO is being established to the remote BD address, refuse this */
  1661. for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
  1662. if ((!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) && (p->state == SCO_ST_CONNECTED)) {
  1663. return (TRUE);
  1664. }
  1665. }
  1666. #endif
  1667. return (FALSE);
  1668. }
  1669. #else /* SCO_EXCLUDED == TRUE (Link in stubs) */
  1670. tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig,
  1671. UINT16 pkt_types, UINT16 *p_sco_inx,
  1672. tBTM_SCO_CB *p_conn_cb,
  1673. tBTM_SCO_CB *p_disc_cb)
  1674. {
  1675. return (BTM_NO_RESOURCES);
  1676. }
  1677. tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx)
  1678. {
  1679. return (BTM_NO_RESOURCES);
  1680. }
  1681. tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types)
  1682. {
  1683. return (BTM_NO_RESOURCES);
  1684. }
  1685. UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx)
  1686. {
  1687. return (0);
  1688. }
  1689. UINT16 BTM_ReadDeviceScoPacketTypes (void)
  1690. {
  1691. return (0);
  1692. }
  1693. UINT16 BTM_ReadScoHandle (UINT16 sco_inx)
  1694. {
  1695. return (BTM_INVALID_HCI_HANDLE);
  1696. }
  1697. UINT8 *BTM_ReadScoBdAddr(UINT16 sco_inx)
  1698. {
  1699. return ((UINT8 *) NULL);
  1700. }
  1701. UINT16 BTM_ReadScoDiscReason (void)
  1702. {
  1703. return (BTM_INVALID_SCO_DISC_REASON);
  1704. }
  1705. tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
  1706. {
  1707. return (BTM_MODE_UNSUPPORTED);
  1708. }
  1709. tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback)
  1710. {
  1711. return (BTM_ILLEGAL_VALUE);
  1712. }
  1713. tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms)
  1714. {
  1715. return (BTM_MODE_UNSUPPORTED);
  1716. }
  1717. tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms)
  1718. {
  1719. return (BTM_MODE_UNSUPPORTED);
  1720. }
  1721. void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms) {}
  1722. UINT8 BTM_GetNumScoLinks (void)
  1723. {
  1724. return (0);
  1725. }
  1726. #endif /* If SCO is being used */