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 */ 33 enum { 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 }; 39 typedef 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 */ 57 typedef 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 109 typedef struct { 110 uint8_t link_type; /* logical link and/or data link */ 111 uint8_t* 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 */ 123 enum { 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 LLCP_DLC_STATE_MAX 131 }; 132 typedef uint8_t tLLCP_DLC_STATE; 133 134 /* 135 ** LLCP data link connection events 136 */ 137 enum { 138 LLCP_DLC_EVENT_API_CONNECT_REQ, /* connection request from upper layer */ 139 LLCP_DLC_EVENT_API_CONNECT_CFM, /* connection confirm from upper layer */ 140 LLCP_DLC_EVENT_API_CONNECT_REJECT, /* connection reject from upper layer */ 141 LLCP_DLC_EVENT_PEER_CONNECT_IND, /* connection request from peer */ 142 LLCP_DLC_EVENT_PEER_CONNECT_CFM, /* connection confirm from peer */ 143 144 LLCP_DLC_EVENT_API_DATA_REQ, /* data packet from upper layer */ 145 LLCP_DLC_EVENT_PEER_DATA_IND, /* data packet from peer */ 146 147 LLCP_DLC_EVENT_API_DISCONNECT_REQ, /* disconnect request from upper layer */ 148 LLCP_DLC_EVENT_PEER_DISCONNECT_IND, /* disconnect request from peer */ 149 LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, /* disconnect response from peer */ 150 151 LLCP_DLC_EVENT_FRAME_ERROR, /* received erroneous frame from peer */ 152 LLCP_DLC_EVENT_LINK_ERROR, /* llcp link has been deactivated */ 153 154 LLCP_DLC_EVENT_TIMEOUT /* timeout event */ 155 }; 156 typedef uint8_t tLLCP_DLC_EVENT; 157 158 /* 159 ** LLCP data link connection control block 160 */ 161 162 /* send DISC when tx queue is empty */ 163 #define LLCP_DATA_LINK_FLAG_PENDING_DISC 0x01 164 /* send RR/RNR with valid sequence */ 165 #define LLCP_DATA_LINK_FLAG_PENDING_RR_RNR 0x02 166 /* notify upper later when tx complete */ 167 #define LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE 0x04 168 169 typedef struct { 170 tLLCP_DLC_STATE state; /* data link connection state */ 171 uint8_t flags; /* specific action flags */ 172 tLLCP_APP_CB* p_app_cb; /* pointer of application registration */ 173 TIMER_LIST_ENT timer; /* timer for connection complete */ 174 175 uint8_t local_sap; /* SAP of local end point */ 176 uint16_t local_miu; /* MIU of local SAP */ 177 uint8_t local_rw; /* RW of local SAP */ 178 bool local_busy; /* TRUE if local SAP is busy */ 179 180 uint8_t remote_sap; /* SAP of remote end point */ 181 uint16_t remote_miu; /* MIU of remote SAP */ 182 uint8_t remote_rw; /* RW of remote SAP */ 183 bool remote_busy; /* TRUE if remote SAP is busy */ 184 185 uint8_t next_tx_seq; /* V(S), send state variable */ 186 uint8_t rcvd_ack_seq; /* V(SA), send ack state variable */ 187 uint8_t next_rx_seq; /* V(R), receive state variable */ 188 uint8_t sent_ack_seq; /* V(RA), receive ack state variable */ 189 190 BUFFER_Q i_xmit_q; /* tx queue of I PDU */ 191 bool is_tx_congested; /* TRUE if tx I PDU is congested */ 192 193 BUFFER_Q i_rx_q; /* rx queue of I PDU */ 194 bool is_rx_congested; /* TRUE if rx I PDU is congested */ 195 uint8_t num_rx_i_pdu; /* number of I PDU in rx queue */ 196 uint8_t rx_congest_threshold; /* dynamic congest threshold for rx I PDU */ 197 198 } tLLCP_DLCB; 199 200 /* 201 ** LLCP service discovery control block 202 */ 203 204 typedef struct { 205 uint8_t tid; /* transaction ID */ 206 tLLCP_SDP_CBACK* p_cback; /* callback function for service discovery */ 207 } tLLCP_SDP_TRANSAC; 208 209 typedef struct { 210 uint8_t next_tid; /* next TID to use */ 211 tLLCP_SDP_TRANSAC transac[LLCP_MAX_SDP_TRANSAC]; /* active SDP transactions */ 212 NFC_HDR* p_snl; /* buffer for SNL PDU */ 213 } tLLCP_SDP_CB; 214 215 /* 216 ** LLCP control block 217 */ 218 219 typedef struct { 220 uint8_t trace_level; /* LLCP trace level */ 221 222 tLLCP_SDP_CB sdp_cb; /* SDP control block */ 223 tLLCP_LCB lcb; /* LLCP link control block */ 224 tLLCP_APP_CB wks_cb[LLCP_MAX_WKS]; /* Application's registration for 225 well-known services */ 226 tLLCP_APP_CB server_cb 227 [LLCP_MAX_SERVER]; /* Application's registration for SDP services */ 228 tLLCP_APP_CB 229 client_cb[LLCP_MAX_CLIENT]; /* Application's registration for client */ 230 tLLCP_DLCB dlcb[LLCP_MAX_DATA_LINK]; /* Data link connection control block */ 231 232 uint8_t max_num_ll_tx_buff; /* max number of tx UI PDU in queue */ 233 uint8_t max_num_tx_buff; /* max number of tx UI/I PDU in queue */ 234 235 uint8_t num_logical_data_link; /* number of logical data link */ 236 uint8_t 237 num_data_link_connection; /* number of established data link connection */ 238 239 /* these two thresholds (number of tx UI PDU) are dynamically adjusted based 240 * on number of logical links */ 241 uint8_t 242 ll_tx_congest_start; /* congest start threshold for each logical link*/ 243 uint8_t ll_tx_congest_end; /* congest end threshold for each logical link */ 244 245 uint8_t total_tx_ui_pdu; /* total number of tx UI PDU in all of ui_xmit_q*/ 246 uint8_t total_tx_i_pdu; /* total number of tx I PDU in all of i_xmit_q */ 247 bool overall_tx_congested; /* TRUE if tx link is congested */ 248 249 /* start point of uncongested status notification is in round robin */ 250 uint8_t ll_tx_uncongest_ntf_start_sap; /* next start of logical data link */ 251 uint8_t 252 dl_tx_uncongest_ntf_start_idx; /* next start of data link connection */ 253 254 /* 255 ** when overall rx link congestion starts, RNR is sent to remote end point 256 ** of data link connection while rx link is congested, UI PDU is discarded. 257 */ 258 uint8_t num_rx_buff; /* reserved number of rx UI/I PDU in queue */ 259 uint8_t 260 overall_rx_congest_start; /* threshold of overall rx congestion start */ 261 uint8_t overall_rx_congest_end; /* threshold of overall rx congestion end */ 262 uint8_t max_num_ll_rx_buff; /* max number of rx UI PDU in queue */ 263 264 /* 265 ** threshold (number of rx UI PDU) is dynamically adjusted based on number 266 ** of logical links when number of rx UI PDU is more than 267 ** ll_rx_congest_start, the oldest UI PDU is discarded 268 */ 269 uint8_t ll_rx_congest_start; /* rx congest start threshold for each logical 270 link */ 271 272 uint8_t total_rx_ui_pdu; /* total number of rx UI PDU in all of ui_rx_q */ 273 uint8_t total_rx_i_pdu; /* total number of rx I PDU in all of i_rx_q */ 274 bool overall_rx_congested; /* TRUE if overall rx link is congested */ 275 tLLCP_DTA_CBACK* p_dta_cback; /* callback to notify DTA when respoding SNL */ 276 bool dta_snl_resp; /* TRUE if need to notify DTA when respoding SNL*/ 277 } tLLCP_CB; 278 279 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */ 280 281 typedef struct { 282 uint8_t version; 283 uint16_t wks; 284 } tLLCP_TEST_PARAMS; 285 286 #endif 287 288 #ifdef __cplusplus 289 extern "C" { 290 #endif 291 292 /* 293 ** LLCP global data 294 */ 295 296 extern tLLCP_CB llcp_cb; 297 298 /* 299 ** Functions provided by llcp_main.c 300 */ 301 void llcp_init(void); 302 void llcp_cleanup(void); 303 void llcp_process_timeout(TIMER_LIST_ENT* p_tle); 304 305 /* 306 ** Functions provided by llcp_link.c 307 */ 308 tLLCP_STATUS llcp_link_activate(tLLCP_ACTIVATE_CONFIG* p_config); 309 void llcp_link_process_link_timeout(void); 310 void llcp_link_deactivate(uint8_t reason); 311 312 void llcp_link_check_send_data(void); 313 void llcp_link_connection_cback(uint8_t conn_id, tNFC_CONN_EVT event, 314 tNFC_CONN* p_data); 315 316 /* 317 ** Functions provided by llcp_util.c 318 */ 319 void llcp_util_adjust_ll_congestion(void); 320 void llcp_util_adjust_dl_rx_congestion(void); 321 void llcp_util_check_rx_congested_status(void); 322 bool llcp_util_parse_link_params(uint16_t length, uint8_t* p_bytes); 323 tLLCP_STATUS llcp_util_send_ui(uint8_t ssap, uint8_t dsap, 324 tLLCP_APP_CB* p_app_cb, NFC_HDR* p_msg); 325 void llcp_util_send_disc(uint8_t dsap, uint8_t ssap); 326 tLLCP_DLCB* llcp_util_allocate_data_link(uint8_t reg_sap, uint8_t remote_sap); 327 void llcp_util_deallocate_data_link(tLLCP_DLCB* p_dlcb); 328 tLLCP_STATUS llcp_util_send_connect(tLLCP_DLCB* p_dlcb, 329 tLLCP_CONNECTION_PARAMS* p_params); 330 tLLCP_STATUS llcp_util_parse_connect(uint8_t* p_bytes, uint16_t length, 331 tLLCP_CONNECTION_PARAMS* p_params); 332 tLLCP_STATUS llcp_util_send_cc(tLLCP_DLCB* p_dlcb, 333 tLLCP_CONNECTION_PARAMS* p_params); 334 tLLCP_STATUS llcp_util_parse_cc(uint8_t* p_bytes, uint16_t length, 335 uint16_t* p_miu, uint8_t* p_rw); 336 void llcp_util_send_dm(uint8_t dsap, uint8_t ssap, uint8_t reason); 337 void llcp_util_build_info_pdu(tLLCP_DLCB* p_dlcb, NFC_HDR* p_msg); 338 tLLCP_STATUS llcp_util_send_frmr(tLLCP_DLCB* p_dlcb, uint8_t flags, 339 uint8_t ptype, uint8_t sequence); 340 void llcp_util_send_rr_rnr(tLLCP_DLCB* p_dlcb); 341 tLLCP_APP_CB* llcp_util_get_app_cb(uint8_t sap); 342 /* 343 ** Functions provided by llcp_dlc.c 344 */ 345 tLLCP_STATUS llcp_dlsm_execute(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event, 346 void* p_data); 347 tLLCP_DLCB* llcp_dlc_find_dlcb_by_sap(uint8_t local_sap, uint8_t remote_sap); 348 void llcp_dlc_flush_q(tLLCP_DLCB* p_dlcb); 349 void llcp_dlc_proc_i_pdu(uint8_t dsap, uint8_t ssap, uint16_t i_pdu_length, 350 uint8_t* p_i_pdu, NFC_HDR* p_msg); 351 void llcp_dlc_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap, 352 uint16_t length, uint8_t* p_data); 353 void llcp_dlc_check_to_send_rr_rnr(void); 354 bool llcp_dlc_is_rw_open(tLLCP_DLCB* p_dlcb); 355 NFC_HDR* llcp_dlc_get_next_pdu(tLLCP_DLCB* p_dlcb); 356 uint16_t llcp_dlc_get_next_pdu_length(tLLCP_DLCB* p_dlcb); 357 358 /* 359 ** Functions provided by llcp_sdp.c 360 */ 361 void llcp_sdp_proc_data(tLLCP_SAP_CBACK_DATA* p_data); 362 tLLCP_STATUS llcp_sdp_send_sdreq(uint8_t tid, char* p_name); 363 uint8_t llcp_sdp_get_sap_by_name(char* p_name, uint8_t length); 364 tLLCP_STATUS llcp_sdp_proc_snl(uint16_t sdu_length, uint8_t* p); 365 void llcp_sdp_check_send_snl(void); 366 void llcp_sdp_proc_deactivation(void); 367 #ifdef __cplusplus 368 } 369 #endif 370 371 #endif 372