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