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