OSDN Git Service

Merge commit '27c4e634' into mnc-dr-dev-plus-aosp
[android-x86/system-bt.git] / stack / gap / gap_conn.c
1 /******************************************************************************
2  *
3  *  Copyright (C) 2009-2013 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 #include "bt_target.h"
21 #include "bt_utils.h"
22 #include "btu.h"
23 #include "gap_int.h"
24 #include "l2cdefs.h"
25 #include "l2c_int.h"
26 #include <string.h>
27 #if GAP_CONN_INCLUDED == TRUE
28 #include "btm_int.h"
29
30 /********************************************************************************/
31 /*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
32 /********************************************************************************/
33 static void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id);
34 static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result);
35 static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
36 static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
37 static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed);
38 static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg);
39 static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested);
40
41 static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid);
42 static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle);
43 static tGAP_CCB *gap_allocate_ccb (void);
44 static void      gap_release_ccb (tGAP_CCB *p_ccb);
45
46 /*******************************************************************************
47 **
48 ** Function         gap_conn_init
49 **
50 ** Description      This function is called to initialize GAP connection management
51 **
52 ** Returns          void
53 **
54 *******************************************************************************/
55 void gap_conn_init (void)
56 {
57 #if AMP_INCLUDED == TRUE
58     gap_cb.conn.reg_info.pAMP_ConnectInd_Cb         = gap_connect_ind;
59     gap_cb.conn.reg_info.pAMP_ConnectCfm_Cb         = gap_connect_cfm;
60     gap_cb.conn.reg_info.pAMP_ConnectPnd_Cb         = NULL;
61     gap_cb.conn.reg_info.pAMP_ConfigInd_Cb          = gap_config_ind;
62     gap_cb.conn.reg_info.pAMP_ConfigCfm_Cb          = gap_config_cfm;
63     gap_cb.conn.reg_info.pAMP_DisconnectInd_Cb      = gap_disconnect_ind;
64     gap_cb.conn.reg_info.pAMP_DisconnectCfm_Cb      = NULL;
65     gap_cb.conn.reg_info.pAMP_QoSViolationInd_Cb    = NULL;
66     gap_cb.conn.reg_info.pAMP_DataInd_Cb            = gap_data_ind;
67     gap_cb.conn.reg_info.pAMP_CongestionStatus_Cb   = gap_congestion_ind;
68     gap_cb.conn.reg_info.pAMP_TxComplete_Cb         = NULL;
69     gap_cb.conn.reg_info.pAMP_MoveInd_Cb            = NULL;
70     gap_cb.conn.reg_info.pAMP_MoveRsp_Cb            = NULL;
71     gap_cb.conn.reg_info.pAMP_MoveCfm_Cb            = NULL; //gap_move_cfm
72     gap_cb.conn.reg_info.pAMP_MoveCfmRsp_Cb         = NULL; //gap_move_cfm_rsp
73
74 #else
75     gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb       = gap_connect_ind;
76     gap_cb.conn.reg_info.pL2CA_ConnectCfm_Cb       = gap_connect_cfm;
77     gap_cb.conn.reg_info.pL2CA_ConnectPnd_Cb       = NULL;
78     gap_cb.conn.reg_info.pL2CA_ConfigInd_Cb        = gap_config_ind;
79     gap_cb.conn.reg_info.pL2CA_ConfigCfm_Cb        = gap_config_cfm;
80     gap_cb.conn.reg_info.pL2CA_DisconnectInd_Cb    = gap_disconnect_ind;
81     gap_cb.conn.reg_info.pL2CA_DisconnectCfm_Cb    = NULL;
82     gap_cb.conn.reg_info.pL2CA_QoSViolationInd_Cb  = NULL;
83     gap_cb.conn.reg_info.pL2CA_DataInd_Cb          = gap_data_ind;
84     gap_cb.conn.reg_info.pL2CA_CongestionStatus_Cb = gap_congestion_ind;
85     gap_cb.conn.reg_info.pL2CA_TxComplete_Cb       = NULL;
86 #endif
87 }
88
89
90 /*******************************************************************************
91 **
92 ** Function         GAP_ConnOpen
93 **
94 ** Description      This function is called to open an L2CAP connection.
95 **
96 ** Parameters:      is_server   - If TRUE, the connection is not created
97 **                                but put into a "listen" mode waiting for
98 **                                the remote side to connect.
99 **
100 **                  service_id  - Unique service ID from
101 **                                BTM_SEC_SERVICE_FIRST_EMPTY (6)
102 **                                to BTM_SEC_MAX_SERVICE_RECORDS (32)
103 **
104 **                  p_rem_bda   - Pointer to remote BD Address.
105 **                                If a server, and we don't care about the
106 **                                remote BD Address, then NULL should be passed.
107 **
108 **                  psm         - the PSM used for the connection
109 **
110 **                  p_config    - Optional pointer to configuration structure.
111 **                                If NULL, the default GAP configuration will
112 **                                be used.
113 **
114 **                  security    - security flags
115 **                  chan_mode_mask - (GAP_FCR_CHAN_OPT_BASIC, GAP_FCR_CHAN_OPT_ERTM,
116 **                                    GAP_FCR_CHAN_OPT_STREAM)
117 **
118 **                  p_cb        - Pointer to callback function for events.
119 **
120 ** Returns          handle of the connection if successful, else GAP_INVALID_HANDLE
121 **
122 *******************************************************************************/
123 UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
124                      BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg,
125                      tL2CAP_ERTM_INFO *ertm_info, UINT16 security, UINT8 chan_mode_mask,
126                      tGAP_CONN_CALLBACK *p_cb)
127 {
128     tGAP_CCB    *p_ccb;
129     UINT16       cid;
130
131     GAP_TRACE_EVENT ("GAP_CONN - Open Request");
132
133     /* Allocate a new CCB. Return if none available. */
134     if ((p_ccb = gap_allocate_ccb()) == NULL)
135         return (GAP_INVALID_HANDLE);
136
137     /* If caller specified a BD address, save it */
138     if (p_rem_bda)
139     {
140         /* the bd addr is not BT_BD_ANY, then a bd address was specified */
141         if (memcmp (p_rem_bda, BT_BD_ANY, BD_ADDR_LEN))
142             p_ccb->rem_addr_specified = TRUE;
143
144         memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
145     }
146     else if (!is_server)
147     {
148         /* remore addr is not specified and is not a server -> bad */
149         return (GAP_INVALID_HANDLE);
150     }
151
152     /* A client MUST have specified a bd addr to connect with */
153     if (!p_ccb->rem_addr_specified && !is_server)
154     {
155         gap_release_ccb (p_ccb);
156         GAP_TRACE_ERROR ("GAP ERROR: Client must specify a remote BD ADDR to connect to!");
157         return (GAP_INVALID_HANDLE);
158     }
159
160     /* Check if configuration was specified */
161     if (p_cfg)
162         p_ccb->cfg = *p_cfg;
163
164     p_ccb->p_callback     = p_cb;
165
166     /* If originator, use a dynamic PSM */
167 #if AMP_INCLUDED == TRUE
168     if (!is_server)
169         gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = NULL;
170     else
171         gap_cb.conn.reg_info.pAMP_ConnectInd_Cb  = gap_connect_ind;
172 #else
173     if (!is_server)
174         gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = NULL;
175     else
176         gap_cb.conn.reg_info.pL2CA_ConnectInd_Cb = gap_connect_ind;
177 #endif
178
179     /* Register the PSM with L2CAP */
180     if ((p_ccb->psm = L2CA_REGISTER (psm, &gap_cb.conn.reg_info,
181                     AMP_AUTOSWITCH_ALLOWED|AMP_USE_AMP_IF_POSSIBLE)) == 0)
182     {
183         GAP_TRACE_ERROR ("GAP_ConnOpen: Failure registering PSM 0x%04x", psm);
184         gap_release_ccb (p_ccb);
185         return (GAP_INVALID_HANDLE);
186     }
187
188     /* Register with Security Manager for the specific security level */
189     p_ccb->service_id = service_id;
190     if (!BTM_SetSecurityLevel ((UINT8)!is_server, p_serv_name,
191                 p_ccb->service_id, security, p_ccb->psm, 0, 0))
192     {
193         GAP_TRACE_ERROR ("GAP_CONN - Security Error");
194         gap_release_ccb (p_ccb);
195         return (GAP_INVALID_HANDLE);
196     }
197
198     /* Fill in eL2CAP parameter data */
199     if( p_ccb->cfg.fcr_present )
200     {
201         if(ertm_info == NULL) {
202             p_ccb->ertm_info.preferred_mode = p_ccb->cfg.fcr.mode;
203             p_ccb->ertm_info.user_rx_pool_id = GAP_DATA_POOL_ID;
204             p_ccb->ertm_info.user_tx_pool_id = GAP_DATA_POOL_ID;
205             p_ccb->ertm_info.fcr_rx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
206             p_ccb->ertm_info.fcr_tx_pool_id = L2CAP_DEFAULT_ERM_POOL_ID;
207         } else {
208             p_ccb->ertm_info = *ertm_info;
209         }
210     }
211
212     /* optional FCR channel modes */
213     if(ertm_info != NULL) {
214         p_ccb->ertm_info.allowed_modes =
215             (chan_mode_mask) ? chan_mode_mask : (UINT8)L2CAP_FCR_CHAN_OPT_BASIC;
216     }
217
218     if (is_server)
219     {
220         p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE; /* assume btm/l2cap would handle it */
221         p_ccb->con_state = GAP_CCB_STATE_LISTENING;
222         return (p_ccb->gap_handle);
223     }
224     else
225     {
226         /* We are the originator of this connection */
227         p_ccb->con_flags = GAP_CCB_FLAGS_IS_ORIG;
228
229         /* Transition to the next appropriate state, waiting for connection confirm. */
230         p_ccb->con_state = GAP_CCB_STATE_CONN_SETUP;
231
232         /* mark security done flag, when security is not required */
233         if ((security & (BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT) ) == 0)
234             p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
235
236         /* Check if L2CAP started the connection process */
237         if (p_rem_bda && ((cid = L2CA_CONNECT_REQ (p_ccb->psm, p_rem_bda, &p_ccb->ertm_info)) != 0))
238         {
239             p_ccb->connection_id = cid;
240             return (p_ccb->gap_handle);
241         }
242         else
243         {
244             gap_release_ccb (p_ccb);
245             return (GAP_INVALID_HANDLE);
246         }
247     }
248 }
249
250
251 /*******************************************************************************
252 **
253 ** Function         GAP_ConnClose
254 **
255 ** Description      This function is called to close a connection.
256 **
257 ** Parameters:      handle      - Handle of the connection returned by GAP_ConnOpen
258 **
259 ** Returns          BT_PASS             - closed OK
260 **                  GAP_ERR_BAD_HANDLE  - invalid handle
261 **
262 *******************************************************************************/
263 UINT16 GAP_ConnClose (UINT16 gap_handle)
264 {
265     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
266
267     GAP_TRACE_EVENT ("GAP_CONN - close  handle: 0x%x", gap_handle);
268
269     if (p_ccb)
270     {
271         /* Check if we have a connection ID */
272         if (p_ccb->con_state != GAP_CCB_STATE_LISTENING)
273             L2CA_DISCONNECT_REQ (p_ccb->connection_id);
274
275         gap_release_ccb (p_ccb);
276
277         return (BT_PASS);
278     }
279
280     return (GAP_ERR_BAD_HANDLE);
281 }
282
283
284
285 /*******************************************************************************
286 **
287 ** Function         GAP_ConnReadData
288 **
289 ** Description      Normally not GKI aware application will call this function
290 **                  after receiving GAP_EVT_RXDATA event.
291 **
292 ** Parameters:      handle      - Handle of the connection returned in the Open
293 **                  p_data      - Data area
294 **                  max_len     - Byte count requested
295 **                  p_len       - Byte count received
296 **
297 ** Returns          BT_PASS             - data read
298 **                  GAP_ERR_BAD_HANDLE  - invalid handle
299 **                  GAP_NO_DATA_AVAIL   - no data available
300 **
301 *******************************************************************************/
302 UINT16 GAP_ConnReadData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
303 {
304     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
305     BT_HDR     *p_buf;
306     UINT16      copy_len;
307
308     if (!p_ccb)
309         return (GAP_ERR_BAD_HANDLE);
310
311     *p_len = 0;
312
313     p_buf = (BT_HDR *)GKI_getfirst (&p_ccb->rx_queue);
314     if (!p_buf)
315         return (GAP_NO_DATA_AVAIL);
316
317     GKI_disable();
318
319     while (max_len && p_buf)
320     {
321         copy_len = (p_buf->len > max_len)?max_len:p_buf->len;
322         max_len -= copy_len;
323         *p_len  += copy_len;
324         if (p_data)
325         {
326             memcpy (p_data, (UINT8 *)(p_buf + 1) + p_buf->offset, copy_len);
327             p_data += copy_len;
328         }
329
330         if (p_buf->len > copy_len)
331         {
332             p_buf->offset += copy_len;
333             p_buf->len    -= copy_len;
334             break;
335         }
336         else
337         {
338             if (max_len)
339             {
340                 p_buf = (BT_HDR *)GKI_getnext (p_buf);
341             }
342             GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));
343         }
344     }
345
346     p_ccb->rx_queue_size -= *p_len;
347
348     GKI_enable();
349
350     GAP_TRACE_EVENT ("GAP_ConnReadData - rx_queue_size left=%d, *p_len=%d",
351                                        p_ccb->rx_queue_size, *p_len);
352
353     return (BT_PASS);
354 }
355
356 /*******************************************************************************
357 **
358 ** Function         GAP_GetRxQueueCnt
359 **
360 ** Description      This function return number of bytes on the rx queue.
361 **
362 ** Parameters:      handle     - Handle returned in the GAP_ConnOpen
363 **                  p_rx_queue_count - Pointer to return queue count in.
364 **
365 **
366 *******************************************************************************/
367 int GAP_GetRxQueueCnt (UINT16 handle, UINT32 *p_rx_queue_count)
368 {
369     tGAP_CCB    *p_ccb;
370     int         rc = BT_PASS;
371
372     /* Check that handle is valid */
373     if (handle < GAP_MAX_CONNECTIONS)
374     {
375         p_ccb = &gap_cb.conn.ccb_pool[handle];
376
377         if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
378         {
379             *p_rx_queue_count = p_ccb->rx_queue_size;
380         }
381         else
382             rc = GAP_INVALID_HANDLE;
383     }
384     else
385         rc = GAP_INVALID_HANDLE;
386
387     GAP_TRACE_EVENT ("GAP_GetRxQueueCnt - rc = 0x%04x, rx_queue_count=%d",
388                                        rc , *p_rx_queue_count);
389
390     return (rc);
391 }
392
393 /*******************************************************************************
394 **
395 ** Function         GAP_ConnBTRead
396 **
397 ** Description      Bluetooth aware applications will call this function after receiving
398 **                  GAP_EVT_RXDATA event.
399 **
400 ** Parameters:      handle      - Handle of the connection returned in the Open
401 **                  pp_buf      - pointer to address of buffer with data,
402 **
403 ** Returns          BT_PASS             - data read
404 **                  GAP_ERR_BAD_HANDLE  - invalid handle
405 **                  GAP_NO_DATA_AVAIL   - no data available
406 **
407 *******************************************************************************/
408 UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf)
409 {
410     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
411     BT_HDR      *p_buf;
412
413     if (!p_ccb)
414         return (GAP_ERR_BAD_HANDLE);
415
416     p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->rx_queue);
417
418     if (p_buf)
419     {
420         *pp_buf = p_buf;
421
422         p_ccb->rx_queue_size -= p_buf->len;
423         return (BT_PASS);
424     }
425     else
426     {
427         *pp_buf = NULL;
428         return (GAP_NO_DATA_AVAIL);
429     }
430 }
431
432
433 /*******************************************************************************
434 **
435 ** Function         GAP_ConnBTWrite
436 **
437 ** Description      Bluetooth Aware applications can call this function to write data.
438 **
439 ** Parameters:      handle      - Handle of the connection returned in the Open
440 **                  p_buf      - pointer to address of buffer with data,
441 **
442 ** Returns          BT_PASS                 - data read
443 **                  GAP_ERR_BAD_HANDLE      - invalid handle
444 **                  GAP_ERR_BAD_STATE       - connection not established
445 **                  GAP_INVALID_BUF_OFFSET  - buffer offset is invalid
446 *******************************************************************************/
447 UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf)
448 {
449     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
450
451     if (!p_ccb)
452     {
453         GKI_freebuf (p_buf);
454         return (GAP_ERR_BAD_HANDLE);
455     }
456
457     if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
458     {
459         GKI_freebuf (p_buf);
460         return (GAP_ERR_BAD_STATE);
461     }
462
463     if (p_buf->offset < L2CAP_MIN_OFFSET)
464     {
465         GKI_freebuf (p_buf);
466         return (GAP_ERR_BUF_OFFSET);
467     }
468
469     GKI_enqueue (&p_ccb->tx_queue, p_buf);
470
471     if (p_ccb->is_congested)
472     {
473         return (BT_PASS);
474     }
475
476     /* Send the buffer through L2CAP */
477 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
478     gap_send_event (gap_handle);
479 #else
480     while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
481     {
482         UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
483
484         if (status == L2CAP_DW_CONGESTED)
485         {
486             p_ccb->is_congested = TRUE;
487             break;
488         }
489         else if (status != L2CAP_DW_SUCCESS)
490             return (GAP_ERR_BAD_STATE);
491     }
492 #endif
493     return (BT_PASS);
494 }
495
496
497 /*******************************************************************************
498 **
499 ** Function         GAP_ConnWriteData
500 **
501 ** Description      Normally not GKI aware application will call this function
502 **                  to send data to the connection.
503 **
504 ** Parameters:      handle      - Handle of the connection returned in the Open
505 **                  p_data      - Data area
506 **                  max_len     - Byte count requested
507 **                  p_len       - Byte count received
508 **
509 ** Returns          BT_PASS                 - data read
510 **                  GAP_ERR_BAD_HANDLE      - invalid handle
511 **                  GAP_ERR_BAD_STATE       - connection not established
512 **                  GAP_CONGESTION          - system is congested
513 **
514 *******************************************************************************/
515 UINT16 GAP_ConnWriteData (UINT16 gap_handle, UINT8 *p_data, UINT16 max_len, UINT16 *p_len)
516 {
517     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
518     BT_HDR     *p_buf;
519
520     *p_len = 0;
521
522     if (!p_ccb)
523         return (GAP_ERR_BAD_HANDLE);
524
525     if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
526         return (GAP_ERR_BAD_STATE);
527
528     while (max_len)
529     {
530         if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
531         {
532             if ((p_buf = (BT_HDR *)GKI_getpoolbuf (p_ccb->ertm_info.user_tx_pool_id)) == NULL)
533                 return (GAP_ERR_CONGESTED);
534         }
535         else
536         {
537             if ((p_buf = (BT_HDR *)GKI_getpoolbuf (GAP_DATA_POOL_ID)) == NULL)
538                 return (GAP_ERR_CONGESTED);
539         }
540
541         p_buf->offset = L2CAP_MIN_OFFSET;
542         p_buf->len = (p_ccb->rem_mtu_size < max_len) ? p_ccb->rem_mtu_size : max_len;
543         p_buf->event = BT_EVT_TO_BTU_SP_DATA;
544
545         memcpy ((UINT8 *)(p_buf + 1) + p_buf->offset, p_data, p_buf->len);
546
547         *p_len  += p_buf->len;
548         max_len -= p_buf->len;
549         p_data  += p_buf->len;
550
551         GAP_TRACE_EVENT ("GAP_WriteData %d bytes", p_buf->len);
552
553         GKI_enqueue (&p_ccb->tx_queue, p_buf);
554     }
555
556     if (p_ccb->is_congested)
557     {
558         return (BT_PASS);
559     }
560
561     /* Send the buffer through L2CAP */
562 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
563     gap_send_event (gap_handle);
564 #else
565     while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
566     {
567         UINT8 status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
568
569         if (status == L2CAP_DW_CONGESTED)
570         {
571             p_ccb->is_congested = TRUE;
572             break;
573         }
574         else if (status != L2CAP_DW_SUCCESS)
575             return (GAP_ERR_BAD_STATE);
576     }
577 #endif
578     return (BT_PASS);
579 }
580
581
582 /*******************************************************************************
583 **
584 ** Function         GAP_ConnReconfig
585 **
586 ** Description      Applications can call this function to reconfigure the connection.
587 **
588 ** Parameters:      handle      - Handle of the connection
589 **                  p_cfg       - Pointer to new configuration
590 **
591 ** Returns          BT_PASS                 - config process started
592 **                  GAP_ERR_BAD_HANDLE      - invalid handle
593 **
594 *******************************************************************************/
595 UINT16 GAP_ConnReconfig (UINT16 gap_handle, tL2CAP_CFG_INFO *p_cfg)
596 {
597     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
598
599     if (!p_ccb)
600         return (GAP_ERR_BAD_HANDLE);
601
602     p_ccb->cfg = *p_cfg;
603
604     if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
605         L2CA_CONFIG_REQ (p_ccb->connection_id, p_cfg);
606
607     return (BT_PASS);
608 }
609
610
611
612 /*******************************************************************************
613 **
614 ** Function         GAP_ConnSetIdleTimeout
615 **
616 ** Description      Higher layers call this function to set the idle timeout for
617 **                  a connection, or for all future connections. The "idle timeout"
618 **                  is the amount of time that a connection can remain up with
619 **                  no L2CAP channels on it. A timeout of zero means that the
620 **                  connection will be torn down immediately when the last channel
621 **                  is removed. A timeout of 0xFFFF means no timeout. Values are
622 **                  in seconds.
623 **
624 ** Parameters:      handle      - Handle of the connection
625 **                  timeout     - in secs
626 **                                0 = immediate disconnect when last channel is removed
627 **                                0xFFFF = no idle timeout
628 **
629 ** Returns          BT_PASS                 - config process started
630 **                  GAP_ERR_BAD_HANDLE      - invalid handle
631 **
632 *******************************************************************************/
633 UINT16 GAP_ConnSetIdleTimeout (UINT16 gap_handle, UINT16 timeout)
634 {
635     tGAP_CCB    *p_ccb;
636
637     if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
638         return (GAP_ERR_BAD_HANDLE);
639
640     if (L2CA_SetIdleTimeout (p_ccb->connection_id, timeout, FALSE))
641         return (BT_PASS);
642     else
643         return (GAP_ERR_BAD_HANDLE);
644 }
645
646
647
648 /*******************************************************************************
649 **
650 ** Function         GAP_ConnGetRemoteAddr
651 **
652 ** Description      This function is called to get the remote BD address
653 **                  of a connection.
654 **
655 ** Parameters:      handle      - Handle of the connection returned by GAP_ConnOpen
656 **
657 ** Returns          BT_PASS             - closed OK
658 **                  GAP_ERR_BAD_HANDLE  - invalid handle
659 **
660 *******************************************************************************/
661 UINT8 *GAP_ConnGetRemoteAddr (UINT16 gap_handle)
662 {
663     tGAP_CCB    *p_ccb = gap_find_ccb_by_handle (gap_handle);
664
665     GAP_TRACE_EVENT ("GAP_ConnGetRemoteAddr gap_handle = %d", gap_handle);
666
667     if ((p_ccb) && (p_ccb->con_state > GAP_CCB_STATE_LISTENING))
668     {
669         GAP_TRACE_EVENT("GAP_ConnGetRemoteAddr bda :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n", \
670                          p_ccb->rem_dev_address[0],p_ccb->rem_dev_address[1],p_ccb->rem_dev_address[2],
671                          p_ccb->rem_dev_address[3],p_ccb->rem_dev_address[4],p_ccb->rem_dev_address[5]);
672         return (p_ccb->rem_dev_address);
673     }
674     else
675     {
676         GAP_TRACE_EVENT ("GAP_ConnGetRemoteAddr return Error ");
677         return (NULL);
678     }
679 }
680
681
682 /*******************************************************************************
683 **
684 ** Function         GAP_ConnGetRemMtuSize
685 **
686 ** Description      Returns the remote device's MTU size
687 **
688 ** Parameters:      handle      - Handle of the connection
689 **
690 ** Returns          UINT16      - maximum size buffer that can be transmitted to the peer
691 **
692 *******************************************************************************/
693 UINT16 GAP_ConnGetRemMtuSize (UINT16 gap_handle)
694 {
695     tGAP_CCB    *p_ccb;
696
697     if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
698         return (0);
699
700     return (p_ccb->rem_mtu_size);
701 }
702
703 /*******************************************************************************
704 **
705 ** Function         GAP_ConnGetL2CAPCid
706 **
707 ** Description      Returns the L2CAP channel id
708 **
709 ** Parameters:      handle      - Handle of the connection
710 **
711 ** Returns          UINT16      - The L2CAP channel id
712 **                  0, if error
713 **
714 *******************************************************************************/
715 UINT16 GAP_ConnGetL2CAPCid (UINT16 gap_handle)
716 {
717     tGAP_CCB    *p_ccb;
718
719     if ((p_ccb = gap_find_ccb_by_handle (gap_handle)) == NULL)
720         return (0);
721
722     return (p_ccb->connection_id);
723 }
724
725
726 /*******************************************************************************
727 **
728 ** Function         gap_connect_ind
729 **
730 ** Description      This function handles an inbound connection indication
731 **                  from L2CAP. This is the case where we are acting as a
732 **                  server.
733 **
734 ** Returns          void
735 **
736 *******************************************************************************/
737 static void gap_connect_ind (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id)
738 {
739     UINT16       xx;
740     tGAP_CCB     *p_ccb;
741
742     /* See if we have a CCB listening for the connection */
743     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
744     {
745         if ((p_ccb->con_state == GAP_CCB_STATE_LISTENING)
746          && (p_ccb->psm == psm)
747          && ((p_ccb->rem_addr_specified == FALSE)
748            || (!memcmp (bd_addr, p_ccb->rem_dev_address, BD_ADDR_LEN))))
749             break;
750     }
751
752     if (xx == GAP_MAX_CONNECTIONS)
753     {
754         GAP_TRACE_WARNING("*******");
755         GAP_TRACE_WARNING("WARNING: GAP Conn Indication for Unexpected Bd Addr...Disconnecting");
756         GAP_TRACE_WARNING("*******");
757
758         /* Disconnect because it is an unexpected connection */
759         L2CA_DISCONNECT_REQ (l2cap_cid);
760         return;
761     }
762
763     /* Transition to the next appropriate state, waiting for config setup. */
764     p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
765
766     /* Save the BD Address and Channel ID. */
767     memcpy (&p_ccb->rem_dev_address[0], bd_addr, BD_ADDR_LEN);
768     p_ccb->connection_id = l2cap_cid;
769
770     /* Send response to the L2CAP layer. */
771     L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, &p_ccb->ertm_info);
772
773     GAP_TRACE_EVENT("GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x", p_ccb->connection_id);
774
775     /* Send a Configuration Request. */
776     L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
777 }
778
779 /*******************************************************************************
780 **
781 ** Function         gap_checks_con_flags
782 **
783 ** Description      This function processes the L2CAP configuration indication
784 **                  event.
785 **
786 ** Returns          void
787 **
788 *******************************************************************************/
789 static void gap_checks_con_flags (tGAP_CCB    *p_ccb)
790 {
791     GAP_TRACE_EVENT ("gap_checks_con_flags conn_flags:0x%x, ", p_ccb->con_flags);
792     /* if all the required con_flags are set, report the OPEN event now */
793     if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE)
794     {
795         p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
796
797         p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
798     }
799 }
800
801 /*******************************************************************************
802 **
803 ** Function         gap_sec_check_complete
804 **
805 ** Description      The function called when Security Manager finishes
806 **                  verification of the service side connection
807 **
808 ** Returns          void
809 **
810 *******************************************************************************/
811 static void gap_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
812 {
813     tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data;
814     UNUSED(bd_addr);
815     UNUSED (transport);
816
817     GAP_TRACE_EVENT ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d",
818         p_ccb->con_state, p_ccb->con_flags, res);
819     if (p_ccb->con_state == GAP_CCB_STATE_IDLE)
820         return;
821
822     if (res == BTM_SUCCESS)
823     {
824         p_ccb->con_flags |= GAP_CCB_FLAGS_SEC_DONE;
825         gap_checks_con_flags (p_ccb);
826     }
827     else
828     {
829         /* security failed - disconnect the channel */
830         L2CA_DISCONNECT_REQ (p_ccb->connection_id);
831     }
832 }
833
834 /*******************************************************************************
835 **
836 ** Function         gap_connect_cfm
837 **
838 ** Description      This function handles the connect confirm events
839 **                  from L2CAP. This is the case when we are acting as a
840 **                  client and have sent a connect request.
841 **
842 ** Returns          void
843 **
844 *******************************************************************************/
845 static void gap_connect_cfm (UINT16 l2cap_cid, UINT16 result)
846 {
847     tGAP_CCB    *p_ccb;
848
849     /* Find CCB based on CID */
850     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
851         return;
852
853     /* initiate security process, if needed */
854     if ( (p_ccb->con_flags & GAP_CCB_FLAGS_SEC_DONE) == 0)
855     {
856         btm_sec_mx_access_request (p_ccb->rem_dev_address, p_ccb->psm, TRUE,
857                                    0, 0, &gap_sec_check_complete, p_ccb);
858     }
859
860     /* If the connection response contains success status, then */
861     /* Transition to the next state and startup the timer.      */
862     if ((result == L2CAP_CONN_OK) && (p_ccb->con_state == GAP_CCB_STATE_CONN_SETUP))
863     {
864         p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
865
866         /* Send a Configuration Request. */
867         L2CA_CONFIG_REQ (l2cap_cid, &p_ccb->cfg);
868     }
869     else
870     {
871         /* Tell the user if he has a callback */
872         if (p_ccb->p_callback)
873             (*p_ccb->p_callback) (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
874
875         gap_release_ccb (p_ccb);
876     }
877 }
878
879 /*******************************************************************************
880 **
881 ** Function         gap_config_ind
882 **
883 ** Description      This function processes the L2CAP configuration indication
884 **                  event.
885 **
886 ** Returns          void
887 **
888 *******************************************************************************/
889 static void gap_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
890 {
891     tGAP_CCB    *p_ccb;
892     UINT16      local_mtu_size;
893
894     /* Find CCB based on CID */
895     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
896         return;
897
898     /* Remember the remote MTU size */
899
900     if (p_ccb->cfg.fcr.mode == L2CAP_FCR_ERTM_MODE)
901     {
902         local_mtu_size = GKI_get_pool_bufsize (p_ccb->ertm_info.user_tx_pool_id)
903                        - sizeof(BT_HDR) - L2CAP_MIN_OFFSET;
904     }
905     else
906         local_mtu_size = L2CAP_MTU_SIZE;
907
908     if ((!p_cfg->mtu_present)||(p_cfg->mtu > local_mtu_size))
909     {
910         p_ccb->rem_mtu_size = local_mtu_size;
911     }
912     else
913         p_ccb->rem_mtu_size = p_cfg->mtu;
914
915     /* For now, always accept configuration from the other side */
916     p_cfg->flush_to_present = FALSE;
917     p_cfg->mtu_present      = FALSE;
918     p_cfg->result           = L2CAP_CFG_OK;
919     p_cfg->fcs_present      = FALSE;
920
921     L2CA_CONFIG_RSP (l2cap_cid, p_cfg);
922
923     p_ccb->con_flags |= GAP_CCB_FLAGS_HIS_CFG_DONE;
924
925     gap_checks_con_flags (p_ccb);
926 }
927
928
929 /*******************************************************************************
930 **
931 ** Function         gap_config_cfm
932 **
933 ** Description      This function processes the L2CAP configuration confirmation
934 **                  event.
935 **
936 ** Returns          void
937 **
938 *******************************************************************************/
939 static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
940 {
941     tGAP_CCB    *p_ccb;
942
943     /* Find CCB based on CID */
944     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
945         return;
946
947     if (p_cfg->result == L2CAP_CFG_OK)
948     {
949         p_ccb->con_flags |= GAP_CCB_FLAGS_MY_CFG_DONE;
950
951
952         if (p_ccb->cfg.fcr_present)
953             p_ccb->cfg.fcr.mode = p_cfg->fcr.mode;
954         else
955             p_ccb->cfg.fcr.mode = L2CAP_FCR_BASIC_MODE;
956
957         gap_checks_con_flags (p_ccb);
958     }
959     else
960     {
961         p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
962         gap_release_ccb (p_ccb);
963     }
964 }
965
966
967 /*******************************************************************************
968 **
969 ** Function         gap_disconnect_ind
970 **
971 ** Description      This function handles a disconnect event from L2CAP. If
972 **                  requested to, we ack the disconnect before dropping the CCB
973 **
974 ** Returns          void
975 **
976 *******************************************************************************/
977 static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
978 {
979     tGAP_CCB    *p_ccb;
980
981     GAP_TRACE_EVENT ("GAP_CONN - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid);
982
983     /* Find CCB based on CID */
984     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
985         return;
986
987     if (ack_needed)
988         L2CA_DISCONNECT_RSP (l2cap_cid);
989
990     p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
991     gap_release_ccb (p_ccb);
992 }
993
994
995 /*******************************************************************************
996 **
997 ** Function         gap_data_ind
998 **
999 ** Description      This function is called when data is received from L2CAP.
1000 **
1001 ** Returns          void
1002 **
1003 *******************************************************************************/
1004 static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
1005 {
1006     tGAP_CCB    *p_ccb;
1007
1008     /* Find CCB based on CID */
1009     if ((p_ccb = gap_find_ccb_by_cid (l2cap_cid)) == NULL)
1010     {
1011         GKI_freebuf (p_msg);
1012         return;
1013     }
1014
1015     if (p_ccb->con_state == GAP_CCB_STATE_CONNECTED)
1016     {
1017         GKI_enqueue (&p_ccb->rx_queue, p_msg);
1018
1019         p_ccb->rx_queue_size += p_msg->len;
1020         /*
1021         GAP_TRACE_EVENT ("gap_data_ind - rx_queue_size=%d, msg len=%d",
1022                                        p_ccb->rx_queue_size, p_msg->len);
1023          */
1024
1025         p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
1026     }
1027     else
1028     {
1029         GKI_freebuf (p_msg);
1030     }
1031 }
1032
1033
1034 /*******************************************************************************
1035 **
1036 ** Function         gap_congestion_ind
1037 **
1038 ** Description      This is a callback function called by L2CAP when
1039 **                  data L2CAP congestion status changes
1040 **
1041 *******************************************************************************/
1042 static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested)
1043 {
1044     tGAP_CCB    *p_ccb;
1045     UINT16       event;
1046     BT_HDR      *p_buf;
1047     UINT8        status;
1048
1049     GAP_TRACE_EVENT ("GAP_CONN - Rcvd L2CAP Is Congested (%d), CID: 0x%x",
1050                       is_congested, lcid);
1051
1052     /* Find CCB based on CID */
1053     if ((p_ccb = gap_find_ccb_by_cid (lcid)) == NULL)
1054         return;
1055
1056     p_ccb->is_congested = is_congested;
1057
1058     event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED;
1059     p_ccb->p_callback (p_ccb->gap_handle, event);
1060
1061     if (!is_congested)
1062     {
1063         while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
1064         {
1065             status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
1066
1067             if (status == L2CAP_DW_CONGESTED)
1068             {
1069                 p_ccb->is_congested = TRUE;
1070                 break;
1071             }
1072             else if (status != L2CAP_DW_SUCCESS)
1073                 break;
1074         }
1075     }
1076 }
1077
1078
1079 /*******************************************************************************
1080 **
1081 ** Function         gap_find_ccb_by_cid
1082 **
1083 ** Description      This function searches the CCB table for an entry with the
1084 **                  passed CID.
1085 **
1086 ** Returns          the CCB address, or NULL if not found.
1087 **
1088 *******************************************************************************/
1089 static tGAP_CCB *gap_find_ccb_by_cid (UINT16 cid)
1090 {
1091     UINT16       xx;
1092     tGAP_CCB     *p_ccb;
1093
1094     /* Look through each connection control block */
1095     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
1096     {
1097         if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->connection_id == cid))
1098             return (p_ccb);
1099     }
1100
1101     /* If here, not found */
1102     return (NULL);
1103 }
1104
1105
1106 /*******************************************************************************
1107 **
1108 ** Function         gap_find_ccb_by_handle
1109 **
1110 ** Description      This function searches the CCB table for an entry with the
1111 **                  passed handle.
1112 **
1113 ** Returns          the CCB address, or NULL if not found.
1114 **
1115 *******************************************************************************/
1116 static tGAP_CCB *gap_find_ccb_by_handle (UINT16 handle)
1117 {
1118     tGAP_CCB     *p_ccb;
1119
1120     /* Check that handle is valid */
1121     if (handle < GAP_MAX_CONNECTIONS)
1122     {
1123         p_ccb = &gap_cb.conn.ccb_pool[handle];
1124
1125         if (p_ccb->con_state != GAP_CCB_STATE_IDLE)
1126             return (p_ccb);
1127     }
1128
1129     /* If here, handle points to invalid connection */
1130     return (NULL);
1131 }
1132
1133
1134 /*******************************************************************************
1135 **
1136 ** Function         gap_allocate_ccb
1137 **
1138 ** Description      This function allocates a new CCB.
1139 **
1140 ** Returns          CCB address, or NULL if none available.
1141 **
1142 *******************************************************************************/
1143 static tGAP_CCB *gap_allocate_ccb (void)
1144 {
1145     UINT16       xx;
1146     tGAP_CCB     *p_ccb;
1147
1148     /* Look through each connection control block for a free one */
1149     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
1150     {
1151         if (p_ccb->con_state == GAP_CCB_STATE_IDLE)
1152         {
1153             memset (p_ccb, 0, sizeof (tGAP_CCB));
1154
1155             p_ccb->gap_handle   = xx;
1156             p_ccb->rem_mtu_size = L2CAP_MTU_SIZE;
1157
1158             return (p_ccb);
1159         }
1160     }
1161
1162     /* If here, no free CCB found */
1163     return (NULL);
1164 }
1165
1166
1167 /*******************************************************************************
1168 **
1169 ** Function         gap_release_ccb
1170 **
1171 ** Description      This function releases a CCB.
1172 **
1173 ** Returns          void
1174 **
1175 *******************************************************************************/
1176 static void gap_release_ccb (tGAP_CCB *p_ccb)
1177 {
1178     UINT16       xx;
1179     UINT16      psm = p_ccb->psm;
1180     UINT8       service_id = p_ccb->service_id;
1181
1182     /* Drop any buffers we may be holding */
1183     p_ccb->rx_queue_size = 0;
1184
1185     while (p_ccb->rx_queue._p_first)
1186         GKI_freebuf (GKI_dequeue (&p_ccb->rx_queue));
1187
1188     while (p_ccb->tx_queue._p_first)
1189         GKI_freebuf (GKI_dequeue (&p_ccb->tx_queue));
1190
1191     p_ccb->con_state = GAP_CCB_STATE_IDLE;
1192
1193     /* If no-one else is using the PSM, deregister from L2CAP */
1194     for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++)
1195     {
1196         if ((p_ccb->con_state != GAP_CCB_STATE_IDLE) && (p_ccb->psm == psm))
1197             return;
1198     }
1199
1200     /* Free the security record for this PSM */
1201     BTM_SecClrService(service_id);
1202     L2CA_DEREGISTER (psm);
1203 }
1204
1205 #if (GAP_CONN_POST_EVT_INCLUDED == TRUE)
1206
1207 /*******************************************************************************
1208 **
1209 ** Function     gap_send_event
1210 **
1211 ** Description  Send BT_EVT_TO_GAP_MSG event to BTU task
1212 **
1213 ** Returns      None
1214 **
1215 *******************************************************************************/
1216 void gap_send_event (UINT16 gap_handle)
1217 {
1218     BT_HDR  *p_msg;
1219
1220     if ((p_msg = (BT_HDR*)GKI_getbuf(BT_HDR_SIZE)) != NULL)
1221     {
1222         p_msg->event  = BT_EVT_TO_GAP_MSG;
1223         p_msg->len    = 0;
1224         p_msg->offset = 0;
1225         p_msg->layer_specific = gap_handle;
1226
1227         GKI_send_msg(BTU_TASK, BTU_HCI_RCV_MBOX, p_msg);
1228     }
1229     else
1230     {
1231         GAP_TRACE_ERROR("Unable to allocate message buffer for event.");
1232     }
1233 }
1234
1235 /*******************************************************************************
1236 **
1237 ** Function     gap_proc_btu_event
1238 **
1239 ** Description  Event handler for BT_EVT_TO_GAP_MSG event from BTU task
1240 **
1241 ** Returns      None
1242 **
1243 *******************************************************************************/
1244 void gap_proc_btu_event(BT_HDR *p_msg)
1245 {
1246     tGAP_CCB   *p_ccb = gap_find_ccb_by_handle (p_msg->layer_specific);
1247     UINT8       status;
1248     BT_HDR     *p_buf;
1249
1250     if (!p_ccb)
1251     {
1252         return;
1253     }
1254
1255     if (p_ccb->con_state != GAP_CCB_STATE_CONNECTED)
1256     {
1257         return;
1258     }
1259
1260     if (p_ccb->is_congested)
1261     {
1262         return;
1263     }
1264
1265     /* Send the buffer through L2CAP */
1266
1267     while ((p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->tx_queue)) != NULL)
1268     {
1269         status = L2CA_DATA_WRITE (p_ccb->connection_id, p_buf);
1270
1271         if (status == L2CAP_DW_CONGESTED)
1272         {
1273             p_ccb->is_congested = TRUE;
1274             break;
1275         }
1276         else if (status != L2CAP_DW_SUCCESS)
1277             break;
1278     }
1279
1280 }
1281 #endif /* (GAP_CONN_POST_EVT_INCLUDED == TRUE) */
1282 #endif  /* GAP_CONN_INCLUDED */