1/******************************************************************************
2 *
3 *  Copyright (C) 2010-2014 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 LLCP internal definitions
22 *
23 ******************************************************************************/
24#ifndef LLCP_INT_H
25#define LLCP_INT_H
26
27#include "llcp_api.h"
28#include "nfc_api.h"
29
30/*
31** LLCP link states
32*/
33enum {
34  LLCP_LINK_STATE_DEACTIVATED,      /* llcp link is deactivated     */
35  LLCP_LINK_STATE_ACTIVATED,        /* llcp link has been activated */
36  LLCP_LINK_STATE_DEACTIVATING,     /* llcp link is deactivating    */
37  LLCP_LINK_STATE_ACTIVATION_FAILED /* llcp link activation was failed */
38};
39typedef uint8_t tLLCP_LINK_STATE;
40
41/*
42** LLCP Symmetric state
43*/
44
45#define LLCP_LINK_SYMM_LOCAL_XMIT_NEXT 0
46#define LLCP_LINK_SYMM_REMOTE_XMIT_NEXT 1
47
48/*
49** LLCP internal flags
50*/
51/* Received any LLC PDU in activated state */
52#define LLCP_LINK_FLAGS_RX_ANY_LLC_PDU 0x01
53
54/*
55** LLCP link control block
56*/
57typedef struct {
58  tLLCP_LINK_STATE link_state; /* llcp link state */
59  tLLCP_LINK_CBACK*
60      p_link_cback; /* callback function to report llcp link status */
61  uint16_t wks;     /* well-known service bit-map                   */
62
63  bool is_initiator;    /* TRUE if initiator role                       */
64  bool is_sending_data; /* TRUE if llcp_link_check_send_data() is excuting    */
65  uint8_t flags;        /* LLCP internal flags                          */
66  bool received_first_packet; /* TRUE if a packet has been received from remote
67                                 */
68  uint8_t agreed_major_version; /* llcp major version used in activated state */
69  uint8_t agreed_minor_version; /* llcp minor version used in activated state */
70
71  uint8_t peer_version;   /* llcp version of peer device                  */
72  uint16_t peer_miu;      /* link MIU of peer device                      */
73  uint16_t peer_wks;      /* WKS of peer device                           */
74  uint16_t peer_lto;      /* link timeout of peer device in ms            */
75  uint8_t peer_opt;       /* Option field of peer device                  */
76  uint16_t effective_miu; /* MIU to send PDU in activated state           */
77
78  TIMER_LIST_ENT timer; /* link timer for LTO and SYMM response         */
79  uint8_t symm_state;   /* state of symmectric procedure                */
80  bool ll_served;       /* TRUE if last transmisstion was for UI        */
81  uint8_t ll_idx;       /* for scheduler of logical link connection     */
82  uint8_t dl_idx;       /* for scheduler of data link connection        */
83
84  TIMER_LIST_ENT inact_timer; /* inactivity timer                             */
85  uint16_t inact_timeout;     /* inactivity timeout in ms                     */
86
87  uint8_t link_deact_reason; /* reason of LLCP link deactivated              */
88
89  BUFFER_Q sig_xmit_q; /* tx signaling PDU queue                       */
90
91  /* runtime configuration parameters */
92  uint16_t local_link_miu; /* Maximum Information Unit                     */
93  uint8_t local_opt;       /* Option parameter                             */
94  uint8_t local_wt;        /* Response Waiting Time Index                  */
95  uint16_t local_lto;      /* Local Link Timeout                           */
96  uint16_t inact_timeout_init;   /* Inactivity Timeout as initiator role */
97  uint16_t inact_timeout_target; /* Inactivity Timeout as target role */
98  uint16_t symm_delay;        /* Delay SYMM response                          */
99  uint16_t data_link_timeout; /* data link conneciton timeout                 */
100  uint16_t delay_first_pdu_timeout; /* delay timeout to send first PDU as
101                                       initiator */
102
103} tLLCP_LCB;
104
105/*
106** LLCP Application's registration control block on service access point (SAP)
107*/
108
109typedef struct {
110  uint8_t link_type;    /* logical link and/or data link                */
111  char* p_service_name; /* GKI buffer containing service name           */
112  tLLCP_APP_CBACK* p_app_cback; /* application's callback pointer */
113
114  BUFFER_Q ui_xmit_q;      /* UI PDU queue for transmitting                */
115  BUFFER_Q ui_rx_q;        /* UI PDU queue for receiving                   */
116  bool is_ui_tx_congested; /* TRUE if transmitting UI PDU is congested     */
117
118} tLLCP_APP_CB;
119
120/*
121** LLCP data link connection states
122*/
123enum {
124  LLCP_DLC_STATE_IDLE, /* initial state                                    */
125  LLCP_DLC_STATE_W4_REMOTE_RESP, /* waiting for connection confirm from peer */
126  LLCP_DLC_STATE_W4_LOCAL_RESP,  /* waiting for connection confirm from upper
127                                    layer  */
128  LLCP_DLC_STATE_CONNECTED,      /* data link connection has been established */
129  LLCP_DLC_STATE_W4_REMOTE_DM /* waiting for disconnection confirm from peer */
130};
131typedef uint8_t tLLCP_DLC_STATE;
132
133/*
134** LLCP data link connection events
135*/
136enum {
137  LLCP_DLC_EVENT_API_CONNECT_REQ,    /* connection request from upper layer  */
138  LLCP_DLC_EVENT_API_CONNECT_CFM,    /* connection confirm from upper layer  */
139  LLCP_DLC_EVENT_API_CONNECT_REJECT, /* connection reject from upper layer   */
140  LLCP_DLC_EVENT_PEER_CONNECT_IND,   /* connection request from peer         */
141  LLCP_DLC_EVENT_PEER_CONNECT_CFM,   /* connection confirm from peer         */
142
143  LLCP_DLC_EVENT_API_DATA_REQ,  /* data packet from upper layer         */
144  LLCP_DLC_EVENT_PEER_DATA_IND, /* data packet from peer                */
145
146  LLCP_DLC_EVENT_API_DISCONNECT_REQ,  /* disconnect request from upper layer  */
147  LLCP_DLC_EVENT_PEER_DISCONNECT_IND, /* disconnect request from peer         */
148  LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, /* disconnect response from peer */
149
150  LLCP_DLC_EVENT_FRAME_ERROR, /* received erroneous frame from peer   */
151  LLCP_DLC_EVENT_LINK_ERROR,  /* llcp link has been deactivated       */
152
153  LLCP_DLC_EVENT_TIMEOUT /* timeout event                        */
154};
155typedef uint8_t tLLCP_DLC_EVENT;
156
157/*
158** LLCP data link connection control block
159*/
160
161/* send DISC when tx queue is empty       */
162#define LLCP_DATA_LINK_FLAG_PENDING_DISC 0x01
163/* send RR/RNR with valid sequence        */
164#define LLCP_DATA_LINK_FLAG_PENDING_RR_RNR 0x02
165/* notify upper later when tx complete    */
166#define LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE 0x04
167
168typedef struct {
169  tLLCP_DLC_STATE state;  /* data link connection state               */
170  uint8_t flags;          /* specific action flags                    */
171  tLLCP_APP_CB* p_app_cb; /* pointer of application registration      */
172  TIMER_LIST_ENT timer;   /* timer for connection complete            */
173
174  uint8_t local_sap;  /* SAP of local end point                   */
175  uint16_t local_miu; /* MIU of local SAP                         */
176  uint8_t local_rw;   /* RW of local SAP                          */
177  bool local_busy;    /* TRUE if local SAP is busy                */
178
179  uint8_t remote_sap;  /* SAP of remote end point                  */
180  uint16_t remote_miu; /* MIU of remote SAP                        */
181  uint8_t remote_rw;   /* RW of remote SAP                         */
182  bool remote_busy;    /* TRUE if remote SAP is busy               */
183
184  uint8_t next_tx_seq;  /* V(S), send state variable                */
185  uint8_t rcvd_ack_seq; /* V(SA), send ack state variable           */
186  uint8_t next_rx_seq;  /* V(R), receive state variable             */
187  uint8_t sent_ack_seq; /* V(RA), receive ack state variable        */
188
189  BUFFER_Q i_xmit_q;    /* tx queue of I PDU                        */
190  bool is_tx_congested; /* TRUE if tx I PDU is congested            */
191
192  BUFFER_Q i_rx_q;              /* rx queue of I PDU                        */
193  bool is_rx_congested;         /* TRUE if rx I PDU is congested            */
194  uint8_t num_rx_i_pdu;         /* number of I PDU in rx queue              */
195  uint8_t rx_congest_threshold; /* dynamic congest threshold for rx I PDU */
196
197} tLLCP_DLCB;
198
199/*
200** LLCP service discovery control block
201*/
202
203typedef struct {
204  uint8_t tid;              /* transaction ID                           */
205  tLLCP_SDP_CBACK* p_cback; /* callback function for service discovery  */
206} tLLCP_SDP_TRANSAC;
207
208typedef struct {
209  uint8_t next_tid;                                /* next TID to use         */
210  tLLCP_SDP_TRANSAC transac[LLCP_MAX_SDP_TRANSAC]; /* active SDP transactions */
211  NFC_HDR* p_snl;                                  /* buffer for SNL PDU      */
212} tLLCP_SDP_CB;
213
214/*
215** LLCP control block
216*/
217
218typedef struct {
219  tLLCP_SDP_CB sdp_cb; /* SDP control block                            */
220  tLLCP_LCB lcb;       /* LLCP link control block                      */
221  tLLCP_APP_CB wks_cb[LLCP_MAX_WKS]; /* Application's registration for
222                                        well-known services */
223  tLLCP_APP_CB server_cb
224      [LLCP_MAX_SERVER]; /* Application's registration for SDP services  */
225  tLLCP_APP_CB
226      client_cb[LLCP_MAX_CLIENT]; /* Application's registration for client */
227  tLLCP_DLCB dlcb[LLCP_MAX_DATA_LINK]; /* Data link connection control block */
228
229  uint8_t max_num_ll_tx_buff; /* max number of tx UI PDU in queue             */
230  uint8_t max_num_tx_buff;    /* max number of tx UI/I PDU in queue           */
231
232  uint8_t num_logical_data_link; /* number of logical data link */
233  uint8_t
234      num_data_link_connection; /* number of established data link connection */
235
236  /* these two thresholds (number of tx UI PDU) are dynamically adjusted based
237   * on number of logical links */
238  uint8_t
239      ll_tx_congest_start;   /* congest start threshold for each logical link*/
240  uint8_t ll_tx_congest_end; /* congest end threshold for each logical link  */
241
242  uint8_t total_tx_ui_pdu;   /* total number of tx UI PDU in all of ui_xmit_q*/
243  uint8_t total_tx_i_pdu;    /* total number of tx I PDU in all of i_xmit_q  */
244  bool overall_tx_congested; /* TRUE if tx link is congested                 */
245
246  /* start point of uncongested status notification is in round robin */
247  uint8_t ll_tx_uncongest_ntf_start_sap; /* next start of logical data link */
248  uint8_t
249      dl_tx_uncongest_ntf_start_idx; /* next start of data link connection */
250
251  /*
252  ** when overall rx link congestion starts, RNR is sent to remote end point
253  ** of data link connection while rx link is congested, UI PDU is discarded.
254  */
255  uint8_t num_rx_buff; /* reserved number of rx UI/I PDU in queue      */
256  uint8_t
257      overall_rx_congest_start;   /* threshold of overall rx congestion start */
258  uint8_t overall_rx_congest_end; /* threshold of overall rx congestion end */
259  uint8_t max_num_ll_rx_buff; /* max number of rx UI PDU in queue             */
260
261  /*
262  ** threshold (number of rx UI PDU) is dynamically adjusted based on number
263  ** of logical links when number of rx UI PDU is more than
264  ** ll_rx_congest_start, the oldest UI PDU is discarded
265  */
266  uint8_t ll_rx_congest_start; /* rx congest start threshold for each logical
267                                  link */
268
269  uint8_t total_rx_ui_pdu;   /* total number of rx UI PDU in all of ui_rx_q  */
270  uint8_t total_rx_i_pdu;    /* total number of rx I PDU in all of i_rx_q    */
271  bool overall_rx_congested; /* TRUE if overall rx link is congested         */
272  tLLCP_DTA_CBACK* p_dta_cback; /* callback to notify DTA when respoding SNL */
273  bool dta_snl_resp; /* TRUE if need to notify DTA when respoding SNL*/
274} tLLCP_CB;
275
276#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
277
278typedef struct {
279  uint8_t version;
280  uint16_t wks;
281} tLLCP_TEST_PARAMS;
282
283#endif
284
285/*
286** LLCP global data
287*/
288
289extern tLLCP_CB llcp_cb;
290
291/*
292** Functions provided by llcp_main.c
293*/
294void llcp_init(void);
295void llcp_cleanup(void);
296void llcp_process_timeout(TIMER_LIST_ENT* p_tle);
297
298/*
299** Functions provided by llcp_link.c
300*/
301tLLCP_STATUS llcp_link_activate(tLLCP_ACTIVATE_CONFIG* p_config);
302void llcp_link_process_link_timeout(void);
303void llcp_link_deactivate(uint8_t reason);
304
305void llcp_link_check_send_data(void);
306void llcp_link_connection_cback(uint8_t conn_id, tNFC_CONN_EVT event,
307                                tNFC_CONN* p_data);
308
309/*
310**  Functions provided by llcp_util.c
311*/
312void llcp_util_adjust_ll_congestion(void);
313void llcp_util_adjust_dl_rx_congestion(void);
314void llcp_util_check_rx_congested_status(void);
315bool llcp_util_parse_link_params(uint16_t length, uint8_t* p_bytes);
316tLLCP_STATUS llcp_util_send_ui(uint8_t ssap, uint8_t dsap,
317                               tLLCP_APP_CB* p_app_cb, NFC_HDR* p_msg);
318void llcp_util_send_disc(uint8_t dsap, uint8_t ssap);
319tLLCP_DLCB* llcp_util_allocate_data_link(uint8_t reg_sap, uint8_t remote_sap);
320void llcp_util_deallocate_data_link(tLLCP_DLCB* p_dlcb);
321tLLCP_STATUS llcp_util_send_connect(tLLCP_DLCB* p_dlcb,
322                                    tLLCP_CONNECTION_PARAMS* p_params);
323tLLCP_STATUS llcp_util_parse_connect(uint8_t* p_bytes, uint16_t length,
324                                     tLLCP_CONNECTION_PARAMS* p_params);
325tLLCP_STATUS llcp_util_send_cc(tLLCP_DLCB* p_dlcb,
326                               tLLCP_CONNECTION_PARAMS* p_params);
327tLLCP_STATUS llcp_util_parse_cc(uint8_t* p_bytes, uint16_t length,
328                                uint16_t* p_miu, uint8_t* p_rw);
329void llcp_util_send_dm(uint8_t dsap, uint8_t ssap, uint8_t reason);
330void llcp_util_build_info_pdu(tLLCP_DLCB* p_dlcb, NFC_HDR* p_msg);
331tLLCP_STATUS llcp_util_send_frmr(tLLCP_DLCB* p_dlcb, uint8_t flags,
332                                 uint8_t ptype, uint8_t sequence);
333void llcp_util_send_rr_rnr(tLLCP_DLCB* p_dlcb);
334tLLCP_APP_CB* llcp_util_get_app_cb(uint8_t sap);
335/*
336** Functions provided by llcp_dlc.c
337*/
338tLLCP_STATUS llcp_dlsm_execute(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
339                               void* p_data);
340tLLCP_DLCB* llcp_dlc_find_dlcb_by_sap(uint8_t local_sap, uint8_t remote_sap);
341void llcp_dlc_flush_q(tLLCP_DLCB* p_dlcb);
342void llcp_dlc_proc_i_pdu(uint8_t dsap, uint8_t ssap, uint16_t i_pdu_length,
343                         uint8_t* p_i_pdu, NFC_HDR* p_msg);
344void llcp_dlc_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
345                          uint16_t length, uint8_t* p_data);
346void llcp_dlc_check_to_send_rr_rnr(void);
347bool llcp_dlc_is_rw_open(tLLCP_DLCB* p_dlcb);
348NFC_HDR* llcp_dlc_get_next_pdu(tLLCP_DLCB* p_dlcb);
349uint16_t llcp_dlc_get_next_pdu_length(tLLCP_DLCB* p_dlcb);
350
351/*
352** Functions provided by llcp_sdp.c
353*/
354void llcp_sdp_proc_data(tLLCP_SAP_CBACK_DATA* p_data);
355tLLCP_STATUS llcp_sdp_send_sdreq(uint8_t tid, char* p_name);
356uint8_t llcp_sdp_get_sap_by_name(char* p_name, uint8_t length);
357tLLCP_STATUS llcp_sdp_proc_snl(uint16_t sdu_length, uint8_t* p);
358void llcp_sdp_check_send_snl(void);
359void llcp_sdp_proc_deactivation(void);
360#endif
361