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

📄 rfcomm.c

📁 blue tooth 核心协议栈在linux上的实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************** INCLUDE FILES SECTION ***********************************/#define __NO_VERSION__ /* don't define kernel_version in module.h */#ifdef __KERNEL__ #include <linux/config.h>#include <linux/bluetooth/sysdep-2.1.h>#include <linux/malloc.h>#include <linux/types.h>#include <linux/string.h>#include <linux/sched.h>#include <asm/unaligned.h>#include <linux/bluetooth/rfcomm.h>#include <linux/bluetooth/rfcomm_sec.h>#include <linux/bluetooth/btmem.h>#include <linux/bluetooth/l2cap.h>#include <linux/bluetooth/bluetooth.h>#include <linux/bluetooth/btconfig.h>#include <linux/bluetooth/bt_errno.h>#else#include <stdlib.h>#include <string.h>#include <errno.h>#include <asm/unaligned.h>#include "include/rfcomm.h"#include "include/rfcomm_sec.h"#include "include/btmem.h"#include "include/l2cap.h"#include "include/bluetooth.h"#include "include/local.h"#include "include/bt_errno.h"#endif/****************** DEBUG CONSTANT AND MACRO SECTION ************************//* Defines for the debug macros */#if DEBUG_RFCOMM_RECEIVE_FLOW#define D_REC(fmt...) printk(RFCOMM_DBG_STR fmt)#else#define D_REC(fmt...) #endif#if DEBUG_RFCOMM_SEND_PROCESS#define D_SND(fmt...) printk(RFCOMM_DBG_STR fmt)#else#define D_SND(fmt...)#endif#if DEBUG_RFCOMM_INTERNAL_SIGNALING#define D_CTRL(fmt...) printk(RFCOMM_DBG_STR fmt)#else#define D_CTRL(fmt...)#endif#if PRINT_DATA_ENABLE#define RF_DATA(str, data, len) print_data(str, data, len)#else#define RF_DATA(str, data, len)#endif#define FNC __FUNCTION__ ": "/****************** CONSTANT AND MACRO SECTION ******************************/#define SET_PF(ctr) ((ctr) | (1 << 4)) /* Sets the P/F-bit in the control field */#define CLR_PF(ctr) ((ctr) & 0xef)/* clears the P/F-bit in the control field */#define GET_PF(ctr) (((ctr) >> 4) & 0x1)/* Returns the P/F bit */#define SHORT_CRC_CHECK 2/* Used for uih packets */#define LONG_CRC_CHECK 3/* Used for all packet exepts for the uih packets */#define SHORT_HDR 2/* Short header for short uih packets */#define LONG_HDR 3/* and long header for long uih packets *//* FIXME: Should thsi one be define here? */#define SHORT_PAYLOAD_SIZE 127#define EA 1/* Used for setting the EA field in different packets,  really neccessary? */#define FCS_SIZE 1/* Yes the FCS size is only one byte */#define RFCOMM_MAX_HDR_SIZE 5#define MAX_CREDITS   30#define START_CREDITS 7#define MIN_CREDITS   15#define DEF_RFCOMM_MTU 127/* The values in the control field when sending ordinary rfcomm packets */#define SABM      0x2f#define SABM_SIZE 4#define UA        0x63#define UA_SIZE   4#define DM        0x0f#define DISC      0x43#define UIH       0xef/* The values in the type field in a multiplexer command packet */#define TEST  0x08#define FCON  0x28#define FCOFF 0x18#define MSC   0x38#define RPN   0x24#define RLS   0x14#define PN    0x20#define NSC   0x04/* Define of some V.24 signals modem control signals in RFCOMM */#define FC  0x02#define RTC 0x04#define RTR 0x08#define DV  0x80/* endian-swapping macros for structs */#define swap_long_frame(x) ((x)->h.length.val = le16_to_cpu((x)->h.length.val))#define swap_mcc_long_frame(x) (swap_long_frame(x))#define RFCOMM_CON_TIMEOUT (5*HZ)/****************** TYPE DEFINITION SECTION *********************************//* Typedefinitions of stuctures used for creating and parsing packets, for a   further description of the structures please se the bluetooth core   specification part F:1 and the ETSI TS 07.10 specification  */#include <asm/byteorder.h>#ifdef __LITTLE_ENDIAN_BITFIELDtypedef struct address_field {	u8 ea:1;	u8 cr:1;	u8 d:1;	u8 server_chn:5;} __attribute__ ((packed)) address_field;typedef struct short_length {	u8 ea:1;	u8 len:7;} __attribute__ ((packed)) short_length;typedef union long_length {	struct bits {		u16 ea:1;		u16 len:15;	} __attribute__ ((packed)) bits;	u16 val;} __attribute__ ((packed)) long_length;typedef struct short_frame_head {	address_field addr;	u8 control;	short_length length;} __attribute__ ((packed)) short_frame_head;typedef struct short_frame {	short_frame_head h;	u8 data[0];} __attribute__ ((packed)) short_frame;typedef struct long_frame_head {	address_field addr;	u8 control;	long_length length;	u8 data[0];} __attribute__ ((packed)) long_frame_head;typedef struct long_frame {	long_frame_head h;	u8 data[0];} __attribute__ ((packed)) long_frame;/* Typedefinitions for structures used for the multiplexer commands */typedef struct mcc_type {	u8 ea:1;	u8 cr:1;	u8 type:6;} __attribute__ ((packed)) mcc_type;typedef struct mcc_short_frame_head {	mcc_type type;	short_length length;	u8 value[0];} __attribute__ ((packed)) mcc_short_frame_head;typedef struct mcc_short_frame {	mcc_short_frame_head h;	u8 value[0];} __attribute__ ((packed)) mcc_short_frame;typedef struct mcc_long_frame_head {	mcc_type type;	long_length length;	u8 value[0];} __attribute__ ((packed)) mcc_long_frame_head;typedef struct mcc_long_frame {	mcc_long_frame_head h;	u8 value[0];} __attribute__ ((packed)) mcc_long_frame;/* MSC command */typedef struct v24_signals {	u8 ea:1;	u8 fc:1;	u8 rtc:1;	u8 rtr:1;	u8 reserved:2;	u8 ic:1;	u8 dv:1;} __attribute__ ((packed)) v24_sigs;typedef struct brk_sigs {	u8 ea:1;	u8 b1:1;	u8 b2:1;	u8 b3:1;	u8 len:4;} __attribute__ ((packed)) brk_sigs;typedef struct msc_msg {	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;	address_field dlci;	u8 v24_sigs;//	brk_sigs break_signals;	u8 fcs;} __attribute__ ((packed)) msc_msg;/* RPN command */typedef struct rpn_msg {	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;	address_field dlci;	rpn_values rpn_val;	u8 fcs;} __attribute__ ((packed)) rpn_msg;/* RLS command */  typedef struct rls_msg {	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;	address_field dlci;	u8 error:4;	u8 res:4;	u8 fcs;} __attribute__ ((packed)) rls_msg;/* PN command */typedef struct pn_msg {	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;/* The res1, res2 and res3 values have to be set to 0 by the sender */	u8 dlci:6;	u8 res1:2;	u8 frame_type:4;	u8 credit_flow:4;	u8 prior:6;	u8 res2:2;	u8 ack_timer;	u16 frame_size;	u8 max_nbrof_retrans;	u8 credits;	u8 fcs;} __attribute__ ((packed)) pn_msg;/* NSC-command */typedef struct nsc_msg {	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;	mcc_type command_type;	u8 fcs;} __attribute__ ((packed)) nsc_msg;#elif defined(__BIG_ENDIAN_BITFIELD)typedef struct address_field {	u8 server_chn:5;	u8 d:1;	u8 cr:1;	u8 ea:1;} __attribute__ ((packed)) address_field;typedef struct short_length {	u8 len:7;	u8 ea:1;} __attribute__ ((packed)) short_length;typedef union long_length {	struct bits {		u16 len:15;		u16 ea:1;	} __attribute__ ((packed)) bits;	u16 val;} __attribute__ ((packed)) long_length;typedef struct short_frame_head { 	address_field addr;	u8 control;	short_length length;} __attribute__ ((packed)) short_frame_head;typedef struct short_frame {	short_frame_head h;	u8 data[0];} __attribute__ ((packed)) short_frame;typedef struct long_frame_head { 	address_field addr;	u8 control;	long_length length;	u8 data[0];} __attribute__ ((packed)) long_frame_head;typedef struct long_frame { 	long_frame_head h;	u8 data[0];} __attribute__ ((packed)) long_frame;/* Typedefinitions for structures used for the multiplexer commands */typedef struct mcc_type { 	u8 type:6;	u8 cr:1;	u8 ea:1;} __attribute__ ((packed)) mcc_type;typedef struct mcc_short_frame_head { 	mcc_type type;	short_length length;	u8 value[0];} __attribute__ ((packed)) mcc_short_frame_head;typedef struct mcc_short_frame { 	mcc_short_frame_head h;	u8 value[0];} __attribute__ ((packed)) mcc_short_frame;typedef struct mcc_long_frame_head { 	mcc_type type;	long_length length;	u8 value[0];} __attribute__ ((packed)) mcc_long_frame_head;typedef struct mcc_long_frame { 	mcc_long_frame_head h;	u8 value[0];} __attribute__ ((packed)) mcc_long_frame;/* MSC command */typedef struct v24_signals { 	u8 dv:1;	u8 ic:1;	u8 reserved:2;	u8 rtr:1;	u8 rtc:1;	u8 fc:1;	u8 ea:1;} __attribute__ ((packed)) v24_sigs;typedef struct brk_sigs { 	u8 len:4;	u8 b3:1;	u8 b2:1;	u8 b1:1;	u8 ea:1;} __attribute__ ((packed)) brk_sigs;typedef struct msc_msg { 	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;	address_field dlci;	u8 v24_sigs;//	brk_sigs break_signals;	u8 fcs;} __attribute__ ((packed)) msc_msg;/* RPN command */typedef struct rpn_msg { 	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;	address_field dlci;	rpn_values rpn_val;	u8 fcs;} __attribute__ ((packed)) rpn_msg;/* RLS command */  typedef struct rls_msg { 	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;	address_field dlci;	u8 res:4;	u8 error:4;	u8 fcs;} __attribute__ ((packed)) rls_msg;/* PN command */typedef struct pn_msg { 	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;/* The res1, res2 and res3 values have to be set to 0 by the sender */	u8 res1:2;	u8 dlci:6;	u8 credit_flow:4;	u8 frame_type:4;	u8 res2:2;	u8 prior:6;	u8 ack_timer;	u16 frame_size;	u8 max_nbrof_retrans;	u8 credits;	u8 fcs;} __attribute__ ((packed)) pn_msg;/* NSC-command */typedef struct nsc_msg { 	short_frame_head s_head;	mcc_short_frame_head mcc_s_head;	mcc_type command_type;	u8 fcs;} __attribute__ ((packed)) nsc_msg;#else /* __XXX_ENDIAN */#error Processor endianness unknown!#endif /* __XXX_ENDIAN *//****************** LOCAL FUNCTION DECLARATION SECTION **********************/static void process_mcc(u8* data, u32 len, rfcomm_con *rfcomm, s32 long_pkt);static s32 send_ua(rfcomm_con *rfcomm, u8 dlci);static s32 send_dm(rfcomm_con *rfcomm, u8 dlci);static s32 send_sabm(rfcomm_con *rfcomm, u8 dlci);static s32 send_disc(rfcomm_con *rfcomm, u8 dlci);static s32 send_uih(u8 *data, u32 len, rfcomm_con *rfcomm, u8 dlci);static s32 send_pn_msg(rfcomm_con *rfcomm, u8 prior, u32 frame_size, u8 credit_flow, u8 credits, u8 dlci, u8 cr);static s32 send_nsc_msg(rfcomm_con *rfcomm, mcc_type cmd, u8 cr);static void set_uih_hdr(short_frame *uih_pkt, u8 dlci, u32 len, u8 cr);static u32 crc_check(u8 *data, u32 length, u8 check_sum);static u8 crc_calc(u8 *data, u32 length);static void create_crctable(u8 table[]);static rfcomm_con* get_new_rfcomm_con(void);static rfcomm_con* get_rfcomm_con(u8 line);static s32 get_connected_dlci(rfcomm_con *rfcomm);/****************** GLOBAL VARIABLE DECLARATION SECTION *********************//****************** LOCAL VARIABLE DECLARATION SECTION **********************//* The crctable for the FEC field */static u8 crctable[256];/* One RFCOMM connection for each ttyBTx */rfcomm_con rfcomm_con_list[BT_NBR_DATAPORTS];#ifdef __KERNEL__static struct timer_list rfcomm_timer;#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)static struct wait_queue *rfcomm_disconnect_wq = NULL;#elsestatic wait_queue_head_t rfcomm_disconnect_wq;#endif /* LINUX_VERSION_CODE */rpn_values rpn_val;/****************** FUNCTION DEFINITION SECTION *****************************//**************************************************************************** * Functions reachable outside this file ****************************************************************************/void rfcomm_reset_con(u8 line){		s32 j;	/* check if valid line number */	if (line >= BT_NBR_DATAPORTS)	{		D_ERR(FNC"invalid line!\n");		return;	}	D_CTRL(FNC"line %d\n", line);	rfcomm_con_list[line].magic = RFCOMM_MAGIC;	rfcomm_con_list[line].line = line;	rfcomm_con_list[line].credit_flow = 0;	for (j = 0; j < 62; j++) {		rfcomm_con_list[line].dlci[j].local_credits = 0;		rfcomm_con_list[line].dlci[j].state = DISCONNECTED;		rfcomm_con_list[line].dlci[j].mtu = DEF_RFCOMM_MTU;

⌨️ 快捷键说明

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