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

📄 rfcomm.c

📁 blue tooth protocol stack source code
💻 C
📖 第 1 页 / 共 5 页
字号:
	u32 rfcomm_frame_size;   	if (len > SHORT_PAYLOAD_SIZE) {		long_frame *uih_pkt;		mcc_long_frame *mcc_pkt;    		/* Create long uih packet and long mcc packet */		rfcomm_frame_size = (sizeof(long_frame)				     + sizeof(mcc_long_frame) + len +FCS_SIZE);		tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf)					  + rfcomm_frame_size);		if (!tx_buf) {			D_ERR("rfcomm_test_msg : didn't get a valid tx_buf\n");			return -ENOMEM;		}		tx_buf->cur_len = rfcomm_frame_size;		uih_pkt = (long_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));    		set_uih_hdr((short_frame*) uih_pkt, CTRL_CHAN, len + 			    sizeof(mcc_long_frame), rfcomm->initiator);		uih_pkt->data[uih_pkt->h.length.bits.len] = crc_calc((u8*) uih_pkt, 								SHORT_CRC_CHECK);		mcc_pkt = (mcc_long_frame*) uih_pkt->data;		/* Always one in the TEST messages */		mcc_pkt->h.type.ea = EA;		/* cr tells whether it is a commmand (1) or a response (0) */		mcc_pkt->h.type.cr = cr;		mcc_pkt->h.type.type = TEST;		mcc_pkt->h.length.bits.ea = EA;		mcc_pkt->h.length.bits.len = len;		swap_long_frame(uih_pkt);		swap_mcc_long_frame(mcc_pkt);		memcpy(mcc_pkt->value,test_pattern,len);	} else if (len > (SHORT_PAYLOAD_SIZE-sizeof(mcc_short_frame))) {		long_frame *uih_pkt;		mcc_short_frame *mcc_pkt;    		/* Create long uih packet and short mcc packet */		rfcomm_frame_size = (sizeof(long_frame)				     + sizeof(mcc_short_frame) + len+FCS_SIZE);		tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf)					  + rfcomm_frame_size);		if (!tx_buf) {			D_ERR("rfcomm_test_msg : didn't get a valid tx_buf\n");			return -ENOMEM;		}				tx_buf->cur_len = rfcomm_frame_size;		uih_pkt = (long_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));    		set_uih_hdr((short_frame*) uih_pkt, CTRL_CHAN, len +			    sizeof(mcc_short_frame), rfcomm->initiator);		uih_pkt->data[uih_pkt->h.length.bits.len] = crc_calc((u8*) uih_pkt, 								SHORT_CRC_CHECK);		mcc_pkt = (mcc_short_frame*) uih_pkt->data;		/* Always one in the TEST messages */		mcc_pkt->h.type.ea = EA;		/* cr tells whether it is a commmand (1) or a response (0) */		mcc_pkt->h.type.cr = cr;		mcc_pkt->h.type.type = TEST;		mcc_pkt->h.length.ea = EA;		mcc_pkt->h. length.len = len;		swap_long_frame(uih_pkt);		memcpy(mcc_pkt->value,test_pattern,len);	} else {		short_frame *uih_pkt;		mcc_short_frame *mcc_pkt;		/* Creat short uih packet and short mcc packet */		rfcomm_frame_size = (sizeof(short_frame)				     + sizeof(mcc_short_frame) + len+FCS_SIZE);		tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf)					  + rfcomm_frame_size);		if (!tx_buf) {			D_ERR("rfcomm_test_msg : didn't get a valid tx_buf\n");			return -ENOMEM;		}				tx_buf->cur_len = rfcomm_frame_size;    		uih_pkt = (short_frame*) (tx_buf->data +sizeof(rfcomm_tx_buf));    		set_uih_hdr((void*) uih_pkt, CTRL_CHAN, len			    + sizeof(mcc_short_frame), rfcomm->initiator);		uih_pkt->data[uih_pkt->h.length.len] = crc_calc((u8*) uih_pkt, 								SHORT_CRC_CHECK);		mcc_pkt = (mcc_short_frame*) uih_pkt->data;    		/* Always one in the TEST messages */		mcc_pkt->h.type.ea = EA;		/* cr tells whether it is a commmand (1) or a response (0) */		mcc_pkt->h.type.cr = cr;		mcc_pkt->h.type.type = TEST;		mcc_pkt->h.length.ea = EA;		mcc_pkt->h. length.len = len;		memcpy(mcc_pkt->value,test_pattern,len);    	}	return l2cap_send_data(tx_buf, rfcomm->l2cap);}/* Turns on the RFCOMM flow control */s32 rfcomm_fcon_msg(rfcomm_con *rfcomm, u8 cr){	bt_tx_buf *tx_buf;	short_frame *uih_pkt;	mcc_short_frame *mcc_pkt;	u32 rfcomm_frame_size;  	rfcomm_frame_size = (sizeof(short_frame) + sizeof(mcc_short_frame)			     + FCS_SIZE);	tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);	if (!tx_buf) {		D_ERR("rfcomm_fcon_msg : didn't get a valid tx_buf\n");		return -ENOMEM;	}	tx_buf->cur_len = rfcomm_frame_size;  	uih_pkt = (short_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));	set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame),		    rfcomm->initiator);	uih_pkt->data[sizeof(mcc_short_frame)] = crc_calc((u8*) uih_pkt, 							  SHORT_CRC_CHECK);	mcc_pkt = (mcc_short_frame*) (uih_pkt->data);  	mcc_pkt->h.type.ea = EA;	mcc_pkt->h.type.cr = cr;	mcc_pkt->h.type.type = FCON;	mcc_pkt->h.length.ea = EA;	mcc_pkt->h.length.len = 0;  	return l2cap_send_data(tx_buf, rfcomm->l2cap);}/* Turns off the RFCOMM flow control */s32 rfcomm_fcoff_msg(rfcomm_con *rfcomm, u8 cr){	bt_tx_buf *tx_buf;	short_frame *uih_pkt;	mcc_short_frame *mcc_pkt;	u32 rfcomm_frame_size;  	rfcomm_frame_size = (sizeof(short_frame) + sizeof(mcc_short_frame)			     + FCS_SIZE);	tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);	if (!tx_buf) {		D_ERR("rfcomm_fcoff_msg : didn't get a valid tx_buf\n");		return -ENOMEM;	}	tx_buf->cur_len = rfcomm_frame_size;  	uih_pkt = (short_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf));	set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame),		    rfcomm->initiator);	uih_pkt->data[sizeof(mcc_short_frame)] = crc_calc((u8*) uih_pkt, 							  SHORT_CRC_CHECK);	mcc_pkt = (mcc_short_frame*) (uih_pkt->data);	mcc_pkt->h.type.ea = 1;	mcc_pkt->h.type.cr = cr;	mcc_pkt->h.type.type = FCOFF;	mcc_pkt->h.length.ea = 1;	mcc_pkt->h.length.len = 0;	return l2cap_send_data(tx_buf, rfcomm->l2cap);}s32 rfcomm_rpn_msg(rfcomm_con *rfcomm, u8 cr, u8 dlci, u8 req){	bt_tx_buf *tx_buf;	rpn_msg* rpn_pkt;	u32 rfcomm_frame_size;	u32 rfcomm_payload_size;	rfcomm_frame_size = sizeof(rpn_msg);	if (req) {		rfcomm_frame_size -= sizeof(rpn_values);	}		rfcomm_payload_size = (rfcomm_frame_size - sizeof(short_frame)			       - FCS_SIZE);		tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);	if (!tx_buf) {		D_ERR("rfcomm_rpn_msg : didn't get a valid tx_buf\n");		return -ENOMEM;	}	tx_buf->cur_len = rfcomm_frame_size;  	rpn_pkt = (rpn_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf));  	set_uih_hdr((short_frame*) rpn_pkt, CTRL_CHAN, rfcomm_payload_size,		    rfcomm->initiator);	rpn_pkt->fcs = crc_calc((u8*) rpn_pkt, SHORT_CRC_CHECK);	rpn_pkt->mcc_s_head.type.ea = EA;	rpn_pkt->mcc_s_head.type.cr = cr;	rpn_pkt->mcc_s_head.type.type = RPN;	rpn_pkt->mcc_s_head.length.ea = EA;	rpn_pkt->dlci.ea = EA;	rpn_pkt->dlci.cr = 1; /* Fixed value */	rpn_pkt->dlci.d = dlci & 1;	rpn_pkt->dlci.server_chn = (dlci >> 1);		if (req) {		rpn_pkt->mcc_s_head.length.len = 1;		/* Fix, since the packet is ends here when it is a request */		rpn_pkt->rpn_val.bit_rate = rpn_pkt->fcs;		return l2cap_send_data(tx_buf, rfcomm->l2cap);	} else {		rpn_pkt->mcc_s_head.length.len = 8;		memcpy(&(rpn_pkt->rpn_val), &rpn_val, sizeof(rpn_values));		//print_data("",(u8*) rpn_pkt, rfcomm_frame_size);		return l2cap_send_data(tx_buf, rfcomm->l2cap);	}}s32 rfcomm_rls_msg(rfcomm_con *rfcomm, u8 cr, u8 dlci, u8 err_code){	bt_tx_buf *tx_buf;	rls_msg* rls_pkt;	u32 rfcomm_frame_size;	u32 rfcomm_payload_size;	rfcomm_frame_size = sizeof(rls_msg);	rfcomm_payload_size = rfcomm_frame_size - sizeof(short_frame)-FCS_SIZE;	tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);	if (!tx_buf) {		D_ERR("rfcomm_rls_msg : didn't get a valid tx_buf\n");		return -ENOMEM;	}	tx_buf->cur_len = rfcomm_frame_size;  	rls_pkt = (rls_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf));  	set_uih_hdr((short_frame*) rls_pkt, CTRL_CHAN, rfcomm_payload_size,		    rfcomm->initiator);	rls_pkt->fcs = crc_calc((u8*) rls_pkt, SHORT_CRC_CHECK);  	rls_pkt->mcc_s_head.type.ea = EA;	rls_pkt->mcc_s_head.type.cr = cr;	rls_pkt->mcc_s_head.type.type = RLS;	rls_pkt->mcc_s_head.length.ea = EA;	rls_pkt->mcc_s_head.length.len = 2;  	rls_pkt->dlci.ea = EA;	rls_pkt->dlci.cr = 1; /* Fixed value */	rls_pkt->dlci.d = dlci & 1;	rls_pkt->dlci.server_chn = dlci >> 1;	rls_pkt->error = err_code;	rls_pkt->res = 0;  	return l2cap_send_data(tx_buf, rfcomm->l2cap);}/* Sends an PN-messages and sets the not negotiable parameters to their   default values in RFCOMM */s32 send_pn_msg(rfcomm_con *rfcomm, u8 prior, u32 frame_size, u8 credit_flow, u8 credits, u8 dlci, u8 cr){	bt_tx_buf *tx_buf;	pn_msg *pn_pkt;	u32 rfcomm_frame_size;	D_CTRL("send_pn_msg: DLCI 0x%02x, prior:0x%02x, frame_size:%d, credit_flow:%x, credits:%d, cr:%x\n",	      dlci, prior, frame_size, credit_flow, credits, cr);	rfcomm_frame_size = sizeof *pn_pkt;	tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);	if (!tx_buf) {		D_ERR("send_pn_msg : didn't get a valid tx_buf\n");		return -ENOMEM;	}	tx_buf->cur_len = rfcomm_frame_size;	pn_pkt = (pn_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf));	/* Set the UIH headers */	set_uih_hdr((void*) pn_pkt, CTRL_CHAN, rfcomm_frame_size - 		    (sizeof(short_frame) + FCS_SIZE), rfcomm->initiator);	pn_pkt->fcs = crc_calc((u8*) pn_pkt, SHORT_CRC_CHECK);	/* set the MCC-packet header */	pn_pkt->mcc_s_head.type.ea = 1;	pn_pkt->mcc_s_head.type.cr = cr;	pn_pkt->mcc_s_head.type.type = PN;	pn_pkt->mcc_s_head.length.ea = 1;	/* The PN packet has a fix length of 8 bytes */	pn_pkt->mcc_s_head.length.len = 8;	/* Set the parameters in the PN-packet */	pn_pkt->res1 = 0;	pn_pkt->res2 = 0;	pn_pkt->dlci = dlci;	pn_pkt->frame_type = 0;	pn_pkt->credit_flow = credit_flow;	pn_pkt->prior = prior;	pn_pkt->ack_timer = 0;	put_unaligned(cpu_to_le16(frame_size), &pn_pkt->frame_size);	pn_pkt->credits = credits;	pn_pkt->max_nbrof_retrans = 0;  	return l2cap_send_data(tx_buf, rfcomm->l2cap);}/* Sendares a Not supported command - command, which needs 3 bytes */s32 send_nsc_msg(rfcomm_con *rfcomm, mcc_type cmd, u8 cr) {	bt_tx_buf *tx_buf;	nsc_msg *nsc_pkt;	u32 rfcomm_frame_size;  	rfcomm_frame_size = sizeof(nsc_msg);	tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);	if (!tx_buf) {		D_ERR("send_nsc_msg : didn't get a valid tx_buf\n");		return -ENOMEM;	}	tx_buf->cur_len = rfcomm_frame_size;		nsc_pkt = (nsc_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf)); 	set_uih_hdr((void*) nsc_pkt, CTRL_CHAN, sizeof(nsc_msg)		    - sizeof(short_frame) - FCS_SIZE, rfcomm->initiator);	nsc_pkt->fcs = crc_calc((u8*) nsc_pkt, SHORT_CRC_CHECK);	nsc_pkt->mcc_s_head.type.ea = 1;	nsc_pkt->mcc_s_head.type.cr = cr;	nsc_pkt->mcc_s_head.type.type = NSC;	nsc_pkt->mcc_s_head.length.ea = 1;	nsc_pkt->mcc_s_head.length.len = 1;	nsc_pkt->command_type.ea = 1;	nsc_pkt->command_type.cr = cmd.cr;	nsc_pkt->command_type.type = cmd.type;	return l2cap_send_data(tx_buf, rfcomm->l2cap);}s32 rfcomm_msc_msg(rfcomm_con *rfcomm, u8 value, u8 cr, u8 dlci){	bt_tx_buf *tx_buf;	msc_msg *msc_pkt;	u32 rfcomm_frame_size;  	D_CTRL(FNC"val:%d, cr:%d, dlci:%d\n", value, cr, dlci);	rfcomm_frame_size = sizeof(msc_msg);	tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size);	if (!tx_buf) {		D_ERR(FNC"didn't get a valid tx_buf\n");		return -ENOMEM;	}	tx_buf->cur_len = rfcomm_frame_size;	msc_pkt = (msc_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf)); 	set_uih_hdr((void*) msc_pkt, CTRL_CHAN, sizeof(msc_msg)		    - sizeof(short_frame) - FCS_SIZE, rfcomm->initiator);	msc_pkt->fcs = crc_calc((u8*) msc_pkt, SHORT_CRC_CHECK);	msc_pkt->mcc_s_head.type.ea = 1;	msc_pkt->mcc_s_head.type.cr = cr;	msc_pkt->mcc_s_head.type.type = MSC;	msc_pkt->mcc_s_head.length.ea = 1;	msc_pkt->mcc_s_head.length.len = 2;	msc_pkt->dlci.ea = 1;	msc_pkt->dlci.cr = 1;	msc_pkt->dlci.d = dlci & 1;	msc_pkt->dlci.server_chn = (dlci >> 1) & 0x1f;	msc_pkt->v24_sigs = value;return l2cap_send_data(tx_buf, rfcomm->l2cap);}voidset_uih_hdr(short_frame *uih_pkt, u8 dlci, u32 len, u8 cr){	uih_pkt->h.addr.ea = 1;	uih_pkt->h.addr.cr = cr;	uih_pkt->h.addr.d = dlci & 0x1;	uih_pkt->h.addr.server_chn = dlci >> 1;	uih_pkt->h.control = CLR_PF(UIH);		if (len > SHORT_PAYLOAD_SIZE) {		((long_frame*) uih_pkt)->h.length.bits.ea = 0;		((long_frame*) uih_pkt)->h.length.bits.len = len;  	} else {		uih_pkt->h.length.ea = 1;		uih_pkt->h.length.len = len;  	}}rfcomm_con* get_new_rfcomm_con(void){	s32 i = 0;	D_CTRL(FNC"rfcomm_con -> ttyBT%d\n",i);        for (i = 0 ; i < BT_NBR_DATAPORTS ; i ++)        {           if (rfcomm_con_list[i].dlci[0].state == DISCONNECTED)           {              rfcomm_con_list[i].l2cap = NULL;              return &rfcomm_con_list[i];           }        }        return NULL;}rfcomm_con* get_rfcomm_con(u8 line){	if(line >= BT_NBR_DATAPORTS) {		return NULL;	}	return &rfcomm_con_list[line];}s32valid_dlci(u8 dlci){	if ((dlci < 62) && (dlci > 1)) {		return TRUE;	} else {		return FALSE;	}}/* fetches the 'last' non DISCONNECTED dlci number in this session,    returns -1 if no connected dlci was found */s32 get_connected_dlci(rfcomm_con *rfcomm){	s32 tmp;	tmp = 61;	while ((tmp >= 0) && (rfcomm != NULL) && 	       (rfcomm->dlci[tmp].state == DISCONNECTED)) {		tmp--;	}	return tmp;}/* Functions for the crc-check and calculation */#define CRC_VALID 0xcf/* This functions check whether the checksum is correct or not. Length is   the number of bytes in the message, data points to the beginning of the   message */u32 crc_check(u8 *data, u32 length, u8 check_sum){	u8 fcs = 0xff;	RF_DATA(FNC, data, length);	while (length--) {		fcs = crctab

⌨️ 快捷键说明

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