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