1 /******************************************************************************
3 * Copyright (C) 1999-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * this file contains the Serial Port API code
23 ******************************************************************************/
25 #define LOG_TAG "bt_port_api"
27 #include <base/logging.h>
30 #include "osi/include/log.h"
31 #include "osi/include/mutex.h"
33 #include "bt_common.h"
43 /* duration of break in 200ms units */
44 #define PORT_BREAK_DURATION 1
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__)
52 LOG_ERROR(LOG_TAG, "## %s assert %s failed at line:%d ##", __func__, #s, \
55 /* Mapping from PORT_* result codes to human readable strings. */
56 static const char* result_code_strings[] = {"Success",
69 "Parameter negotiation failed",
70 "Port negotiation failed",
72 "Peer connection failed",
82 "Unknown result code"};
84 /*******************************************************************************
86 * Function RFCOMM_CreateConnection
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
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.
106 * Server can call this function with the same scn parameter multiple times if
107 * it is ready to accept multiple simulteneous connections.
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.
114 ******************************************************************************/
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) {
120 tRFC_MCB* p_mcb = port_find_mcb(bd_addr);
123 VLOG(0) << __func__ << " BDA: " << bd_addr;
127 if ((scn == 0) || (scn >= PORT_MAX_RFC_PORTS)) {
128 /* Server Channel Number(SCN) should be in range 1...30 */
129 RFCOMM_TRACE_ERROR("RFCOMM_CreateConnection - invalid SCN");
130 return (PORT_INVALID_SCN);
133 /* For client that originate connection on the existing none initiator */
134 /* multiplexer channel DLCI should be odd */
135 if (p_mcb && !p_mcb->is_initiator && !is_server)
136 dlci = (scn << 1) + 1;
140 "RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, "
142 scn, dlci, is_server, mtu, p_mcb);
144 /* For the server side always allocate a new port. On the client side */
145 /* do not allow the same (dlci, bd_addr) to be opened twice by application */
147 p_port = port_find_port(dlci, bd_addr);
148 if (p_port != NULL) {
149 /* if existing port is also a client port */
150 if (p_port->is_server == false) {
152 "RFCOMM_CreateConnection - already opened state:%d, RFC state:%d, "
154 p_port->state, p_port->rfc.state,
155 p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0);
156 *p_handle = p_port->inx;
157 return (PORT_ALREADY_OPENED);
162 p_port = port_allocate_port(dlci, bd_addr);
163 if (p_port == NULL) {
164 RFCOMM_TRACE_WARNING("RFCOMM_CreateConnection - no resources");
165 return (PORT_NO_RESOURCES);
168 "RFCOMM_CreateConnection(): scn:%d, dlci:%d, is_server:%d mtu:%d, "
169 "p_mcb:%p, p_port:%p",
170 scn, dlci, is_server, mtu, p_mcb, p_port);
172 p_port->default_signal_state =
173 (PORT_DTRDSR_ON | PORT_CTSRTS_ON | PORT_DCD_ON);
176 case UUID_PROTOCOL_OBEX:
177 p_port->default_signal_state = PORT_OBEX_DEFAULT_SIGNAL_STATE;
179 case UUID_SERVCLASS_SERIAL_PORT:
180 p_port->default_signal_state = PORT_SPP_DEFAULT_SIGNAL_STATE;
182 case UUID_SERVCLASS_LAN_ACCESS_USING_PPP:
183 p_port->default_signal_state = PORT_PPP_DEFAULT_SIGNAL_STATE;
185 case UUID_SERVCLASS_DIALUP_NETWORKING:
186 case UUID_SERVCLASS_FAX:
187 p_port->default_signal_state = PORT_DUN_DEFAULT_SIGNAL_STATE;
191 RFCOMM_TRACE_EVENT("RFCOMM_CreateConnection dlci:%d signal state:0x%x", dlci,
192 p_port->default_signal_state);
194 *p_handle = p_port->inx;
196 p_port->state = PORT_STATE_OPENING;
198 p_port->is_server = is_server;
202 /* If the MTU is not specified (0), keep MTU decision until the
203 * PN frame has to be send
204 * at that time connection should be established and we
205 * will know for sure our prefered MTU
208 rfcomm_mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD;
211 p_port->mtu = (mtu < rfcomm_mtu) ? mtu : rfcomm_mtu;
213 p_port->mtu = rfcomm_mtu;
215 /* server doesn't need to release port when closing */
217 p_port->keep_port_handle = true;
219 /* keep mtu that user asked, p_port->mtu could be updated during param
221 p_port->keep_mtu = p_port->mtu;
224 p_port->local_ctrl.modem_signal = p_port->default_signal_state;
225 p_port->local_ctrl.fc = false;
227 p_port->p_mgmt_callback = p_mgmt_cb;
229 p_port->bd_addr = bd_addr;
231 /* If this is not initiator of the connection need to just wait */
232 if (p_port->is_server) {
233 return (PORT_SUCCESS);
236 /* Open will be continued after security checks are passed */
237 return port_open_continue(p_port);
240 /*******************************************************************************
242 * Function RFCOMM_RemoveConnection
244 * Description This function is called to close the specified connection.
246 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
248 ******************************************************************************/
249 int RFCOMM_RemoveConnection(uint16_t handle) {
252 RFCOMM_TRACE_API("RFCOMM_RemoveConnection() handle:%d", handle);
254 /* Check if handle is valid to avoid crashing */
255 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
256 RFCOMM_TRACE_ERROR("RFCOMM_RemoveConnection() BAD handle:%d", handle);
257 return (PORT_BAD_HANDLE);
259 p_port = &rfc_cb.port.port[handle - 1];
261 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
262 RFCOMM_TRACE_EVENT("RFCOMM_RemoveConnection() Not opened:%d", handle);
263 return (PORT_SUCCESS);
266 p_port->state = PORT_STATE_CLOSING;
268 port_start_close(p_port);
270 return (PORT_SUCCESS);
273 /*******************************************************************************
275 * Function RFCOMM_RemoveServer
277 * Description This function is called to close the server port.
279 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
281 ******************************************************************************/
282 int RFCOMM_RemoveServer(uint16_t handle) {
285 RFCOMM_TRACE_API("RFCOMM_RemoveServer() handle:%d", handle);
287 /* Check if handle is valid to avoid crashing */
288 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
289 RFCOMM_TRACE_ERROR("RFCOMM_RemoveServer() BAD handle:%d", handle);
290 return (PORT_BAD_HANDLE);
292 p_port = &rfc_cb.port.port[handle - 1];
294 /* Do not report any events to the client any more. */
295 p_port->p_mgmt_callback = NULL;
297 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
298 RFCOMM_TRACE_EVENT("RFCOMM_RemoveServer() Not opened:%d", handle);
299 return (PORT_SUCCESS);
302 /* this port will be deallocated after closing */
303 p_port->keep_port_handle = false;
304 p_port->state = PORT_STATE_CLOSING;
306 port_start_close(p_port);
308 return (PORT_SUCCESS);
311 /*******************************************************************************
313 * Function PORT_SetEventCallback
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.
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.
325 ******************************************************************************/
326 int PORT_SetEventCallback(uint16_t port_handle, tPORT_CALLBACK* p_port_cb) {
329 /* Check if handle is valid to avoid crashing */
330 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
331 return (PORT_BAD_HANDLE);
334 p_port = &rfc_cb.port.port[port_handle - 1];
336 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
337 return (PORT_NOT_OPENED);
340 RFCOMM_TRACE_API("PORT_SetEventCallback() handle:%d", port_handle);
342 p_port->p_callback = p_port_cb;
344 return (PORT_SUCCESS);
346 /*******************************************************************************
348 * Function PORT_ClearKeepHandleFlag
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
354 ******************************************************************************/
356 int PORT_ClearKeepHandleFlag(uint16_t port_handle) {
359 /* Check if handle is valid to avoid crashing */
360 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
361 return (PORT_BAD_HANDLE);
364 p_port = &rfc_cb.port.port[port_handle - 1];
365 p_port->keep_port_handle = 0;
366 return (PORT_SUCCESS);
369 /*******************************************************************************
371 * Function PORT_SetDataCallback
373 * Description This function is when a data packet is received
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
381 ******************************************************************************/
382 int PORT_SetDataCallback(uint16_t port_handle, tPORT_DATA_CALLBACK* p_port_cb) {
385 RFCOMM_TRACE_API("PORT_SetDataCallback() handle:%d cb 0x%x", port_handle,
388 /* Check if handle is valid to avoid crashing */
389 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
390 return (PORT_BAD_HANDLE);
393 p_port = &rfc_cb.port.port[port_handle - 1];
395 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
396 return (PORT_NOT_OPENED);
399 p_port->p_data_callback = p_port_cb;
401 return (PORT_SUCCESS);
403 /*******************************************************************************
405 * Function PORT_SetCODataCallback
407 * Description This function is when a data packet is received
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
415 ******************************************************************************/
416 int PORT_SetDataCOCallback(uint16_t port_handle,
417 tPORT_DATA_CO_CALLBACK* p_port_cb) {
420 RFCOMM_TRACE_API("PORT_SetDataCOCallback() handle:%d cb 0x%x", port_handle,
423 /* Check if handle is valid to avoid crashing */
424 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
425 return (PORT_BAD_HANDLE);
428 p_port = &rfc_cb.port.port[port_handle - 1];
430 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
431 return (PORT_NOT_OPENED);
434 p_port->p_data_co_callback = p_port_cb;
436 return (PORT_SUCCESS);
439 /*******************************************************************************
441 * Function PORT_SetEventMask
443 * Description This function is called to close the specified connection.
445 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
446 * mask - Bitmask of the events the host is interested in
448 ******************************************************************************/
449 int PORT_SetEventMask(uint16_t port_handle, uint32_t mask) {
452 RFCOMM_TRACE_API("PORT_SetEventMask() handle:%d mask:0x%x", port_handle,
455 /* Check if handle is valid to avoid crashing */
456 if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) {
457 return (PORT_BAD_HANDLE);
460 p_port = &rfc_cb.port.port[port_handle - 1];
462 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
463 return (PORT_NOT_OPENED);
466 p_port->ev_mask = mask;
468 return (PORT_SUCCESS);
471 /*******************************************************************************
473 * Function PORT_CheckConnection
475 * Description This function returns PORT_SUCCESS if connection referenced
476 * by handle is up and running
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
482 ******************************************************************************/
483 int PORT_CheckConnection(uint16_t handle, RawAddress& bd_addr,
487 RFCOMM_TRACE_API("PORT_CheckConnection() handle:%d", handle);
489 /* Check if handle is valid to avoid crashing */
490 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
491 return (PORT_BAD_HANDLE);
494 p_port = &rfc_cb.port.port[handle - 1];
496 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
497 return (PORT_NOT_OPENED);
500 if (!p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready ||
501 (p_port->rfc.state != RFC_STATE_OPENED)) {
502 return (PORT_LINE_ERR);
505 bd_addr = p_port->rfc.p_mcb->bd_addr;
506 if (p_lcid) *p_lcid = p_port->rfc.p_mcb->lcid;
508 return (PORT_SUCCESS);
511 /*******************************************************************************
513 * Function PORT_IsOpening
515 * Description This function returns true if there is any RFCOMM connection
516 * opening in process.
518 * Parameters: true if any connection opening is found
519 * bd_addr - bd_addr of the peer
521 ******************************************************************************/
522 bool PORT_IsOpening(RawAddress& bd_addr) {
524 tRFC_MCB* p_mcb = NULL;
528 /* Check for any rfc_mcb which is in the middle of opening. */
529 for (xx = 0; xx < MAX_BD_CONNECTIONS; xx++) {
530 if ((rfc_cb.port.rfc_mcb[xx].state > RFC_MX_STATE_IDLE) &&
531 (rfc_cb.port.rfc_mcb[xx].state < RFC_MX_STATE_CONNECTED)) {
532 bd_addr = rfc_cb.port.rfc_mcb[xx].bd_addr;
536 if (rfc_cb.port.rfc_mcb[xx].state == RFC_MX_STATE_CONNECTED) {
538 p_mcb = &rfc_cb.port.rfc_mcb[xx];
539 p_port = &rfc_cb.port.port[0];
541 for (yy = 0; yy < MAX_RFC_PORTS; yy++, p_port++) {
542 if (p_port->rfc.p_mcb == p_mcb) {
549 (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) {
550 /* Port is not established yet. */
551 bd_addr = rfc_cb.port.rfc_mcb[xx].bd_addr;
560 /*******************************************************************************
562 * Function PORT_SetState
564 * Description This function configures connection according to the
565 * specifications in the tPORT_STATE structure.
567 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
568 * p_settings - Pointer to a tPORT_STATE structure containing
569 * configuration information for the connection.
572 ******************************************************************************/
573 int PORT_SetState(uint16_t handle, tPORT_STATE* p_settings) {
577 RFCOMM_TRACE_API("PORT_SetState() handle:%d", handle);
579 /* Check if handle is valid to avoid crashing */
580 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
581 return (PORT_BAD_HANDLE);
584 p_port = &rfc_cb.port.port[handle - 1];
586 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
587 return (PORT_NOT_OPENED);
590 if (p_port->line_status) {
591 return (PORT_LINE_ERR);
594 RFCOMM_TRACE_API("PORT_SetState() handle:%d FC_TYPE:0x%x", handle,
595 p_settings->fc_type);
597 baud_rate = p_port->user_port_pars.baud_rate;
598 p_port->user_port_pars = *p_settings;
600 /* for now we've been asked to pass only baud rate */
601 if (baud_rate != p_settings->baud_rate) {
602 port_start_par_neg(p_port);
604 return (PORT_SUCCESS);
607 /*******************************************************************************
609 * Function PORT_GetRxQueueCnt
611 * Description This function return number of buffers on the rx queue.
613 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
614 * p_rx_queue_count - Pointer to return queue count in.
616 ******************************************************************************/
617 int PORT_GetRxQueueCnt(uint16_t handle, uint16_t* p_rx_queue_count) {
620 RFCOMM_TRACE_API("PORT_GetRxQueueCnt() handle:%d", handle);
622 /* Check if handle is valid to avoid crashing */
623 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
624 return (PORT_BAD_HANDLE);
627 p_port = &rfc_cb.port.port[handle - 1];
629 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
630 return (PORT_NOT_OPENED);
633 if (p_port->line_status) {
634 return (PORT_LINE_ERR);
637 *p_rx_queue_count = p_port->rx.queue_size;
640 "PORT_GetRxQueueCnt() p_rx_queue_count:%d, p_port->rx.queue.count = %d",
641 *p_rx_queue_count, p_port->rx.queue_size);
643 return (PORT_SUCCESS);
646 /*******************************************************************************
648 * Function PORT_GetState
650 * Description This function is called to fill tPORT_STATE structure
651 * with the curremt control settings for the port
653 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
654 * p_settings - Pointer to a tPORT_STATE structure in which
655 * configuration information is returned.
657 ******************************************************************************/
658 int PORT_GetState(uint16_t handle, tPORT_STATE* p_settings) {
661 RFCOMM_TRACE_API("PORT_GetState() handle:%d", handle);
663 /* Check if handle is valid to avoid crashing */
664 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
665 return (PORT_BAD_HANDLE);
668 p_port = &rfc_cb.port.port[handle - 1];
670 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
671 return (PORT_NOT_OPENED);
674 if (p_port->line_status) {
675 return (PORT_LINE_ERR);
678 *p_settings = p_port->user_port_pars;
679 return (PORT_SUCCESS);
682 /*******************************************************************************
684 * Function PORT_Control
686 * Description This function directs a specified connection to pass control
687 * control information to the peer device.
689 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
690 * signal = specify the function to be passed
692 ******************************************************************************/
693 int PORT_Control(uint16_t handle, uint8_t signal) {
695 uint8_t old_modem_signal;
697 RFCOMM_TRACE_API("PORT_Control() handle:%d signal:0x%x", handle, signal);
699 /* Check if handle is valid to avoid crashing */
700 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
701 return (PORT_BAD_HANDLE);
704 p_port = &rfc_cb.port.port[handle - 1];
706 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
707 return (PORT_NOT_OPENED);
710 old_modem_signal = p_port->local_ctrl.modem_signal;
711 p_port->local_ctrl.break_signal = 0;
714 case PORT_SET_CTSRTS:
715 p_port->local_ctrl.modem_signal |= PORT_CTSRTS_ON;
718 case PORT_CLR_CTSRTS:
719 p_port->local_ctrl.modem_signal &= ~PORT_CTSRTS_ON;
722 case PORT_SET_DTRDSR:
723 p_port->local_ctrl.modem_signal |= PORT_DTRDSR_ON;
726 case PORT_CLR_DTRDSR:
727 p_port->local_ctrl.modem_signal &= ~PORT_DTRDSR_ON;
731 p_port->local_ctrl.modem_signal |= PORT_RING_ON;
735 p_port->local_ctrl.modem_signal &= ~PORT_RING_ON;
739 p_port->local_ctrl.modem_signal |= PORT_DCD_ON;
743 p_port->local_ctrl.modem_signal &= ~PORT_DCD_ON;
747 if (signal == PORT_BREAK)
748 p_port->local_ctrl.break_signal = PORT_BREAK_DURATION;
749 else if (p_port->local_ctrl.modem_signal == old_modem_signal)
750 return (PORT_SUCCESS);
752 port_start_control(p_port);
755 "PORT_Control DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d",
756 ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0),
757 ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0),
758 ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0),
759 ((p_port->local_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0));
761 return (PORT_SUCCESS);
764 /*******************************************************************************
766 * Function PORT_FlowControl
768 * Description This function directs a specified connection to pass
769 * flow control message to the peer device. Enable flag passed
770 * shows if port can accept more data.
772 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
773 * enable - enables data flow
775 ******************************************************************************/
776 int PORT_FlowControl(uint16_t handle, bool enable) {
781 RFCOMM_TRACE_API("PORT_FlowControl() handle:%d enable: %d", handle, enable);
783 /* Check if handle is valid to avoid crashing */
784 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
785 return (PORT_BAD_HANDLE);
788 p_port = &rfc_cb.port.port[handle - 1];
790 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
791 return (PORT_NOT_OPENED);
794 if (!p_port->rfc.p_mcb) {
795 return (PORT_NOT_OPENED);
798 p_port->rx.user_fc = !enable;
800 if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
801 if (!p_port->rx.user_fc) {
802 port_flow_control_peer(p_port, true, 0);
805 old_fc = p_port->local_ctrl.fc;
807 /* FC is set if user is set or peer is set */
808 p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
810 if (p_port->local_ctrl.fc != old_fc) port_start_control(p_port);
813 /* Need to take care of the case when we could not deliver events */
814 /* to the application because we were flow controlled */
815 if (enable && (p_port->rx.queue_size != 0)) {
816 events = PORT_EV_RXCHAR;
817 if (p_port->rx_flag_ev_pending) {
818 p_port->rx_flag_ev_pending = false;
819 events |= PORT_EV_RXFLAG;
822 events &= p_port->ev_mask;
823 if (p_port->p_callback && events) {
824 p_port->p_callback(events, p_port->inx);
827 return (PORT_SUCCESS);
829 /*******************************************************************************
831 * Function PORT_FlowControl_MaxCredit
833 * Description This function directs a specified connection to pass
834 * flow control message to the peer device. Enable flag passed
835 * shows if port can accept more data. It also sends max credit
836 * when data flow enabled
838 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
839 * enable - enables data flow
841 ******************************************************************************/
843 int PORT_FlowControl_MaxCredit(uint16_t handle, bool enable) {
848 RFCOMM_TRACE_API("PORT_FlowControl() handle:%d enable: %d", handle, enable);
850 /* Check if handle is valid to avoid crashing */
851 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
852 return (PORT_BAD_HANDLE);
855 p_port = &rfc_cb.port.port[handle - 1];
857 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
858 return (PORT_NOT_OPENED);
861 if (!p_port->rfc.p_mcb) {
862 return (PORT_NOT_OPENED);
865 p_port->rx.user_fc = !enable;
867 if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) {
868 if (!p_port->rx.user_fc) {
869 port_flow_control_peer(p_port, true, p_port->credit_rx);
872 old_fc = p_port->local_ctrl.fc;
874 /* FC is set if user is set or peer is set */
875 p_port->local_ctrl.fc = (p_port->rx.user_fc | p_port->rx.peer_fc);
877 if (p_port->local_ctrl.fc != old_fc) port_start_control(p_port);
880 /* Need to take care of the case when we could not deliver events */
881 /* to the application because we were flow controlled */
882 if (enable && (p_port->rx.queue_size != 0)) {
883 events = PORT_EV_RXCHAR;
884 if (p_port->rx_flag_ev_pending) {
885 p_port->rx_flag_ev_pending = false;
886 events |= PORT_EV_RXFLAG;
889 events &= p_port->ev_mask;
890 if (p_port->p_callback && events) {
891 p_port->p_callback(events, p_port->inx);
894 return (PORT_SUCCESS);
897 /*******************************************************************************
899 * Function PORT_GetModemStatus
901 * Description This function retrieves modem control signals. Normally
902 * application will call this function after a callback
903 * function is called with notification that one of signals
906 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
907 * p_signal - specify the pointer to control signals info
909 ******************************************************************************/
910 int PORT_GetModemStatus(uint16_t handle, uint8_t* p_signal) {
913 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
914 return (PORT_BAD_HANDLE);
917 p_port = &rfc_cb.port.port[handle - 1];
919 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
920 return (PORT_NOT_OPENED);
923 *p_signal = p_port->peer_ctrl.modem_signal;
925 RFCOMM_TRACE_API("PORT_GetModemStatus() handle:%d signal:%x", handle,
928 return (PORT_SUCCESS);
931 /*******************************************************************************
933 * Function PORT_ClearError
935 * Description This function retreives information about a communications
936 * error and reports current status of a connection. The
937 * function should be called when an error occures to clear
938 * the connection error flag and to enable additional read
939 * and write operations.
941 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
942 * p_errors - pointer of the variable to receive error codes
943 * p_status - pointer to the tPORT_STATUS structur to receive
946 ******************************************************************************/
947 int PORT_ClearError(uint16_t handle, uint16_t* p_errors,
948 tPORT_STATUS* p_status) {
951 RFCOMM_TRACE_API("PORT_ClearError() handle:%d", handle);
953 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
954 return (PORT_BAD_HANDLE);
957 p_port = &rfc_cb.port.port[handle - 1];
959 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
960 return (PORT_NOT_OPENED);
963 *p_errors = p_port->line_status;
965 /* This is the only call to clear error status. We can not clear */
966 /* connection failed status. To clean it port should be closed and reopened
968 p_port->line_status = (p_port->line_status & LINE_STATUS_FAILED);
970 PORT_GetQueueStatus(handle, p_status);
971 return (PORT_SUCCESS);
974 /*******************************************************************************
976 * Function PORT_SendError
978 * Description This function send a communications error to the peer device
980 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
981 * errors - receive error codes
983 ******************************************************************************/
984 int PORT_SendError(uint16_t handle, uint8_t errors) {
987 RFCOMM_TRACE_API("PORT_SendError() handle:%d errors:0x%x", handle, errors);
989 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
990 return (PORT_BAD_HANDLE);
993 p_port = &rfc_cb.port.port[handle - 1];
995 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
996 return (PORT_NOT_OPENED);
999 if (!p_port->rfc.p_mcb) {
1000 return (PORT_NOT_OPENED);
1003 RFCOMM_LineStatusReq(p_port->rfc.p_mcb, p_port->dlci, errors);
1004 return (PORT_SUCCESS);
1007 /*******************************************************************************
1009 * Function PORT_GetQueueStatus
1011 * Description This function reports current status of a connection.
1013 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1014 * p_status - pointer to the tPORT_STATUS structur to receive
1017 ******************************************************************************/
1018 int PORT_GetQueueStatus(uint16_t handle, tPORT_STATUS* p_status) {
1021 /* RFCOMM_TRACE_API ("PORT_GetQueueStatus() handle:%d", handle); */
1023 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1024 return (PORT_BAD_HANDLE);
1027 p_port = &rfc_cb.port.port[handle - 1];
1029 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1030 return (PORT_NOT_OPENED);
1033 p_status->in_queue_size = (uint16_t)p_port->rx.queue_size;
1034 p_status->out_queue_size = (uint16_t)p_port->tx.queue_size;
1036 p_status->mtu_size = (uint16_t)p_port->peer_mtu;
1038 p_status->flags = 0;
1040 if (!(p_port->peer_ctrl.modem_signal & PORT_CTSRTS_ON))
1041 p_status->flags |= PORT_FLAG_CTS_HOLD;
1043 if (!(p_port->peer_ctrl.modem_signal & PORT_DTRDSR_ON))
1044 p_status->flags |= PORT_FLAG_DSR_HOLD;
1046 if (!(p_port->peer_ctrl.modem_signal & PORT_DCD_ON))
1047 p_status->flags |= PORT_FLAG_RLSD_HOLD;
1049 return (PORT_SUCCESS);
1052 /*******************************************************************************
1054 * Function PORT_Purge
1056 * Description This function discards all the data from the output or
1057 * input queues of the specified connection.
1059 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1060 * purge_flags - specify the action to take.
1062 ******************************************************************************/
1063 int PORT_Purge(uint16_t handle, uint8_t purge_flags) {
1069 RFCOMM_TRACE_API("PORT_Purge() handle:%d flags:0x%x", handle, purge_flags);
1071 /* Check if handle is valid to avoid crashing */
1072 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1073 return (PORT_BAD_HANDLE);
1076 p_port = &rfc_cb.port.port[handle - 1];
1078 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1079 return (PORT_NOT_OPENED);
1082 if (purge_flags & PORT_PURGE_RXCLEAR) {
1083 mutex_global_lock(); /* to prevent missing credit */
1085 count = fixed_queue_length(p_port->rx.queue);
1087 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue)) != NULL)
1090 p_port->rx.queue_size = 0;
1092 mutex_global_unlock();
1094 /* If we flowed controlled peer based on rx_queue size enable data again */
1095 if (count) port_flow_control_peer(p_port, true, count);
1098 if (purge_flags & PORT_PURGE_TXCLEAR) {
1099 mutex_global_lock(); /* to prevent tx.queue_size from being negative */
1101 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->tx.queue)) != NULL)
1104 p_port->tx.queue_size = 0;
1106 mutex_global_unlock();
1108 events = PORT_EV_TXEMPTY;
1110 events |= port_flow_control_user(p_port);
1112 events &= p_port->ev_mask;
1114 if ((p_port->p_callback != NULL) && events)
1115 (p_port->p_callback)(events, p_port->inx);
1118 return (PORT_SUCCESS);
1121 /*******************************************************************************
1123 * Function PORT_ReadData
1125 * Description Normally not GKI aware application will call this function
1126 * after receiving PORT_EV_RXCHAR event.
1128 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1129 * p_data - Data area
1130 * max_len - Byte count requested
1131 * p_len - Byte count received
1133 ******************************************************************************/
1134 int PORT_ReadData(uint16_t handle, char* p_data, uint16_t max_len,
1140 RFCOMM_TRACE_API("PORT_ReadData() handle:%d max_len:%d", handle, max_len);
1142 /* Initialize this in case of an error */
1145 /* Check if handle is valid to avoid crashing */
1146 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1147 return (PORT_BAD_HANDLE);
1150 p_port = &rfc_cb.port.port[handle - 1];
1152 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1153 return (PORT_NOT_OPENED);
1156 if (p_port->line_status) {
1157 return (PORT_LINE_ERR);
1160 if (fixed_queue_is_empty(p_port->rx.queue)) return (PORT_SUCCESS);
1165 p_buf = (BT_HDR*)fixed_queue_try_peek_first(p_port->rx.queue);
1166 if (p_buf == NULL) break;
1168 if (p_buf->len > max_len) {
1169 memcpy(p_data, (uint8_t*)(p_buf + 1) + p_buf->offset, max_len);
1170 p_buf->offset += max_len;
1171 p_buf->len -= max_len;
1175 mutex_global_lock();
1177 p_port->rx.queue_size -= max_len;
1179 mutex_global_unlock();
1183 memcpy(p_data, (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len);
1185 *p_len += p_buf->len;
1186 max_len -= p_buf->len;
1188 mutex_global_lock();
1190 p_port->rx.queue_size -= p_buf->len;
1193 p_data += p_buf->len;
1196 osi_free(fixed_queue_try_dequeue(p_port->rx.queue));
1198 mutex_global_unlock();
1205 RFCOMM_TRACE_EVENT("PORT_ReadData queue:%d returned:%d %x",
1206 p_port->rx.queue_size, *p_len, (p_data[0]));
1208 RFCOMM_TRACE_EVENT("PORT_ReadData queue:%d returned:%d",
1209 p_port->rx.queue_size, *p_len);
1212 /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
1213 /* check if it can be resumed now */
1214 port_flow_control_peer(p_port, true, count);
1216 return (PORT_SUCCESS);
1219 /*******************************************************************************
1221 * Function PORT_Read
1223 * Description Normally application will call this function after receiving
1224 * PORT_EV_RXCHAR event.
1226 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1227 * pp_buf - pointer to address of buffer with data,
1229 ******************************************************************************/
1230 int PORT_Read(uint16_t handle, BT_HDR** pp_buf) {
1234 RFCOMM_TRACE_API("PORT_Read() handle:%d", handle);
1236 /* Check if handle is valid to avoid crashing */
1237 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1238 return (PORT_BAD_HANDLE);
1240 p_port = &rfc_cb.port.port[handle - 1];
1242 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1243 return (PORT_NOT_OPENED);
1246 if (p_port->line_status) {
1247 return (PORT_LINE_ERR);
1250 mutex_global_lock();
1252 p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue);
1254 p_port->rx.queue_size -= p_buf->len;
1256 mutex_global_unlock();
1258 /* If rfcomm suspended traffic from the peer based on the rx_queue_size */
1259 /* check if it can be resumed now */
1260 port_flow_control_peer(p_port, true, 1);
1262 mutex_global_unlock();
1266 return (PORT_SUCCESS);
1269 /*******************************************************************************
1271 * Function port_write
1273 * Description This function when a data packet is received from the apper
1276 * Parameters: p_port - pointer to address of port control block
1277 * p_buf - pointer to address of buffer with data,
1279 ******************************************************************************/
1280 static int port_write(tPORT* p_port, BT_HDR* p_buf) {
1281 /* We should not allow to write data in to server port when connection is not
1283 if (p_port->is_server && (p_port->rfc.state != RFC_STATE_OPENED)) {
1285 return (PORT_CLOSED);
1288 /* Keep the data in pending queue if peer does not allow data, or */
1289 /* Peer is not ready or Port is not yet opened or initial port control */
1290 /* command has not been sent */
1291 if (p_port->tx.peer_fc || !p_port->rfc.p_mcb ||
1292 !p_port->rfc.p_mcb->peer_ready ||
1293 (p_port->rfc.state != RFC_STATE_OPENED) ||
1294 ((p_port->port_ctrl & (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED)) !=
1295 (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED))) {
1296 if ((p_port->tx.queue_size > PORT_TX_CRITICAL_WM) ||
1297 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_CRITICAL_WM)) {
1298 RFCOMM_TRACE_WARNING("PORT_Write: Queue size: %d", p_port->tx.queue_size);
1302 if ((p_port->p_callback != NULL) && (p_port->ev_mask & PORT_EV_ERR))
1303 p_port->p_callback(PORT_EV_ERR, p_port->inx);
1305 return (PORT_TX_FULL);
1309 "PORT_Write : Data is enqued. flow disabled %d peer_ready %d state %d "
1312 (p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready), p_port->rfc.state,
1315 fixed_queue_enqueue(p_port->tx.queue, p_buf);
1316 p_port->tx.queue_size += p_buf->len;
1318 return (PORT_CMD_PENDING);
1320 RFCOMM_TRACE_EVENT("PORT_Write : Data is being sent");
1322 RFCOMM_DataReq(p_port->rfc.p_mcb, p_port->dlci, p_buf);
1323 return (PORT_SUCCESS);
1327 /*******************************************************************************
1329 * Function PORT_Write
1331 * Description This function when a data packet is received from the apper
1334 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1335 * pp_buf - pointer to address of buffer with data,
1337 ******************************************************************************/
1338 int PORT_Write(uint16_t handle, BT_HDR* p_buf) {
1343 RFCOMM_TRACE_API("PORT_Write() handle:%d", handle);
1345 /* Check if handle is valid to avoid crashing */
1346 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1348 return (PORT_BAD_HANDLE);
1351 p_port = &rfc_cb.port.port[handle - 1];
1353 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1355 return (PORT_NOT_OPENED);
1358 if (p_port->line_status) {
1359 RFCOMM_TRACE_WARNING("PORT_Write: Data dropped line_status:0x%x",
1360 p_port->line_status);
1362 return (PORT_LINE_ERR);
1365 rc = port_write(p_port, p_buf);
1366 event |= port_flow_control_user(p_port);
1370 event |= PORT_EV_ERR;
1374 event |= (PORT_EV_TXCHAR | PORT_EV_TXEMPTY);
1377 /* Mask out all events that are not of interest to user */
1378 event &= p_port->ev_mask;
1380 /* Send event to the application */
1381 if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->inx);
1383 return (PORT_SUCCESS);
1385 /*******************************************************************************
1387 * Function PORT_WriteDataCO
1389 * Description Normally not GKI aware application will call this function
1390 * to send data to the port by callout functions
1392 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1394 * p_len - Byte count returned
1396 ******************************************************************************/
1397 int PORT_WriteDataCO(uint16_t handle, int* p_len) {
1404 RFCOMM_TRACE_API("PORT_WriteDataCO() handle:%d", handle);
1407 /* Check if handle is valid to avoid crashing */
1408 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1409 return (PORT_BAD_HANDLE);
1411 p_port = &rfc_cb.port.port[handle - 1];
1413 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1414 RFCOMM_TRACE_WARNING("PORT_WriteDataByFd() no port state:%d",
1416 return (PORT_NOT_OPENED);
1419 if (!p_port->peer_mtu) {
1420 RFCOMM_TRACE_ERROR("PORT_WriteDataByFd() peer_mtu:%d", p_port->peer_mtu);
1421 return (PORT_UNKNOWN_ERROR);
1424 // if(ioctl(fd, FIONREAD, &available) < 0)
1425 if (p_port->p_data_co_callback(
1426 handle, (uint8_t*)&available, sizeof(available),
1427 DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE) == false) {
1429 "p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, "
1432 return (PORT_UNKNOWN_ERROR);
1434 if (available == 0) return PORT_SUCCESS;
1435 /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len
1437 length = RFCOMM_DATA_BUF_SIZE -
1438 (uint16_t)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
1440 /* If there are buffers scheduled for transmission check if requested */
1441 /* data fits into the end of the queue */
1442 mutex_global_lock();
1444 p_buf = (BT_HDR*)fixed_queue_try_peek_last(p_port->tx.queue);
1445 if ((p_buf != NULL) &&
1446 (((int)p_buf->len + available) <= (int)p_port->peer_mtu) &&
1447 (((int)p_buf->len + available) <= (int)length)) {
1448 // if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len,
1449 // available, 0) != available)
1450 if (p_port->p_data_co_callback(
1451 handle, (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len,
1452 available, DATA_CO_CALLBACK_TYPE_OUTGOING) == false)
1456 "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, "
1459 mutex_global_unlock();
1460 return (PORT_UNKNOWN_ERROR);
1462 // memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len, p_data,
1464 p_port->tx.queue_size += (uint16_t)available;
1467 p_buf->len += (uint16_t)available;
1469 mutex_global_unlock();
1471 return (PORT_SUCCESS);
1474 mutex_global_unlock();
1476 // int max_read = length < p_port->peer_mtu ? length : p_port->peer_mtu;
1478 // max_read = available < max_read ? available : max_read;
1481 /* if we're over buffer high water mark, we're done */
1482 if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
1483 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM)) {
1484 port_flow_control_user(p_port);
1485 event |= PORT_EV_FC;
1487 "tx queue is full,tx.queue_size:%d,tx.queue.count:%d,available:%d",
1488 p_port->tx.queue_size, fixed_queue_length(p_port->tx.queue),
1493 /* continue with rfcomm data write */
1494 p_buf = (BT_HDR*)osi_malloc(RFCOMM_DATA_BUF_SIZE);
1495 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
1496 p_buf->layer_specific = handle;
1498 if (p_port->peer_mtu < length) length = p_port->peer_mtu;
1499 if (available < (int)length) length = (uint16_t)available;
1500 p_buf->len = length;
1501 p_buf->event = BT_EVT_TO_BTU_SP_DATA;
1503 // memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset, p_data, length);
1504 // if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset, (int)length, 0) !=
1506 if (p_port->p_data_co_callback(
1507 handle, (uint8_t*)(p_buf + 1) + p_buf->offset, length,
1508 DATA_CO_CALLBACK_TYPE_OUTGOING) == false) {
1510 "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:%d",
1512 return (PORT_UNKNOWN_ERROR);
1515 RFCOMM_TRACE_EVENT("PORT_WriteData %d bytes", length);
1517 rc = port_write(p_port, p_buf);
1519 /* If queue went below the threashold need to send flow control */
1520 event |= port_flow_control_user(p_port);
1522 if (rc == PORT_SUCCESS) event |= PORT_EV_TXCHAR;
1524 if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) break;
1527 available -= (int)length;
1529 if (!available && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
1530 event |= PORT_EV_TXEMPTY;
1532 /* Mask out all events that are not of interest to user */
1533 event &= p_port->ev_mask;
1535 /* Send event to the application */
1536 if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->inx);
1538 return (PORT_SUCCESS);
1541 /*******************************************************************************
1543 * Function PORT_WriteData
1545 * Description Normally not GKI aware application will call this function
1546 * to send data to the port.
1548 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1549 * p_data - Data area
1550 * max_len - Byte count requested
1551 * p_len - Byte count received
1553 ******************************************************************************/
1554 int PORT_WriteData(uint16_t handle, const char* p_data, uint16_t max_len,
1562 RFCOMM_TRACE_API("PORT_WriteData() max_len:%d", max_len);
1566 /* Check if handle is valid to avoid crashing */
1567 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1568 return (PORT_BAD_HANDLE);
1570 p_port = &rfc_cb.port.port[handle - 1];
1572 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1573 RFCOMM_TRACE_WARNING("PORT_WriteData() no port state:%d", p_port->state);
1574 return (PORT_NOT_OPENED);
1577 if (!max_len || !p_port->peer_mtu) {
1578 RFCOMM_TRACE_ERROR("PORT_WriteData() peer_mtu:%d", p_port->peer_mtu);
1579 return (PORT_UNKNOWN_ERROR);
1582 /* Length for each buffer is the smaller of GKI buffer, peer MTU, or max_len
1584 length = RFCOMM_DATA_BUF_SIZE -
1585 (uint16_t)(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + RFCOMM_DATA_OVERHEAD);
1587 /* If there are buffers scheduled for transmission check if requested */
1588 /* data fits into the end of the queue */
1589 mutex_global_lock();
1591 p_buf = (BT_HDR*)fixed_queue_try_peek_last(p_port->tx.queue);
1592 if ((p_buf != NULL) && ((p_buf->len + max_len) <= p_port->peer_mtu) &&
1593 ((p_buf->len + max_len) <= length)) {
1594 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len, p_data, max_len);
1595 p_port->tx.queue_size += max_len;
1598 p_buf->len += max_len;
1600 mutex_global_unlock();
1602 return (PORT_SUCCESS);
1605 mutex_global_unlock();
1608 /* if we're over buffer high water mark, we're done */
1609 if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) ||
1610 (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM))
1613 /* continue with rfcomm data write */
1614 p_buf = (BT_HDR*)osi_malloc(RFCOMM_DATA_BUF_SIZE);
1615 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET;
1616 p_buf->layer_specific = handle;
1618 if (p_port->peer_mtu < length) length = p_port->peer_mtu;
1619 if (max_len < length) length = max_len;
1620 p_buf->len = length;
1621 p_buf->event = BT_EVT_TO_BTU_SP_DATA;
1623 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, length);
1625 RFCOMM_TRACE_EVENT("PORT_WriteData %d bytes", length);
1627 rc = port_write(p_port, p_buf);
1629 /* If queue went below the threashold need to send flow control */
1630 event |= port_flow_control_user(p_port);
1632 if (rc == PORT_SUCCESS) event |= PORT_EV_TXCHAR;
1634 if ((rc != PORT_SUCCESS) && (rc != PORT_CMD_PENDING)) break;
1640 if (!max_len && (rc != PORT_CMD_PENDING) && (rc != PORT_TX_QUEUE_DISABLED))
1641 event |= PORT_EV_TXEMPTY;
1643 /* Mask out all events that are not of interest to user */
1644 event &= p_port->ev_mask;
1646 /* Send event to the application */
1647 if (p_port->p_callback && event) (p_port->p_callback)(event, p_port->inx);
1649 return (PORT_SUCCESS);
1652 /*******************************************************************************
1654 * Function PORT_Test
1656 * Description Application can call this function to send RFCOMM Test frame
1658 * Parameters: handle - Handle returned in the RFCOMM_CreateConnection
1659 * p_data - Data area
1660 * max_len - Byte count requested
1662 ******************************************************************************/
1663 int PORT_Test(uint16_t handle, uint8_t* p_data, uint16_t len) {
1666 RFCOMM_TRACE_API("PORT_Test() len:%d", len);
1668 if ((handle == 0) || (handle > MAX_RFC_PORTS)) {
1669 return (PORT_BAD_HANDLE);
1671 p_port = &rfc_cb.port.port[handle - 1];
1673 if (!p_port->in_use || (p_port->state == PORT_STATE_CLOSED)) {
1674 return (PORT_NOT_OPENED);
1677 if (len > ((p_port->mtu == 0) ? RFCOMM_DEFAULT_MTU : p_port->mtu)) {
1678 return (PORT_UNKNOWN_ERROR);
1681 BT_HDR* p_buf = (BT_HDR*)osi_malloc(RFCOMM_CMD_BUF_SIZE);
1682 p_buf->offset = L2CAP_MIN_OFFSET + RFCOMM_MIN_OFFSET + 2;
1685 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
1687 rfc_send_test(p_port->rfc.p_mcb, true, p_buf);
1689 return (PORT_SUCCESS);
1692 /*******************************************************************************
1694 * Function RFCOMM_Init
1696 * Description This function is called to initialize RFCOMM layer
1698 ******************************************************************************/
1699 void RFCOMM_Init(void) {
1700 memset(&rfc_cb, 0, sizeof(tRFC_CB)); /* Init RFCOMM control block */
1702 rfc_cb.rfc.last_mux = MAX_BD_CONNECTIONS;
1704 #if defined(RFCOMM_INITIAL_TRACE_LEVEL)
1705 rfc_cb.trace_level = RFCOMM_INITIAL_TRACE_LEVEL;
1707 rfc_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
1710 rfcomm_l2cap_if_init();
1713 /*******************************************************************************
1715 * Function PORT_SetTraceLevel
1717 * Description Set the trace level for RFCOMM. If called with 0xFF, it
1718 * simply reads the current trace level.
1720 * Returns the new (current) trace level
1722 ******************************************************************************/
1723 uint8_t PORT_SetTraceLevel(uint8_t new_level) {
1724 if (new_level != 0xFF) rfc_cb.trace_level = new_level;
1726 return (rfc_cb.trace_level);
1729 /*******************************************************************************
1731 * Function PORT_GetResultString
1733 * Description This function returns the human-readable string for a given
1736 * Returns a pointer to the human-readable string for the given result.
1738 ******************************************************************************/
1739 const char* PORT_GetResultString(const uint8_t result_code) {
1740 if (result_code > PORT_ERR_MAX) {
1741 return result_code_strings[PORT_ERR_MAX];
1744 return result_code_strings[result_code];