📄 blue.cpp
字号:
* 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 + -