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