rfc_port_fsm.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  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 state machine and action routines for a port of the
  21. * RFCOMM unit
  22. *
  23. ******************************************************************************/
  24. #include <string.h>
  25. #include "common/bt_target.h"
  26. #include "stack/rfcdefs.h"
  27. #include "stack/btm_api.h"
  28. #include "btm_int.h"
  29. #include "stack/port_api.h"
  30. #include "port_int.h"
  31. #include "rfc_int.h"
  32. #include "common/bt_defs.h"
  33. #include "osi/allocator.h"
  34. #include "osi/mutex.h"
  35. #if (defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
  36. /********************************************************************************/
  37. /* L O C A L F U N C T I O N P R O T O T Y P E S */
  38. /********************************************************************************/
  39. static void rfc_port_sm_state_closed (tPORT *p_port, UINT16 event, void *p_data);
  40. static void rfc_port_sm_sabme_wait_ua (tPORT *p_port, UINT16 event, void *p_data);
  41. static void rfc_port_sm_opened (tPORT *p_port, UINT16 event, void *p_data);
  42. static void rfc_port_sm_orig_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data);
  43. static void rfc_port_sm_term_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data);
  44. static void rfc_port_sm_disc_wait_ua (tPORT *p_port, UINT16 event, void *p_data);
  45. static void rfc_port_uplink_data (tPORT *p_port, BT_HDR *p_buf);
  46. static void rfc_set_port_state(tPORT_STATE *port_pars, MX_FRAME *p_frame);
  47. /*******************************************************************************
  48. **
  49. ** Function rfc_port_sm_execute
  50. **
  51. ** Description This function sends port events through the state
  52. ** machine.
  53. **
  54. ** Returns void
  55. **
  56. *******************************************************************************/
  57. void rfc_port_sm_execute (tPORT *p_port, UINT16 event, void *p_data)
  58. {
  59. if (!p_port) {
  60. RFCOMM_TRACE_WARNING ("NULL port event %d", event);
  61. return;
  62. }
  63. switch (p_port->rfc.state) {
  64. case RFC_STATE_CLOSED:
  65. rfc_port_sm_state_closed (p_port, event, p_data);
  66. break;
  67. case RFC_STATE_SABME_WAIT_UA:
  68. rfc_port_sm_sabme_wait_ua (p_port, event, p_data);
  69. break;
  70. case RFC_STATE_ORIG_WAIT_SEC_CHECK:
  71. rfc_port_sm_orig_wait_sec_check (p_port, event, p_data);
  72. break;
  73. case RFC_STATE_TERM_WAIT_SEC_CHECK:
  74. rfc_port_sm_term_wait_sec_check (p_port, event, p_data);
  75. break;
  76. case RFC_STATE_OPENED:
  77. rfc_port_sm_opened (p_port, event, p_data);
  78. break;
  79. case RFC_STATE_DISC_WAIT_UA:
  80. rfc_port_sm_disc_wait_ua (p_port, event, p_data);
  81. break;
  82. }
  83. }
  84. /*******************************************************************************
  85. **
  86. ** Function rfc_port_sm_state_closed
  87. **
  88. ** Description This function handles events when the port is in
  89. ** CLOSED state. This state exists when port is
  90. ** being initially established.
  91. **
  92. ** Returns void
  93. **
  94. *******************************************************************************/
  95. void rfc_port_sm_state_closed (tPORT *p_port, UINT16 event, void *p_data)
  96. {
  97. switch (event) {
  98. case RFC_EVENT_OPEN:
  99. p_port->rfc.state = RFC_STATE_ORIG_WAIT_SEC_CHECK;
  100. btm_sec_mx_access_request (p_port->rfc.p_mcb->bd_addr, BT_PSM_RFCOMM, TRUE,
  101. BTM_SEC_PROTO_RFCOMM, (UINT32)(p_port->dlci / 2),
  102. &rfc_sec_check_complete, p_port);
  103. return;
  104. case RFC_EVENT_CLOSE:
  105. break;
  106. case RFC_EVENT_CLEAR:
  107. return;
  108. case RFC_EVENT_DATA:
  109. osi_free (p_data);
  110. break;
  111. case RFC_EVENT_SABME:
  112. /* make sure the multiplexer disconnect timer is not running (reconnect case) */
  113. rfc_timer_stop(p_port->rfc.p_mcb );
  114. /* Open will be continued after security checks are passed */
  115. p_port->rfc.state = RFC_STATE_TERM_WAIT_SEC_CHECK;
  116. btm_sec_mx_access_request (p_port->rfc.p_mcb->bd_addr, BT_PSM_RFCOMM, FALSE,
  117. BTM_SEC_PROTO_RFCOMM, (UINT32)(p_port->dlci / 2),
  118. &rfc_sec_check_complete, p_port);
  119. return;
  120. case RFC_EVENT_UA:
  121. return;
  122. case RFC_EVENT_DM:
  123. rfc_port_closed (p_port);
  124. return;
  125. case RFC_EVENT_UIH:
  126. osi_free (p_data);
  127. rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, FALSE);
  128. return;
  129. case RFC_EVENT_DISC:
  130. rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, FALSE);
  131. return;
  132. case RFC_EVENT_TIMEOUT:
  133. Port_TimeOutCloseMux( p_port->rfc.p_mcb ) ;
  134. RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
  135. return;
  136. }
  137. RFCOMM_TRACE_WARNING ("Port state closed Event ignored %d", event);
  138. return;
  139. }
  140. /*******************************************************************************
  141. **
  142. ** Function rfc_port_sm_sabme_wait_ua
  143. **
  144. ** Description This function handles events when SABME on the DLC was
  145. ** sent and SM is waiting for UA or DM.
  146. **
  147. ** Returns void
  148. **
  149. *******************************************************************************/
  150. void rfc_port_sm_sabme_wait_ua (tPORT *p_port, UINT16 event, void *p_data)
  151. {
  152. switch (event) {
  153. case RFC_EVENT_OPEN:
  154. case RFC_EVENT_ESTABLISH_RSP:
  155. RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
  156. return;
  157. case RFC_EVENT_CLOSE:
  158. rfc_port_timer_start (p_port, RFC_DISC_TIMEOUT);
  159. rfc_send_disc (p_port->rfc.p_mcb, p_port->dlci);
  160. p_port->rfc.expected_rsp = 0;
  161. p_port->rfc.state = RFC_STATE_DISC_WAIT_UA;
  162. return;
  163. case RFC_EVENT_CLEAR:
  164. rfc_port_closed (p_port);
  165. return;
  166. case RFC_EVENT_DATA:
  167. osi_free (p_data);
  168. break;
  169. case RFC_EVENT_UA:
  170. rfc_port_timer_stop (p_port);
  171. p_port->rfc.state = RFC_STATE_OPENED;
  172. PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_SUCCESS);
  173. return;
  174. case RFC_EVENT_DM:
  175. p_port->rfc.p_mcb->is_disc_initiator = TRUE;
  176. PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
  177. rfc_port_closed (p_port);
  178. return;
  179. case RFC_EVENT_DISC:
  180. rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
  181. PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
  182. rfc_port_closed (p_port);
  183. return;
  184. case RFC_EVENT_SABME:
  185. /* Continue to wait for the UA the SABME this side sent */
  186. rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
  187. return;
  188. case RFC_EVENT_UIH:
  189. osi_free (p_data);
  190. return;
  191. case RFC_EVENT_TIMEOUT:
  192. p_port->rfc.state = RFC_STATE_CLOSED;
  193. PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
  194. return;
  195. }
  196. RFCOMM_TRACE_WARNING ("Port state sabme_wait_ua Event ignored %d", event);
  197. }
  198. /*******************************************************************************
  199. **
  200. ** Function rfc_port_sm_term_wait_sec_check
  201. **
  202. ** Description This function handles events for the port in the
  203. ** WAIT_SEC_CHECK state. SABME has been received from the
  204. ** peer and Security Manager verifes BD_ADDR, before we can
  205. ** send ESTABLISH_IND to the Port entity
  206. **
  207. ** Returns void
  208. **
  209. *******************************************************************************/
  210. void rfc_port_sm_term_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data)
  211. {
  212. switch (event) {
  213. case RFC_EVENT_SEC_COMPLETE:
  214. if (*((UINT8 *)p_data) != BTM_SUCCESS) {
  215. /* Authentication/authorization failed. If link is still */
  216. /* up send DM and check if we need to start inactive timer */
  217. if (p_port->rfc.p_mcb) {
  218. rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE);
  219. p_port->rfc.p_mcb->is_disc_initiator = TRUE;
  220. port_rfc_closed (p_port, PORT_SEC_FAILED);
  221. }
  222. } else {
  223. PORT_DlcEstablishInd (p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu);
  224. }
  225. return;
  226. case RFC_EVENT_OPEN:
  227. case RFC_EVENT_CLOSE:
  228. RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
  229. return;
  230. case RFC_EVENT_CLEAR:
  231. btm_sec_abort_access_req (p_port->rfc.p_mcb->bd_addr);
  232. rfc_port_closed (p_port);
  233. return;
  234. case RFC_EVENT_DATA:
  235. RFCOMM_TRACE_ERROR ("Port error state Term Wait Sec event Data");
  236. osi_free (p_data);
  237. return;
  238. case RFC_EVENT_SABME:
  239. /* Ignore SABME retransmission if client dares to do so */
  240. return;
  241. case RFC_EVENT_DISC:
  242. btm_sec_abort_access_req (p_port->rfc.p_mcb->bd_addr);
  243. p_port->rfc.state = RFC_STATE_CLOSED;
  244. rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
  245. PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci);
  246. return;
  247. case RFC_EVENT_UIH:
  248. osi_free (p_data);
  249. return;
  250. case RFC_EVENT_ESTABLISH_RSP:
  251. if (*((UINT8 *)p_data) != RFCOMM_SUCCESS) {
  252. if (p_port->rfc.p_mcb) {
  253. rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE);
  254. }
  255. } else {
  256. rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
  257. p_port->rfc.state = RFC_STATE_OPENED;
  258. }
  259. return;
  260. }
  261. RFCOMM_TRACE_WARNING ("Port state term_wait_sec_check Event ignored %d", event);
  262. }
  263. /*******************************************************************************
  264. **
  265. ** Function rfc_port_sm_orig_wait_sec_check
  266. **
  267. ** Description This function handles events for the port in the
  268. ** ORIG_WAIT_SEC_CHECK state. RFCOMM is waiting for Security
  269. ** manager to finish before sending SABME to the peer
  270. **
  271. ** Returns void
  272. **
  273. *******************************************************************************/
  274. void rfc_port_sm_orig_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data)
  275. {
  276. switch (event) {
  277. case RFC_EVENT_SEC_COMPLETE:
  278. if (*((UINT8 *)p_data) != BTM_SUCCESS) {
  279. p_port->rfc.p_mcb->is_disc_initiator = TRUE;
  280. PORT_DlcEstablishCnf (p_port->rfc.p_mcb, p_port->dlci, 0, RFCOMM_SECURITY_ERR);
  281. rfc_port_closed (p_port);
  282. return;
  283. }
  284. rfc_send_sabme (p_port->rfc.p_mcb, p_port->dlci);
  285. rfc_port_timer_start (p_port, RFC_PORT_T1_TIMEOUT);
  286. p_port->rfc.state = RFC_STATE_SABME_WAIT_UA;
  287. return;
  288. case RFC_EVENT_OPEN:
  289. case RFC_EVENT_SABME: /* Peer should not use the same dlci */
  290. RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
  291. return;
  292. case RFC_EVENT_CLOSE:
  293. btm_sec_abort_access_req (p_port->rfc.p_mcb->bd_addr);
  294. rfc_port_closed (p_port);
  295. return;
  296. case RFC_EVENT_DATA:
  297. RFCOMM_TRACE_ERROR ("Port error state Orig Wait Sec event Data");
  298. osi_free (p_data);
  299. return;
  300. case RFC_EVENT_UIH:
  301. osi_free (p_data);
  302. return;
  303. }
  304. RFCOMM_TRACE_WARNING ("Port state orig_wait_sec_check Event ignored %d", event);
  305. }
  306. /*******************************************************************************
  307. **
  308. ** Function rfc_port_sm_opened
  309. **
  310. ** Description This function handles events for the port in the OPENED
  311. ** state
  312. **
  313. ** Returns void
  314. **
  315. *******************************************************************************/
  316. void rfc_port_sm_opened (tPORT *p_port, UINT16 event, void *p_data)
  317. {
  318. switch (event) {
  319. case RFC_EVENT_OPEN:
  320. RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
  321. return;
  322. case RFC_EVENT_CLOSE:
  323. rfc_port_timer_start (p_port, RFC_DISC_TIMEOUT);
  324. rfc_send_disc (p_port->rfc.p_mcb, p_port->dlci);
  325. p_port->rfc.expected_rsp = 0;
  326. p_port->rfc.state = RFC_STATE_DISC_WAIT_UA;
  327. return;
  328. case RFC_EVENT_CLEAR:
  329. rfc_port_closed (p_port);
  330. return;
  331. case RFC_EVENT_DATA:
  332. /* Send credits in the frame. Pass them in the layer specific member of the hdr. */
  333. /* There might be an initial case when we reduced rx_max and credit_rx is still */
  334. /* bigger. Make sure that we do not send 255 */
  335. if ((p_port->rfc.p_mcb->flow == PORT_FC_CREDIT)
  336. && (((BT_HDR *)p_data)->len < p_port->peer_mtu)
  337. && (!p_port->rx.user_fc)
  338. && (p_port->credit_rx_max > p_port->credit_rx)) {
  339. ((BT_HDR *)p_data)->layer_specific = (UINT8) (p_port->credit_rx_max - p_port->credit_rx);
  340. p_port->credit_rx = p_port->credit_rx_max;
  341. } else {
  342. ((BT_HDR *)p_data)->layer_specific = 0;
  343. }
  344. rfc_send_buf_uih (p_port->rfc.p_mcb, p_port->dlci, (BT_HDR *)p_data);
  345. rfc_dec_credit (p_port);
  346. return;
  347. case RFC_EVENT_UA:
  348. return;
  349. case RFC_EVENT_SABME:
  350. rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
  351. return;
  352. case RFC_EVENT_DM:
  353. PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci);
  354. rfc_port_closed (p_port);
  355. return;
  356. case RFC_EVENT_DISC:
  357. p_port->rfc.state = RFC_STATE_CLOSED;
  358. rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
  359. if (! fixed_queue_is_empty(p_port->rx.queue)) {
  360. /* give a chance to upper stack to close port properly */
  361. RFCOMM_TRACE_DEBUG("port queue is not empty");
  362. rfc_port_timer_start (p_port, RFC_DISC_TIMEOUT);
  363. } else {
  364. PORT_DlcReleaseInd (p_port->rfc.p_mcb, p_port->dlci);
  365. }
  366. return;
  367. case RFC_EVENT_UIH:
  368. rfc_port_uplink_data (p_port, (BT_HDR *)p_data);
  369. return;
  370. case RFC_EVENT_TIMEOUT:
  371. Port_TimeOutCloseMux( p_port->rfc.p_mcb ) ;
  372. RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
  373. return;
  374. }
  375. RFCOMM_TRACE_WARNING ("Port state opened Event ignored %d", event);
  376. }
  377. /*******************************************************************************
  378. **
  379. ** Function rfc_port_sm_disc_wait_ua
  380. **
  381. ** Description This function handles events when DISC on the DLC was
  382. ** sent and SM is waiting for UA or DM.
  383. **
  384. ** Returns void
  385. **
  386. *******************************************************************************/
  387. void rfc_port_sm_disc_wait_ua (tPORT *p_port, UINT16 event, void *p_data)
  388. {
  389. switch (event) {
  390. case RFC_EVENT_OPEN:
  391. case RFC_EVENT_ESTABLISH_RSP:
  392. RFCOMM_TRACE_ERROR ("Port error state %d event %d", p_port->rfc.state, event);
  393. return;
  394. case RFC_EVENT_CLEAR:
  395. rfc_port_closed (p_port);
  396. return;
  397. case RFC_EVENT_DATA:
  398. osi_free (p_data);
  399. return;
  400. case RFC_EVENT_UA:
  401. p_port->rfc.p_mcb->is_disc_initiator = TRUE;
  402. /* Case falls through */
  403. case RFC_EVENT_DM:
  404. rfc_port_closed (p_port);
  405. return;
  406. case RFC_EVENT_SABME:
  407. rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE);
  408. return;
  409. case RFC_EVENT_DISC:
  410. rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE);
  411. return;
  412. case RFC_EVENT_UIH:
  413. osi_free (p_data);
  414. rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, FALSE);
  415. return;
  416. case RFC_EVENT_TIMEOUT:
  417. rfc_port_closed (p_port);
  418. return;
  419. }
  420. RFCOMM_TRACE_WARNING ("Port state disc_wait_ua Event ignored %d", event);
  421. }
  422. /*******************************************************************************
  423. **
  424. ** Function rfc_port_uplink_data
  425. **
  426. ** Description This function handles uplink information data frame.
  427. **
  428. *******************************************************************************/
  429. void rfc_port_uplink_data (tPORT *p_port, BT_HDR *p_buf)
  430. {
  431. PORT_DataInd (p_port->rfc.p_mcb, p_port->dlci, p_buf);
  432. }
  433. /*******************************************************************************
  434. **
  435. ** Function rfc_process_pn
  436. **
  437. ** Description This function handles DLC parameter negotiation frame.
  438. ** Record MTU and pass indication to the upper layer.
  439. **
  440. *******************************************************************************/
  441. void rfc_process_pn (tRFC_MCB *p_mcb, BOOLEAN is_command, MX_FRAME *p_frame)
  442. {
  443. tPORT *p_port;
  444. UINT8 dlci = p_frame->dlci;
  445. if (is_command) {
  446. /* Ignore if Multiplexer is being shut down */
  447. if (p_mcb->state != RFC_MX_STATE_DISC_WAIT_UA) {
  448. PORT_ParNegInd (p_mcb, dlci, p_frame->u.pn.mtu,
  449. p_frame->u.pn.conv_layer, p_frame->u.pn.k);
  450. } else {
  451. rfc_send_dm(p_mcb, dlci, FALSE);
  452. RFCOMM_TRACE_WARNING("***** MX PN while disconnecting *****");
  453. }
  454. return;
  455. }
  456. /* If we are not awaiting response just ignore it */
  457. p_port = port_find_mcb_dlci_port (p_mcb, dlci);
  458. if ((p_port == NULL) || !(p_port->rfc.expected_rsp & RFC_RSP_PN)) {
  459. return;
  460. }
  461. p_port->rfc.expected_rsp &= ~RFC_RSP_PN;
  462. rfc_port_timer_stop (p_port);
  463. PORT_ParNegCnf (p_mcb, dlci, p_frame->u.pn.mtu,
  464. p_frame->u.pn.conv_layer, p_frame->u.pn.k);
  465. }
  466. /*******************************************************************************
  467. **
  468. ** Function rfc_process_rpn
  469. **
  470. ** Description This function handles Remote DLC parameter negotiation
  471. ** command/response. Pass command to the user.
  472. **
  473. *******************************************************************************/
  474. void rfc_process_rpn (tRFC_MCB *p_mcb, BOOLEAN is_command,
  475. BOOLEAN is_request, MX_FRAME *p_frame)
  476. {
  477. tPORT_STATE port_pars;
  478. tPORT *p_port;
  479. if ((p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci)) == NULL) {
  480. /* This is the first command on the port */
  481. if (is_command) {
  482. memset(&port_pars, 0, sizeof(tPORT_STATE));
  483. rfc_set_port_state(&port_pars, p_frame);
  484. PORT_PortNegInd(p_mcb, p_frame->dlci, &port_pars, p_frame->u.rpn.param_mask);
  485. }
  486. return;
  487. }
  488. if (is_command && is_request) {
  489. /* This is the special situation when peer just request local pars */
  490. port_pars = p_port->peer_port_pars;
  491. rfc_send_rpn (p_mcb, p_frame->dlci, FALSE, &p_port->peer_port_pars, 0);
  492. return;
  493. }
  494. port_pars = p_port->peer_port_pars;
  495. rfc_set_port_state(&port_pars, p_frame);
  496. if (is_command) {
  497. PORT_PortNegInd (p_mcb, p_frame->dlci, &port_pars, p_frame->u.rpn.param_mask);
  498. return;
  499. }
  500. /* If we are not awaiting response just ignore it */
  501. p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci);
  502. if ((p_port == NULL) || !(p_port->rfc.expected_rsp & (RFC_RSP_RPN | RFC_RSP_RPN_REPLY))) {
  503. return;
  504. }
  505. /* If we sent a request for port parameters to the peer he is replying with */
  506. /* mask 0. */
  507. rfc_port_timer_stop (p_port);
  508. if (p_port->rfc.expected_rsp & RFC_RSP_RPN_REPLY) {
  509. p_port->rfc.expected_rsp &= ~RFC_RSP_RPN_REPLY;
  510. p_port->peer_port_pars = port_pars;
  511. if ((port_pars.fc_type == (RFCOMM_FC_RTR_ON_INPUT | RFCOMM_FC_RTR_ON_OUTPUT))
  512. || (port_pars.fc_type == (RFCOMM_FC_RTC_ON_INPUT | RFCOMM_FC_RTC_ON_OUTPUT))) {
  513. /* This is satisfactory port parameters. Set mask as it was Ok */
  514. p_frame->u.rpn.param_mask = RFCOMM_RPN_PM_MASK;
  515. } else {
  516. /* Current peer parameters are not good, try to fix them */
  517. p_port->peer_port_pars.fc_type = (RFCOMM_FC_RTR_ON_INPUT | RFCOMM_FC_RTR_ON_OUTPUT);
  518. p_port->rfc.expected_rsp |= RFC_RSP_RPN;
  519. rfc_send_rpn (p_mcb, p_frame->dlci, TRUE, &p_port->peer_port_pars,
  520. RFCOMM_RPN_PM_RTR_ON_INPUT | RFCOMM_RPN_PM_RTR_ON_OUTPUT);
  521. rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
  522. return;
  523. }
  524. } else {
  525. p_port->rfc.expected_rsp &= ~RFC_RSP_RPN;
  526. }
  527. /* Check if all suggested parameters were accepted */
  528. if (((p_frame->u.rpn.param_mask & (RFCOMM_RPN_PM_RTR_ON_INPUT | RFCOMM_RPN_PM_RTR_ON_OUTPUT)) ==
  529. (RFCOMM_RPN_PM_RTR_ON_INPUT | RFCOMM_RPN_PM_RTR_ON_OUTPUT))
  530. || ((p_frame->u.rpn.param_mask & (RFCOMM_RPN_PM_RTC_ON_INPUT | RFCOMM_RPN_PM_RTC_ON_OUTPUT)) ==
  531. (RFCOMM_RPN_PM_RTC_ON_INPUT | RFCOMM_RPN_PM_RTC_ON_OUTPUT))) {
  532. PORT_PortNegCnf (p_mcb, p_port->dlci, &port_pars, RFCOMM_SUCCESS);
  533. return;
  534. }
  535. /* If we were proposing RTR flow control try RTC flow control */
  536. /* If we were proposing RTC flow control try no flow control */
  537. /* otherwise drop the connection */
  538. if (p_port->peer_port_pars.fc_type == (RFCOMM_FC_RTR_ON_INPUT | RFCOMM_FC_RTR_ON_OUTPUT)) {
  539. /* Current peer parameters are not good, try to fix them */
  540. p_port->peer_port_pars.fc_type = (RFCOMM_FC_RTC_ON_INPUT | RFCOMM_FC_RTC_ON_OUTPUT);
  541. p_port->rfc.expected_rsp |= RFC_RSP_RPN;
  542. rfc_send_rpn (p_mcb, p_frame->dlci, TRUE, &p_port->peer_port_pars,
  543. RFCOMM_RPN_PM_RTC_ON_INPUT | RFCOMM_RPN_PM_RTC_ON_OUTPUT);
  544. rfc_port_timer_start (p_port, RFC_T2_TIMEOUT) ;
  545. return;
  546. }
  547. /* Other side does not support flow control */
  548. if (p_port->peer_port_pars.fc_type == (RFCOMM_FC_RTC_ON_INPUT | RFCOMM_FC_RTC_ON_OUTPUT)) {
  549. p_port->peer_port_pars.fc_type = RFCOMM_FC_OFF;
  550. PORT_PortNegCnf (p_mcb, p_port->dlci, &port_pars, RFCOMM_SUCCESS);
  551. }
  552. }
  553. /*******************************************************************************
  554. **
  555. ** Function rfc_process_msc
  556. **
  557. ** Description This function handles Modem Status Command.
  558. ** Pass command to the user.
  559. **
  560. *******************************************************************************/
  561. void rfc_process_msc (tRFC_MCB *p_mcb, BOOLEAN is_command, MX_FRAME *p_frame)
  562. {
  563. tPORT_CTRL pars;
  564. tPORT *p_port;
  565. UINT8 modem_signals = p_frame->u.msc.signals;
  566. BOOLEAN new_peer_fc = FALSE;
  567. p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci);
  568. if (p_port == NULL) {
  569. return;
  570. }
  571. pars.modem_signal = 0;
  572. if (modem_signals & RFCOMM_MSC_RTC) {
  573. pars.modem_signal |= MODEM_SIGNAL_DTRDSR;
  574. }
  575. if (modem_signals & RFCOMM_MSC_RTR) {
  576. pars.modem_signal |= MODEM_SIGNAL_RTSCTS;
  577. }
  578. if (modem_signals & RFCOMM_MSC_IC) {
  579. pars.modem_signal |= MODEM_SIGNAL_RI;
  580. }
  581. if (modem_signals & RFCOMM_MSC_DV) {
  582. pars.modem_signal |= MODEM_SIGNAL_DCD;
  583. }
  584. pars.fc = ((modem_signals & RFCOMM_MSC_FC) == RFCOMM_MSC_FC);
  585. pars.break_signal = (p_frame->u.msc.break_present) ?
  586. p_frame->u.msc.break_duration : 0;
  587. pars.discard_buffers = 0;
  588. pars.break_signal_seq = RFCOMM_CTRL_BREAK_IN_SEQ; /* this is default */
  589. /* Check if this command is passed only to indicate flow control */
  590. if (is_command) {
  591. rfc_send_msc (p_mcb, p_frame->dlci, FALSE, &pars);
  592. if (p_port->rfc.p_mcb->flow != PORT_FC_CREDIT) {
  593. /* Spec 1.1 indicates that only FC bit is used for flow control */
  594. p_port->peer_ctrl.fc = new_peer_fc = pars.fc;
  595. if (new_peer_fc != p_port->tx.peer_fc) {
  596. PORT_FlowInd (p_mcb, p_frame->dlci, (BOOLEAN)!new_peer_fc);
  597. }
  598. }
  599. PORT_ControlInd (p_mcb, p_frame->dlci, &pars);
  600. return;
  601. }
  602. /* If we are not awaiting response just ignore it */
  603. if (!(p_port->rfc.expected_rsp & RFC_RSP_MSC)) {
  604. return;
  605. }
  606. p_port->rfc.expected_rsp &= ~RFC_RSP_MSC;
  607. rfc_port_timer_stop (p_port);
  608. PORT_ControlCnf (p_port->rfc.p_mcb, p_port->dlci, &pars);
  609. }
  610. /*******************************************************************************
  611. **
  612. ** Function rfc_process_rls
  613. **
  614. ** Description This function handles Remote Line Status command.
  615. ** Pass command to the user.
  616. **
  617. *******************************************************************************/
  618. void rfc_process_rls (tRFC_MCB *p_mcb, BOOLEAN is_command, MX_FRAME *p_frame)
  619. {
  620. tPORT *p_port;
  621. if (is_command) {
  622. PORT_LineStatusInd (p_mcb, p_frame->dlci, p_frame->u.rls.line_status);
  623. rfc_send_rls (p_mcb, p_frame->dlci, FALSE, p_frame->u.rls.line_status);
  624. } else {
  625. p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci);
  626. /* If we are not awaiting response just ignore it */
  627. if (!p_port || !(p_port->rfc.expected_rsp & RFC_RSP_RLS)) {
  628. return;
  629. }
  630. p_port->rfc.expected_rsp &= ~RFC_RSP_RLS;
  631. rfc_port_timer_stop (p_port);
  632. }
  633. }
  634. /*******************************************************************************
  635. **
  636. ** Function rfc_process_nsc
  637. **
  638. ** Description This function handles None Supported Command frame.
  639. **
  640. *******************************************************************************/
  641. void rfc_process_nsc (tRFC_MCB *p_mcb, MX_FRAME *p_frame)
  642. {
  643. UNUSED(p_mcb);
  644. UNUSED(p_frame);
  645. }
  646. /*******************************************************************************
  647. **
  648. ** Function rfc_process_test
  649. **
  650. ** Description This function handles Test frame. If this is a command
  651. ** reply to it. Otherwise pass response to the user.
  652. **
  653. *******************************************************************************/
  654. void rfc_process_test_rsp (tRFC_MCB *p_mcb, BT_HDR *p_buf)
  655. {
  656. UNUSED(p_mcb);
  657. osi_free (p_buf);
  658. }
  659. /*******************************************************************************
  660. **
  661. ** Function rfc_process_fcon
  662. **
  663. ** Description This function handles FCON frame. The peer entity is able
  664. ** to receive new information
  665. **
  666. *******************************************************************************/
  667. void rfc_process_fcon (tRFC_MCB *p_mcb, BOOLEAN is_command)
  668. {
  669. if (is_command) {
  670. rfc_cb.rfc.peer_rx_disabled = FALSE;
  671. rfc_send_fcon (p_mcb, FALSE);
  672. if (!p_mcb->l2cap_congested) {
  673. PORT_FlowInd (p_mcb, 0, TRUE);
  674. }
  675. }
  676. }
  677. /*******************************************************************************
  678. **
  679. ** Function rfc_process_fcoff
  680. **
  681. ** Description This function handles FCOFF frame. The peer entity is unable
  682. ** to receive new information
  683. **
  684. *******************************************************************************/
  685. void rfc_process_fcoff (tRFC_MCB *p_mcb, BOOLEAN is_command)
  686. {
  687. if (is_command) {
  688. rfc_cb.rfc.peer_rx_disabled = TRUE;
  689. if (!p_mcb->l2cap_congested) {
  690. PORT_FlowInd (p_mcb, 0, FALSE);
  691. }
  692. rfc_send_fcoff (p_mcb, FALSE);
  693. }
  694. }
  695. /*******************************************************************************
  696. **
  697. ** Function rfc_process_l2cap_congestion
  698. **
  699. ** Description This function handles L2CAP congestion messages
  700. **
  701. *******************************************************************************/
  702. void rfc_process_l2cap_congestion (tRFC_MCB *p_mcb, BOOLEAN is_congested)
  703. {
  704. p_mcb->l2cap_congested = is_congested;
  705. if (!is_congested) {
  706. rfc_check_send_cmd(p_mcb, NULL);
  707. }
  708. if (!rfc_cb.rfc.peer_rx_disabled) {
  709. if (!is_congested) {
  710. PORT_FlowInd (p_mcb, 0, TRUE);
  711. } else {
  712. PORT_FlowInd (p_mcb, 0, FALSE);
  713. }
  714. }
  715. }
  716. /*******************************************************************************
  717. **
  718. ** Function rfc_set_port_pars
  719. **
  720. ** Description This function sets the tPORT_STATE structure given a p_frame.
  721. **
  722. *******************************************************************************/
  723. void rfc_set_port_state(tPORT_STATE *port_pars, MX_FRAME *p_frame)
  724. {
  725. if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_BIT_RATE) {
  726. port_pars->baud_rate = p_frame->u.rpn.baud_rate;
  727. }
  728. if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_DATA_BITS) {
  729. port_pars->byte_size = p_frame->u.rpn.byte_size;
  730. }
  731. if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_STOP_BITS) {
  732. port_pars->stop_bits = p_frame->u.rpn.stop_bits;
  733. }
  734. if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_PARITY) {
  735. port_pars->parity = p_frame->u.rpn.parity;
  736. }
  737. if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_PARITY_TYPE) {
  738. port_pars->parity_type = p_frame->u.rpn.parity_type;
  739. }
  740. if (p_frame->u.rpn.param_mask & (RFCOMM_RPN_PM_XONXOFF_ON_INPUT |
  741. RFCOMM_RPN_PM_XONXOFF_ON_OUTPUT |
  742. RFCOMM_RPN_PM_RTR_ON_INPUT |
  743. RFCOMM_RPN_PM_RTR_ON_OUTPUT |
  744. RFCOMM_RPN_PM_RTC_ON_INPUT |
  745. RFCOMM_RPN_PM_RTC_ON_OUTPUT)) {
  746. port_pars->fc_type = p_frame->u.rpn.fc_type;
  747. }
  748. if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_XON_CHAR) {
  749. port_pars->xon_char = p_frame->u.rpn.xon_char;
  750. }
  751. if (p_frame->u.rpn.param_mask & RFCOMM_RPN_PM_XOFF_CHAR) {
  752. port_pars->xoff_char = p_frame->u.rpn.xoff_char;
  753. }
  754. }
  755. #endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)