rfc_port_if.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 1999-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 callable by an application
  21. * running on top of RFCOMM
  22. *
  23. *****************************************************************************/
  24. #include <string.h>
  25. #include "common/bt_target.h"
  26. #include "stack/rfcdefs.h"
  27. #include "stack/port_api.h"
  28. #include "stack/l2c_api.h"
  29. #include "port_int.h"
  30. #include "rfc_int.h"
  31. #include "common/bt_defs.h"
  32. #if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
  33. #if RFC_DYNAMIC_MEMORY == FALSE
  34. tRFC_CB rfc_cb;
  35. #else
  36. tRFC_CB *rfc_cb_ptr;
  37. #endif
  38. /*******************************************************************************
  39. **
  40. ** Function RFCOMM_StartReq
  41. **
  42. ** Description This function handles Start Request from the upper layer.
  43. ** If RFCOMM multiplexer channel can not be allocated
  44. ** send start not accepted confirmation. Otherwise dispatch
  45. ** start event to the state machine.
  46. **
  47. *******************************************************************************/
  48. void RFCOMM_StartReq (tRFC_MCB *p_mcb)
  49. {
  50. rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_REQ, NULL);
  51. }
  52. /*******************************************************************************
  53. **
  54. ** Function RFCOMM_StartRsp
  55. **
  56. ** Description This function handles Start Response from the upper layer.
  57. ** Save upper layer handle and result of the Start Indication
  58. ** in the control block and dispatch event to the FSM.
  59. **
  60. *******************************************************************************/
  61. void RFCOMM_StartRsp (tRFC_MCB *p_mcb, UINT16 result)
  62. {
  63. rfc_mx_sm_execute (p_mcb, RFC_MX_EVENT_START_RSP, &result);
  64. }
  65. /*******************************************************************************
  66. **
  67. ** Function RFCOMM_DlcEstablishReq
  68. **
  69. ** Description This function is called by the user app to establish
  70. ** connection with the specific dlci on a specific bd device.
  71. ** It will allocate RFCOMM connection control block if not
  72. ** allocated before and dispatch open event to the state
  73. ** machine.
  74. **
  75. *******************************************************************************/
  76. void RFCOMM_DlcEstablishReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
  77. {
  78. UNUSED(mtu);
  79. if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
  80. PORT_DlcEstablishCnf (p_mcb, dlci, 0, RFCOMM_ERROR);
  81. return;
  82. }
  83. tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
  84. if (p_port == NULL) {
  85. RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
  86. dlci);
  87. return;
  88. }
  89. rfc_port_sm_execute(p_port, RFC_EVENT_OPEN, NULL);
  90. }
  91. /*******************************************************************************
  92. **
  93. ** Function RFCOMM_DlcEstablishRsp
  94. **
  95. ** Description This function is called by the port emulation entity
  96. ** acks Establish Indication.
  97. **
  98. *******************************************************************************/
  99. void RFCOMM_DlcEstablishRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result)
  100. {
  101. UNUSED(mtu);
  102. if ((p_mcb->state != RFC_MX_STATE_CONNECTED) && (result == RFCOMM_SUCCESS)) {
  103. PORT_DlcReleaseInd (p_mcb, dlci);
  104. return;
  105. }
  106. tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
  107. if (p_port == NULL) {
  108. RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
  109. dlci);
  110. return;
  111. }
  112. rfc_port_sm_execute(p_port, RFC_EVENT_ESTABLISH_RSP, &result);
  113. }
  114. /*******************************************************************************
  115. **
  116. ** Function RFCOMM_ParNegReq
  117. **
  118. ** Description This function is called by the user app to start
  119. ** DLC parameter negotiation. Port emulation can send this
  120. ** request before actually establishing the DLC. In this
  121. ** case the function will allocate RFCOMM connection control
  122. ** block.
  123. **
  124. *******************************************************************************/
  125. void RFCOMM_ParNegReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
  126. {
  127. UINT8 flow;
  128. UINT8 cl;
  129. UINT8 k;
  130. tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
  131. if (p_port == NULL) {
  132. RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
  133. dlci);
  134. return;
  135. }
  136. if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
  137. p_port->error = PORT_PAR_NEG_FAILED;
  138. return;
  139. }
  140. /* Negotiate the flow control mechanism. If flow control mechanism for */
  141. /* mux has not been set yet, use our default value. If it has been set, */
  142. /* use that value. */
  143. flow = (p_mcb->flow == PORT_FC_UNDEFINED) ? PORT_FC_DEFAULT : p_mcb->flow;
  144. /* Set convergence layer and number of credits (k) */
  145. if (flow == PORT_FC_CREDIT) {
  146. cl = RFCOMM_PN_CONV_LAYER_CBFC_I;
  147. k = (p_port->credit_rx_max < RFCOMM_K_MAX) ? p_port->credit_rx_max : RFCOMM_K_MAX;
  148. p_port->credit_rx = k;
  149. } else {
  150. cl = RFCOMM_PN_CONV_LAYER_TYPE_1;
  151. k = 0;
  152. }
  153. /* Send Parameter Negotiation Command UIH frame */
  154. p_port->rfc.expected_rsp |= RFC_RSP_PN;
  155. rfc_send_pn (p_mcb, dlci, TRUE, mtu, cl, k);
  156. rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
  157. }
  158. /*******************************************************************************
  159. **
  160. ** Function RFCOMM_ParNegRsp
  161. **
  162. ** Description This function is called by the user app to acknowledge
  163. ** DLC parameter negotiation.
  164. **
  165. *******************************************************************************/
  166. void RFCOMM_ParNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
  167. {
  168. if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
  169. return;
  170. }
  171. /* Send Parameter Negotiation Response UIH frame */
  172. rfc_send_pn (p_mcb, dlci, FALSE, mtu, cl, k);
  173. }
  174. /*******************************************************************************
  175. **
  176. ** Function RFCOMM_PortNegReq
  177. **
  178. ** Description This function is called by the user app to start
  179. ** Remote Port parameter negotiation. Port emulation can
  180. ** send this request before actually establishing the DLC.
  181. ** In this case the function will allocate RFCOMM connection
  182. ** control block.
  183. **
  184. *******************************************************************************/
  185. void RFCOMM_PortNegReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars)
  186. {
  187. if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
  188. PORT_PortNegCnf (p_mcb, dlci, NULL, RFCOMM_ERROR);
  189. return;
  190. }
  191. tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
  192. if (p_port == NULL) {
  193. RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
  194. dlci);
  195. return;
  196. }
  197. /* Send Parameter Negotiation Command UIH frame */
  198. if (!p_pars) {
  199. p_port->rfc.expected_rsp |= RFC_RSP_RPN_REPLY;
  200. } else {
  201. p_port->rfc.expected_rsp |= RFC_RSP_RPN;
  202. }
  203. rfc_send_rpn (p_mcb, dlci, TRUE, p_pars, RFCOMM_RPN_PM_MASK);
  204. rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
  205. }
  206. /*******************************************************************************
  207. **
  208. ** Function RFCOMM_PortNegRsp
  209. **
  210. ** Description This function is called by the user app to acknowledge
  211. ** Port parameters negotiation.
  212. **
  213. *******************************************************************************/
  214. void RFCOMM_PortNegRsp (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_STATE *p_pars,
  215. UINT16 param_mask)
  216. {
  217. if (p_mcb->state != RFC_MX_STATE_CONNECTED) {
  218. return;
  219. }
  220. rfc_send_rpn (p_mcb, dlci, FALSE, p_pars, param_mask);
  221. }
  222. /*******************************************************************************
  223. **
  224. ** Function RFCOMM_ControlReq
  225. **
  226. ** Description This function is called by the port entity to send control
  227. ** parameters to remote port emulation entity.
  228. **
  229. *******************************************************************************/
  230. void RFCOMM_ControlReq (tRFC_MCB *p_mcb, UINT8 dlci, tPORT_CTRL *p_pars)
  231. {
  232. tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
  233. if (p_port == NULL) {
  234. RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
  235. dlci);
  236. return;
  237. }
  238. if ((p_port->state != PORT_STATE_OPENED)
  239. || (p_port->rfc.state != RFC_STATE_OPENED)) {
  240. return;
  241. }
  242. p_port->port_ctrl |= PORT_CTRL_REQ_SENT;
  243. p_port->rfc.expected_rsp |= RFC_RSP_MSC;
  244. rfc_send_msc (p_mcb, dlci, TRUE, p_pars);
  245. rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
  246. }
  247. /*******************************************************************************
  248. **
  249. ** Function RFCOMM_FlowReq
  250. **
  251. ** Description This function is called by the port entity when flow
  252. ** control state has changed. Enable flag passed shows if
  253. ** port can accept more data.
  254. **
  255. *******************************************************************************/
  256. void RFCOMM_FlowReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 enable)
  257. {
  258. tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
  259. if (p_port == NULL) {
  260. RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
  261. dlci);
  262. return;
  263. }
  264. if ((p_port->state != PORT_STATE_OPENED)
  265. || (p_port->rfc.state != RFC_STATE_OPENED)) {
  266. return;
  267. }
  268. p_port->local_ctrl.fc = !enable;
  269. p_port->rfc.expected_rsp |= RFC_RSP_MSC;
  270. rfc_send_msc (p_mcb, dlci, TRUE, &p_port->local_ctrl);
  271. rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
  272. }
  273. /*******************************************************************************
  274. **
  275. ** Function RFCOMM_LineStatusReq
  276. **
  277. ** Description This function is called by the port entity when line
  278. ** status should be delivered to the peer.
  279. **
  280. *******************************************************************************/
  281. void RFCOMM_LineStatusReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 status)
  282. {
  283. tPORT *p_port = port_find_mcb_dlci_port(p_mcb, dlci);
  284. if (p_port == NULL) {
  285. RFCOMM_TRACE_WARNING("%s Unable to find DLCI port dlci:%d", __func__,
  286. dlci);
  287. return;
  288. }
  289. if ((p_port->state != PORT_STATE_OPENED)
  290. || (p_port->rfc.state != RFC_STATE_OPENED)) {
  291. return;
  292. }
  293. p_port->rfc.expected_rsp |= RFC_RSP_RLS;
  294. rfc_send_rls (p_mcb, dlci, TRUE, status);
  295. rfc_port_timer_start (p_port, RFC_T2_TIMEOUT);
  296. }
  297. /*******************************************************************************
  298. **
  299. ** Function RFCOMM_DlcReleaseReq
  300. **
  301. ** Description This function is called by the PORT unit to close DLC
  302. **
  303. *******************************************************************************/
  304. void RFCOMM_DlcReleaseReq (tRFC_MCB *p_mcb, UINT8 dlci)
  305. {
  306. rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_CLOSE, 0);
  307. }
  308. /*******************************************************************************
  309. **
  310. ** Function RFCOMM_DataReq
  311. **
  312. ** Description This function is called by the user app to send data buffer
  313. **
  314. *******************************************************************************/
  315. void RFCOMM_DataReq (tRFC_MCB *p_mcb, UINT8 dlci, BT_HDR *p_buf)
  316. {
  317. rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_DATA, p_buf);
  318. }
  319. #endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)