⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l2cap.h

📁 蓝牙协议源代码 bluetooth stack for lwip
💻 H
📖 第 1 页 / 共 2 页
字号:
				on a queue */
  struct pbuf *p;          /* buffer containing data + L2CAP header */
  u16_t sigid; /* Identification */
  u16_t ertx; /* extended response timeout expired */
  u8_t rtx; /* response timeout expired */
  u8_t nrtx; /* number of retransmissions */
};

struct l2cap_cfg {
  u16_t inmtu; /* Maximum transmission unit this channel can accept */
  u16_t outmtu; /* Maximum transmission unit that can be sent on this channel */
  u16_t influshto; /* In flush timeout */
  u16_t outflushto; /* Out flush timeout */
  
  struct pbuf *opt; /* Any received non-hint unknown option(s) or option(s) with unacceptable parameters 
		       will be temporarily stored here */

  u8_t cfgto; /* Configuration timeout */
  u8_t l2capcfg; /* Bit 1 indicates if we are the initiator of this connection
		  * Bit 2 indicates if a successful configuration response has been received
		  * Bit 3 indicates if a successful configuration response has been sent
		  * Bit 4 indicates if an initial configuration request has been sent
		  */
};

struct l2cap_seg {
  struct l2cap_seg *next; /* For the linked list */

  struct bd_addr bdaddr;

  struct pbuf *p;          /* Buffer containing data + L2CAP header */
  u16_t len;               /* The L2CAP length of this segment */
  struct l2cap_hdr *l2caphdr;  /* The L2CAP header */
  struct l2cap_pcb *pcb; /* The L2CAP Protocol Control Block */
};

struct l2cap_pcb {
  struct l2cap_pcb *next; /* For the linked list */

  enum l2cap_state state; /* L2CAP state */

  void *callback_arg;
  
  u16_t scid; /* Source CID */
  u16_t dcid; /* Destination CID */

  u16_t psm; /* Protocol/Service Multiplexer */

  u16_t ursp_id; /* Signal id to respond to */
  u8_t encrypt; /* encryption mode */
  
  struct l2cap_sig *unrsp_sigs;  /* List of sent but unresponded signals */

  struct bd_addr remote_bdaddr;
  
  struct l2cap_cfg cfg; /* Configuration parameters */
  
  /* Upper layer to L2CAP confirmation functions */

  /* Function to be called when a connection has been set up */
  err_t (* l2ca_connect_cfm)(void *arg, struct l2cap_pcb *pcb, u16_t result, u16_t status);
  /* Function to be called when a connection has been closed */
  err_t (* l2ca_disconnect_cfm)(void *arg, struct l2cap_pcb *pcb);
  /* Function to be called when a echo reply has been received */
  err_t (* l2ca_pong)(void *arg, struct l2cap_pcb *pcb, u8_t result);

  /* L2CAP to upper layer indication functions */

  /* Function to be called when a connection indication event occurs */
  err_t (* l2ca_connect_ind)(void *arg, struct l2cap_pcb *pcb, err_t err);
  /* Function to be called when a disconnection indication event occurs */
  err_t (* l2ca_disconnect_ind)(void *arg, struct l2cap_pcb *pcb, err_t err);
  /* Function to be called when a timeout indication event occurs */
  err_t (* l2ca_timeout_ind)(void *arg, struct l2cap_pcb *newpcb, err_t err);
  /* Function to be called when a L2CAP connection receives data */
  err_t (* l2ca_recv)(void *arg, struct l2cap_pcb *pcb, struct pbuf *p, err_t err);
};

struct l2cap_pcb_listen {
  struct l2cap_pcb_listen *next; /* for the linked list */

  enum l2cap_state state; /* L2CAP state */
  
  void *callback_arg;

  u16_t psm; /* Protocol/Service Multiplexer */
  
  /* Function to call when a connection request has been received
     from a remote device. */
  err_t (* l2ca_connect_ind)(void *arg, struct l2cap_pcb *pcb, err_t err);
};

/* Internal functions and global variables */
#define L2CA_ACTION_CONN_CFM(pcb,result,status,ret) if((pcb)->l2ca_connect_cfm != NULL) (ret = (pcb)->l2ca_connect_cfm((pcb)->callback_arg,(pcb),(result),(status)))
#define L2CA_ACTION_DISCONN_CFM(pcb,ret) if((pcb)->l2ca_disconnect_cfm != NULL) (ret = (pcb)->l2ca_disconnect_cfm((pcb)->callback_arg,(pcb)))
#define L2CA_ACTION_PING_CFM(pcb,result,ret) if((pcb)->l2ca_pong != NULL) (ret = (pcb)->l2ca_pong((pcb)->callback_arg,(pcb),(result)))

#define L2CA_ACTION_CONN_IND(pcb,err,ret) if((pcb)->l2ca_connect_ind != NULL) (ret = (pcb)->l2ca_connect_ind((pcb)->callback_arg,(pcb),(err)))
#define L2CA_ACTION_DISCONN_IND(pcb,err,ret) \
                                if((pcb)->l2ca_disconnect_ind != NULL) { \
                                LWIP_DEBUGF(L2CAP_DEBUG, ("l2cap_disconnect_ind called\n")); \
                                (ret = (pcb)->l2ca_disconnect_ind((pcb)->callback_arg,(pcb),(err))); \
                                } else { \
                                l2cap_close(pcb); \
                                }
#define L2CA_ACTION_TO_IND(pcb,err,ret) if((pcb)->l2ca_timeout_ind != NULL) (ret = (pcb)->l2ca_timeout_ind((pcb)->callback_arg,(pcb),(err)))
#define L2CA_ACTION_RECV(pcb,p,err,ret) \
                         if((pcb)->l2ca_recv != NULL) { \
			 (ret = (pcb)->l2ca_recv((pcb)->callback_arg,(pcb),(p),(err))); \
			 } else { \
			 pbuf_free(p); \
                         }

#define L2CAP_OPTH_TYPE(hdr) (((hdr)->type) & 0x7f)
#define L2CAP_OPTH_TOA(hdr) (((hdr)->type) >> 7)

/* The L2CAP PCB lists. */
extern struct l2cap_pcb_listen *l2cap_listen_pcbs; /* List of all L2CAP PCBs in CLOSED state
						but awaing an incoming conn req. */
extern struct l2cap_pcb *l2cap_active_pcbs; /* List of all L2CAP PCBs that has
					       established or is about to establish
					       an ACL link */

extern struct l2cap_pcb *l2cap_tmp_pcb;      /* Only used for temporary storage. */

/* Axoims about the above list:   
   1) A PCB is only in one of the lists.
   2) All PCBs in the l2cap_active_pcbs list has established or is about to
   establish an ACL link.
*/

/* Define two macros, L2CAP_REG and L2CAP_RMV that registers a L2CAP PCB
   with a PCB list or removes a PCB from a list, respectively. */
#ifdef LWBT_DEBUG
#define L2CAP_REG(pcbs, npcb) do { \
                            for(l2cap_tmp_pcb = *pcbs; \
				  l2cap_tmp_pcb != NULL; \
				l2cap_tmp_pcb = l2cap_tmp_pcb->next) { \
                                LWIP_ASSERT("L2CAP_REG: already registered\n", l2cap_tmp_pcb != npcb); \
                            } \
                            npcb->next = *pcbs; \
                            LWIP_ASSERT("L2CAP_REG: npcb->next != npcb", npcb->next != npcb); \
                            *pcbs = npcb; \
                            } while(0)
#define L2CAP_RMV(pcbs, npcb) do { \
                            LWIP_ASSERT("L2CAP_RMV: pcbs != NULL", *pcbs != NULL); \
                            LWIP_DEBUGF(L2CAP_DEBUG, ("L2CAP_RMV: removing %p from %p\n", npcb, *pcbs)); \
                            if(*pcbs == npcb) { \
                               *pcbs = (*pcbs)->next; \
                            } else for(l2cap_tmp_pcb = *pcbs; l2cap_tmp_pcb != NULL; l2cap_tmp_pcb = l2cap_tmp_pcb->next) { \
                               if(l2cap_tmp_pcb->next != NULL && l2cap_tmp_pcb->next == npcb) { \
                                  l2cap_tmp_pcb->next = npcb->next; \
                                  break; \
                               } \
                            } \
                            npcb->next = NULL; \
                            LWIP_DEBUGF(L2CAP_DEBUG, ("L2CAP_RMV: removed %p from %p\n", npcb, *pcbs)); \
                            } while(0)

#else /* LWBT_DEBUG */
#define L2CAP_REG(pcbs, npcb) do { \
                            npcb->next = *pcbs; \
                            *pcbs = npcb; \
                            } while(0)
#define L2CAP_RMV(pcbs, npcb) do { \
                            if(*pcbs == npcb) { \
                               *pcbs = (*pcbs)->next; \
                            } else for(l2cap_tmp_pcb = *pcbs; l2cap_tmp_pcb != NULL; l2cap_tmp_pcb = l2cap_tmp_pcb->next) { \
                               if(l2cap_tmp_pcb->next != NULL && l2cap_tmp_pcb->next == npcb) { \
                                  l2cap_tmp_pcb->next = npcb->next; \
                                  break; \
                               } \
                            } \
                            npcb->next = NULL; \
                            } while(0)
#endif /* LWBT_DEBUG */

/* The L2CAP SIG list macros */
extern struct l2cap_sig *l2cap_tmp_sig;      /* Only used for temporary storage. */

#define L2CAP_SIG_REG(ursp_sigs, nsig) do { \
                            nsig->next = *ursp_sigs; \
                            *ursp_sigs = nsig; \
                            } while(0)
#define L2CAP_SIG_RMV(ursp_sigs, nsig) do { \
                            if(*ursp_sigs == nsig) { \
                               *ursp_sigs = (*ursp_sigs)->next; \
                            } else for(l2cap_tmp_sig = *ursp_sigs; l2cap_tmp_sig != NULL; l2cap_tmp_sig = l2cap_tmp_sig->next) { \
                               if(l2cap_tmp_sig->next != NULL && l2cap_tmp_sig->next == nsig) { \
                                  l2cap_tmp_sig->next = nsig->next; \
                                  break; \
                               } \
                            } \
                            nsig->next = NULL; \
                            } while(0)

/* The L2CAP incoming segments list macros */
extern struct l2cap_seg *l2cap_tmp_inseg;      /* Only used for temporary storage. */

#define L2CAP_SEG_REG(segs, nseg) do { \
                            nseg->next = *segs; \
                            *segs = nseg; \
                            } while(0)
#define L2CAP_SEG_RMV(segs, nseg) do { \
                            if(*segs == nseg) { \
                               *segs = (*segs)->next; \
                            } else for(l2cap_tmp_inseg = *segs; l2cap_tmp_inseg != NULL; l2cap_tmp_inseg = l2cap_tmp_inseg->next) { \
                               if(l2cap_tmp_inseg->next != NULL && l2cap_tmp_inseg->next == nseg) { \
                                  l2cap_tmp_inseg->next = nseg->next; \
                                  break; \
                               } \
                            } \
                            nseg->next = NULL; \
                            } while(0)
#endif /* __LWBT_L2CAP_H__ */


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -