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

📄 l2cap.c

📁 linux系统下的关于蓝牙模块的源代码!十分的经典的程序!
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS                        disable_rtx(con);#endif			ENTERSTATE(con, CONFIG);			PRINTSTATE(con);			l2ca_connect_cfm(con, conrsp->result);			break;           		case RES_PENDING:			/* wake up when real con resp comes */			l2ca_connect_pnd(con, conrsp->status);#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS			/* Disable RTX timer and start ERTX */                        disable_rtx(con);			start_ertx(con, ERTX_TIMEOUT);#endif			D_STATE(__FUNCTION__ ": connection pending\n");			break;		case RES_PSMNEG:			DSYS(__FUNCTION__ ": connection refused, psm 0x%x not supp\n", 			     con->psm);			failure = 1;			break;		case RES_SECNEG:			DSYS(__FUNCTION__ ": connection refused, security block\n");			failure = 1;			break;           		case RES_NOSRC:			DSYS(__FUNCTION__ ": connection refused, no resources\n");			failure = 1;			break;           		default:			D_ERR(__FUNCTION__ ": SIG_CONRSP\n");			break;		}         		if (failure) {#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS			disable_rtx(con);			disable_ertx(con);#endif			l2ca_connect_cfm(con, MSGCODE(MSG_LAYER_L2CAP, conrsp->result));			l2ca_wakeup("Got connect rsp neg", con);						ENTERSTATE(con, CLOSED);			delete_con(con);		}		break;       	case SIG_CONFRSP:		D_STATE(__FUNCTION__ ": Got configuration response\n");		confrsp = (sig_confrsp *)rsp->data;		confrsp->src_cid = le16_to_cpu(confrsp->src_cid);		confrsp->flags = le16_to_cpu(confrsp->flags);		confrsp->result = le16_to_cpu(confrsp->result);		opt_len = rsp->len - sizeof(sig_confrsp);		PRINTPKT(__FUNCTION__ ": config response", rsp->data, rsp->len);		/* check that remote CID is in list */		if ((con = get_lcon(confrsp->src_cid)) == NULL)			return;		if (con->current_state != CONFIG) {			D_ERR(__FUNCTION__ ": SIG_CONFRSP invalid state\n");			PRINTSTATE(con);			return; 		}			       		/* match id with request */		if (!id_matched(con, rsp->id)) {			D_ERR(__FUNCTION__ ": ID doesn't match ! [%d:%d]\n", con->sig_id_sent, rsp->id);						return;		}		switch (confrsp->result) {		case CONF_SUCCESS:#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS			disable_rtx(con);#endif			con->conf_req_ready = TRUE; 			if (!con->conf_rsp_ready) {				/* Upper layers still haven't replied pos */				D_STATE(__FUNCTION__": Still haven't replied pos on other sides conf req\n");				return ;			} else {								ENTERSTATE(con, OPEN);				PRINTSTATE(con);				DSYS("l2cap channel (%d,%d) [%s] connected\n", 				     con->local_cid, con->remote_cid, 				     psm2str(con->psm));								/* notify upper layers that we successfully				   opened a connection ! */				l2ca_config_cfm(con, confrsp->result);				/* reset variable */				con->conf_req_sent = 0;				return;			}					case CONF_FAILURE:			/* store remote side configuration */			parse_options(con, confrsp->options, opt_len);			D_STATE(__FUNCTION__ ": config failure, unacceptable params\n");			l2ca_config_cfm(con, confrsp->result);			break;           		case CONF_REJ:			D_STATE(__FUNCTION__ ": connection refused, no reason\n");			l2ca_config_cfm(con, confrsp->result);			break;           		case CONF_UNKNOWN:			D_STATE(__FUNCTION__ ": connection refused, unknown options\n");			l2ca_config_cfm(con, confrsp->result);			break;            		default:			D_ERR(__FUNCTION__ ": SIG_CONFRSP\n");			break;		}     		/* If we end up here, config failed */#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS		disable_rtx(con);#endif		if (con->current_state != CONFIG)			D_ERR(__FUNCTION__ ": SIG_CONFRSP invalid state\n");		PRINTSTATE(con);		/* print failed options */		if (opt_len > 0)			print_data("Options not accepted\n", confrsp->options, 				   rsp->len - sizeof(sig_confrsp));		break;        	case SIG_DISCRSP:		D_STATE(__FUNCTION__ ": Got disconnect response\n");		discrsp = (sig_discrsp *)rsp->data;		discrsp->dst_cid = le16_to_cpu(discrsp->dst_cid);		discrsp->src_cid = le16_to_cpu(discrsp->src_cid);		PRINTPKT(__FUNCTION__ ": disconnect response", rsp->data, rsp->len);		/* find connection */		if ((con = get_lcon(discrsp->src_cid)) == NULL)			return;		if (con->current_state != W4_L2CAP_DISCONNECT_RSP) {			D_ERR(__FUNCTION__ ": SIG_DISCRSP invalid state\n");			PRINTSTATE(con);			return; 		}	       	       		/* match id with request */		if (!id_matched(con, rsp->id)) {			D_ERR(__FUNCTION__ ": ID doesn't match ! [%d:%d]\n", 			      con->sig_id_sent, rsp->id);			return;		}		con->c_status = CSTATUS_SUCCESS;	#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS		disable_rtx(con);#endif		con->c_result = RES_SUCCESS;		l2ca_disconnect_cfm(con);		l2ca_wakeup("l2cap disc rsp", con);		break;       	case SIG_ECHORSP: {		l2cap_con *tempcon;				D_STATE(__FUNCTION__ ": Got echo response\n");				if ((tempcon = get_con_hcihdl(hci_handle))==NULL) {			D_STATE(__FUNCTION__": Echo rsp, could not find connection\n");			return;		}				echo = (sig_echo_pkt *)(rsp->data);		opt_len = rsp->len;					if (opt_len > 0)			PRINTPKT(__FUNCTION__ ": optional data ", 				 echo->data, rsp->len-sizeof(sig_echo_pkt));#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS		disable_rtx(tempcon);#endif		/* now wake up l2ca_ping */		tempcon->c_status = CSTATUS_SUCCESS;		tempcon->c_result = RES_SUCCESS;		l2ca_wakeup("echo resp received", tempcon);		break;	}           	case SIG_INFORSP: {		l2cap_con *tempcon;		if ((tempcon = get_con_hcihdl(hci_handle))==NULL) {			D_STATE(__FUNCTION__": Echo rsp, could not find connection\n");			return;		}		info = (sig_info_rsp *)(rsp->data);		info->type = le16_to_cpu(info->type);		info->result = le16_to_cpu(info->result);				D_STATE(__FUNCTION__ ": Got info response: result %d\n", info->result);#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS		disable_rtx(tempcon);#endif		/* now wake up l2ca_ping */				tempcon->c_status = RES_SUCCESS;		l2ca_wakeup("info resp received", tempcon);				break;	}		default:		/* Not a valid command */		DSYS(__FUNCTION__ ": Invalid command 0x%x\n", rsp->code);		l2cap_cmdrej(hci_handle, CMDREJ_NOTUNDERSTOOD, NULL, 0);		break;	}}/*******************************************************************//*-------------------------- EVENTS -------------------------------*//*******************************************************************//*  Events are all incoming messages to the L2CA layer along with the  timeouts. Events are partitioned into five categories :  1. Indications and confirms from lower layers  2. Signal requests and responses from peers  3. L2CAP to L2CAP Data  4. Requests and responses from upper layers  5. Events caused by timers *//*******************************************************************//* (E1) Lower layer to l2cap *//****************************//* Indicates the lower protocol has successfully established connection */void lp_connect_ind(BD_ADDR bd_addr){	PRINTPKT(__FUNCTION__ ": from: ", bd_addr, 6);        /* Check BD_ADDR */        if (!bd_addr[0] && !bd_addr[1] && !bd_addr[2] &&            !bd_addr[3] && !bd_addr[4] && !bd_addr[5]) {		D_ERR(__FUNCTION__ ": no BD addr\n");		return;        } 	/* FIXME - add check with control block if this bd_addr is allowed */	/* We are server and creates an l2cap connection object 	   which we set hci handle when we received lp_connect_cfm */	/* Denying a connection at this state does not allow	   SDP queries when max amount of connections is reached*/	if (hci_ctrl.nbr_of_connections < bt_max_connections) {		D_CON(__FUNCTION__ ": Accepting connection\n");		l2cap_create_con(bd_addr);		lp_connect_rsp(bd_addr, 1);	} else {		D_CON(__FUNCTION__ ": Denying connection. Current connections: %d, max connections: %d\n", hci_ctrl.nbr_of_connections, bt_max_connections);		lp_connect_rsp(bd_addr, 0);	}}	/* is called when we accept a _new_ baseband connection */void l2cap_create_con(BD_ADDR bd){	l2cap_con *con;	D_RCV(__FUNCTION__ "\n");		PRINTPKT(__FUNCTION__ ": bd ", bd, 6);	/* create a new l2cap connection obj and insert it in list */	/* HACK! - remote CID = 0 indicates that remote cid has not '	   been set yet */	con = create_con(0 /* not yet set*/ , get_cid(), 0/*not yet set*/);		/* Check connection */        if (con == NULL) {		D_ERR(__FUNCTION__ ": no connection created");		return;        }        	con->link_up = TRUE;	memcpy(con->remote_bd, bd, 6);	/* have not received l2cap connection req yet */	ENTERSTATE(con, CLOSED); 	insert_con(con);	return;}/*    Confirms the request to establish a baseband connection*/  s32lp_connect_cfm(u8 *bd_addr, u32 status, u16 con_hdl){	l2cap_con *con;	u8 rev_bd[6];	s32 i;	D_STATE(__FUNCTION__ ": %s (hci_handle : %d)\n", 		get_err_msg(status), con_hdl);	/* reverse byte order */	for (i = 0; i < 6; i++) {		rev_bd[5-i] = bd_addr[i];	}	D_STATE(__FUNCTION__ ": bd %s\n", bd2str(rev_bd));	/* FIXME -- use bt session list to notify upper layers that 	   con failed !!! */	/* search for the corresponding l2cap connection */	if ((con = get_con(bd_addr, CLOSED)) == NULL) {		D_ERR(__FUNCTION__ ": couldn't find l2cap con!\n");		return 0;	}	con->c_status = status;	con->c_result = status;	if (status == 0) {		/* pos cfm */		con->hci_hdl = con_hdl;		con->link_up = TRUE;		/* see if there is someone to wakeup */		l2ca_wakeup("lp_connect_cfm (pos)", con);				if (con->c_flags & FLAG_RETURNNOW) {			D_STATE(__FUNCTION__" Return NOW\n");			/* clear flag & set status */			con->c_flags &= ~FLAG_RETURNNOW;			return 0;		}				if (!(con->initiator)) {					D_STATE("We are server\n");			/* now wait for a connection request */		} else {			D_STATE("We are client\n");			PRINTPKT(__FUNCTION__ ": HCI connected to ", 				 bd_addr, 6);      			ENTERSTATE(con, W4_L2CAP_CONNECT_RSP);			PRINTSTATE(con);						l2ca_wakeup(__FUNCTION__, con);		}		return 1;	} else {		/* neg cfm */		D_STATE(__FUNCTION__ ": (neg) %s\n",get_err_msg(status));		con->link_up = FALSE;		l2ca_wakeup(__FUNCTION__ " (neg)", con);				if (con->c_flags & FLAG_RETURNNOW) {			con->c_flags &= ~FLAG_RETURNNOW;			return 0;		}		if (con->initiator) {			/* only notify upper layers if we are initiator */			l2ca_connect_cfm(con, MSGCODE(MSG_LAYER_HCI, 						      status));		} else {			/* delete connection if non-initiator */			delete_con(con);		} 		return 0;	}} /* Indicates that one of the baseband connections has been shutdown */s32lp_disconnect_ind(u32 con_hdl){	l2cap_con *con;	s32 found = 0;	/* temp link down */	DSYS(__FUNCTION__": Connection handle %d disconnected\n",	     con_hdl);	/* find & notify/remove l2cap connection(s) on this hci handle */	SHOW_LIST();	while (((con = get_con_hcihdl(con_hdl)) != NULL)) {		D_STATE("l2cap connection (%d:%d) found on handle %d\n", 			con->local_cid, con->remote_cid, con_hdl);		D_STATE("now closing it...\n");				PRINTSTATE(con);    		/* flag phys link as down */		con->link_up = FALSE;#ifdef CONFIG_BLUETOOTH_L2CAP_USE_TIMERS		/* cancel any outstanding timers */		disable_rtx(con);		disable_ertx(con);#endif		/* if not connected yet simply remove it */		if (con->current_state == CLOSED) {      			D_STATE("connection closed, remove it!\n");			delete_con(con);		} else {			ENTERSTATE(con, W4_L2CA_DISCONNECT_RSP);			DSYS("closing l2cap con (%d,%d)\n",			     con->local_cid, con->remote_cid);			/* notify upper layers that phys link is down */			get_upper(con->psm)->disc_ind(con);		}		found = 1;	}	D_CON(__FUNCTION__ ": no more l2cap cons on this handle\n");	/* flush old buffers waiting to be sent on this handle */	btmem_flushhandle((u16)con_hdl);	return found;}/* FIXME - lp_qos_violation_ind() *//* FIXME - lp_qos_cfm() */ /********************************************************************//* (E2) l2cap to l2cap signalling *//*********************************//* is handled in signal_handler() *//******************************************************************//* (E3) L2CAP to L2CAP Data*//**************************/void process_frame(l2cap_con *con, u8 *data, u32 len){  	PRINTPKT(__FUNCTION__ ": ", data, len);	if (len > (con->local_mtu)) {		DSYS("l2cap process_frame : len > local_mtu (%ld/%d)\n", 		     (long)(len - L2CAP_HDRSIZE), con->local_mtu);		l2cap_cmdrej(con->hci_hdl, CMDREJ_MTUEXCEEDED, NULL, 0);		return;	} 	get_upper(con->psm)->receive_data(con, data, len);}/**************************************************************//* (E4) Upper layers to l2cap *//*****************************/s32 l2ca_connect_req(BD_ADDR bd, u16 psm){	l2cap_con *con;	l2cap_con *tmpcon;

⌨️ 快捷键说明

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