avct_api.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2003-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 module contains API of the audio/video control transport protocol.
  21. *
  22. ******************************************************************************/
  23. #include <string.h>
  24. #include "bt_types.h"
  25. #include "bt_target.h"
  26. #include "bt_utils.h"
  27. #include "gki.h"
  28. #include "l2c_api.h"
  29. #include "l2cdefs.h"
  30. #include "btm_api.h"
  31. #include "avct_api.h"
  32. #include "avct_int.h"
  33. #if (defined(AVCT_INCLUDED) && AVCT_INCLUDED == TRUE)
  34. /* Control block for AVCT */
  35. #if AVCT_DYNAMIC_MEMORY == FALSE
  36. tAVCT_CB avct_cb;
  37. #endif
  38. /*******************************************************************************
  39. **
  40. ** Function AVCT_Register
  41. **
  42. ** Description This is the system level registration function for the
  43. ** AVCTP protocol. This function initializes AVCTP and
  44. ** prepares the protocol stack for its use. This function
  45. ** must be called once by the system or platform using AVCTP
  46. ** before the other functions of the API an be used.
  47. **
  48. **
  49. ** Returns void
  50. **
  51. *******************************************************************************/
  52. void AVCT_Register(UINT16 mtu, UINT16 mtu_br, UINT8 sec_mask)
  53. {
  54. UNUSED(mtu_br);
  55. AVCT_TRACE_API("AVCT_Register");
  56. /* register PSM with L2CAP */
  57. L2CA_Register(AVCT_PSM, (tL2CAP_APPL_INFO *) &avct_l2c_appl);
  58. /* set security level */
  59. BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0, 0);
  60. BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0, 0);
  61. /* initialize AVCTP data structures */
  62. memset(&avct_cb, 0, sizeof(tAVCT_CB));
  63. #if (AVCT_BROWSE_INCLUDED == TRUE)
  64. /* Include the browsing channel which uses eFCR */
  65. L2CA_Register(AVCT_BR_PSM, (tL2CAP_APPL_INFO *) &avct_l2c_br_appl);
  66. BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVCTP_BROWSE, sec_mask, AVCT_BR_PSM, 0, 0);
  67. BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVCTP_BROWSE, sec_mask, AVCT_BR_PSM, 0, 0);
  68. if (mtu_br < AVCT_MIN_BROWSE_MTU) {
  69. mtu_br = AVCT_MIN_BROWSE_MTU;
  70. }
  71. avct_cb.mtu_br = mtu_br;
  72. #endif
  73. #if defined(AVCT_INITIAL_TRACE_LEVEL)
  74. avct_cb.trace_level = AVCT_INITIAL_TRACE_LEVEL;
  75. #else
  76. avct_cb.trace_level = BT_TRACE_LEVEL_NONE;
  77. #endif
  78. if (mtu < AVCT_MIN_CONTROL_MTU) {
  79. mtu = AVCT_MIN_CONTROL_MTU;
  80. }
  81. /* store mtu */
  82. avct_cb.mtu = mtu;
  83. }
  84. /*******************************************************************************
  85. **
  86. ** Function AVCT_Deregister
  87. **
  88. ** Description This function is called to deregister use AVCTP protocol.
  89. ** It is called when AVCTP is no longer being used by any
  90. ** application in the system. Before this function can be
  91. ** called, all connections must be removed with
  92. ** AVCT_RemoveConn().
  93. **
  94. **
  95. ** Returns void
  96. **
  97. *******************************************************************************/
  98. void AVCT_Deregister(void)
  99. {
  100. AVCT_TRACE_API("AVCT_Deregister");
  101. /* deregister PSM with L2CAP */
  102. L2CA_Deregister(AVCT_PSM);
  103. }
  104. /*******************************************************************************
  105. **
  106. ** Function AVCT_CreateConn
  107. **
  108. ** Description Create an AVCTP connection. There are two types of
  109. ** connections, initiator and acceptor, as determined by
  110. ** the p_cc->role parameter. When this function is called to
  111. ** create an initiator connection, an AVCTP connection to
  112. ** the peer device is initiated if one does not already exist.
  113. ** If an acceptor connection is created, the connection waits
  114. ** passively for an incoming AVCTP connection from a peer device.
  115. **
  116. **
  117. ** Returns AVCT_SUCCESS if successful, otherwise error.
  118. **
  119. *******************************************************************************/
  120. UINT16 AVCT_CreateConn(UINT8 *p_handle, tAVCT_CC *p_cc, BD_ADDR peer_addr)
  121. {
  122. UINT16 result = AVCT_SUCCESS;
  123. tAVCT_CCB *p_ccb;
  124. tAVCT_LCB *p_lcb;
  125. AVCT_TRACE_API("AVCT_CreateConn: %d, control:%d", p_cc->role, p_cc->control);
  126. /* Allocate ccb; if no ccbs, return failure */
  127. if ((p_ccb = avct_ccb_alloc(p_cc)) == NULL) {
  128. result = AVCT_NO_RESOURCES;
  129. } else {
  130. /* get handle */
  131. *p_handle = avct_ccb_to_idx(p_ccb);
  132. /* if initiator connection */
  133. if (p_cc->role == AVCT_INT) {
  134. /* find link; if none allocate a new one */
  135. if ((p_lcb = avct_lcb_by_bd(peer_addr)) == NULL) {
  136. if ((p_lcb = avct_lcb_alloc(peer_addr)) == NULL) {
  137. /* no link resources; free ccb as well */
  138. avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
  139. result = AVCT_NO_RESOURCES;
  140. }
  141. }
  142. /* check if PID already in use */
  143. else if (avct_lcb_has_pid(p_lcb, p_cc->pid)) {
  144. avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
  145. result = AVCT_PID_IN_USE;
  146. }
  147. if (result == AVCT_SUCCESS) {
  148. /* bind lcb to ccb */
  149. p_ccb->p_lcb = p_lcb;
  150. AVCT_TRACE_DEBUG("ch_state: %d", p_lcb->ch_state);
  151. avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT *) &p_ccb);
  152. }
  153. }
  154. }
  155. return result;
  156. }
  157. /*******************************************************************************
  158. **
  159. ** Function AVCT_RemoveConn
  160. **
  161. ** Description Remove an AVCTP connection. This function is called when
  162. ** the application is no longer using a connection. If this
  163. ** is the last connection to a peer the L2CAP channel for AVCTP
  164. ** will be closed.
  165. **
  166. **
  167. ** Returns AVCT_SUCCESS if successful, otherwise error.
  168. **
  169. *******************************************************************************/
  170. UINT16 AVCT_RemoveConn(UINT8 handle)
  171. {
  172. UINT16 result = AVCT_SUCCESS;
  173. tAVCT_CCB *p_ccb;
  174. AVCT_TRACE_API("AVCT_RemoveConn");
  175. /* map handle to ccb */
  176. if ((p_ccb = avct_ccb_by_idx(handle)) == NULL) {
  177. result = AVCT_BAD_HANDLE;
  178. }
  179. /* if connection not bound to lcb, dealloc */
  180. else if (p_ccb->p_lcb == NULL) {
  181. avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
  182. }
  183. /* send unbind event to lcb */
  184. else {
  185. avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, (tAVCT_LCB_EVT *) &p_ccb);
  186. }
  187. return result;
  188. }
  189. /*******************************************************************************
  190. **
  191. ** Function AVCT_CreateBrowse
  192. **
  193. ** Description Create an AVCTP Browse channel. There are two types of
  194. ** connections, initiator and acceptor, as determined by
  195. ** the role parameter. When this function is called to
  196. ** create an initiator connection, the Browse channel to
  197. ** the peer device is initiated if one does not already exist.
  198. ** If an acceptor connection is created, the connection waits
  199. ** passively for an incoming AVCTP connection from a peer device.
  200. **
  201. **
  202. ** Returns AVCT_SUCCESS if successful, otherwise error.
  203. **
  204. *******************************************************************************/
  205. UINT16 AVCT_CreateBrowse (UINT8 handle, UINT8 role)
  206. {
  207. #if (AVCT_BROWSE_INCLUDED == TRUE)
  208. UINT16 result = AVCT_SUCCESS;
  209. tAVCT_CCB *p_ccb;
  210. tAVCT_BCB *p_bcb;
  211. int index;
  212. AVCT_TRACE_API("AVCT_CreateBrowse: %d", role);
  213. /* map handle to ccb */
  214. if ((p_ccb = avct_ccb_by_idx(handle)) == NULL) {
  215. return AVCT_BAD_HANDLE;
  216. } else {
  217. /* mark this CCB as supporting browsing channel */
  218. if ((p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
  219. p_ccb->allocated |= AVCT_ALOC_BCB;
  220. }
  221. }
  222. /* if initiator connection */
  223. if (role == AVCT_INT) {
  224. /* the link control block must exist before this function is called as INT. */
  225. if ((p_ccb->p_lcb == NULL) || (p_ccb->p_lcb->allocated == 0)) {
  226. result = AVCT_NOT_OPEN;
  227. } else {
  228. /* find link; if none allocate a new one */
  229. index = p_ccb->p_lcb->allocated;
  230. if (index > AVCT_NUM_LINKS) {
  231. result = AVCT_BAD_HANDLE;
  232. } else {
  233. p_bcb = &avct_cb.bcb[index - 1];
  234. p_bcb->allocated = index;
  235. }
  236. }
  237. if (result == AVCT_SUCCESS) {
  238. /* bind bcb to ccb */
  239. p_ccb->p_bcb = p_bcb;
  240. AVCT_TRACE_DEBUG("ch_state: %d", p_bcb->ch_state);
  241. avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT *) &p_ccb);
  242. }
  243. }
  244. return result;
  245. #else
  246. UNUSED(handle);
  247. UNUSED(role);
  248. return AVCT_NO_RESOURCES;
  249. #endif
  250. }
  251. /*******************************************************************************
  252. **
  253. ** Function AVCT_RemoveBrowse
  254. **
  255. ** Description Remove an AVCTP Browse channel. This function is called when
  256. ** the application is no longer using a connection. If this
  257. ** is the last connection to a peer the L2CAP channel for AVCTP
  258. ** will be closed.
  259. **
  260. **
  261. ** Returns AVCT_SUCCESS if successful, otherwise error.
  262. **
  263. *******************************************************************************/
  264. UINT16 AVCT_RemoveBrowse (UINT8 handle)
  265. {
  266. #if (AVCT_BROWSE_INCLUDED == TRUE)
  267. UINT16 result = AVCT_SUCCESS;
  268. tAVCT_CCB *p_ccb;
  269. AVCT_TRACE_API("AVCT_RemoveBrowse");
  270. /* map handle to ccb */
  271. if ((p_ccb = avct_ccb_by_idx(handle)) == NULL) {
  272. result = AVCT_BAD_HANDLE;
  273. } else if (p_ccb->p_bcb != NULL)
  274. /* send unbind event to bcb */
  275. {
  276. avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, (tAVCT_LCB_EVT *) &p_ccb);
  277. }
  278. return result;
  279. #else
  280. UNUSED(handle);
  281. return AVCT_NO_RESOURCES;
  282. #endif
  283. }
  284. /*******************************************************************************
  285. **
  286. ** Function AVCT_GetBrowseMtu
  287. **
  288. ** Description Get the peer_mtu for the AVCTP Browse channel of the given
  289. ** connection.
  290. **
  291. ** Returns the peer browsing channel MTU.
  292. **
  293. *******************************************************************************/
  294. UINT16 AVCT_GetBrowseMtu (UINT8 handle)
  295. {
  296. UINT16 peer_mtu = AVCT_MIN_BROWSE_MTU;
  297. #if (AVCT_BROWSE_INCLUDED == TRUE)
  298. tAVCT_CCB *p_ccb;
  299. if ((p_ccb = avct_ccb_by_idx(handle)) != NULL && p_ccb->p_bcb != NULL) {
  300. peer_mtu = p_ccb->p_bcb->peer_mtu;
  301. }
  302. #else
  303. UNUSED(handle);
  304. #endif
  305. return peer_mtu;
  306. }
  307. /*******************************************************************************
  308. **
  309. ** Function AVCT_GetPeerMtu
  310. **
  311. ** Description Get the peer_mtu for the AVCTP channel of the given
  312. ** connection.
  313. **
  314. ** Returns the peer MTU size.
  315. **
  316. *******************************************************************************/
  317. UINT16 AVCT_GetPeerMtu (UINT8 handle)
  318. {
  319. UINT16 peer_mtu = L2CAP_DEFAULT_MTU;
  320. tAVCT_CCB *p_ccb;
  321. /* map handle to ccb */
  322. if ((p_ccb = avct_ccb_by_idx(handle)) != NULL) {
  323. if (p_ccb->p_lcb) {
  324. peer_mtu = p_ccb->p_lcb->peer_mtu;
  325. }
  326. }
  327. return peer_mtu;
  328. }
  329. /*******************************************************************************
  330. **
  331. ** Function AVCT_MsgReq
  332. **
  333. ** Description Send an AVCTP message to a peer device. In calling
  334. ** AVCT_MsgReq(), the application should keep track of the
  335. ** congestion state of AVCTP as communicated with events
  336. ** AVCT_CONG_IND_EVT and AVCT_UNCONG_IND_EVT. If the
  337. ** application calls AVCT_MsgReq() when AVCTP is congested
  338. ** the message may be discarded. The application may make its
  339. ** first call to AVCT_MsgReq() after it receives an
  340. ** AVCT_CONNECT_CFM_EVT or AVCT_CONNECT_IND_EVT on control channel or
  341. ** AVCT_BROWSE_CONN_CFM_EVT or AVCT_BROWSE_CONN_IND_EVT on browsing channel.
  342. **
  343. ** p_msg->layer_specific must be set to
  344. ** AVCT_DATA_CTRL for control channel traffic;
  345. ** AVCT_DATA_BROWSE for for browse channel traffic.
  346. **
  347. ** Returns AVCT_SUCCESS if successful, otherwise error.
  348. **
  349. *******************************************************************************/
  350. UINT16 AVCT_MsgReq(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR *p_msg)
  351. {
  352. UINT16 result = AVCT_SUCCESS;
  353. tAVCT_CCB *p_ccb;
  354. tAVCT_UL_MSG ul_msg;
  355. AVCT_TRACE_API("AVCT_MsgReq");
  356. /* verify p_msg parameter */
  357. if (p_msg == NULL) {
  358. return AVCT_NO_RESOURCES;
  359. }
  360. AVCT_TRACE_API("len: %d", p_msg->len);
  361. /* map handle to ccb */
  362. if ((p_ccb = avct_ccb_by_idx(handle)) == NULL) {
  363. result = AVCT_BAD_HANDLE;
  364. GKI_freebuf(p_msg);
  365. }
  366. /* verify channel is bound to link */
  367. else if (p_ccb->p_lcb == NULL) {
  368. result = AVCT_NOT_OPEN;
  369. GKI_freebuf(p_msg);
  370. }
  371. if (result == AVCT_SUCCESS) {
  372. ul_msg.p_buf = p_msg;
  373. ul_msg.p_ccb = p_ccb;
  374. ul_msg.label = label;
  375. ul_msg.cr = cr;
  376. #if (AVCT_BROWSE_INCLUDED == TRUE)
  377. /* send msg event to bcb */
  378. if (p_msg->layer_specific == AVCT_DATA_BROWSE) {
  379. if (p_ccb->p_bcb == NULL && (p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
  380. /* BCB channel is not open and not allocated */
  381. result = AVCT_BAD_HANDLE;
  382. GKI_freebuf(p_msg);
  383. } else {
  384. p_ccb->p_bcb = avct_bcb_by_lcb(p_ccb->p_lcb);
  385. avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT, (tAVCT_LCB_EVT *) &ul_msg);
  386. }
  387. }
  388. /* send msg event to lcb */
  389. else
  390. #endif
  391. {
  392. avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT, (tAVCT_LCB_EVT *) &ul_msg);
  393. }
  394. }
  395. return result;
  396. }
  397. #endif /* #if (defined(AVCT_INCLUDED) && AVCT_INCLUDED == TRUE) */