?? rfcomm.c
字號:
/* * rfcomm.c -- Implementation of Bluetooth RFCOMM with TS 07.10, * Serial Port Emulation * * Copyright (C) 2000, 2001 Axis Communications AB * * Author: Mats Friden <mats.friden@axis.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Exceptionally, Axis Communications AB grants discretionary and * conditional permissions for additional use of the text contained * in the company's release of the AXIS OpenBT Stack under the * provisions set forth hereunder. * * Provided that, if you use the AXIS OpenBT Stack with other files, * that do not implement functionality as specified in the Bluetooth * System specification, to produce an executable, this does not by * itself cause the resulting executable to be covered by the GNU * General Public License. Your use of that executable is in no way * restricted on account of using the AXIS OpenBT Stack code with it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the provisions of the GNU* General Public License. * * $Id: rfcomm.c,v 1.127 2001/10/18 15:49:25 pkj Exp $ * *//****************** 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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -