nfa_p2p_act.c revision 63f80ce896f0f8c203191b4e44e038fecb6be02a
1/*****************************************************************************
2**
3**  Name:           nfa_p2p_act.c
4**
5**  Description:    This is the implementation file for the NFA P2P.
6**
7**  Copyright (c) 2010-2011, Broadcom Corp., All Rights Reserved.
8**  Broadcom Bluetooth Core. Proprietary and confidential.
9**
10*****************************************************************************/
11
12#include "string.h"
13#include "nfc_api.h"
14#include "nfa_sys.h"
15#include "nfa_sys_int.h"
16#include "nfa_dm_int.h"
17#include "llcp_defs.h"
18#include "llcp_api.h"
19#include "nfa_p2p_api.h"
20#include "nfa_p2p_int.h"
21
22/*****************************************************************************
23**  Global Variables
24*****************************************************************************/
25
26/*****************************************************************************
27**  Static Functions
28*****************************************************************************/
29
30/*****************************************************************************
31**  Constants
32*****************************************************************************/
33
34/*******************************************************************************
35**
36** Function         nfa_p2p_allocate_conn_cb
37**
38** Description      Allocate data link connection control block
39**
40**
41** Returns          UINT8
42**
43*******************************************************************************/
44static UINT8 nfa_p2p_allocate_conn_cb (UINT8 local_sap)
45{
46    UINT8 xx;
47
48    for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
49    {
50        if (nfa_p2p_cb.conn_cb[xx].flags == 0)
51        {
52            nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_IN_USE;
53            nfa_p2p_cb.conn_cb[xx].local_sap = local_sap;
54
55            return (xx);
56        }
57    }
58
59    P2P_TRACE_ERROR0 ("nfa_p2p_allocate_conn_cb (): No resource");
60
61    return LLCP_MAX_DATA_LINK;
62}
63
64/*******************************************************************************
65**
66** Function         nfa_p2p_deallocate_conn_cb
67**
68** Description      Deallocate data link connection control block
69**
70**
71** Returns          void
72**
73*******************************************************************************/
74static void nfa_p2p_deallocate_conn_cb (UINT8 xx)
75{
76    if (xx < LLCP_MAX_DATA_LINK)
77    {
78        nfa_p2p_cb.conn_cb[xx].flags = 0;
79    }
80    else
81    {
82        P2P_TRACE_ERROR1 ("nfa_p2p_deallocate_conn_cb (): Invalid index (%d)", xx);
83    }
84}
85
86/*******************************************************************************
87**
88** Function         nfa_p2p_find_conn_cb
89**
90** Description      Find data link connection control block by local/remote SAP
91**
92**
93** Returns          UINT8
94**
95*******************************************************************************/
96static UINT8 nfa_p2p_find_conn_cb (UINT8 local_sap, UINT8 remote_sap)
97{
98    UINT8 xx;
99
100    for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
101    {
102        if (  (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
103            &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap)
104            &&(nfa_p2p_cb.conn_cb[xx].remote_sap == remote_sap)  )
105        {
106            return (xx);
107        }
108    }
109
110    return (LLCP_MAX_DATA_LINK);
111}
112
113/*******************************************************************************
114**
115** Function         nfa_p2p_llcp_cback
116**
117** Description      Processing SAP callback events from LLCP
118**
119**
120** Returns          None
121**
122*******************************************************************************/
123static void nfa_p2p_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data)
124{
125    P2P_TRACE_DEBUG2 ("nfa_p2p_llcp_cback (): event:0x%02X, local_sap:0x%02X", p_data->hdr.event, p_data->hdr.local_sap);
126
127    switch (p_data->hdr.event)
128    {
129    case LLCP_SAP_EVT_DATA_IND:
130         nfa_p2p_proc_llcp_data_ind (p_data);
131        break;
132
133    case LLCP_SAP_EVT_CONNECT_IND:
134        nfa_p2p_proc_llcp_connect_ind (p_data);
135        break;
136
137    case LLCP_SAP_EVT_CONNECT_RESP:
138        nfa_p2p_proc_llcp_connect_resp (p_data);
139        break;
140
141    case LLCP_SAP_EVT_DISCONNECT_IND:
142        nfa_p2p_proc_llcp_disconnect_ind (p_data);
143        break;
144
145    case LLCP_SAP_EVT_DISCONNECT_RESP:
146        nfa_p2p_proc_llcp_disconnect_resp (p_data);
147        break;
148
149    case LLCP_SAP_EVT_CONGEST:
150        nfa_p2p_proc_llcp_congestion (p_data);
151        break;
152
153    case LLCP_SAP_EVT_LINK_STATUS:
154        nfa_p2p_proc_llcp_link_status (p_data);
155        break;
156
157    default:
158        P2P_TRACE_ERROR1 ("nfa_p2p_llcp_cback (): Unknown event:0x%02X", p_data->hdr.event);
159        return;
160    }
161}
162
163/*******************************************************************************
164**
165** Function         nfa_p2p_sdp_cback
166**
167** Description      Process SDP callback event from LLCP
168**
169**
170** Returns          None
171**
172*******************************************************************************/
173void nfa_p2p_sdp_cback (UINT8 tid, UINT8 remote_sap)
174{
175    UINT8             local_sap;
176    UINT8             xx;
177    tNFA_P2P_EVT_DATA evt_data;
178
179    P2P_TRACE_DEBUG2 ("nfa_p2p_sdp_cback (): tid:0x%02X, remote_sap:0x%02X", tid, remote_sap);
180
181    /* search for callback function to process */
182    for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++)
183    {
184        if (  (nfa_p2p_cb.sdp_cb[xx].local_sap != LLCP_INVALID_SAP)
185            &&(nfa_p2p_cb.sdp_cb[xx].tid == tid)  )
186        {
187            local_sap = nfa_p2p_cb.sdp_cb[xx].local_sap;
188
189            evt_data.sdp.handle     = (NFA_HANDLE_GROUP_P2P | local_sap);
190            evt_data.sdp.remote_sap = remote_sap;
191            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_SDP_EVT, &evt_data);
192
193            nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP;
194            break;
195        }
196    }
197}
198
199/*******************************************************************************
200**
201** Function         nfa_p2p_start_sdp
202**
203** Description      Initiate SDP
204**
205**
206** Returns          TRUE if success
207**
208*******************************************************************************/
209BOOLEAN nfa_p2p_start_sdp (char *p_service_name, UINT8 local_sap)
210{
211    int xx;
212
213    P2P_TRACE_DEBUG1 ("nfa_p2p_start_sdp (): SN:<%s>", p_service_name);
214
215    /* search for empty slot */
216    for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++)
217    {
218        if (nfa_p2p_cb.sdp_cb[xx].local_sap == LLCP_INVALID_SAP)
219        {
220            if (LLCP_DiscoverService (p_service_name,
221                                      nfa_p2p_sdp_cback,
222                                      &(nfa_p2p_cb.sdp_cb[xx].tid)) == LLCP_STATUS_SUCCESS)
223            {
224                nfa_p2p_cb.sdp_cb[xx].local_sap    = local_sap;
225                return TRUE;
226            }
227            else
228            {
229                /* failure of SDP */
230                return FALSE;
231            }
232        }
233    }
234    return FALSE;
235}
236
237/*******************************************************************************
238**
239** Function         nfa_p2p_proc_llcp_data_ind
240**
241** Description      Processing incoming data event from LLCP
242**
243**
244** Returns          None
245**
246*******************************************************************************/
247void nfa_p2p_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA  *p_data)
248{
249    UINT8             local_sap, xx;
250    tNFA_P2P_EVT_DATA evt_data;
251
252    P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_data_ind ()");
253
254    local_sap = p_data->data_ind.local_sap;
255
256    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
257    {
258        evt_data.data.handle    = 0;
259        /* if connectionless */
260        if (p_data->data_ind.link_type == NFA_P2P_LLINK_TYPE)
261        {
262            evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
263        }
264        else
265        {
266            xx = nfa_p2p_find_conn_cb (p_data->data_ind.local_sap,
267                                       p_data->data_ind.remote_sap);
268
269            if (xx != LLCP_MAX_DATA_LINK)
270            {
271                evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
272            }
273        }
274
275        evt_data.data.remote_sap = p_data->data_ind.remote_sap;
276        evt_data.data.link_type  = p_data->data_ind.link_type;
277
278        /* notify upper layer that there are data at LLCP */
279        nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DATA_EVT, &evt_data);
280    }
281}
282
283/*******************************************************************************
284**
285** Function         nfa_p2p_proc_llcp_connect_ind
286**
287** Description      Processing connection request from peer
288**
289**
290** Returns          None
291**
292*******************************************************************************/
293void nfa_p2p_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA  *p_data)
294{
295    UINT8             server_sap, local_sap;
296    tNFA_P2P_EVT_DATA evt_data;
297    UINT8             xx;
298
299    P2P_TRACE_DEBUG1 ("nfa_p2p_proc_llcp_connect_ind () server_sap:0x%x",
300                       p_data->connect_ind.server_sap);
301
302    server_sap = p_data->connect_ind.server_sap;
303    local_sap  = p_data->connect_ind.local_sap;
304
305    if (nfa_p2p_cb.sap_cb[server_sap].p_cback)
306    {
307        xx = nfa_p2p_allocate_conn_cb (server_sap);
308
309        if (xx != LLCP_MAX_DATA_LINK)
310        {
311            nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_ind.remote_sap;
312            nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_ind.miu;
313
314            /* peer will not receive any data */
315            if (p_data->connect_ind.rw == 0)
316                nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO;
317
318            evt_data.conn_req.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
319            evt_data.conn_req.conn_handle   = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
320            evt_data.conn_req.remote_sap    = p_data->connect_ind.remote_sap;
321            evt_data.conn_req.remote_miu    = p_data->connect_ind.miu;
322            evt_data.conn_req.remote_rw     = p_data->connect_ind.rw;
323
324            nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_CONN_REQ_EVT, &evt_data);
325        }
326    }
327    else
328    {
329        P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_connect_ind (): Not registered");
330    }
331}
332
333/*******************************************************************************
334**
335** Function         nfa_p2p_proc_llcp_connect_resp
336**
337** Description      Processing connection response from peer
338**
339**
340** Returns          None
341**
342*******************************************************************************/
343void nfa_p2p_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA  *p_data)
344{
345    UINT8             local_sap, xx;
346    tNFA_P2P_EVT_DATA evt_data;
347
348    P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_connect_resp ()");
349
350    local_sap  = p_data->connect_resp.local_sap;
351
352    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
353    {
354        xx = nfa_p2p_allocate_conn_cb (local_sap);
355
356        if (xx != LLCP_MAX_DATA_LINK)
357        {
358            nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_resp.remote_sap;
359            nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_resp.miu;
360
361            /* peer will not receive any data */
362            if (p_data->connect_resp.rw == 0)
363                nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO;
364
365            evt_data.connected.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap);
366            evt_data.connected.conn_handle   = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
367            evt_data.connected.remote_sap    = p_data->connect_resp.remote_sap;
368            evt_data.connected.remote_miu    = p_data->connect_resp.miu;
369            evt_data.connected.remote_rw     = p_data->connect_resp.rw;
370
371            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONNECTED_EVT, &evt_data);
372        }
373    }
374}
375
376/*******************************************************************************
377**
378** Function         nfa_p2p_proc_llcp_disconnect_ind
379**
380** Description      Processing disconnection request from peer
381**
382**
383** Returns          None
384**
385*******************************************************************************/
386void nfa_p2p_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA  *p_data)
387{
388    UINT8             local_sap, xx;
389    tNFA_P2P_EVT_DATA evt_data;
390
391    P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_disconnect_ind ()");
392
393    local_sap  = p_data->disconnect_ind.local_sap;
394
395    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
396    {
397        xx = nfa_p2p_find_conn_cb (p_data->disconnect_ind.local_sap,
398                                   p_data->disconnect_ind.remote_sap);
399
400        if (xx != LLCP_MAX_DATA_LINK)
401        {
402            evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
403            evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_INITIATE;
404
405            nfa_p2p_deallocate_conn_cb (xx);
406
407            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
408        }
409        else
410        {
411            /*
412            ** LLCP link has been deactivated before receiving CC or DM.
413            ** Return NFA_P2P_DISC_EVT to indicate failure of creating connection
414            */
415
416            evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
417            evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
418
419            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
420
421            P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_disconnect_ind (): Link deactivated");
422        }
423    }
424}
425
426/*******************************************************************************
427**
428** Function         nfa_p2p_proc_llcp_disconnect_resp
429**
430** Description      Processing rejected connection from peer
431**
432**
433** Returns          None
434**
435*******************************************************************************/
436void nfa_p2p_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA  *p_data)
437{
438    UINT8             local_sap, xx;
439    tNFA_P2P_EVT_DATA evt_data = {0};
440
441    P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_disconnect_resp ()");
442
443    local_sap  = p_data->disconnect_resp.local_sap;
444
445    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
446    {
447        if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_RESP_DISC)
448        {
449            evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE;
450        }
451        else if (  (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_APP_REJECTED)
452                 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_PERM_REJECT_THIS)
453                 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_PERM_REJECT_ANY)
454                 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_TEMP_REJECT_THIS)
455                 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_TEMP_REJECT_ANY)  )
456        {
457            evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_REJECT;
458        }
459        else if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_NO_SERVICE)
460        {
461            evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_SERVICE;
462        }
463
464        if (evt_data.disc.reason == NFA_P2P_DISC_REASON_LOCAL_INITITATE)
465        {
466            xx = nfa_p2p_find_conn_cb (p_data->disconnect_resp.local_sap,
467                                       p_data->disconnect_resp.remote_sap);
468
469            if (xx != LLCP_MAX_DATA_LINK)
470            {
471                evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
472
473                nfa_p2p_deallocate_conn_cb (xx);
474
475                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
476            }
477            else
478            {
479                P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_disconnect_resp (): No connection found");
480            }
481        }
482        else
483        {
484            evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
485            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
486        }
487    }
488}
489
490/*******************************************************************************
491**
492** Function         nfa_p2p_proc_llcp_congest
493**
494** Description      Processing LLCP congestion event
495**
496**
497** Returns          None
498**
499*******************************************************************************/
500void nfa_p2p_proc_llcp_congestion (tLLCP_SAP_CBACK_DATA  *p_data)
501{
502    UINT8             local_sap, remote_sap, xx;
503    tNFA_P2P_EVT_DATA evt_data;
504
505    local_sap  = p_data->congest.local_sap;
506    remote_sap = p_data->congest.remote_sap;
507
508    evt_data.congest.link_type    = p_data->congest.link_type;
509    evt_data.congest.is_congested = p_data->congest.is_congested;
510
511    if (p_data->congest.is_congested)
512    {
513        P2P_TRACE_DEBUG2 ("nfa_p2p_proc_llcp_congestion () START SAP=(0x%x,0x%x)",
514                          local_sap, remote_sap);
515
516    }
517    else
518    {
519        P2P_TRACE_DEBUG2 ("nfa_p2p_proc_llcp_congestion () END SAP=(0x%x,0x%x)",
520                          local_sap, remote_sap);
521    }
522
523    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
524    {
525        if (evt_data.congest.link_type == NFA_P2P_LLINK_TYPE)
526        {
527            evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
528
529            if (  (evt_data.congest.is_congested == FALSE)
530                &&(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED)  )
531            {
532                nfa_p2p_cb.sap_cb[local_sap].flags &= ~NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
533                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
534            }
535            else if (  (evt_data.congest.is_congested == TRUE)
536                     &&(!(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED))  )
537            {
538                /* this is overall congestion due to high usage of buffer pool */
539                nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
540                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
541            }
542        }
543        else
544        {
545            xx = nfa_p2p_find_conn_cb (local_sap, remote_sap);
546
547            if (xx != LLCP_MAX_DATA_LINK)
548            {
549                evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
550
551                if (  (evt_data.congest.is_congested == FALSE)
552                    &&(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)  )
553                {
554                    nfa_p2p_cb.conn_cb[xx].flags &= ~NFA_P2P_CONN_FLAG_CONGESTED;
555                    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
556                }
557                else if (  (evt_data.congest.is_congested == TRUE)
558                         &&(!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED))  )
559                {
560                    /* this is overall congestion due to high usage of buffer pool */
561                    nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
562                    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
563                }
564            }
565            else
566            {
567                P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_congestion (): No connection found");
568            }
569        }
570    }
571}
572
573/*******************************************************************************
574**
575** Function         nfa_p2p_proc_llcp_link_status
576**
577** Description      Processing LLCP link status
578**
579**
580** Returns          next state after processing this event
581**
582*******************************************************************************/
583void nfa_p2p_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA  *p_data)
584{
585    UINT8             local_sap, xx;
586    tNFA_P2P_EVT_DATA evt_data;
587
588    P2P_TRACE_DEBUG1 ("nfa_p2p_proc_llcp_link_status () is_activated:%d",
589                       p_data->link_status.is_activated);
590
591    local_sap  = p_data->link_status.local_sap;
592
593    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
594    {
595        if (p_data->link_status.is_activated)
596        {
597            /* only for server */
598            evt_data.activated.handle           = (NFA_HANDLE_GROUP_P2P | local_sap);
599            evt_data.activated.local_link_miu   = nfa_p2p_cb.local_link_miu;
600            evt_data.activated.remote_link_miu  = nfa_p2p_cb.remote_link_miu;
601
602            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
603        }
604        else /* if LLCP link is deactivated */
605        {
606            for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
607            {
608                if (  (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
609                    &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap))
610                {
611                    evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
612                    evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
613
614                    nfa_p2p_deallocate_conn_cb (xx);
615                    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
616                }
617            }
618
619            /* notify deactivation and clear flags */
620            if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_SERVER)
621            {
622                evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
623                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DEACTIVATED_EVT, &evt_data);
624
625                nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_SERVER;
626            }
627            else if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_CLIENT)
628            {
629                evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
630                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DEACTIVATED_EVT, &evt_data);
631
632                nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_CLIENT;
633            }
634            else /* if this is not registered service */
635            {
636                nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL;
637            }
638        }
639    }
640}
641
642/*******************************************************************************
643**
644** Function         nfa_p2p_reg_server
645**
646** Description      Allocate a service as server and register to LLCP
647**
648**
649** Returns          FALSE if need to keep buffer
650**
651*******************************************************************************/
652BOOLEAN nfa_p2p_reg_server (tNFA_P2P_MSG *p_msg)
653{
654    tNFA_P2P_EVT_DATA  evt_data;
655    UINT8              server_sap;
656
657    P2P_TRACE_DEBUG0 ("nfa_p2p_reg_server ()");
658
659    server_sap = LLCP_RegisterServer (p_msg->api_reg_server.server_sap,
660                                      p_msg->api_reg_server.link_type,
661                                      p_msg->api_reg_server.service_name,
662                                      nfa_p2p_llcp_cback);
663
664    if (server_sap == LLCP_INVALID_SAP)
665    {
666        evt_data.reg_server.server_handle = NFA_HANDLE_INVALID;
667        evt_data.reg_server.server_sap    = NFA_P2P_INVALID_SAP;
668        BCM_STRNCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name),
669                       p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
670        evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
671
672        p_msg->api_reg_server.p_cback (NFA_P2P_REG_SERVER_EVT, &evt_data);
673
674        return TRUE;
675    }
676
677    /* if need to update WKS in LLCP Gen bytes */
678    if (server_sap <= LLCP_UPPER_BOUND_WK_SAP)
679    {
680        nfa_p2p_enable_listening (NFA_ID_P2P, TRUE);
681    }
682    else if (!nfa_p2p_cb.is_p2p_listening)
683    {
684        nfa_p2p_enable_listening (NFA_ID_P2P, FALSE);
685    }
686
687    nfa_p2p_cb.sap_cb[server_sap].p_cback    = p_msg->api_reg_server.p_cback;
688    nfa_p2p_cb.sap_cb[server_sap].flags      = NFA_P2P_SAP_FLAG_SERVER;
689
690    evt_data.reg_server.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
691    evt_data.reg_server.server_sap    = server_sap;
692    BCM_STRNCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name),
693                   p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
694    evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
695
696    /* notify NFA_P2P_REG_SERVER_EVT to server */
697    nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_REG_SERVER_EVT, &evt_data);
698
699    /* if LLCP is already activated */
700    if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED)
701    {
702        evt_data.activated.handle          = (NFA_HANDLE_GROUP_P2P | server_sap);
703        evt_data.activated.local_link_miu  = nfa_p2p_cb.local_link_miu;
704        evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
705
706        /* notify NFA_P2P_ACTIVATED_EVT to server */
707        nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
708    }
709
710    return TRUE;
711}
712
713/*******************************************************************************
714**
715** Function         nfa_p2p_reg_client
716**
717** Description      Allocate a service as client and register to LLCP
718**
719**
720** Returns          TRUE to deallocate buffer
721**
722*******************************************************************************/
723BOOLEAN nfa_p2p_reg_client (tNFA_P2P_MSG *p_msg)
724{
725    tNFA_P2P_EVT_DATA  evt_data;
726    UINT8              local_sap;
727
728    P2P_TRACE_DEBUG0 ("nfa_p2p_reg_client ()");
729
730    local_sap = LLCP_RegisterClient (p_msg->api_reg_client.link_type,
731                                     nfa_p2p_llcp_cback);
732
733    if (local_sap == LLCP_INVALID_SAP)
734    {
735        evt_data.reg_client.client_handle = NFA_HANDLE_INVALID;
736        p_msg->api_reg_client.p_cback (NFA_P2P_REG_CLIENT_EVT, &evt_data);
737        return TRUE;
738    }
739
740    nfa_p2p_cb.sap_cb[local_sap].p_cback = p_msg->api_reg_client.p_cback;
741    nfa_p2p_cb.sap_cb[local_sap].flags   = NFA_P2P_SAP_FLAG_CLIENT;
742
743    evt_data.reg_client.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap);
744    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_REG_CLIENT_EVT, &evt_data);
745
746    /* if LLCP is already activated */
747    if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED)
748    {
749        evt_data.activated.handle           = (NFA_HANDLE_GROUP_P2P | local_sap);
750        evt_data.activated.local_link_miu   = nfa_p2p_cb.local_link_miu;
751        evt_data.activated.remote_link_miu  = nfa_p2p_cb.remote_link_miu;
752
753        /* notify NFA_P2P_ACTIVATED_EVT to client */
754        nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
755    }
756
757    return TRUE;
758}
759
760/*******************************************************************************
761**
762** Function         nfa_p2p_dereg
763**
764** Description      Deallocate a service as server or client and deregister to LLCP
765**                  LLCP will deallocate data link connection created by this server
766**
767** Returns          TRUE to deallocate buffer
768**
769*******************************************************************************/
770BOOLEAN nfa_p2p_dereg (tNFA_P2P_MSG *p_msg)
771{
772    UINT8 local_sap, xx;
773
774    P2P_TRACE_DEBUG0 ("nfa_p2p_dereg ()");
775
776    local_sap = (UINT8) (p_msg->api_dereg.handle & NFA_HANDLE_MASK);
777
778    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
779    {
780        for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
781        {
782            if (  (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
783                &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap)  )
784            {
785                nfa_p2p_deallocate_conn_cb (xx);
786            }
787        }
788    }
789
790    LLCP_Deregister (local_sap);
791    nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL;
792
793    if (nfa_p2p_cb.is_p2p_listening)
794    {
795        /* check if this is the last server on NFA P2P */
796        for (xx = 0; xx < NFA_P2P_NUM_SAP; xx++)
797        {
798            if (  (nfa_p2p_cb.sap_cb[xx].p_cback)
799                &&(nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_SERVER)  )
800            {
801                break;
802            }
803        }
804
805        if (xx >= NFA_P2P_NUM_SAP)
806        {
807            /* if need to update WKS in LLCP Gen bytes */
808            if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
809                nfa_p2p_disable_listening (NFA_ID_P2P, TRUE);
810            else
811                nfa_p2p_disable_listening (NFA_ID_P2P, FALSE);
812        }
813        /* if need to update WKS in LLCP Gen bytes */
814        else if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
815        {
816            nfa_p2p_enable_listening (NFA_ID_P2P, TRUE);
817        }
818    }
819
820    return TRUE;
821}
822
823/*******************************************************************************
824**
825** Function         nfa_p2p_accept_connection
826**
827** Description      Connection Confirm from local application
828**
829**
830** Returns          TRUE to deallocate buffer
831**
832*******************************************************************************/
833BOOLEAN nfa_p2p_accept_connection (tNFA_P2P_MSG *p_msg)
834{
835    UINT8                   xx;
836    tLLCP_CONNECTION_PARAMS params;
837
838    P2P_TRACE_DEBUG0 ("nfa_p2p_accept_connection ()");
839
840    xx  = (UINT8) (p_msg->api_accept.conn_handle & NFA_HANDLE_MASK);
841    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
842
843    params.miu   = p_msg->api_accept.miu;
844    params.rw    = p_msg->api_accept.rw;
845    params.sn[0] = 0;
846
847    LLCP_ConnectCfm (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap, &params);
848
849    return TRUE;
850}
851
852/*******************************************************************************
853**
854** Function         nfa_p2p_reject_connection
855**
856** Description      Reject connection by local application
857**
858**
859** Returns          TRUE to deallocate buffer
860**
861*******************************************************************************/
862BOOLEAN nfa_p2p_reject_connection (tNFA_P2P_MSG *p_msg)
863{
864    UINT8 xx;
865
866    P2P_TRACE_DEBUG0 ("nfa_p2p_reject_connection ()");
867
868    xx  = (UINT8) (p_msg->api_reject.conn_handle & NFA_HANDLE_MASK);
869    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
870
871    LLCP_ConnectReject (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap,
872                        LLCP_SAP_DM_REASON_APP_REJECTED);
873
874    /* no need to deregister service on LLCP */
875    nfa_p2p_deallocate_conn_cb (xx);
876
877    return TRUE;
878}
879
880/*******************************************************************************
881**
882** Function         nfa_p2p_disconnect
883**
884** Description      Disconnect data link connection by local application
885**
886**
887** Returns          TRUE to deallocate buffer
888**
889*******************************************************************************/
890BOOLEAN nfa_p2p_disconnect (tNFA_P2P_MSG *p_msg)
891{
892    UINT8             local_sap, xx;
893    tLLCP_STATUS      status;
894    tNFA_P2P_EVT_DATA evt_data;
895
896    P2P_TRACE_DEBUG0 ("nfa_p2p_disconnect ()");
897
898    xx = (UINT8) (p_msg->api_disconnect.conn_handle & NFA_HANDLE_MASK);
899
900    /* if this is for data link connection */
901    if (xx & NFA_P2P_HANDLE_FLAG_CONN)
902    {
903        xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
904
905        status = LLCP_DisconnectReq (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap,
906                                     p_msg->api_disconnect.flush);
907
908        if (status == LLCP_STATUS_SUCCESS)
909        {
910            /* wait for disconnect response if successful */
911            return TRUE;
912        }
913        else
914        {
915            /*
916            ** while we are waiting for connect confirm,
917            ** we cannot sent DISC because we don't know DSAP yet
918            */
919            local_sap = nfa_p2p_cb.conn_cb[xx].local_sap;
920
921            if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
922            {
923                evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
924                evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE;
925
926                nfa_p2p_deallocate_conn_cb (xx);
927                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
928            }
929        }
930    }
931    else
932    {
933        P2P_TRACE_ERROR0 ("Handle is not for Data link connection");
934    }
935
936    return TRUE;
937}
938
939/*******************************************************************************
940**
941** Function         nfa_p2p_create_data_link_connection
942**
943** Description      Create data link connection
944**
945**
946** Returns          TRUE to deallocate buffer
947**
948*******************************************************************************/
949BOOLEAN nfa_p2p_create_data_link_connection (tNFA_P2P_MSG *p_msg)
950{
951    UINT8                   local_sap;
952    tNFA_P2P_EVT_DATA       evt_data;
953    tLLCP_CONNECTION_PARAMS conn_params;
954    tLLCP_STATUS            status;
955
956    P2P_TRACE_DEBUG0 ("nfa_p2p_create_data_link_connection ()");
957
958    local_sap = (UINT8) (p_msg->api_connect.client_handle & NFA_HANDLE_MASK);
959
960    conn_params.miu = p_msg->api_connect.miu;
961    conn_params.rw  = p_msg->api_connect.rw;
962
963    /* NFA_P2pConnectBySap () */
964    if (p_msg->api_connect.dsap != LLCP_INVALID_SAP)
965    {
966        conn_params.sn[0] = 0;
967        status = LLCP_ConnectReq (local_sap, p_msg->api_connect.dsap, &conn_params);
968    }
969    /* NFA_P2pConnectByName () */
970    else
971    {
972        BCM_STRNCPY_S (conn_params.sn, sizeof (conn_params.sn),
973                       p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
974        conn_params.sn[LLCP_MAX_SN_LEN] = 0;
975
976        status = LLCP_ConnectReq (local_sap, LLCP_SAP_SDP, &conn_params);
977    }
978
979    if (status != LLCP_STATUS_SUCCESS)
980    {
981        evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
982        evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_INFORMATION;
983
984        nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
985    }
986
987    return TRUE;
988}
989
990/*******************************************************************************
991**
992** Function         nfa_p2p_send_ui
993**
994** Description      Send UI PDU
995**
996**
997** Returns          TRUE to deallocate buffer
998**
999*******************************************************************************/
1000BOOLEAN nfa_p2p_send_ui (tNFA_P2P_MSG *p_msg)
1001{
1002    UINT8             local_sap;
1003    tLLCP_STATUS      status;
1004    tNFA_P2P_EVT_DATA evt_data;
1005
1006    P2P_TRACE_DEBUG0 ("nfa_p2p_send_ui ()");
1007
1008    local_sap = (UINT8) (p_msg->api_send_ui.handle & NFA_HANDLE_MASK);
1009
1010    /* decrease number of tx UI PDU which is not processed by NFA for congestion control */
1011    if (nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu)
1012        nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu--;
1013
1014    if (nfa_p2p_cb.total_pending_ui_pdu)
1015        nfa_p2p_cb.total_pending_ui_pdu--;
1016
1017    status = LLCP_SendUI (local_sap,
1018                          p_msg->api_send_ui.dsap,
1019                          p_msg->api_send_ui.p_msg);
1020
1021    if (status == LLCP_STATUS_CONGESTED)
1022    {
1023        if (!(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED))
1024        {
1025            nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
1026
1027            /* notify that this logical link is congested */
1028            evt_data.congest.link_type    = NFA_P2P_LLINK_TYPE;
1029            evt_data.congest.handle       = (NFA_HANDLE_GROUP_P2P | local_sap);
1030            evt_data.congest.is_congested = TRUE;
1031
1032            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
1033        }
1034    }
1035
1036    return TRUE;
1037}
1038
1039/*******************************************************************************
1040**
1041** Function         nfa_p2p_send_data
1042**
1043** Description      Send I PDU
1044**
1045**
1046** Returns          TRUE to deallocate buffer
1047**
1048*******************************************************************************/
1049BOOLEAN nfa_p2p_send_data (tNFA_P2P_MSG *p_msg)
1050{
1051    tNFA_P2P_EVT_DATA evt_data;
1052    tLLCP_STATUS      status;
1053    UINT8             xx;
1054
1055    P2P_TRACE_DEBUG0 ("nfa_p2p_send_data ()");
1056
1057    xx = (UINT8) (p_msg->api_send_data.conn_handle & NFA_HANDLE_MASK);
1058    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
1059
1060    /* decrease number of tx I PDU which is not processed by NFA for congestion control */
1061    if (nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu)
1062        nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu--;
1063
1064    if (nfa_p2p_cb.total_pending_i_pdu)
1065        nfa_p2p_cb.total_pending_i_pdu--;
1066
1067    status = LLCP_SendData (nfa_p2p_cb.conn_cb[xx].local_sap,
1068                            nfa_p2p_cb.conn_cb[xx].remote_sap,
1069                            p_msg->api_send_data.p_msg);
1070
1071    if (status == LLCP_STATUS_CONGESTED)
1072    {
1073        if (!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED))
1074        {
1075            nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
1076
1077            /* notify that this data link is congested */
1078            evt_data.congest.link_type    = NFA_P2P_DLINK_TYPE;
1079            evt_data.congest.handle       = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
1080            evt_data.congest.is_congested = TRUE;
1081
1082            nfa_p2p_cb.sap_cb[nfa_p2p_cb.conn_cb[xx].local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
1083        }
1084    }
1085
1086    return TRUE;
1087}
1088
1089/*******************************************************************************
1090**
1091** Function         nfa_p2p_set_local_busy
1092**
1093** Description      Set or reset local busy
1094**
1095**
1096** Returns          TRUE to deallocate buffer
1097**
1098*******************************************************************************/
1099BOOLEAN nfa_p2p_set_local_busy (tNFA_P2P_MSG *p_msg)
1100{
1101    UINT8 xx;
1102
1103    P2P_TRACE_DEBUG0 ("nfa_p2p_set_local_busy ()");
1104
1105    xx = (UINT8) (p_msg->api_local_busy.conn_handle & NFA_HANDLE_MASK);
1106    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
1107
1108    LLCP_SetLocalBusyStatus (nfa_p2p_cb.conn_cb[xx].local_sap,
1109                             nfa_p2p_cb.conn_cb[xx].remote_sap,
1110                             p_msg->api_local_busy.is_busy);
1111
1112    return TRUE;
1113}
1114
1115/*******************************************************************************
1116**
1117** Function         nfa_p2p_get_link_info
1118**
1119** Description      Get WKS of remote and link MIU
1120**
1121**
1122** Returns          TRUE to deallocate buffer
1123**
1124*******************************************************************************/
1125BOOLEAN nfa_p2p_get_link_info (tNFA_P2P_MSG *p_msg)
1126{
1127    tNFA_P2P_EVT_DATA evt_data;
1128    UINT8             local_sap;
1129
1130    P2P_TRACE_DEBUG0 ("nfa_p2p_get_link_info ()");
1131
1132    evt_data.link_info.handle          = p_msg->api_link_info.handle;
1133    evt_data.link_info.wks             = LLCP_GetRemoteWKS ();
1134    evt_data.link_info.local_link_miu  = nfa_p2p_cb.local_link_miu;
1135    evt_data.link_info.remote_link_miu = nfa_p2p_cb.remote_link_miu;
1136
1137    local_sap =  (UINT8) (p_msg->api_link_info.handle & NFA_HANDLE_MASK);
1138    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_LINK_INFO_EVT, &evt_data);
1139
1140    return TRUE;
1141}
1142
1143/*******************************************************************************
1144**
1145** Function         nfa_p2p_get_remote_sap
1146**
1147** Description      Get remote SAP
1148**
1149**
1150** Returns          TRUE to deallocate buffer
1151**
1152*******************************************************************************/
1153BOOLEAN nfa_p2p_get_remote_sap (tNFA_P2P_MSG *p_msg)
1154{
1155    tNFA_P2P_EVT_DATA evt_data;
1156    UINT8             local_sap;
1157
1158    P2P_TRACE_DEBUG0 ("nfa_p2p_get_remote_sap ()");
1159
1160    local_sap =  (UINT8) (p_msg->api_remote_sap.handle & NFA_HANDLE_MASK);
1161
1162    if (!nfa_p2p_start_sdp (p_msg->api_remote_sap.service_name,
1163                            local_sap))
1164    {
1165        evt_data.sdp.handle     = p_msg->api_remote_sap.handle;
1166        evt_data.sdp.remote_sap = 0x00;
1167        nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_SDP_EVT, &evt_data);
1168    }
1169
1170    return TRUE;
1171}
1172
1173/*******************************************************************************
1174**
1175** Function         nfa_p2p_set_llcp_cfg
1176**
1177** Description      Set LLCP configuration
1178**
1179**
1180** Returns          TRUE to deallocate buffer
1181**
1182*******************************************************************************/
1183BOOLEAN nfa_p2p_set_llcp_cfg (tNFA_P2P_MSG *p_msg)
1184{
1185    LLCP_SetConfig (p_msg->api_set_llcp_cfg.link_miu,
1186                    p_msg->api_set_llcp_cfg.opt,
1187                    p_msg->api_set_llcp_cfg.wt,
1188                    p_msg->api_set_llcp_cfg.link_timeout,
1189                    p_msg->api_set_llcp_cfg.inact_timeout_init,
1190                    p_msg->api_set_llcp_cfg.inact_timeout_target,
1191                    p_msg->api_set_llcp_cfg.symm_delay,
1192                    p_msg->api_set_llcp_cfg.data_link_timeout,
1193                    p_msg->api_set_llcp_cfg.delay_first_pdu_timeout);
1194
1195    return TRUE;
1196}
1197