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

📄 blue.cpp

📁 blue-usu: (Search, Connect, Playback, Record) with bluetooth devices like headset. Rely on usu dr
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	 * If no msg@all, return 0, !-ESOMETHING	 */	int ritorno=readMsg(proto);	if (log && ritorno<0) {		int l;		switch (ritorno) {			case -EBADMSG  : Dprintf("> msg with unk proto!"); break;			default: break;		}		Dprintf("(len(%d)",lastPduC);		for (l=0; l<lastPduC; l++)			Dprintf("%02x",(unsigned char)lastPdu[l]);		Dprintf(")");	}	/* 2) Deliver pdu to all listener.*/	if (ritorno>0) {		int l;		ritorno=0;		for (l=0; (l<MAX_PENDING_CMD) && (ritorno==0); l++)			if (hcireqres[l] && !hcireqres[l]->done() && hcireqres[l]->getProto()==proto)				ritorno=hcireqres[l]->readRes(lastPdu,lastPduC);		if (ritorno==0) {			/* A: No destination: this msg !have a listener.*/			ritorno=-ESRCH;			if (log) {				Dprintf("> event without listener(");				for (l=0; l<lastPduC; l++)					Dprintf("%02x",(unsigned char)lastPdu[l]);				Dprintf(")");			}		} else if (ritorno>0) {			/* B: msg readed entirely.*/			l--; if (hcireqres[l]->done()) {/*hcireqres[l].detach()~HciReqRes()*/;hcireqres[l]=NULL;}		} else if (ritorno<0) {			/* C: msg readed, but msg have an error that must be signaled here.*/			l--; if (hcireqres[l]->done()) {/*hcireqres[l].detach()~HciReqRes()*/; hcireqres[l]=NULL;}		}		/* Any msg remain here until writeHci(), readHci().*/	}	/* 	 * <0 mean error: (exist msg and is erroneous4listener) || (!exist msg, have problem in get it).	 * >0 mean ok (exist msg .	 * =0 mean no msg available.	 */	if (log) {		Dprintf(" readHci(%s=%s)\n",ritorno>0?"bytes":ritorno==0?"nomsg":"err",linuxErrDes(ritorno));	}	return ritorno;}int HciBus::clear(HciReqRes& hci) {	int l;	int ritorno=-ENOMSG;	for (l=0; (l<MAX_PENDING_CMD) && (ritorno); l++)		if (hcireqres[l]==&hci) {			/*hcireqres[l].detach()~HciReqRes*/;			hcireqres[l]=NULL;			ritorno=0;		}	if (ritorno)		Dprintf("HciBus::clear() object !found !!!\n");	/*		for (l=0; l<lastPduC; l++)			Dprintf("%02x",(unsigned char)lastPdu[l]);	 */	return ritorno;}int HciBus::clear() {	int l;	int ritorno=0;	for (l=0; l<MAX_PENDING_CMD; l++)		if (hcireqres[l]) {			Dprintf("HciBus::clear() found obj!!!\n");			/*hcireqres[l].detach()~HciReqRes()*/;			hcireqres[l]=NULL;			ritorno++;		}	return ritorno;}/* Wait with granularity of 50ms.*/int HciBus::hci_waitRes(int ms) {	return waitRes(ms,HciReqRes::HCI);}int HciBus::l2cap_waitRes(int ms) {	return waitRes(ms,HciReqRes::L2CAP);}/* On timeout return 0.*/int HciBus::waitRes(int ms,HciReqRes::ProtoT proto) {	int ritorno=0;	int msRem=ms;	ritorno=readHci(proto);	while (ritorno==0 && msRem>0) {		struct timespec ts;		ts.tv_sec=0;		ts.tv_nsec=200<<20;		nanosleep(&ts,0); /* nanosleep() seem to ignore 2nd parameter.*/		msRem-=200;		ritorno=readHci(proto);	}	if (log && ritorno==0 && ms!=0) Dprintf("===TimedOut(%d msec)!===\n",ms);	return ritorno;}enum mainErrT {NO_ERR, SCHEDULE_ERR, PROTO_ERR};int mainErr(enum mainErrT err,char* opt=0) {	int ritorno=0;	switch (err) {		case SCHEDULE_ERR:			Dprintf("Error while scheduling a pdu on hci\n");			Dprintf("\t - blue.cpp/MAX_PENDING_CMD too low?\n");			Dprintf("\n - pdu scheduled have done()==true?\n");			ritorno=-ECANCELED;			break;		case PROTO_ERR:			Dprintf("Error on hci handshacking.\n");			ritorno=-EPROTO;			break;		case NO_ERR:			ritorno=0;			break;		default:			ritorno=-EPROTO;			break;	}	return ritorno;}int HciBus::readMac(char* mac) {	int ritorno = -EIO;	HciCmd rHM(READ_HOST_MAC);	/* 1) Discard all msg.*/	while (hci_waitRes(0)==-ESRCH) {}	if (schedule(rHM)>0 && (ritorno=hci_waitRes(100))>0) {		rHM.scanRes(mac,6);		ritorno = 0;	}	return ritorno;}int HciBus::searchDevice(char macs[][6], char opts[][8], int nMac, int nSec) {	int ritorno = -EINVAL;	if (macs && nMac>0 && nMac<255 && nSec>0 && nSec<255) {		HciCmd ds(SEARCH_DEVICE);		ds.compileReq("\x33\x8B\x9e",3); /* lap filed: fixed in openbt, little var in bluez.*/		char tmp;		tmp = (char) nSec; ds.compileReq(&tmp,1);		tmp = (char) nMac; ds.compileReq(&tmp,1);				/* 1) Discard all msg.*/		while (hci_waitRes(0)==-ESRCH) {}		if (schedule(ds)>0 && (ritorno=hci_waitRes(100))>0)			ritorno=0;		/*    		 *    02 0F ...  (0 or more times).		 *    01 01 00		 */		/* schedule() return 0 because4event we !write any byte to hci file.*/		if (ritorno>=0) {		HciEvt sde(SEARCH_DEVICE_END);		HciEvt sdf(SEARCH_DEVICE_FOUND);		int cMac=0;		if ((ritorno = schedule(sde))>=0 && (ritorno = schedule(sdf))>=0) {			while (ritorno>=0 && !sde.done()) {				ritorno = hci_waitRes((nSec+1)*1000);				if (sdf.done()) {					/* Got a response. Decode it & reschedule it.*/					sdf.scanRes(&tmp,1);					sdf.scanRes(macs[cMac],6);					sdf.scanRes(opts[cMac],8);										Dprintf("device %d) ",nMac);					int l;					for (l=0; l<6; l++)						Dprintf("%2.2x:",(unsigned char)macs[cMac][l]);					Dprintf("opt ");					for (l=0; l<8; l++)						Dprintf("%2.2x:",(unsigned char)opts[cMac][l]);					cMac++;					/* 					 * page scan repetition mode   	(1)					 * page scan period mode	(1)					 * page scan mode		(1)					 * class (3 bytes)					 * clock (2 bytes)					 *					 */					ritorno = schedule(sdf);				}			}			if (ritorno>=0)				ritorno = cMac;		}		if (!sde.done()) clear(sde); if (!sdf.done()) clear(sdf);		}	}	return ritorno;}/*  * opt will derive from inquiry. * If none, memset(opt,0,8). */int HciBus::readRemoteName(char* mac, char* opt, char* nome, int nomeL) {	int ritorno;	HciCmd rn(READ_REMOTE_NAME);	rn.compileReq(mac,6);/*	rn.compileReq("\x00\x00\x00\x00",4);  *	Perhaps page scan * are !related to inquiry res[i]. *	If use inquiryres[i] page_scan_rep_mode, page_scan_mode, hci level crash, *	causing extract of usu module, crash in /proc read() or other proc related crash. * *	Seeing from bluez we see that, *	  		      (rep,mode) *	  inquiryRes		0   0 *	  readRemoteName()	1   0 * *	  or, without having clock offset, * *	  readRemoteName()	2   0  (clock offset= 0 0)	opt[0]=(opt[6]==0 && opt[7]==0)?2:1;	opt[2]=0;	opt[0]=2;	opt[2]=0;	opt[6]=opt[7]=0; */	opt[7]|=0x80;		rn.compileReq(opt  ,1);	/* page scan rep mode.*/	rn.compileReq(opt+2,1); /* page scan mode */	rn.compileReq(opt+6,2); /* clock offset */	/* 1) Discard all msg.*/	while (hci_waitRes(0)==-ESRCH) {}	if ((ritorno = schedule(rn))>0 && (ritorno = hci_waitRes(15000))>0) {		HciEvt dn(DEVICE_NAME);		if ((ritorno = schedule(dn))>=0 && (ritorno = hci_waitRes(15000))>=0) {			if (!dn.done()) {ritorno = -EBADMSG;}			else {				char tmp=0;				char mactmp[6];				if (ritorno>nomeL)					ritorno = nomeL;				dn.scanRes(&tmp,1);				dn.scanRes(mactmp,6);				if (tmp==0) {dn.scanRes(nome,ritorno); nome[ritorno-1]='\x0';}				if (tmp==4) memcpy(nome,"-EHOSTDOWN",ritorno);				else if (tmp) snprintf(nome,ritorno,"(err=%d)",tmp);			}		}		}	return ritorno;}int HciBus::Dump() {	Dprintf("fd{Command,Event,Data{Async,Sync}}=%d,%d,%d,%d.\n",fdCommand,fdEvent,fdDataAsync,fdDataSync);	return 0;}#define HCICMD_start(nome, id, opt) HciCmd nome(id);nome.writeReq(opt,nome.getReqL());hci.schedule(nome)/*HCICMD_start(wVS, WRITE_VOICE_SETTING,	"\x60\x00");*/HciConn::HciConn(HciBus& hcib):hciBus(hcib) {	hciHandle=hciScoHandle=hciL2capHandleDst=hciL2capHandleSrc=0;}HciConn::~HciConn() {}int HciConn::writeConf() {	int ritorno=1;	HciCmd wSF(SET_EVENT_FILTER,"\x00\x80");	HciCmd wPT(WRITE_PAGESCAN_TIMEOUT,	"\x00\x80");	HciCmd wCT(WRITE_INCONNECTION_TIMEOUT,	"\x00\x7d");	HciCmd wSE(WRITE_SCAN_ENABLE,	"\x03");	HciCmd wAE(WRITE_AUTH_ENABLE, 	"\x00");	HciCmd wEM(WRITE_ENCR_MODE, 	"\x00");	HciCmd wLN(WRITE_LOCAL_NAME, 	"gattigerII-0");	HciCmd wCD(WRITE_CLASS_OF_DEV,	"\x00\x01\x3e");	HciCmd wVS(WRITE_VOICE_SETTING,	"\x60\x00");		/* 1) Discard all msg.*/	while (hciBus.hci_waitRes(0)==-ESRCH) {}	ritorno*=hciBus.schedule(wSF);	ritorno*=hciBus.schedule(wPT);	ritorno*=hciBus.schedule(wCT);	ritorno*=hciBus.schedule(wSE);	ritorno*=hciBus.schedule(wAE);	ritorno*=hciBus.schedule(wEM);	ritorno*=hciBus.schedule(wLN);	ritorno*=hciBus.schedule(wCD);	ritorno*=hciBus.schedule(wVS);	if (ritorno<0)		return mainErr(SCHEDULE_ERR);	hciBus.hci_waitRes(100); /* Ignore EINVAL for SET_EVENT_FILTER.*/	if (hciBus.hci_waitRes(100)<=0) return mainErr(PROTO_ERR);	if (hciBus.hci_waitRes(100)<=0) return mainErr(PROTO_ERR);	if (hciBus.hci_waitRes(100)<=0) return mainErr(PROTO_ERR);	if (hciBus.hci_waitRes(100)<=0) return mainErr(PROTO_ERR);	if (hciBus.hci_waitRes(100)<=0) return mainErr(PROTO_ERR);	if (hciBus.hci_waitRes(100)<=0) return mainErr(PROTO_ERR);	if (hciBus.hci_waitRes(100)<=0) return mainErr(PROTO_ERR);	if (hciBus.hci_waitRes(100)<=0) return mainErr(PROTO_ERR);	return 0;}bool isEmpty(char* str,int len) {	if ((str==NULL)||(len<=0))		return true;	int l;	for (l=0; l<len; l++)		if (str[l])			return false;	return true;}/* Only parameter needed.*/int HciConn::connectHci(enum ConnInitByT whoStartConn) {	int ritorno=0;	//	memcpy(mac,m,6);	if (whoStartConn==HOST) {		HciCmd connCmd(CREATE_CONNECTION);		connCmd.compileReq(mac,6);		connCmd.compileReq("\x18\xcc",2);	/* pktType=D{M,H}{1,3,5}.*/		connCmd.compileReq("\x01\x00",2);	/* pscanRepMode, pscanMode.*/		connCmd.compileReq("\x00\x00\x01",3); 	/* ClockOffset 0000, roleSwitch=1.*/		/* PageScanRepMode: messo a 2, dopo la connessione hci mi manda un evento:		 * PAGE SCAN REP MODE CHANGE 20 7 mac 1		 */				if (hciBus.schedule(connCmd)<0)			return mainErr(SCHEDULE_ERR);		/* Can return -EBUSY, that is a temporary state.*/		while (hciBus.hci_waitRes(1000)<=-ESRCH) return mainErr(PROTO_ERR);	} else {		/* 0) Wait for spontaneous event.*/		HciEvt connReq(CONNECT_REQUEST);		if (hciBus.schedule(connReq)<0)			return mainErr(SCHEDULE_ERR);		/* Stop when 		 * 	=0 mean no msg available, or		 * 	>0 found event, or		 * 	!=-ESRCH mean some error.*/		while ((ritorno=hciBus.hci_waitRes(0))==-ESRCH && !connReq.done()) {}		if (!connReq.done())  {			hciBus.clear(connReq);			return -1/* To avoid error on screen, cause we retry whoIn=HOST mainErr(PROTO_ERR)*/;		}		connReq.scanRes(mac,6);	}	/* Data flow trifurcation:*/	HciEvt connectComplete(CONNECT_COMPLETE);	HciEvt pinCodeReq(PINCODE_REQ);	HciEvt linkKeyReq(LINKKEY_REQ); /* has !any state so hci_waitRes()<0 if bus error.*/	if (hciBus.schedule(connectComplete)<0 || hciBus.schedule(pinCodeReq)<0 || hciBus.schedule(linkKeyReq)<0)		return mainErr(SCHEDULE_ERR);	/* Wait one event.	 * If connectComplete.done()==true but status!=0 => return mainErr(PROTO_ERR).*/	if (hciBus.hci_waitRes(5000)<=0) return mainErr(PROTO_ERR);//	while ((ritorno=hciBus.hci_waitRes(0))==-ESRCH) {}//	if (ritorno!=-ESRCH && ritorno<0) return mainErr(PROTO_ERR);//	if (connectComplete.done()) {//		if (log) Dprintf("Retry connection\n");//		return connectHci(mac,DEVICE);//	}	if (whoStartConn==DEVICE) {		HciCmd connAcceptCmd(ACCEPT_CONNECTION);		connAcceptCmd.compileReq(mac,6);		connAcceptCmd.compileReq("\x01",1); /* 1 Remain slave, 0 Become master.*/		if (hciBus.schedule(connAcceptCmd)<0)			return mainErr(SCHEDULE_ERR);		while (hciBus.hci_waitRes(100)<0 && !connAcceptCmd.done()) {}		if (!connAcceptCmd.done())			return mainErr(PROTO_ERR);	}		ritorno=-EPROTO;	if (linkKeyReq.done()) {		/* If we are here we have correct (status==0) linkKeyEvent.*/		HciCmd linkKeyRes(!isEmpty(linkkey,16)?					LINKKEY_REPLY:					LINKKEY_NEG_REPLY);		linkKeyRes.compileReq(mac,6);		if (!isEmpty(linkkey,16))			linkKeyRes.compileReq(linkkey,16);		if (hciBus.schedule(linkKeyRes)<0) return mainErr(SCHEDULE_ERR);		/* hci_waitRes() can return:		 * 	-ENODEV		 *	-ETIMEOUT		 * 	-EBADMSG		 * 	-ESRCH		 * 	read(fd)		 * 	readRes() = status || other.		 */		/* Wait response(ignoring result) & next event=PINCODE REQ || connectComplete.done().*/		ritorno = hciBus.hci_waitRes(1000);		if ((ritorno = hciBus.hci_waitRes(1000))<0) return mainErr(PROTO_ERR);	}	if (pinCodeReq.done()) {		char tmp=/*16*/strlen(pin);		HciCmd pinCodeRes(PINCODE_REPLY);		pinCodeRes.compileReq(mac,6);		pinCodeRes.compileReq(&tmp,1);		pinCodeRes.compileReq(pin,16/*tmp*/);		if (hciBus.schedule(pinCodeRes)<0) return mainErr(SCHEDULE_ERR);		if (hciBus.hci_waitRes(1000)<=0) return mainErr(PROTO_ERR);		/* Wait [link key notify] and connectComplete event.*/		HciEvt lkn(LINKKEY_NOTIFY);		if (hciBus.schedule(lkn)<0) return mainErr(SCHEDULE_ERR);

⌨️ 快捷键说明

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