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  *
21  *  this file contains the Serial Port API code
22  *
23  ******************************************************************************/
24 
25 #define LOG_TAG "bt_port_api"
26 
27 #include <string.h>
28 
29 #include "osi/include/log.h"
30 #include "osi/include/mutex.h"
31 
32 #include "bt_common.h"
33 #include "btm_api.h"
34 #include "btm_int.h"
35 #include "l2c_api.h"
36 #include "port_api.h"
37 #include "port_int.h"
38 #include "rfc_int.h"
39 #include "rfcdefs.h"
40 #include "sdp_api.h"
41 
42 /* duration of break in 200ms units */
43 #define PORT_BREAK_DURATION 1
44 
45 #define info(fmt, ...) LOG_INFO(LOG_TAG, "%s: " fmt, __func__, ##__VA_ARGS__)
46 #define debug(fmt, ...) LOG_DEBUG(LOG_TAG, "%s: " fmt, __func__, ##__VA_ARGS__)
47 #define error(fmt, ...) \
48   LOG_ERROR(LOG_TAG, "## ERROR : %s: " fmt "##", __func__, ##__VA_ARGS__)
49 #define asrt(s)                                                            \
50   if (!(s))                                                                \
51   LOG_ERROR(LOG_TAG, "## %s assert %s failed at line:%d ##", __func__, #s, \
52             __LINE__)
53 
54 /* Mapping from PORT_* result codes to human readable strings. */
55 static const char* result_code_strings[] = {"Success",
56                                             "Unknown error",
57                                             "Already opened",
58                                             "Command pending",
59                                             "App not registered",
60                                             "No memory",
61                                             "No resources",
62                                             "Bad BD address",
63                                             "Unspecified error",
64                                             "Bad handle",
65                                             "Not opened",
66                                             "Line error",
67                                             "Start failed",
68                                             "Parameter negotiation failed",
69                                             "Port negotiation failed",
70                                             "Sec failed",
71                                             "Peer connection failed",
72                                             "Peer failed",
73                                             "Peer timeout",
74                                             "Closed",
75                                             "TX full",
76                                             "Local closed",
77                                             "Local timeout",
78                                             "TX queue disabled",
79                                             "Page timeout",
80                                             "Invalid SCN",
81                                             "Unknown result code"};
82 
83 /*******************************************************************************
84  *
85  * Function         RFCOMM_CreateConnection
86  *
87  * Description      RFCOMM_CreateConnection function is used from the
88  *                  application to establish serial port connection to the peer
89  *                  device, or allow RFCOMM to accept a connection from the peer
90  *                  application.
91  *
92  * Parameters:      scn          - Service Channel Number as registered with
93  *                                 the SDP (server) or obtained using SDP from
94  *                                 the peer device (client).
95  *                  is_server    - true if requesting application is a server
96  *                  mtu          - Maximum frame size the application can accept
97  *                  bd_addr      - BD_ADDR of the peer (client)
98  *                  mask         - specifies events to be enabled.  A value
99  *                                 of zero disables all events.
100  *                  p_handle     - OUT pointer to the handle.
101  *                  p_mgmt_cb    - pointer to callback function to receive
102  *                                 connection up/down events.
103  * Notes:
104  *
105  * Server can call this function with the same scn parameter multiple times if
106  * it is ready to accept multiple simulteneous connections.
107  *
108  * DLCI for the connection is (scn * 2 + 1) if client originates connection on
109  * existing none initiator multiplexer channel.  Otherwise it is (scn * 2).
110  * For the server DLCI can be changed later if client will be calling it using
111  * (scn * 2 + 1) dlci.
112  *
113  ******************************************************************************/
RFCOMM_CreateConnection(uint16_t uuid,uint8_t scn,bool is_server,uint16_t mtu,BD_ADDR bd_addr,uint16_t * p_handle,tPORT_CALLBACK * p_mgmt_cb)114 int RFCOMM_CreateConnection(uint16_t uuid, uint8_t scn, bool is_server,
115                             uint16_t mtu, BD_ADDR bd_addr, uint16_t* p_handle,
116                             tPORT_CALLBACK* p_mgmt_cb) {
117   tPORT* p_port;
118   int i;
119   uint8_t dlci;
120   tRFC_MCB* p_mcb = port_find_mcb(bd_addr);
121   uint16_t rfcomm_mtu;
122 
123   RFCOMM_TRACE_API(
124       "RFCOMM_CreateConnection()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
125       bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
126 
127   *p_handle = 0;
128 
129   if ((scn == 0) || (scn >= PORT_MAX_RFC_PORTS)) {
130     /* Server Channel Number(SCN) should be in range 1...30 */
131     RFCOMM_TRACE_ERROR("RFCOMM_CreateConnection - invalid SCN");
132     return (PORT_INVALID_SCN);
133   }
134 
135   /* For client that originate connection on the existing none initiator */
136   /* multiplexer channel DLCI should be odd */
137   if (p_mcb && !p_mcb->is_initiator && !is_server)
138     dlci = (scn << 1) + 1;
139   else
140     dlci = (scn << 1);
141   RFCOMM_TRACE_API(
142       "RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, "
143       "p_mcb:%p",
144       scn, dlci, is_server, mtu, p_mcb);
145 
146   /* For the server side always allocate a new port.  On the client side */
147   /* do not allow the same (dlci, bd_addr) to be opened twice by application */
148   if (!is_server) {
149     p_port = port_find_port(dlci, bd_addr);
150     if (p_port != NULL) {
151       /* if existing port is also a client port */
152       if (p_port->is_server == false) {
153         RFCOMM_TRACE_ERROR(
154             "RFCOMM_CreateConnection - already opened state:%d, RFC state:%d, "
155             "MCB state:%d",
156             p_port->state, p_port->rfc.state,
157             p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0);
158         *p_handle = p_port->inx;
159         return (PORT_ALREADY_OPENED);
160       }
161     }
162   }
163 
164   p_port = port_allocate_port(dlci, bd_addr);
165   if (p_port == NULL) {
166     RFCOMM_TRACE_WARNING("RFCOMM_CreateConnection - no resources");
167     return (PORT_NO_RESOURCES);
168   }
169   RFCOMM_TRACE_API(
170       "RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, "
171       "p_mcb:%p, p_port:%p",
172       scn, dlci, is_server, mtu, p_mcb, p_port);
173 
174   p_port->default_signal_state =
175       (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
176 
177   switch (uuid) {
178     case UUID_PROTOCOL_OBEX:
179       p_port->default_signal_state = PORT_OBEX_DEFAULT_SIGNAL_STATE;
180       break;
181     case UUID_SERVCLASS_SERIAL_PORT:
182       p_port->default_signal_state = PORT_SPP_DEFAULT_SIGNAL_STATE;
183       break;
184     case UUID_SERVCLASS_LAN_ACCESS_USING_PPP:
185       p_port->default_signal_state = PORT_PPP_DEFAULT_SIGNAL_STATE;
186       break;
187     case UUID_SERVCLASS_DIALUP_NETWORKING:
188     case UUID_SERVCLASS_FAX:
189       p_port->default_signal_state = PORT_DUN_DEFAULT_SIGNAL_STATE;
190       break;
191   }
192 
193   RFCOMM_TRACE_EVENT("RFCOMM_CreateConnection dlci:%d signal state:0x%x", dlci,
194                      p_port->default_signal_state);
195 
196   *p_handle = p_port->inx;
197 
198   p_port->state = PORT_STATE_OPENING;
199   p_port->uuid = uuid;
200   p_port->is_server = is_server;
201   p_port->scn = scn;
202   p_port->ev_mask = 0;
203 
204   /* If the MTU is not specified (0), keep MTU decision until the
205    * PN frame has to be send
206    * at that time connection should be established and we
207    * will know for sure our prefered MTU
208    */
209 
210   rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
211 
212   if (mtu)
213     p_port->mtu = (mtu < rfcomm_mtu) ? mtu : rfcomm_mtu;
214   else
215     p_port->mtu = rfcomm_mtu;
216 
217   /* server doesn't need to release port when closing */
218   if (is_server) {
219     p_port->keep_port_handle = true;
220 
221     /* keep mtu that user asked, p_port->mtu could be updated during param
222      * negotiation */
223     p_port->keep_mtu = p_port->mtu;
224   }
225 
226   p_port->local_ctrl.modem_signal = p_port->default_signal_state;
227   p_port->local_ctrl.fc = false;
228 
229   p_port->p_mgmt_callback = p_mgmt_cb;
230 
231   for (i = 0; i < BD_ADDR_LEN; i++) p_port->bd_addr[i] = bd_addr[i];
232 
233   /* If this is not initiator of the connection need to just wait */
234   if (p_port->is_server) {
235     return (PORT_SUCCESS);
236   }
237 
238   /* Open will be continued after security checks are passed */
239   return port_open_continue(p_port);
240 }
241 
242 /*******************************************************************************
243  *
244  * Function         RFCOMM_RemoveConnection
245  *
246  * Description      This function is called to close the specified connection.
247  *
248  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
249  *
250  ******************************************************************************/
RFCOMM_RemoveConnection(uint16_t handle)251 int RFCOMM_RemoveConnection(uint16_t handle) {
252   tPORT* p_port;
253 
254   RFCOMM_TRACE_API("RFCOMM_RemoveConnection() handle:%d", handle);
255 
256   /* Check if handle is valid to avoid crashing */
257   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
258     RFCOMM_TRACE_ERROR("RFCOMM_RemoveConnection() BAD handle:%d", handle);
259     return (PORT_BAD_HANDLE);
260   }
261   p_port = &rfc_cb.port.port[handle - 1];
262 
263   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
264     RFCOMM_TRACE_EVENT("RFCOMM_RemoveConnection() Not opened:%d", handle);
265     return (PORT_SUCCESS);
266   }
267 
268   p_port->state = PORT_STATE_CLOSING;
269 
270   port_start_close(p_port);
271 
272   return (PORT_SUCCESS);
273 }
274 
275 /*******************************************************************************
276  *
277  * Function         RFCOMM_RemoveServer
278  *
279  * Description      This function is called to close the server port.
280  *
281  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
282  *
283  ******************************************************************************/
RFCOMM_RemoveServer(uint16_t handle)284 int RFCOMM_RemoveServer(uint16_t handle) {
285   tPORT* p_port;
286 
287   RFCOMM_TRACE_API("RFCOMM_RemoveServer() handle:%d", handle);
288 
289   /* Check if handle is valid to avoid crashing */
290   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
291     RFCOMM_TRACE_ERROR("RFCOMM_RemoveServer() BAD handle:%d", handle);
292     return (PORT_BAD_HANDLE);
293   }
294   p_port = &rfc_cb.port.port[handle - 1];
295 
296   /* Do not report any events to the client any more. */
297   p_port->p_mgmt_callback = NULL;
298 
299   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
300     RFCOMM_TRACE_EVENT("RFCOMM_RemoveServer() Not opened:%d", handle);
301     return (PORT_SUCCESS);
302   }
303 
304   /* this port will be deallocated after closing */
305   p_port->keep_port_handle = false;
306   p_port->state = PORT_STATE_CLOSING;
307 
308   port_start_close(p_port);
309 
310   return (PORT_SUCCESS);
311 }
312 
313 /*******************************************************************************
314  *
315  * Function         PORT_SetEventCallback
316  *
317  * Description      This function is called to provide an address of the
318  *                  function which will be called when one of the events
319  *                  specified in the mask occures.
320  *
321  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
322  *                  p_callback - address of the callback function which should
323  *                               be called from the RFCOMM when an event
324  *                               specified in the mask occures.
325  *
326  *
327  ******************************************************************************/
PORT_SetEventCallback(uint16_t port_handle,tPORT_CALLBACK * p_port_cb)328 int PORT_SetEventCallback(uint16_t port_handle, tPORT_CALLBACK* p_port_cb) {
329   tPORT* p_port;
330 
331   /* Check if handle is valid to avoid crashing */
332   if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
333     return (PORT_BAD_HANDLE);
334   }
335 
336   p_port = &rfc_cb.port.port[port_handle - 1];
337 
338   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
339     return (PORT_NOT_OPENED);
340   }
341 
342   RFCOMM_TRACE_API("PORT_SetEventCallback() handle:%d", port_handle);
343 
344   p_port->p_callback = p_port_cb;
345 
346   return (PORT_SUCCESS);
347 }
348 /*******************************************************************************
349  *
350  * Function         PORT_ClearKeepHandleFlag
351  *
352  * Description      Clear the keep handle flag, which will cause not to keep the
353  *                  port handle open when closed
354  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
355  *
356  ******************************************************************************/
357 
PORT_ClearKeepHandleFlag(uint16_t port_handle)358 int PORT_ClearKeepHandleFlag(uint16_t port_handle) {
359   tPORT* p_port;
360 
361   /* Check if handle is valid to avoid crashing */
362   if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
363     return (PORT_BAD_HANDLE);
364   }
365 
366   p_port = &rfc_cb.port.port[port_handle - 1];
367   p_port->keep_port_handle = 0;
368   return (PORT_SUCCESS);
369 }
370 
371 /*******************************************************************************
372  *
373  * Function         PORT_SetDataCallback
374  *
375  * Description      This function is when a data packet is received
376  *
377  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
378  *                  p_callback - address of the callback function which should
379  *                               be called from the RFCOMM when data packet
380  *                               is received.
381  *
382  *
383  ******************************************************************************/
PORT_SetDataCallback(uint16_t port_handle,tPORT_DATA_CALLBACK * p_port_cb)384 int PORT_SetDataCallback(uint16_t port_handle, tPORT_DATA_CALLBACK* p_port_cb) {
385   tPORT* p_port;
386 
387   RFCOMM_TRACE_API("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle,
388                    p_port_cb);
389 
390   /* Check if handle is valid to avoid crashing */
391   if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
392     return (PORT_BAD_HANDLE);
393   }
394 
395   p_port = &rfc_cb.port.port[port_handle - 1];
396 
397   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
398     return (PORT_NOT_OPENED);
399   }
400 
401   p_port->p_data_callback = p_port_cb;
402 
403   return (PORT_SUCCESS);
404 }
405 /*******************************************************************************
406  *
407  * Function         PORT_SetCODataCallback
408  *
409  * Description      This function is when a data packet is received
410  *
411  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
412  *                  p_callback - address of the callback function which should
413  *                               be called from the RFCOMM when data packet
414  *                               is received.
415  *
416  *
417  ******************************************************************************/
PORT_SetDataCOCallback(uint16_t port_handle,tPORT_DATA_CO_CALLBACK * p_port_cb)418 int PORT_SetDataCOCallback(uint16_t port_handle,
419                            tPORT_DATA_CO_CALLBACK* p_port_cb) {
420   tPORT* p_port;
421 
422   RFCOMM_TRACE_API("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle,
423                    p_port_cb);
424 
425   /* Check if handle is valid to avoid crashing */
426   if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
427     return (PORT_BAD_HANDLE);
428   }
429 
430   p_port = &rfc_cb.port.port[port_handle - 1];
431 
432   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
433     return (PORT_NOT_OPENED);
434   }
435 
436   p_port->p_data_co_callback = p_port_cb;
437 
438   return (PORT_SUCCESS);
439 }
440 
441 /*******************************************************************************
442  *
443  * Function         PORT_SetEventMask
444  *
445  * Description      This function is called to close the specified connection.
446  *
447  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
448  *                  mask   - Bitmask of the events the host is interested in
449  *
450  ******************************************************************************/
PORT_SetEventMask(uint16_t port_handle,uint32_t mask)451 int PORT_SetEventMask(uint16_t port_handle, uint32_t mask) {
452   tPORT* p_port;
453 
454   RFCOMM_TRACE_API("PORT_SetEventMask() handle:%d mask:0x%x", port_handle,
455                    mask);
456 
457   /* Check if handle is valid to avoid crashing */
458   if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
459     return (PORT_BAD_HANDLE);
460   }
461 
462   p_port = &rfc_cb.port.port[port_handle - 1];
463 
464   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
465     return (PORT_NOT_OPENED);
466   }
467 
468   p_port->ev_mask = mask;
469 
470   return (PORT_SUCCESS);
471 }
472 
473 /*******************************************************************************
474  *
475  * Function         PORT_CheckConnection
476  *
477  * Description      This function returns PORT_SUCCESS if connection referenced
478  *                  by handle is up and running
479  *
480  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
481  *                  bd_addr    - OUT bd_addr of the peer
482  *                  p_lcid     - OUT L2CAP's LCID
483  *
484  ******************************************************************************/
PORT_CheckConnection(uint16_t handle,BD_ADDR bd_addr,uint16_t * p_lcid)485 int PORT_CheckConnection(uint16_t handle, BD_ADDR bd_addr, uint16_t* p_lcid) {
486   tPORT* p_port;
487 
488   RFCOMM_TRACE_API("PORT_CheckConnection() handle:%d", handle);
489 
490   /* Check if handle is valid to avoid crashing */
491   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
492     return (PORT_BAD_HANDLE);
493   }
494 
495   p_port = &rfc_cb.port.port[handle - 1];
496 
497   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
498     return (PORT_NOT_OPENED);
499   }
500 
501   if (!p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready ||
502       (p_port->rfc.state != RFC_STATE_OPENED)) {
503     return (PORT_LINE_ERR);
504   }
505 
506   memcpy(bd_addr, p_port->rfc.p_mcb->bd_addr, BD_ADDR_LEN);
507   if (p_lcid) *p_lcid = p_port->rfc.p_mcb->lcid;
508 
509   return (PORT_SUCCESS);
510 }
511 
512 /*******************************************************************************
513  *
514  * Function         PORT_IsOpening
515  *
516  * Description      This function returns true if there is any RFCOMM connection
517  *                  opening in process.
518  *
519  * Parameters:      true if any connection opening is found
520  *                  bd_addr    - bd_addr of the peer
521  *
522  ******************************************************************************/
PORT_IsOpening(BD_ADDR bd_addr)523 bool PORT_IsOpening(BD_ADDR bd_addr) {
524   uint8_t xx, yy;
525   tRFC_MCB* p_mcb = NULL;
526   tPORT* p_port;
527   bool found_port;
528 
529   /* Check for any rfc_mcb which is in the middle of opening. */
530   for (xx = 0; xx < MAX_BD_CONNECTIONS; xx++) {
531     if ((rfc_cb.port.rfc_mcb[xx].state > RFC_MX_STATE_IDLE) &&
532         (rfc_cb.port.rfc_mcb[xx].state < RFC_MX_STATE_CONNECTED)) {
533       memcpy(bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
534       return true;
535     }
536 
537     if (rfc_cb.port.rfc_mcb[xx].state == RFC_MX_STATE_CONNECTED) {
538       found_port = false;
539       p_mcb = &rfc_cb.port.rfc_mcb[xx];
540       p_port = &rfc_cb.port.port[0];
541 
542       for (yy = 0; yy < MAX_RFC_PORTS; yy++, p_port++) {
543         if (p_port->rfc.p_mcb == p_mcb) {
544           found_port = true;
545           break;
546         }
547       }
548 
549       if ((!found_port) ||
550           (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) {
551         /* Port is not established yet. */
552         memcpy(bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
553         return true;
554       }
555     }
556   }
557 
558   return false;
559 }
560 
561 /*******************************************************************************
562  *
563  * Function         PORT_SetState
564  *
565  * Description      This function configures connection according to the
566  *                  specifications in the tPORT_STATE structure.
567  *
568  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
569  *                  p_settings - Pointer to a tPORT_STATE structure containing
570  *                               configuration information for the connection.
571  *
572  *
573  ******************************************************************************/
PORT_SetState(uint16_t handle,tPORT_STATE * p_settings)574 int PORT_SetState(uint16_t handle, tPORT_STATE* p_settings) {
575   tPORT* p_port;
576   uint8_t baud_rate;
577 
578   RFCOMM_TRACE_API("PORT_SetState() handle:%d", handle);
579 
580   /* Check if handle is valid to avoid crashing */
581   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
582     return (PORT_BAD_HANDLE);
583   }
584 
585   p_port = &rfc_cb.port.port[handle - 1];
586 
587   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
588     return (PORT_NOT_OPENED);
589   }
590 
591   if (p_port->line_status) {
592     return (PORT_LINE_ERR);
593   }
594 
595   RFCOMM_TRACE_API("PORT_SetState() handle:%d FC_TYPE:0x%x", handle,
596                    p_settings->fc_type);
597 
598   baud_rate = p_port->user_port_pars.baud_rate;
599   p_port->user_port_pars = *p_settings;
600 
601   /* for now we've been asked to pass only baud rate */
602   if (baud_rate != p_settings->baud_rate) {
603     port_start_par_neg(p_port);
604   }
605   return (PORT_SUCCESS);
606 }
607 
608 /*******************************************************************************
609  *
610  * Function         PORT_GetRxQueueCnt
611  *
612  * Description      This function return number of buffers on the rx queue.
613  *
614  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
615  *                  p_rx_queue_count - Pointer to return queue count in.
616  *
617  ******************************************************************************/
PORT_GetRxQueueCnt(uint16_t handle,uint16_t * p_rx_queue_count)618 int PORT_GetRxQueueCnt(uint16_t handle, uint16_t* p_rx_queue_count) {
619   tPORT* p_port;
620 
621   RFCOMM_TRACE_API("PORT_GetRxQueueCnt() handle:%d", handle);
622 
623   /* Check if handle is valid to avoid crashing */
624   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
625     return (PORT_BAD_HANDLE);
626   }
627 
628   p_port = &rfc_cb.port.port[handle - 1];
629 
630   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
631     return (PORT_NOT_OPENED);
632   }
633 
634   if (p_port->line_status) {
635     return (PORT_LINE_ERR);
636   }
637 
638   *p_rx_queue_count = p_port->rx.queue_size;
639 
640   RFCOMM_TRACE_API(
641       "PORT_GetRxQueueCnt() p_rx_queue_count:%d, p_port->rx.queue.count = %d",
642       *p_rx_queue_count, p_port->rx.queue_size);
643 
644   return (PORT_SUCCESS);
645 }
646 
647 /*******************************************************************************
648  *
649  * Function         PORT_GetState
650  *
651  * Description      This function is called to fill tPORT_STATE structure
652  *                  with the curremt control settings for the port
653  *
654  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
655  *                  p_settings - Pointer to a tPORT_STATE structure in which
656  *                               configuration information is returned.
657  *
658  ******************************************************************************/
PORT_GetState(uint16_t handle,tPORT_STATE * p_settings)659 int PORT_GetState(uint16_t handle, tPORT_STATE* p_settings) {
660   tPORT* p_port;
661 
662   RFCOMM_TRACE_API("PORT_GetState() handle:%d", handle);
663 
664   /* Check if handle is valid to avoid crashing */
665   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
666     return (PORT_BAD_HANDLE);
667   }
668 
669   p_port = &rfc_cb.port.port[handle - 1];
670 
671   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
672     return (PORT_NOT_OPENED);
673   }
674 
675   if (p_port->line_status) {
676     return (PORT_LINE_ERR);
677   }
678 
679   *p_settings = p_port->user_port_pars;
680   return (PORT_SUCCESS);
681 }
682 
683 /*******************************************************************************
684  *
685  * Function         PORT_Control
686  *
687  * Description      This function directs a specified connection to pass control
688  *                  control information to the peer device.
689  *
690  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
691  *                  signal     = specify the function to be passed
692  *
693  ******************************************************************************/
PORT_Control(uint16_t handle,uint8_t signal)694 int PORT_Control(uint16_t handle, uint8_t signal) {
695   tPORT* p_port;
696   uint8_t old_modem_signal;
697 
698   RFCOMM_TRACE_API("PORT_Control() handle:%d signal:0x%x", handle, signal);
699 
700   /* Check if handle is valid to avoid crashing */
701   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
702     return (PORT_BAD_HANDLE);
703   }
704 
705   p_port = &rfc_cb.port.port[handle - 1];
706 
707   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
708     return (PORT_NOT_OPENED);
709   }
710 
711   old_modem_signal = p_port->local_ctrl.modem_signal;
712   p_port->local_ctrl.break_signal = 0;
713 
714   switch (signal) {
715     case PORT_SET_CTSRTS:
716       p_port->local_ctrl.modem_signal |= PORT_CTSRTS_ON;
717       break;
718 
719     case PORT_CLR_CTSRTS:
720       p_port->local_ctrl.modem_signal &= ~PORT_CTSRTS_ON;
721       break;
722 
723     case PORT_SET_DTRDSR:
724       p_port->local_ctrl.modem_signal |= PORT_DTRDSR_ON;
725       break;
726 
727     case PORT_CLR_DTRDSR:
728       p_port->local_ctrl.modem_signal &= ~PORT_DTRDSR_ON;
729       break;
730 
731     case PORT_SET_RI:
732       p_port->local_ctrl.modem_signal |= PORT_RING_ON;
733       break;
734 
735     case PORT_CLR_RI:
736       p_port->local_ctrl.modem_signal &= ~PORT_RING_ON;
737       break;
738 
739     case PORT_SET_DCD:
740       p_port->local_ctrl.modem_signal |= PORT_DCD_ON;
741       break;
742 
743     case PORT_CLR_DCD:
744       p_port->local_ctrl.modem_signal &= ~PORT_DCD_ON;
745       break;
746   }
747 
748   if (signal == PORT_BREAK)
749     p_port->local_ctrl.break_signal = PORT_BREAK_DURATION;
750   else if (p_port->local_ctrl.modem_signal == old_modem_signal)
751     return (PORT_SUCCESS);
752 
753   port_start_control(p_port);
754 
755   RFCOMM_TRACE_EVENT(
756       "PORT_Control DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d",
757       ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0),
758       ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0),
759       ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0),
760       ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0));
761 
762   return (PORT_SUCCESS);
763 }
764 
765 /*******************************************************************************
766  *
767  * Function         PORT_FlowControl
768  *
769  * Description      This function directs a specified connection to pass
770  *                  flow control message to the peer device.  Enable flag passed
771  *                  shows if port can accept more data.
772  *
773  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
774  *                  enable     - enables data flow
775  *
776  ******************************************************************************/
PORT_FlowControl(uint16_t handle,bool enable)777 int PORT_FlowControl(uint16_t handle, bool enable) {
778   tPORT* p_port;
779   bool old_fc;
780   uint32_t events;
781 
782   RFCOMM_TRACE_API("PORT_FlowControl() handle:%d enable: %d", handle, enable);
783 
784   /* Check if handle is valid to avoid crashing */
785   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
786     return (PORT_BAD_HANDLE);
787   }
788 
789   p_port = &rfc_cb.port.port[handle - 1];
790 
791   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
792     return (PORT_NOT_OPENED);
793   }
794 
795   if (!p_port->rfc.p_mcb) {
796     return (PORT_NOT_OPENED);
797   }
798 
799   p_port->rx.user_fc = !enable;
800 
801   if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
802     if (!p_port->rx.user_fc) {
803       port_flow_control_peer(p_port, true, 0);
804     }
805   } else {
806     old_fc = p_port->local_ctrl.fc;
807 
808     /* FC is set if user is set or peer is set */
809     p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
810 
811     if (p_port->local_ctrl.fc != old_fc) port_start_control(p_port);
812   }
813 
814   /* Need to take care of the case when we could not deliver events */
815   /* to the application because we were flow controlled */
816   if (enable && (p_port->rx.queue_size != 0)) {
817     events = PORT_EV_RXCHAR;
818     if (p_port->rx_flag_ev_pending) {
819       p_port->rx_flag_ev_pending = false;
820       events |= PORT_EV_RXFLAG;
821     }
822 
823     events &= p_port->ev_mask;
824     if (p_port->p_callback && events) {
825       p_port->p_callback(events, p_port->inx);
826     }
827   }
828   return (PORT_SUCCESS);
829 }
830 /*******************************************************************************
831  *
832  * Function         PORT_FlowControl_MaxCredit
833  *
834  * Description      This function directs a specified connection to pass
835  *                  flow control message to the peer device.  Enable flag passed
836  *                  shows if port can accept more data. It also sends max credit
837  *                  when data flow enabled
838  *
839  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
840  *                  enable     - enables data flow
841  *
842  ******************************************************************************/
843 
PORT_FlowControl_MaxCredit(uint16_t handle,bool enable)844 int PORT_FlowControl_MaxCredit(uint16_t handle, bool enable) {
845   tPORT* p_port;
846   bool old_fc;
847   uint32_t events;
848 
849   RFCOMM_TRACE_API("PORT_FlowControl() handle:%d enable: %d", handle, enable);
850 
851   /* Check if handle is valid to avoid crashing */
852   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
853     return (PORT_BAD_HANDLE);
854   }
855 
856   p_port = &rfc_cb.port.port[handle - 1];
857 
858   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
859     return (PORT_NOT_OPENED);
860   }
861 
862   if (!p_port->rfc.p_mcb) {
863     return (PORT_NOT_OPENED);
864   }
865 
866   p_port->rx.user_fc = !enable;
867 
868   if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
869     if (!p_port->rx.user_fc) {
870       port_flow_control_peer(p_port, true, p_port->credit_rx);
871     }
872   } else {
873     old_fc = p_port->local_ctrl.fc;
874 
875     /* FC is set if user is set or peer is set */
876     p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
877 
878     if (p_port->local_ctrl.fc != old_fc) port_start_control(p_port);
879   }
880 
881   /* Need to take care of the case when we could not deliver events */
882   /* to the application because we were flow controlled */
883   if (enable && (p_port->rx.queue_size != 0)) {
884     events = PORT_EV_RXCHAR;
885     if (p_port->rx_flag_ev_pending) {
886       p_port->rx_flag_ev_pending = false;
887       events |= PORT_EV_RXFLAG;
888     }
889 
890     events &= p_port->ev_mask;
891     if (p_port->p_callback && events) {
892       p_port->p_callback(events, p_port->inx);
893     }
894   }
895   return (PORT_SUCCESS);
896 }
897 
898 /*******************************************************************************
899  *
900  * Function         PORT_GetModemStatus
901  *
902  * Description      This function retrieves modem control signals.  Normally
903  *                  application will call this function after a callback
904  *                  function is called with notification that one of signals
905  *                  has been changed.
906  *
907  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
908  *                  p_signal   - specify the pointer to control signals info
909  *
910  ******************************************************************************/
PORT_GetModemStatus(uint16_t handle,uint8_t * p_signal)911 int PORT_GetModemStatus(uint16_t handle, uint8_t* p_signal) {
912   tPORT* p_port;
913 
914   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
915     return (PORT_BAD_HANDLE);
916   }
917 
918   p_port = &rfc_cb.port.port[handle - 1];
919 
920   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
921     return (PORT_NOT_OPENED);
922   }
923 
924   *p_signal = p_port->peer_ctrl.modem_signal;
925 
926   RFCOMM_TRACE_API("PORT_GetModemStatus() handle:%d signal:%x", handle,
927                    *p_signal);
928 
929   return (PORT_SUCCESS);
930 }
931 
932 /*******************************************************************************
933  *
934  * Function         PORT_ClearError
935  *
936  * Description      This function retreives information about a communications
937  *                  error and reports current status of a connection.  The
938  *                  function should be called when an error occures to clear
939  *                  the connection error flag and to enable additional read
940  *                  and write operations.
941  *
942  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
943  *                  p_errors   - pointer of the variable to receive error codes
944  *                  p_status   - pointer to the tPORT_STATUS structur to receive
945  *                               connection status
946  *
947  ******************************************************************************/
PORT_ClearError(uint16_t handle,uint16_t * p_errors,tPORT_STATUS * p_status)948 int PORT_ClearError(uint16_t handle, uint16_t* p_errors,
949                     tPORT_STATUS* p_status) {
950   tPORT* p_port;
951 
952   RFCOMM_TRACE_API("PORT_ClearError() handle:%d", handle);
953 
954   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
955     return (PORT_BAD_HANDLE);
956   }
957 
958   p_port = &rfc_cb.port.port[handle - 1];
959 
960   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
961     return (PORT_NOT_OPENED);
962   }
963 
964   *p_errors = p_port->line_status;
965 
966   /* This is the only call to clear error status.  We can not clear */
967   /* connection failed status.  To clean it port should be closed and reopened
968    */
969   p_port->line_status = (p_port->line_status & LINE_STATUS_FAILED);
970 
971   PORT_GetQueueStatus(handle, p_status);
972   return (PORT_SUCCESS);
973 }
974 
975 /*******************************************************************************
976  *
977  * Function         PORT_SendError
978  *
979  * Description      This function send a communications error to the peer device
980  *
981  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
982  *                  errors     - receive error codes
983  *
984  ******************************************************************************/
PORT_SendError(uint16_t handle,uint8_t errors)985 int PORT_SendError(uint16_t handle, uint8_t errors) {
986   tPORT* p_port;
987 
988   RFCOMM_TRACE_API("PORT_SendError() handle:%d errors:0x%x", handle, errors);
989 
990   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
991     return (PORT_BAD_HANDLE);
992   }
993 
994   p_port = &rfc_cb.port.port[handle - 1];
995 
996   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
997     return (PORT_NOT_OPENED);
998   }
999 
1000   if (!p_port->rfc.p_mcb) {
1001     return (PORT_NOT_OPENED);
1002   }
1003 
1004   RFCOMM_LineStatusReq(p_port->rfc.p_mcb, p_port->dlci, errors);
1005   return (PORT_SUCCESS);
1006 }
1007 
1008 /*******************************************************************************
1009  *
1010  * Function         PORT_GetQueueStatus
1011  *
1012  * Description      This function reports current status of a connection.
1013  *
1014  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
1015  *                  p_status   - pointer to the tPORT_STATUS structur to receive
1016  *                               connection status
1017  *
1018  ******************************************************************************/
PORT_GetQueueStatus(uint16_t handle,tPORT_STATUS * p_status)1019 int PORT_GetQueueStatus(uint16_t handle, tPORT_STATUS* p_status) {
1020   tPORT* p_port;
1021 
1022   /* RFCOMM_TRACE_API ("PORT_GetQueueStatus() handle:%d", handle); */
1023 
1024   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1025     return (PORT_BAD_HANDLE);
1026   }
1027 
1028   p_port = &rfc_cb.port.port[handle - 1];
1029 
1030   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1031     return (PORT_NOT_OPENED);
1032   }
1033 
1034   p_status->in_queue_size = (uint16_t)p_port->rx.queue_size;
1035   p_status->out_queue_size = (uint16_t)p_port->tx.queue_size;
1036 
1037   p_status->mtu_size = (uint16_t)p_port->peer_mtu;
1038 
1039   p_status->flags = 0;
1040 
1041   if (!(p_port->peer_ctrl.modem_signal & PORT_CTSRTS_ON))
1042     p_status->flags |= PORT_FLAG_CTS_HOLD;
1043 
1044   if (!(p_port->peer_ctrl.modem_signal & PORT_DTRDSR_ON))
1045     p_status->flags |= PORT_FLAG_DSR_HOLD;
1046 
1047   if (!(p_port->peer_ctrl.modem_signal & PORT_DCD_ON))
1048     p_status->flags |= PORT_FLAG_RLSD_HOLD;
1049 
1050   return (PORT_SUCCESS);
1051 }
1052 
1053 /*******************************************************************************
1054  *
1055  * Function         PORT_Purge
1056  *
1057  * Description      This function discards all the data from the output or
1058  *                  input queues of the specified connection.
1059  *
1060  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
1061  *                  purge_flags - specify the action to take.
1062  *
1063  ******************************************************************************/
PORT_Purge(uint16_t handle,uint8_t purge_flags)1064 int PORT_Purge(uint16_t handle, uint8_t purge_flags) {
1065   tPORT* p_port;
1066   BT_HDR* p_buf;
1067   uint16_t count;
1068   uint32_t events;
1069 
1070   RFCOMM_TRACE_API("PORT_Purge() handle:%d flags:0x%x", handle, purge_flags);
1071 
1072   /* Check if handle is valid to avoid crashing */
1073   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1074     return (PORT_BAD_HANDLE);
1075   }
1076 
1077   p_port = &rfc_cb.port.port[handle - 1];
1078 
1079   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1080     return (PORT_NOT_OPENED);
1081   }
1082 
1083   if (purge_flags & PORT_PURGE_RXCLEAR) {
1084     mutex_global_lock(); /* to prevent missing credit */
1085 
1086     count = fixed_queue_length(p_port->rx.queue);
1087 
1088     while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue)) != NULL)
1089       osi_free(p_buf);
1090 
1091     p_port->rx.queue_size = 0;
1092 
1093     mutex_global_unlock();
1094 
1095     /* If we flowed controlled peer based on rx_queue size enable data again */
1096     if (count) port_flow_control_peer(p_port, true, count);
1097   }
1098 
1099   if (purge_flags & PORT_PURGE_TXCLEAR) {
1100     mutex_global_lock(); /* to prevent tx.queue_size from being negative */
1101 
1102     while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->tx.queue)) != NULL)
1103       osi_free(p_buf);
1104 
1105     p_port->tx.queue_size = 0;
1106 
1107     mutex_global_unlock();
1108 
1109     events = PORT_EV_TXEMPTY;
1110 
1111     events |= port_flow_control_user(p_port);
1112 
1113     events &= p_port->ev_mask;
1114 
1115     if ((p_port->p_callback != NULL) && events)
1116       (p_port->p_callback)(events, p_port->inx);
1117   }
1118 
1119   return (PORT_SUCCESS);
1120 }
1121 
1122 /*******************************************************************************
1123  *
1124  * Function         PORT_ReadData
1125  *
1126  * Description      Normally not GKI aware application will call this function
1127  *                  after receiving PORT_EV_RXCHAR event.
1128  *
1129  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
1130  *                  p_data      - Data area
1131  *                  max_len     - Byte count requested
1132  *                  p_len       - Byte count received
1133  *
1134  ******************************************************************************/
PORT_ReadData(uint16_t handle,char * p_data,uint16_t max_len,uint16_t * p_len)1135 int PORT_ReadData(uint16_t handle, char* p_data, uint16_t max_len,
1136                   uint16_t* p_len) {
1137   tPORT* p_port;
1138   BT_HDR* p_buf;
1139   uint16_t count;
1140 
1141   RFCOMM_TRACE_API("PORT_ReadData() handle:%d max_len:%d", handle, max_len);
1142 
1143   /* Initialize this in case of an error */
1144   *p_len = 0;
1145 
1146   /* Check if handle is valid to avoid crashing */
1147   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1148     return (PORT_BAD_HANDLE);
1149   }
1150 
1151   p_port = &rfc_cb.port.port[handle - 1];
1152 
1153   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1154     return (PORT_NOT_OPENED);
1155   }
1156 
1157   if (p_port->line_status) {
1158     return (PORT_LINE_ERR);
1159   }
1160 
1161   if (fixed_queue_is_empty(p_port->rx.queue)) return (PORT_SUCCESS);
1162 
1163   count = 0;
1164 
1165   while (max_len) {
1166     p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_port->rx.queue);
1167     if (p_buf == NULL) break;
1168 
1169     if (p_buf->len > max_len) {
1170       memcpy(p_data, (uint8_t*)(p_buf + 1) + p_buf->offset, max_len);
1171       p_buf->offset += max_len;
1172       p_buf->len -= max_len;
1173 
1174       *p_len += max_len;
1175 
1176       mutex_global_lock();
1177 
1178       p_port->rx.queue_size -= max_len;
1179 
1180       mutex_global_unlock();
1181 
1182       break;
1183     } else {
1184       memcpy(p_data, (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
1185 
1186       *p_len += p_buf->len;
1187       max_len -= p_buf->len;
1188 
1189       mutex_global_lock();
1190 
1191       p_port->rx.queue_size -= p_buf->len;
1192 
1193       if (max_len) {
1194         p_data += p_buf->len;
1195       }
1196 
1197       osi_free(fixed_queue_try_dequeue(p_port->rx.queue));
1198 
1199       mutex_global_unlock();
1200 
1201       count++;
1202     }
1203   }
1204 
1205   if (*p_len == 1) {
1206     RFCOMM_TRACE_EVENT("PORT_ReadData queue:%d returned:%d %x",
1207                        p_port->rx.queue_size, *p_len, (p_data[0]));
1208   } else {
1209     RFCOMM_TRACE_EVENT("PORT_ReadData queue:%d returned:%d",
1210                        p_port->rx.queue_size, *p_len);
1211   }
1212 
1213   /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
1214   /* check if it can be resumed now */
1215   port_flow_control_peer(p_port, true, count);
1216 
1217   return (PORT_SUCCESS);
1218 }
1219 
1220 /*******************************************************************************
1221  *
1222  * Function         PORT_Read
1223  *
1224  * Description      Normally application will call this function after receiving
1225  *                  PORT_EV_RXCHAR event.
1226  *
1227  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
1228  *                  pp_buf      - pointer to address of buffer with data,
1229  *
1230  ******************************************************************************/
PORT_Read(uint16_t handle,BT_HDR ** pp_buf)1231 int PORT_Read(uint16_t handle, BT_HDR** pp_buf) {
1232   tPORT* p_port;
1233   BT_HDR* p_buf;
1234 
1235   RFCOMM_TRACE_API("PORT_Read() handle:%d", handle);
1236 
1237   /* Check if handle is valid to avoid crashing */
1238   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1239     return (PORT_BAD_HANDLE);
1240   }
1241   p_port = &rfc_cb.port.port[handle - 1];
1242 
1243   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1244     return (PORT_NOT_OPENED);
1245   }
1246 
1247   if (p_port->line_status) {
1248     return (PORT_LINE_ERR);
1249   }
1250 
1251   mutex_global_lock();
1252 
1253   p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue);
1254   if (p_buf) {
1255     p_port->rx.queue_size -= p_buf->len;
1256 
1257     mutex_global_unlock();
1258 
1259     /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
1260     /* check if it can be resumed now */
1261     port_flow_control_peer(p_port, true, 1);
1262   } else {
1263     mutex_global_unlock();
1264   }
1265 
1266   *pp_buf = p_buf;
1267   return (PORT_SUCCESS);
1268 }
1269 
1270 /*******************************************************************************
1271  *
1272  * Function         port_write
1273  *
1274  * Description      This function when a data packet is received from the apper
1275  *                  layer task.
1276  *
1277  * Parameters:      p_port     - pointer to address of port control block
1278  *                  p_buf      - pointer to address of buffer with data,
1279  *
1280  ******************************************************************************/
port_write(tPORT * p_port,BT_HDR * p_buf)1281 static int port_write(tPORT* p_port, BT_HDR* p_buf) {
1282   /* We should not allow to write data in to server port when connection is not
1283    * opened */
1284   if (p_port->is_server && (p_port->rfc.state != RFC_STATE_OPENED)) {
1285     osi_free(p_buf);
1286     return (PORT_CLOSED);
1287   }
1288 
1289   /* Keep the data in pending queue if peer does not allow data, or */
1290   /* Peer is not ready or Port is not yet opened or initial port control */
1291   /* command has not been sent */
1292   if (p_port->tx.peer_fc || !p_port->rfc.p_mcb ||
1293       !p_port->rfc.p_mcb->peer_ready ||
1294       (p_port->rfc.state != RFC_STATE_OPENED) ||
1295       ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) !=
1296        (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED))) {
1297     if ((p_port->tx.queue_size > PORT_TX_CRITICAL_WM) ||
1298         (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_CRITICAL_WM)) {
1299       RFCOMM_TRACE_WARNING("PORT_Write: Queue size: %d", p_port->tx.queue_size);
1300 
1301       osi_free(p_buf);
1302 
1303       if ((p_port->p_callback != NULL) && (p_port->ev_mask & PORT_EV_ERR))
1304         p_port->p_callback(PORT_EV_ERR, p_port->inx);
1305 
1306       return (PORT_TX_FULL);
1307     }
1308 
1309     RFCOMM_TRACE_EVENT(
1310         "PORT_Write : Data is enqued. flow disabled %d peer_ready %d state %d "
1311         "ctrl_state %x",
1312         p_port->tx.peer_fc,
1313         (p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready), p_port->rfc.state,
1314         p_port->port_ctrl);
1315 
1316     fixed_queue_enqueue(p_port->tx.queue, p_buf);
1317     p_port->tx.queue_size += p_buf->len;
1318 
1319     return (PORT_CMD_PENDING);
1320   } else {
1321     RFCOMM_TRACE_EVENT("PORT_Write : Data is being sent");
1322 
1323     RFCOMM_DataReq(p_port->rfc.p_mcb, p_port->dlci, p_buf);
1324     return (PORT_SUCCESS);
1325   }
1326 }
1327 
1328 /*******************************************************************************
1329  *
1330  * Function         PORT_Write
1331  *
1332  * Description      This function when a data packet is received from the apper
1333  *                  layer task.
1334  *
1335  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
1336  *                  pp_buf      - pointer to address of buffer with data,
1337  *
1338  ******************************************************************************/
PORT_Write(uint16_t handle,BT_HDR * p_buf)1339 int PORT_Write(uint16_t handle, BT_HDR* p_buf) {
1340   tPORT* p_port;
1341   uint32_t event = 0;
1342   int rc;
1343 
1344   RFCOMM_TRACE_API("PORT_Write() handle:%d", handle);
1345 
1346   /* Check if handle is valid to avoid crashing */
1347   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1348     osi_free(p_buf);
1349     return (PORT_BAD_HANDLE);
1350   }
1351 
1352   p_port = &rfc_cb.port.port[handle - 1];
1353 
1354   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1355     osi_free(p_buf);
1356     return (PORT_NOT_OPENED);
1357   }
1358 
1359   if (p_port->line_status) {
1360     RFCOMM_TRACE_WARNING("PORT_Write: Data dropped line_status:0x%x",
1361                          p_port->line_status);
1362     osi_free(p_buf);
1363     return (PORT_LINE_ERR);
1364   }
1365 
1366   rc = port_write(p_port, p_buf);
1367   event |= port_flow_control_user(p_port);
1368 
1369   switch (rc) {
1370     case PORT_TX_FULL:
1371       event |= PORT_EV_ERR;
1372       break;
1373 
1374     case PORT_SUCCESS:
1375       event |= (PORT_EV_TXCHAR | PORT_EV_TXEMPTY);
1376       break;
1377   }
1378   /* Mask out all events that are not of interest to user */
1379   event &= p_port->ev_mask;
1380 
1381   /* Send event to the application */
1382   if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->inx);
1383 
1384   return (PORT_SUCCESS);
1385 }
1386 /*******************************************************************************
1387  *
1388  * Function         PORT_WriteDataCO
1389  *
1390  * Description      Normally not GKI aware application will call this function
1391  *                  to send data to the port by callout functions
1392  *
1393  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
1394  *                  fd         - socket fd
1395  *                  p_len      - Byte count returned
1396  *
1397  ******************************************************************************/
PORT_WriteDataCO(uint16_t handle,int * p_len)1398 int PORT_WriteDataCO(uint16_t handle, int* p_len) {
1399   tPORT* p_port;
1400   BT_HDR* p_buf;
1401   uint32_t event = 0;
1402   int rc = 0;
1403   uint16_t length;
1404 
1405   RFCOMM_TRACE_API("PORT_WriteDataCO() handle:%d", handle);
1406   *p_len = 0;
1407 
1408   /* Check if handle is valid to avoid crashing */
1409   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1410     return (PORT_BAD_HANDLE);
1411   }
1412   p_port = &rfc_cb.port.port[handle - 1];
1413 
1414   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1415     RFCOMM_TRACE_WARNING("PORT_WriteDataByFd() no port state:%d",
1416                          p_port->state);
1417     return (PORT_NOT_OPENED);
1418   }
1419 
1420   if (!p_port->peer_mtu) {
1421     RFCOMM_TRACE_ERROR("PORT_WriteDataByFd() peer_mtu:%d", p_port->peer_mtu);
1422     return (PORT_UNKNOWN_ERROR);
1423   }
1424   int available = 0;
1425   // if(ioctl(fd, FIONREAD, &available) < 0)
1426   if (p_port->p_data_co_callback(
1427           handle, (uint8_t*)&available, sizeof(available),
1428           DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE) == false) {
1429     RFCOMM_TRACE_ERROR(
1430         "p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, "
1431         "available:%d",
1432         available);
1433     return (PORT_UNKNOWN_ERROR);
1434   }
1435   if (available == 0) return PORT_SUCCESS;
1436   /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len
1437    */
1438   length = RFCOMM_DATA_BUF_SIZE -
1439            (uint16_t)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
1440 
1441   /* If there are buffers scheduled for transmission check if requested */
1442   /* data fits into the end of the queue */
1443   mutex_global_lock();
1444 
1445   p_buf = (BT_HDR*)fixed_queue_try_peek_last(p_port->tx.queue);
1446   if ((p_buf != NULL) &&
1447       (((int)p_buf->len + available) <= (int)p_port->peer_mtu) &&
1448       (((int)p_buf->len + available) <= (int)length)) {
1449     // if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len,
1450     // available, 0) != available)
1451     if (p_port->p_data_co_callback(
1452             handle, (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len,
1453             available, DATA_CO_CALLBACK_TYPE_OUTGOING) == false)
1454 
1455     {
1456       error(
1457           "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, "
1458           "available:%d",
1459           available);
1460       mutex_global_unlock();
1461       return (PORT_UNKNOWN_ERROR);
1462     }
1463     // memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data,
1464     // max_len);
1465     p_port->tx.queue_size += (uint16_t)available;
1466 
1467     *p_len = available;
1468     p_buf->len += (uint16_t)available;
1469 
1470     mutex_global_unlock();
1471 
1472     return (PORT_SUCCESS);
1473   }
1474 
1475   mutex_global_unlock();
1476 
1477   // int max_read = length < p_port->peer_mtu ? length : p_port->peer_mtu;
1478 
1479   // max_read = available < max_read ? available : max_read;
1480 
1481   while (available) {
1482     /* if we're over buffer high water mark, we're done */
1483     if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
1484         (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM)) {
1485       port_flow_control_user(p_port);
1486       event |= PORT_EV_FC;
1487       RFCOMM_TRACE_EVENT(
1488           "tx queue is full,tx.queue_size:%d,tx.queue.count:%d,available:%d",
1489           p_port->tx.queue_size, fixed_queue_length(p_port->tx.queue),
1490           available);
1491       break;
1492     }
1493 
1494     /* continue with rfcomm data write */
1495     p_buf = (BT_HDR*)osi_malloc(RFCOMM_DATA_BUF_SIZE);
1496     p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
1497     p_buf->layer_specific = handle;
1498 
1499     if (p_port->peer_mtu < length) length = p_port->peer_mtu;
1500     if (available < (int)length) length = (uint16_t)available;
1501     p_buf->len = length;
1502     p_buf->event = BT_EVT_TO_BTU_SP_DATA;
1503 
1504     // memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset, p_data, length);
1505     // if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset, (int)length, 0) !=
1506     // (int)length)
1507     if (p_port->p_data_co_callback(
1508             handle, (uint8_t*)(p_buf + 1) + p_buf->offset, length,
1509             DATA_CO_CALLBACK_TYPE_OUTGOING) == false) {
1510       error(
1511           "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:%d",
1512           length);
1513       return (PORT_UNKNOWN_ERROR);
1514     }
1515 
1516     RFCOMM_TRACE_EVENT("PORT_WriteData %d bytes", length);
1517 
1518     rc = port_write(p_port, p_buf);
1519 
1520     /* If queue went below the threashold need to send flow control */
1521     event |= port_flow_control_user(p_port);
1522 
1523     if (rc == PORT_SUCCESS) event |= PORT_EV_TXCHAR;
1524 
1525     if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) break;
1526 
1527     *p_len += length;
1528     available -= (int)length;
1529   }
1530   if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
1531     event |= PORT_EV_TXEMPTY;
1532 
1533   /* Mask out all events that are not of interest to user */
1534   event &= p_port->ev_mask;
1535 
1536   /* Send event to the application */
1537   if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->inx);
1538 
1539   return (PORT_SUCCESS);
1540 }
1541 
1542 /*******************************************************************************
1543  *
1544  * Function         PORT_WriteData
1545  *
1546  * Description      Normally not GKI aware application will call this function
1547  *                  to send data to the port.
1548  *
1549  * Parameters:      handle     - Handle returned in the RFCOMM_CreateConnection
1550  *                  p_data      - Data area
1551  *                  max_len     - Byte count requested
1552  *                  p_len       - Byte count received
1553  *
1554  ******************************************************************************/
PORT_WriteData(uint16_t handle,const char * p_data,uint16_t max_len,uint16_t * p_len)1555 int PORT_WriteData(uint16_t handle, const char* p_data, uint16_t max_len,
1556                    uint16_t* p_len) {
1557   tPORT* p_port;
1558   BT_HDR* p_buf;
1559   uint32_t event = 0;
1560   int rc = 0;
1561   uint16_t length;
1562 
1563   RFCOMM_TRACE_API("PORT_WriteData() max_len:%d", max_len);
1564 
1565   *p_len = 0;
1566 
1567   /* Check if handle is valid to avoid crashing */
1568   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1569     return (PORT_BAD_HANDLE);
1570   }
1571   p_port = &rfc_cb.port.port[handle - 1];
1572 
1573   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1574     RFCOMM_TRACE_WARNING("PORT_WriteData() no port state:%d", p_port->state);
1575     return (PORT_NOT_OPENED);
1576   }
1577 
1578   if (!max_len || !p_port->peer_mtu) {
1579     RFCOMM_TRACE_ERROR("PORT_WriteData() peer_mtu:%d", p_port->peer_mtu);
1580     return (PORT_UNKNOWN_ERROR);
1581   }
1582 
1583   /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len
1584    */
1585   length = RFCOMM_DATA_BUF_SIZE -
1586            (uint16_t)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
1587 
1588   /* If there are buffers scheduled for transmission check if requested */
1589   /* data fits into the end of the queue */
1590   mutex_global_lock();
1591 
1592   p_buf = (BT_HDR*)fixed_queue_try_peek_last(p_port->tx.queue);
1593   if ((p_buf != NULL) && ((p_buf->len + max_len) <= p_port->peer_mtu) &&
1594       ((p_buf->len + max_len) <= length)) {
1595     memcpy((uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
1596     p_port->tx.queue_size += max_len;
1597 
1598     *p_len = max_len;
1599     p_buf->len += max_len;
1600 
1601     mutex_global_unlock();
1602 
1603     return (PORT_SUCCESS);
1604   }
1605 
1606   mutex_global_unlock();
1607 
1608   while (max_len) {
1609     /* if we're over buffer high water mark, we're done */
1610     if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
1611         (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM))
1612       break;
1613 
1614     /* continue with rfcomm data write */
1615     p_buf = (BT_HDR*)osi_malloc(RFCOMM_DATA_BUF_SIZE);
1616     p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
1617     p_buf->layer_specific = handle;
1618 
1619     if (p_port->peer_mtu < length) length = p_port->peer_mtu;
1620     if (max_len < length) length = max_len;
1621     p_buf->len = length;
1622     p_buf->event = BT_EVT_TO_BTU_SP_DATA;
1623 
1624     memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, length);
1625 
1626     RFCOMM_TRACE_EVENT("PORT_WriteData %d bytes", length);
1627 
1628     rc = port_write(p_port, p_buf);
1629 
1630     /* If queue went below the threashold need to send flow control */
1631     event |= port_flow_control_user(p_port);
1632 
1633     if (rc == PORT_SUCCESS) event |= PORT_EV_TXCHAR;
1634 
1635     if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) break;
1636 
1637     *p_len += length;
1638     max_len -= length;
1639     p_data += length;
1640   }
1641   if (!max_len && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
1642     event |= PORT_EV_TXEMPTY;
1643 
1644   /* Mask out all events that are not of interest to user */
1645   event &= p_port->ev_mask;
1646 
1647   /* Send event to the application */
1648   if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->inx);
1649 
1650   return (PORT_SUCCESS);
1651 }
1652 
1653 /*******************************************************************************
1654  *
1655  * Function         PORT_Test
1656  *
1657  * Description      Application can call this function to send RFCOMM Test frame
1658  *
1659  * Parameters:      handle      - Handle returned in the RFCOMM_CreateConnection
1660  *                  p_data      - Data area
1661  *                  max_len     - Byte count requested
1662  *
1663  ******************************************************************************/
PORT_Test(uint16_t handle,uint8_t * p_data,uint16_t len)1664 int PORT_Test(uint16_t handle, uint8_t* p_data, uint16_t len) {
1665   tPORT* p_port;
1666 
1667   RFCOMM_TRACE_API("PORT_Test() len:%d", len);
1668 
1669   if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1670     return (PORT_BAD_HANDLE);
1671   }
1672   p_port = &rfc_cb.port.port[handle - 1];
1673 
1674   if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1675     return (PORT_NOT_OPENED);
1676   }
1677 
1678   if (len > ((p_port->mtu == 0) ? RFCOMM_DEFAULT_MTU : p_port->mtu)) {
1679     return (PORT_UNKNOWN_ERROR);
1680   }
1681 
1682   BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
1683   p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
1684   p_buf->len = len;
1685 
1686   memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
1687 
1688   rfc_send_test(p_port->rfc.p_mcb, true, p_buf);
1689 
1690   return (PORT_SUCCESS);
1691 }
1692 
1693 /*******************************************************************************
1694  *
1695  * Function         RFCOMM_Init
1696  *
1697  * Description      This function is called to initialize RFCOMM layer
1698  *
1699  ******************************************************************************/
RFCOMM_Init(void)1700 void RFCOMM_Init(void) {
1701   memset(&rfc_cb, 0, sizeof(tRFC_CB)); /* Init RFCOMM control block */
1702 
1703   rfc_cb.rfc.last_mux = MAX_BD_CONNECTIONS;
1704 
1705 #if defined(RFCOMM_INITIAL_TRACE_LEVEL)
1706   rfc_cb.trace_level = RFCOMM_INITIAL_TRACE_LEVEL;
1707 #else
1708   rfc_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
1709 #endif
1710 
1711   rfcomm_l2cap_if_init();
1712 }
1713 
1714 /*******************************************************************************
1715  *
1716  * Function         PORT_SetTraceLevel
1717  *
1718  * Description      Set the trace level for RFCOMM. If called with 0xFF, it
1719  *                  simply reads the current trace level.
1720  *
1721  * Returns          the new (current) trace level
1722  *
1723  ******************************************************************************/
PORT_SetTraceLevel(uint8_t new_level)1724 uint8_t PORT_SetTraceLevel(uint8_t new_level) {
1725   if (new_level != 0xFF) rfc_cb.trace_level = new_level;
1726 
1727   return (rfc_cb.trace_level);
1728 }
1729 
1730 /*******************************************************************************
1731  *
1732  * Function         PORT_GetResultString
1733  *
1734  * Description      This function returns the human-readable string for a given
1735  *                  result code.
1736  *
1737  * Returns          a pointer to the human-readable string for the given result.
1738  *
1739  ******************************************************************************/
PORT_GetResultString(const uint8_t result_code)1740 const char* PORT_GetResultString(const uint8_t result_code) {
1741   if (result_code > PORT_ERR_MAX) {
1742     return result_code_strings[PORT_ERR_MAX];
1743   }
1744 
1745   return result_code_strings[result_code];
1746 }
1747