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

📄 test.c

📁 bluetooth 驱动
💻 C
字号:
/* * test.c -- Test layer used to verify stack        * * Copyright (C) 2000, 2001  Axis Communications AB * * Author: Mats Friden <matsf.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: test.c,v 1.31 2001/10/18 15:49:25 pkj Exp $x * *//****************** INCLUDE FILES SECTION ***********************************/#define __NO_VERSION__ /* don't define kernel_version in module.h */#ifdef __KERNEL__#include <linux/malloc.h>#include <linux/interrupt.h>#include <linux/bluetooth/test.h>#include <linux/bluetooth/btcommon.h>#include <linux/bluetooth/btmem.h>#include <linux/bluetooth/l2cap.h>#include <linux/bluetooth/unplug_test.h>#else#include <string.h>#include <errno.h>#include "include/test.h"#include "include/btcommon.h"#include "include/btdebug.h"#include "include/btmem.h"#include "include/l2cap.h"#include "include/unplug_test.h"#endif/****************** DEBUG CONSTANT AND MACRO SECTION ************************/#define TEST_DBG_STR "          TEST "#define TEST_DEBUG_STATE 1#define TEST_DEBUG_CON 1#define TEST_DEBUG_RCV 1#define TEST_DEBUG_XMIT 1#define TEST_DEBUG_MISC 1#define TEST_DEBUG_DATA 1#if TEST_DEBUG_STATE/* State machine */#define D_STATE(fmt...) printk(TEST_DBG_STR fmt)#define PRINTSTATE(con) (printk("Current state : %s\n",\                         state_name[con->current_state]))#else/* State machine */#define D_STATE(fmt)#define PRINTSTATE(con)#endif#if TEST_DEBUG_RCV/* Receive data */#define D_RCV(fmt...) printk(TEST_DBG_STR fmt)#else#define D_RCV(fmt...)#endif#if TEST_DEBUG_XMIT/* Send data */#define D_XMIT(fmt...) printk(TEST_DBG_STR fmt)#else#define D_XMIT(fmt...)#endif#if TEST_DEBUG_MISC/* Misc */#define D_MISC(fmt...) printk(TEST_DBG_STR fmt)#else#define D_MISC(fmt...)#endif#if TEST_DEBUG_DATA#define PRINTPKT(str, data, len) print_data(str, data, len)#else#define PRINTPKT(str, data, len)#endif/* Values used for the L2CAP configuration process */#define TEST_MTU 672 /* Default, why should we be different */#define TEST_QOS 0x01 /* Best effort */#define TEST_FLUSH_TIMEOUT 0xffff /* Reliable channel, infinite amout of retransmissions */#define PRINTPSM(con) (printk("PSM : 0x%x\n", con->psm))/****************** TYPE DEFINITION SECTION *********************************/l2cap_con *testcon;l2cap_con *testcon2;l2cap_con *testcon3;s32 emulate_pending = 0;s32 test_inmtu = 0;s32 dont_send_config_req = 0;s32 use_multiple_conf_params = 0;s32 disable_testpsm = 0;s32 dont_send_disconnect_rsp = 0;u8 testdata[UPTEST_DATA_LEN];#ifdef __KERNEL__#define strtoul simple_strtoul#endifvoid test_init(void){	protocol_layer this_layer;	DSYS("Initialising TEST\n");  	/* Set the confirm and indication functions for the L2CAP-layer */	this_layer.con_ind = test_connect_ind;	this_layer.conf_ind = test_config_ind;	this_layer.disc_ind = test_disconnect_ind;	this_layer.con_pnd = test_connect_pnd;	this_layer.con_cfm = test_connect_cfm;	this_layer.conf_cfm = test_config_cfm;	this_layer.disc_cfm = test_disconnect_cfm;	this_layer.receive_data = test_receive_data;	l2cap_register_upper(L2CAP_TEST_LAYER, &this_layer);	l2cap_register_upper(L2CAP_TEST2_LAYER, &this_layer);	l2cap_register_upper(L2CAP_TEST3_LAYER, &this_layer);}void test_shutdown(void){	DSYS("Shutting down TEST\n");}s32test_connect_req(BD_ADDR bd){	s32 retval = 0;	D_STATE("test_connect_req to psm 0x%x\n", L2CAP_TEST_LAYER);	if ((retval = l2ca_connect_req(bd, L2CAP_TEST_LAYER)) < 0) {		D_ERR(" tcs_connect_req: l2ca_connect_req failed\n"); 	}	return retval;}s32test_connect_psmreq(BD_ADDR bd, u16 psm){	D_STATE("test_connect_req on psm 0x%x\n", psm);	return l2ca_connect_req(bd, psm);}static voidtest_timeout(unsigned long ptr){	struct l2cap_con *con = (struct l2cap_con *)ptr;	printk("Test timeout\n");		if (emulate_pending) {		printk("Now sending config rsp non-pending...\n");		emulate_pending = 0;				if (l2ca_connect_rsp(con, RES_SUCCESS, STAT_NOINFO)) {			D_ERR("test_connect_ind: l2ca_connect_rsp failed\n"); 			return;		}		emulate_pending = 0;	}}void test_connect_ind(l2cap_con *con) {#ifdef __KERNEL__	static struct timer_list test_timer;#endif	D_STATE("test_connect_ind : remote cid : %d\n", con->remote_cid);	PRINTPSM(con);	if (emulate_pending) {		printk("Sending connect rsp pending and waiting 5 secs\n");		if (l2ca_connect_rsp(con, RES_PENDING, STAT_AUTHENTPEND)) {			D_ERR("test_connect_ind: l2ca_connect_rsp failed\n"); 			return;		}		/* start 5 sec timer */		#ifdef __KERNEL__		init_timer(&test_timer);		test_timer.function = test_timeout;		test_timer.data = (unsigned long)con;		test_timer.expires = jiffies + 5*HZ;		add_timer(&test_timer);		return;#else		sleep(5);#endif        }		if (disable_testpsm == 1)	{		/* send back psm not supp */		if (l2ca_connect_rsp(con, RES_PSMNEG, 0)) {			D_ERR("test_connect_ind: l2ca_connect_rsp failed\n"); 			return;		}		printk("Now enabling test psm:s again...\n");		disable_testpsm = 0;		return;	}	printk("now sending back result success !\n");	if (l2ca_connect_rsp(con, RES_SUCCESS, STAT_NOINFO)) {		D_ERR("test_connect_ind: l2ca_connect_rsp failed\n"); 		return;	}	/* (temp fix for test interface) store connection */	if (con->psm == L2CAP_TEST_LAYER)		testcon = con;	else if (con->psm == L2CAP_TEST2_LAYER)		testcon2 = con;	else if (con->psm == L2CAP_TEST3_LAYER)		testcon3 = con;}/* only client receives connect pnd */void test_connect_pnd(l2cap_con *con, s32 status){	D_STATE("test_connect_pnd : reason %d\n", status);		PRINTPSM(con);	if (con->psm == L2CAP_TEST_LAYER)		testcon = con;	else if (con->psm == L2CAP_TEST2_LAYER)		testcon2 = con;	else if (con->psm == L2CAP_TEST3_LAYER)		testcon3 = con;}/* only client receives connect cfm */void test_connect_cfm(l2cap_con *con, s32 status){	D_STATE("test_connect_cfm\n");	PRINTPSM(con);	if(status) {	  D_STATE("Connect failed: Status %d\n", status);	  return;	}		if (!l2ca_local_conf_done(con)) {		if (dont_send_config_req) {			printk("Don't send back config_req...\n");			printk("Now waiting for initator to shutdown link...\n");			dont_send_config_req = 0;			return;		}		/* still haven't sent config request yet */		if (use_multiple_conf_params) {			if (l2ca_config_req(con, 1280, NULL, 0x1234, 0)) {				D_ERR("test_config_cfm : Configuration request failed\n"); }		} else {			if (l2ca_config_req(con, 0, NULL, 0, 0)) {				D_ERR("test_config_cfm : Configuration request failed\n"); }		}				/* store connection */		if (con->psm == L2CAP_TEST_LAYER)			testcon = con;		else if (con->psm == L2CAP_TEST2_LAYER)			testcon2 = con;		else if (con->psm == L2CAP_TEST3_LAYER)			testcon3 = con;	} else 	       		D_RCV("test_config_cfm : already have sent config request\n");}/* someone wants to configure l2cap... */void test_config_ind(l2cap_con* con){ 	D_STATE("test_config_ind : remote cid : %d remote_mtu : %d\n", 		con->remote_cid, con->remote_mtu);		/* check if we have sent a pos response yet */	if (!l2ca_remote_conf_done(con)) {		/* still haven't sent a pos configure response*/		if (l2ca_config_rsp(con, 0, NULL, CONF_SUCCESS)) {			D_ERR("test_config_ind : Configuration response failed\n");		}    	} else 		printk("test_config_ind : 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(con)) {		/* still haven't sent config request yet */		D_RCV("Setting local mtu to %d on con (%d:%d)\n", 		     con->local_mtu, con->local_cid, con->remote_cid);		if (dont_send_config_req) {			printk("Don't send back config_req...\n");			printk("Now waiting for initator to shutdown link...\n");			dont_send_config_req = 0;			return;		}				/* still haven't sent config request yet */		if (use_multiple_conf_params) {			if (l2ca_config_req(con, 1280, NULL, 0x1234, 0)) {				D_ERR("test_config_cfm : Configuration request failed\n");			}		} else {			if (l2ca_config_req(con, test_inmtu, NULL, 0, 0))				D_ERR("test_config_ind : configuration request failed\n");			if (test_inmtu)			{				printk("Set back our test_inmtu to default\n");				test_inmtu = 0;			}		}	} else 		D_RCV("already ready with config req\n");}void test_config_cfm(l2cap_con *con, s32 status){	D_STATE("test_config_cfm : remote cid : %d\n", con->remote_cid);		D_STATE("Now we have an open l2cap channel\n");	/* negotiate upper protocol */}void test_disconnect_ind(l2cap_con *con) {	D_STATE("test_disconnect_ind : (%d:%d)\n", 		con->local_cid, con->remote_cid);	if(!dont_send_disconnect_rsp) {		l2ca_disconnect_rsp(con);	}}void test_disconnect_cfm(l2cap_con *con){	D_STATE("TEST_disconnect_cfm: remote cid : %d\n", con->remote_cid);}s32 test_disconnect_req(l2cap_con *con){	if (!con)		return -1;		D_STATE("test_disconnect_req\n");	return l2ca_disconnect_req(con);}void test_receive_data(l2cap_con *con, unsigned char* data, u32 len){	PRINTPSM(con);	PRINTPKT("test_receive_data : ", data, len);  }s32 test_send_data(l2cap_con *con, u8 *testdata, s32 len){	bt_tx_buf *tx_buf;	printk("test_send_data : sending %d bytes\n", len);		if (!con) {		D_ERR("test_send_data : No connection object\n");		return -1;	}		/* tx bufs are all the same for each upper layer ... FIX one common */	tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + len);	if (!tx_buf) {		D_ERR("test_send_data : didn't get a valid tx_buf\n");		return -ENOMEM;	}	tx_buf->cur_len = len;	memcpy(tx_buf->data+sizeof(rfcomm_tx_buf), testdata, len);	return l2cap_send_data(tx_buf, con);}/* FIXME -- add new commands in user application menu !!!! */s32test_process_cmd(unsigned char *cmd, s32 size){ #ifdef CONFIG_BLUETOOTH_UNPLUG_TEST	int testcase, tmp[10], i;	unsigned char bd[6], char_buf[4];	char_buf[3] = 0;	if(!strncmp(cmd, "bb_conn ", 8)) {		char *p = cmd + 8;				for (i = 5; i >= 0; i--) {			bd[i] = strtoul(p, &p, 16);			printk("bb_conn read [%d] = 0x%x\n", i, bd[i]);			p=p+1;		}				printk("Connecting BB to bd : %02X:%02X:%02X:%02X:%02X:%02X\n",		       bd[5], bd[4], bd[3],		       bd[2], bd[1], bd[0]);				l2cap_create_con(bd);		return lp_connect_req(bd);	}	else if(strncmp(cmd, "t ", 2) == 0) {		testcase = strtoul(cmd+2, NULL, 0);		if (testcase > 0) {			return process_test_cmd(testcase);		}		else {			printk("test_process_cmd: Couldn't parse testcase\n");		}	}	else if(!strncmp(cmd, "bb_disc ", 8)) {		int i = strtoul(cmd+8, NULL, 0);		return lp_disconnect((unsigned short)i);	}	else if(!strncmp(cmd, "lcid_disconnect ", 16)) {		l2cap_con *con = NULL;		int i = strtoul(cmd + 16, NULL, 0);		if((con = get_lcon(i))) {			return l2ca_disconnect_req(con);		}		else {			printk("Didn't find lcid %d\n", i);			return -1;		}	}	else if(!strncmp(cmd, "test_case_reject ", 17)) {		unsigned short fake_psm = 0x4561;		char *p = cmd + 8;		for (i = 0; i < 6; i++) {						bd[i] = strtoul(p, &p, 0);			printk("bb_conn read [%d] = 0x%x\n", i, bd[i]);			p++;		}  		return l2ca_connect_req(bd, fake_psm);	}	else if(!strncmp(cmd, "tx_data ", 8)) {		int lcid, len;		char *p = cmd+8;		l2cap_con *con;		lcid = strtoul(p, &p, 0);		len = strtoul(p+1, &p, 0);				/* first find connection based on local cid */		con = get_lcon(lcid);		if (!con) {			printk("Found no connection with lcid : %d\n", lcid);			return -1;		}		return test_send_data(con, testdata, len);	} else if(!strncmp(cmd, "sdptest ", 8)) {		int n = strtoul(cmd+8, NULL, 0);			return do_sdp_test(n);	} else if(!strcmp(cmd, "test_case_disable_disconnect")) {		dont_send_disconnect_rsp = 1;		return 0;	} else if(!strcmp(cmd, "test_case_enable_disconnect")) {		dont_send_disconnect_rsp = 0;		return 0;	} else {		printk("Unknown test cmd!\n");		return -1;	}	#else	printk("test_process_cmd: Not available\n");	return 0;#endif}/****************** END OF FILE test.c ***************************************/

⌨️ 快捷键说明

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