#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const CAPTION_LASTSCAN = "Last Scan:"; const CAPTION_STATUS = "Status:"; const CAPTION_DEVFOUND = "Devices found:"; /* VIKING Bluetooth Scanner v1.0a Copyright (c) 2004 dataholic you know how its done! compile with: gcc viking.c -o viking -lbluetooth -lcurses :: NOTES :: this is version 1.0 , soon there will be a version with more features :: SPEECH :: if you want the speech to work, install festival from: http://www.cstr.ed.ac.uk/projects/festival/download.html Debian users use apt-get install festival this sourcecode is released under the GPL license http://www.gnu.org/copyleft/gpl.html#SEC3 */ int devs_found =0; FILE *logfile=0; enum {SCREEN_ITEM_STATUS = 1, SCREEN_ITEM_LASTSCAN = 2, SCREEN_ITEM_FOUNDNEW=3, SCREEN_ITEM_DEVFOUND}; inquiry_info devs_cache[1024]; int runbtscan(); int speak(const char *what); void sighandler(int sig); void ontimer(int sig); void gettimestamp(char *out); void update_status_item(int itemid, const char *caption); void logtxt(const char *what); void tellstatus(); void tellstatus() { char temp[200]; gettimestamp((char*)&temp); sprintf((char*)&temp,"status report, %d devices found",devs_found); speak((const char*)&temp); sleep(5); } void add_dev_to_cache(inquiry_info *pinfo) { //devs_found++ required before calling this function devs_cache[devs_found] = *pinfo; } int dev_in_cache(inquiry_info *pinfo) { int x=0; int retval=0; char cache_addr[18]; char his_addr[18]; ba2str(&(pinfo->bdaddr), his_addr); for (x=0;x<(devs_found+1);x++) { ba2str(&(devs_cache[x].bdaddr), cache_addr); if (strcmp((const char*)&cache_addr,(const char*)&his_addr) == 0) { retval =1; break; } } return retval; } void logtxt(const char *what) { fwrite(what,1,strlen(what),logfile); fwrite("\r\n",1,2,logfile); } void gettimestamp(char *out) { time_t result=0; static struct tm mytime; int x=0; result=time(NULL); memcpy((void *)&mytime,(void *)gmtime(&result), sizeof(struct tm)); sprintf(out,"%s",asctime(&mytime)); //filter out breaks for (x=0;x 10 ) { sprintf((char*)&buffer,"Scan failed %d times, aborting!",timesfailed); update_status_item(SCREEN_ITEM_STATUS,(const char*)&buffer); speak(&buffer); break; } else { sprintf((char*)&buffer,"Scan failed, retrying..."); update_status_item(SCREEN_ITEM_STATUS,(const char*)&buffer); sprintf((char*)&buffer,"warning, scan failed, retrying"); speak(&buffer); sleep(10); } } else { // printf("OK\r\n"); } timeslooped++; if (timeslooped > 6 ) { update_status_item(SCREEN_ITEM_STATUS,"Reporting status to user"); tellstatus(); timeslooped =0; } } logtxt("VIKING quited"); exit(0); } int speak(const char *what) { const char execstring[1024]; /* festival -b '(voice_%VOICENAME%)' '(tts "/tmp/speak.txt" nil)' */ sprintf((char*)&execstring,"echo \x22%s\x22 > /tmp/speak.txt",what); system(execstring); //speak to me. miaww sprintf((char*)&execstring,"festival -b '(voice_ked_diphone)' '(tts \x22/tmp/speak.txt\x22 nil)'"); system(execstring); return 0; } int runbtscan() { inquiry_info *info = NULL; int num_rsp, length, flags; char addr[18]; char name[248]; char buffer[1024]; char bufferdatetime[250]; int i, opt, dd; int dev_id =-1; //let hci_get_route find it length = 8; /* ~10 seconds */ num_rsp = 100; flags = 0; if (dev_id < 0) { dev_id = hci_get_route(NULL); if (dev_id < 0) { perror("Device is not available"); return -1; } } num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { perror("Inquiry failed"); return -1; } dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); free(info); exit(1); } for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "no name"); ba2str(&(info+i)->bdaddr, addr); if (dev_in_cache((info+i)) == 0) { sprintf(&buffer,"found bluetooth device, named .. %s",name); speak((const char*)&buffer); //add to GUI list devs_found++; gettimestamp((char*)&bufferdatetime); sprintf(&buffer,"%s\t\t%s, last seen: %s",addr,name,bufferdatetime); update_status_item(SCREEN_ITEM_FOUNDNEW,(const char*)&buffer); logtxt((const char*)&buffer); //add to cache add_dev_to_cache((info+i)); } else { sprintf((char*)&buffer,"%s already in list...",addr); update_status_item(SCREEN_ITEM_STATUS,(const char*)&buffer); } } close(dd); free(info); return 0; } void update_status_item(int itemid, const char *caption) { //first move cursor based on itemid switch (itemid) { case SCREEN_ITEM_STATUS: move(5,17); break; case SCREEN_ITEM_LASTSCAN: move(6,17); break; case SCREEN_ITEM_DEVFOUND: move(7,17); break; case SCREEN_ITEM_FOUNDNEW: move(11 + devs_found,1); //SINGLE LINE: move(11,1); break; } clrtoeol(); printw("%s",caption); refresh(); } void sighandler(int sig) { endwin(); fclose(logfile); printf("\r\n\r\n\x22...and that bitch is slippin!...\x22 -- Ice Cube \r\n;)\r\n\r\n"); //speak("we dont need that smiling mother fucker! going to get some beer, catch ya later on the flipside, mate"); speak("bye bye, mate"); exit(0); } void ontimer(int sig) { char temp[100]; gettimestamp((char*)&temp); move(20,1); printw("timer called @ %s",temp); }