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

📄 sdp.c

📁 blue tooth 核心协议栈在linux上的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			l2cap->upper_con = (void*) sdp;		} else 			DSYS(__FUNCTION__ " already sent back a pos response\n");	} else {		D_ERR(__FUNCTION__ " couldn't find the correct sdp_connection\n");		bt_connect_cfm(CREATE_SDP_ID(sdp->line, 0), -1);	}}/* Sends back info about  MTU, outflow, flush timeout   Get this data from some parameter area controlled by    control block ? */void sdp_config_ind(l2cap_con* l2cap){	D_MISC(__FUNCTION__ " remote cid : %d\n", l2cap->remote_cid);	/* FIXME -- Check whether the received params are 	   acceptable, accept all for now */	/* check if we have sent a pos response yet */	if (!l2ca_remote_conf_done(l2cap)) {		/* still haven't sent a pos configure response*/		if (l2ca_config_rsp(l2cap, 0, NULL, CONF_SUCCESS)) {			D_ERR(__FUNCTION__ " Conf rsp failed\n");		}	} else 		DSYS("already have sent back a pos response\n");	/* check if we received a pos response on a 	   previous config req */ 	if (!l2ca_local_conf_done(l2cap)) {		/* FIXME -- use real options not static values */				if (l2ca_config_req(l2cap, 0, NULL, 0, 0)) {			D_ERR(__FUNCTION__ " Config request failed\n");		}	} else 		D_REC("already ready with config req\n");}#ifdef __KERNEL__/*---------------------------------------------------------------------------*//* sdpStartRequest() - This function is used to initiate a SDP request.      *//*---------------------------------------------------------------------------*/int sdpStartRequest(u8 sdpIndex, u8 sdpCommand, u8 *pduData, u16 pduLength){	s32 returnValue = -1;	/*-------------------------------------------------------------------*/	/* Check the connection state.  State must be SDP_CONNECTED.         */	/*-------------------------------------------------------------------*/	if (sdp_con_list[sdpIndex].state == SDP_CONNECTED) {		/*-----------------------------------------------------------*/		/* Initiate a query here. Send a SDP_SERVICESEARCH_REQ.      */		/*-----------------------------------------------------------*/		sdp_tx_buf *sdp_buf;		bt_tx_buf *tx_buf;		u32 sdp_frame_len;		u16 trans_id;   		/*-----------------------------------------------------------*/		/* What are we sending in the PDU?                           */		/*                                                           */		/* A BB CC D E F GG                                          */		/* A   = SDP_SERVICESEARCH_REQ                               */		/* BB  = Transaction ID                                      */		/* CC  = PDU Length (not including header).                  */		/* D   = Data Element Sequence Header (0x35)                 */		/* E   = Number of bytes (which in this case is 3)           */		/* F   = UUID16_HDR (1 bytes) (0x19).                        */		/* GG  = PublicBrowseGroup (0x1002).                         */		/* Total number of bytes 10.                                 */		/*-----------------------------------------------------------*/		/*-----------------------------------------------------------*/		/* Generate random tranaction ID.                            */		/*-----------------------------------------------------------*/		get_random_bytes(&trans_id, 2 /* bytes */);   		/*-----------------------------------------------------------*/		/* Allocate the buffer.                                      */		/*-----------------------------------------------------------*/		sdp_frame_len = SDP_HDR_SIZE + pduLength;		tx_buf = subscribe_bt_buf(sizeof(sdp_tx_buf) + sdp_frame_len);		if (!tx_buf) {			D_ERR(__FUNCTION__ " failed to get tx buffer\n");		} else {			/*---------------------------------------------------*/			/* Set the current length of the transmission buffer */			/*---------------------------------------------------*/			tx_buf->cur_len = sdp_frame_len;			/*---------------------------------------------------*/			/* Poke the SDP header.                              */			/* Notice that the "poking" is in little endian      */			/*---------------------------------------------------*/			sdp_buf = (sdp_tx_buf*) (tx_buf->data);			sdp_buf->frame[0] = sdpCommand;			sdp_buf->frame[1] = (trans_id >> 8) & 0xff;			sdp_buf->frame[2] = trans_id & 0xff;			sdp_buf->frame[3] = (pduLength >> 8) & 0xff;			sdp_buf->frame[4] = pduLength & 0xff;			/*---------------------------------------------------*/			/* Copy the pduData.                                 */			/*---------------------------------------------------*/			memcpy(&sdp_buf->frame[5], pduData, pduLength);			/*---------------------------------------------------*/			/* Send the l2cap data transfer.                     */			/*---------------------------------------------------*/			l2cap_send_data(tx_buf, sdp_con_list[sdpIndex].l2cap);			DSYS(__FUNCTION__ " Client finished sending data.\n");			returnValue = 0; 		}	} else {		/*-----------------------------------------------------------*/		/* No active SDP connection here!.  This is an error.        */		/*-----------------------------------------------------------*/		D_ERR(__FUNCTION__ " No active connection on SDP ID = %d\n", sdpIndex);	}	return returnValue;}  /* End of sdpStartRequest() */#endif /* __KERNEL__ */void sdp_config_cfm(l2cap_con *l2cap, s32 status){	sdp_con *sdp = NULL;	D_MISC(__FUNCTION__ ", remote cid : %d\n", l2cap->remote_cid);	if (!l2cap->upper_con) {		D_ERR("%s l.%d NULL/magic failed\n", 		      __FILE__, __LINE__);		return;	}	/*-------------------------------------------------------------------*/	/* Get a pointer to the correct SDP data connection structure entry. */	/*-------------------------------------------------------------------*/	sdp = (sdp_con *)l2cap->upper_con;	/*-------------------------------------------------------------------*/	/* Set the state of this SDP connection to SDP_CONNECTED.            */	/*-------------------------------------------------------------------*/	sdp->state = SDP_CONNECTED;	/*-------------------------------------------------------------------*/	/* Check to see if we're the initiator on this running stack.  If    */	/* initator, this is a SDP client connection request.  If not, then  */	/* we're the server and must process requests.                       */	/*-------------------------------------------------------------------*/	if (sdp->initiator) {		/*-----------------------------------------------------------*/		/* We are the initator.  Therefore a SDP client on on this   */		/* machine initiated the connection.  Inform the "ioctl" or  */		/* bluetooth layer.                                          */		/*-----------------------------------------------------------*/		bt_connect_cfm(CREATE_SDP_ID(sdp->line, 0),			       ((sdp_con *)l2cap->upper_con)->id);	} else {		DSYS(__FUNCTION__ ", we are the server\n");	}}void sdp_disconnect_req(u32 sdp_id){	s32 err;		/*-------------------------------------------------------------------*/	/* Get a handle to the proper SDP connection entry.                  */	/*-------------------------------------------------------------------*/	sdp_con *sdp = &sdp_con_list[sdp_id];	/*-------------------------------------------------------------------*/	/* Do some sanity checking.  If the sdpConnectionIndex is within     */	/* range AND the state is either SDP_CONNECTING or SDP_CONNECTED     */	/* then disconnect this connection.                                  */	/*-------------------------------------------------------------------*/	if (sdp_id <= MAX_NBR_SDP &&	    (sdp->state == SDP_CONNECTING || sdp->state == SDP_CONNECTED)) {		if ((err = l2ca_disconnect_req(sdp_con_list[sdp_id].l2cap)) != 0) {			D_ERR(__FUNCTION__ ", An error with error code %d occured during disconnetion of sdp channel %d\n", err, sdp_id);			sdp_con_list[sdp_id].state = SDP_DISCONNECTED;			sdp_con_list[sdp_id].l2cap = NULL;  		} #if 0		/* sdp_disconnect_cfm wakes up this queue, but by the time we		   get here it already did, so we sleep forever!		 */else {			interruptible_sleep_on(&sdp_disc_wq);		}#endif	}}void sdp_disconnect_ind(l2cap_con *l2cap) {	sdp_con *sdp;	D_MISC(__FUNCTION__ ", remote cid : %d\n", l2cap->remote_cid);   	sdp = (sdp_con*) l2cap->upper_con;	sdp->state = SDP_DISCONNECTED;	sdp->l2cap = NULL;	l2ca_disconnect_rsp(l2cap);}void sdp_disconnect_cfm(l2cap_con *l2cap){	sdp_con *sdp;	u8 line;	D_MISC(__FUNCTION__ ", remote cid : %d\n", l2cap->remote_cid);	sdp = (sdp_con*) l2cap->upper_con;	line = sdp->line;	sdp->state = SDP_DISCONNECTED;	sdp->l2cap = NULL;  	bt_unregister_sdp(line);	wake_up_interruptible(&sdp_disc_wq);}void sdp_receive_data(l2cap_con *l2cap, u8* data, u32 len){	sdp_con *sdp;	data_struct *db_hdl;	D_REC(__FUNCTION__ "\n");	if (role == 0) {		print_data(__FUNCTION__, data, len);		return;	}		PRINTPKT(__FUNCTION__, data, len);  	sdp = (sdp_con*) l2cap->upper_con;#ifndef __KERNEL__	if (sdp_sock < 0) {		send_error_rsp(sdp, le16_to_cpu(get_unaligned((u16 *)&data[1])), 6);	}#endif	/*--------------------------------------------------------*/	/* If __KERNEL__ mode, we must bounce the received data   */	/* up if this stack initiated the request.                */	/*--------------------------------------------------------*/#if __KERNEL__	if (sdp->initiator) {		u8 *dataPointer = NULL;		/*------------------------------------------------------*/		/* Grab a copy of the data to send up.                  */		/*------------------------------------------------------*/		dataPointer = (u8 *) kmalloc(len, GFP_ATOMIC);		memcpy(dataPointer, data, len);		bt_send_sdp_data_received(sdp->line, dataPointer, len);	} else#endif	{		db_hdl = (data_struct*)database_query.query;		db_hdl->l2cap_mtu = l2cap->remote_mtu;		db_hdl->sdp_con_id = sdp->id;		db_hdl->len = len;		memcpy(db_hdl->data, data, len);		database_query.count = sizeof(data_struct) + len;#ifdef __KERNEL__		D_PROC("wake_up process %i (%s) awakening\n", current->pid, current->comm);		wake_up_interruptible(&database_wq);		D_PROC("wake_up process %i (%s) woke up\n", current->pid, current->comm);#else		sdp_doquery(sdp_sock, database_query.query, database_query.count);#endif	}}#ifndef __KERNEL__ s32send_error_rsp(sdp_con *sdp, u16 trans_id, u16 err_code){	sdp_tx_buf *sdp_buf;	bt_tx_buf *tx_buf;	u32 sdp_frame_len;	u32 pdu_len;	/* Since we do not send any error information the pdu length is just	   the size of the error code length, which is two bytes */	pdu_len = 2;	sdp_frame_len = SDP_HDR_SIZE + pdu_len;	tx_buf = subscribe_bt_buf(sizeof(sdp_tx_buf) + sdp_frame_len);	if (!tx_buf) {		D_ERR(__FUNCTION__ " failed to get tx buffer\n");		return -1;	}	tx_buf->cur_len = sdp_frame_len;		sdp_buf = (sdp_tx_buf*) (tx_buf->data);	sdp_buf->frame[0] = SDP_ERROR_RSP;	sdp_buf->frame[1] = (trans_id >> 8) & 0xff;	sdp_buf->frame[2] = trans_id & 0xff;	sdp_buf->frame[3] = (pdu_len >> 8) & 0xff;	sdp_buf->frame[4] = pdu_len & 0xff;	sdp_buf->frame[5] = (err_code >> 8) & 0xff;	sdp_buf->frame[6] = err_code & 0xff;		return l2cap_send_data(tx_buf, sdp->l2cap);}#endif#ifdef __KERNEL__s32 sdp_proc_dir_entry_read(char *buf, char **start, off_t offset,			    s32 len, s32 unused){#ifdef USE_NEW_PROC	return sdp_database_read(NULL, buf, len, 0);#else	return sdp_database_read(NULL, NULL, buf, len);#endif}#ifdef USE_NEW_PROCssize_t sdp_database_read(struct file *f, char *buf, 			  size_t count, loff_t *offset)#elses32 sdp_database_read(struct inode *inode, struct file * file,		      char * buf, s32 count)#endif{	s32 len;		D_PROC(__FUNCTION__ " Someone is trying to read %d bytes from sdp proc-file\n",	       count);	cli();	if (database_query.count <= 0) {		D_PROC(__FUNCTION__ " No bytes available, going to sleep\n");		interruptible_sleep_on(&database_wq);	}	sti();	len = MIN(count, database_query.count);	copy_to_user(buf, database_query.query, len);	if (database_query.count > len) {		memmove(database_query.query,			database_query.query + len,			database_query.count - len);	}	database_query.count -= len;	D_PROC(__FUNCTION__ " Returning %d bytes\n", len);	return len;}#ifdef USE_NEW_PROCssize_t sdp_database_write(struct file *f, const char *buf, 			   size_t count, loff_t *offset)#elses32 sdp_database_write(struct inode *inode, struct file * file,		       const char * buf, s32 count)#endif{	static data_struct db_hdl;	sdp_tx_buf *sdp_buf;	s32 read1 = 0;	s32 read2 = 0;	D_PROC(__FUNCTION__ " Someone wrote %d bytes to sdp proc-file\n", count);	if (!bt_initiated())		return 0;		if (!db_write_tx_buf) {		read1 = MIN(sizeof db_hdl - db_write_recv, count);		copy_from_user(&db_hdl + db_write_recv, buf, read1);		db_write_recv += read1;		if (db_write_recv < sizeof db_hdl)			return read1;		db_write_tx_buf = subscribe_bt_buf(sizeof *sdp_buf + db_hdl.len);		if (!db_write_tx_buf) {			D_ERR(__FUNCTION__ " failed to get tx buffer\n");			db_write_recv -= read1;			return -ENOMEM;		}		db_write_tx_buf->cur_len = db_hdl.len;		count -= read1;		buf += read1;		db_write_recv = 0;	}	sdp_buf = (sdp_tx_buf*)db_write_tx_buf->data;	if (db_write_recv < db_hdl.len) {		read2 = MIN(db_hdl.len - db_write_recv, count);		copy_from_user(sdp_buf->frame + db_write_recv, buf, read2);		db_write_recv += read2;		if (db_write_recv < db_hdl.len)			return read1 + read2;	}	D_XMIT(__FUNCTION__ " preparing to send %d bytes data to sdp_con[%d]\n", db_hdl.len, db_hdl.sdp_con_id);	PRINTPKT("Data to be sent to client:", db_hdl.data, db_hdl.len);	l2cap_send_data(db_write_tx_buf, sdp_con_list[db_hdl.sdp_con_id].l2cap);	db_write_tx_buf = NULL;	db_write_recv = 0;	return read1 + read2;}#else /* __KERNEL__ */s32 sdp_doquery(s32 fd, u8 *request, s32 len){	s32 n;	u8 tmpbuf[512];	data_struct *db_hdl;	s32 recv;	D_XMIT("sdp_doquery : sending request %d bytes\n", len);	write(fd, request, len);		if ((n = read(fd, tmpbuf, 512)) < 0)		return n;	D_REC(__FUNCTION__ ", Received %d bytes\n", n);		db_hdl = (data_struct*) tmpbuf;		/* what if not all is written once */	for (recv = n; recv < sizeof *db_hdl + db_hdl->len; recv += n)		if ((n = read(fd, tmpbuf + recv, 512 - recv)) < 0)			return n;	sdp_send_data(&sdp_con_list[db_hdl->sdp_con_id], db_hdl->data, db_hdl->len); 		return recv;}#endifs32sdp_send_data(sdp_con *sdp, u8 *data, u32 len){	sdp_tx_buf *sdp_buf;	bt_tx_buf *tx_buf;		tx_buf = subscribe_bt_buf(sizeof(sdp_tx_buf) + len);	if (!tx_buf) {		D_ERR("sdp_send_data:  failed to get tx buffer\n");		return -1;	}	tx_buf->cur_len = len;	sdp_buf = (sdp_tx_buf*) (tx_buf->data);	memcpy(sdp_buf->frame, data, len);	PRINTPKT("SDP sending:", (u8*) data, len);	return l2cap_send_data(tx_buf, sdp->l2cap);}sdp_con* get_free_sdp_con(void){	s32 i = 0;	while ((i < MAX_NBR_SDP) && 	       (sdp_con_list[i].state != SDP_DISCONNECTED)) {		i++;	}	if (i == MAX_NBR_SDP) {		return 0;	}	return &sdp_con_list[i];}/****************** END OF FILE sdp.c ***************************************/

⌨️ 快捷键说明

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