/WaspBT.cpp

https://github.com/mencey/waspmote-api · C++ · 682 lines · 490 code · 155 blank · 37 comment · 126 complexity · f3dcde9465a445cacdf1653a77d1bce4 MD5 · raw file

  1. /*
  2. * Copyright (C) 2010 Libelium Comunicaciones Distribuidas S.L.
  3. * http://www.libelium.com
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation, either version 2.1 of the License, or
  8. * (at your option) any later version.
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. * You should have received a copy of the GNU Lesser General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. * Version: 0.1
  17. * Design: David Gascón
  18. * Implementation: Alberto Bielsa, Manuel Calahorra
  19. */
  20. #ifndef __WPROGRAM_H__
  21. #include "WaspClasses.h"
  22. #endif
  23. // Private Methods /////////////////////////////////////////////////////////////
  24. // returns '0' if the string is not found
  25. uint16_t WaspBT::waitForData(uint8_t* data, char* expectedAnswer)
  26. {
  27. uint16_t i=0;
  28. for (i = 0; i < 100; i++) received[i] = ' ';
  29. int theLength = 0;
  30. int it=0;
  31. bool theSame=false;
  32. uint8_t first=1;
  33. uint8_t match=0;
  34. i=0;
  35. while( expectedAnswer[theLength]!='\0' ) theLength++;
  36. while( !match && data[i]!='\0' )
  37. {
  38. if( first )
  39. {
  40. for(it=0;it<theLength;it++)
  41. {
  42. received[it]=data[i];
  43. i++;
  44. }
  45. first=0;
  46. }
  47. it=0;
  48. theSame=true;
  49. for(it=0; it<theLength ; it++)
  50. {
  51. if(received[it]!=expectedAnswer[it]){
  52. theSame= false;
  53. break;
  54. }
  55. }
  56. if( theSame ) match=1;
  57. else
  58. {
  59. for(it=0; it<theLength-1 ; it++)
  60. {
  61. received[it]=received[it+1];
  62. }
  63. received[it]=data[i];
  64. i++;
  65. }
  66. }
  67. if( !match ) i=0;
  68. return i;
  69. }
  70. uint8_t WaspBT::parse_data()
  71. {
  72. parse_data("");
  73. }
  74. // Returns '0' on match with answer, '1' on mismatch with answer, '2' no char received with answer, '3' no error without answer, '4' no char received without answer
  75. uint8_t WaspBT::parse_data(char* answer)
  76. {
  77. bool withAnswer = false;
  78. bool match = false;
  79. uint8_t pin_en = 0;
  80. uint8_t lengthAnswer = 0;
  81. long previous=millis();
  82. long previous2=millis();
  83. int16_t interval=50;
  84. int16_t intervalMAX=40000;
  85. uint16_t MAX_BT_DATA=450;
  86. uint8_t* memory = (uint8_t*) calloc(MAX_PARSE,sizeof(uint8_t));
  87. if( memory==NULL ) return -1;
  88. // Checking if we are waiting for a specific answer
  89. i=0;
  90. while(answer[i]!='\0') i++;
  91. lengthAnswer=i;
  92. if( lengthAnswer ) withAnswer = true;
  93. if( !(strcmp(answer,"+RDDSCNF=0")) ) interval=30000;
  94. if( !(strcmp(answer,"+RSDSCNF=0")) ){
  95. interval=10000;
  96. pin_en=1;
  97. }
  98. if( !(strcmp(answer,"ROK")) ) interval=5000;
  99. if( !(strcmp(answer,"+RCCRCNF")) ){
  100. interval=10000;
  101. pin_en=2;
  102. }
  103. // Read data from BT meanwhile data is available
  104. i=0;
  105. previous2=millis();
  106. previous=millis();
  107. while( ((millis()-previous)<interval) && ((millis()-previous2)<intervalMAX) && i<MAX_BT_DATA && !match)
  108. {
  109. if(serialAvailable(0))
  110. {
  111. memory[i]=serialRead(0);
  112. i++;
  113. previous=millis();
  114. }
  115. if( withAnswer ){
  116. if( waitForData(memory,answer) ) match=true;
  117. }
  118. if( millis()-previous < 0 ) previous=millis();
  119. if( millis()-previous2 < 0 ) previous2=millis();
  120. }
  121. printNewline(1);
  122. // If we are here, the answer has not been found or there wasn't any answer to find
  123. if( waitForData(memory,"+RPCI") ){
  124. if(!pin_request(memory,pin_en)) match = true;
  125. }
  126. if( waitForData(memory,"+RCOI") && (auto_accept==BT_MANUAL_ACC) ) accept_connection(memory);
  127. if( waitForData(memory,"+RDAI") ){
  128. if(!data_request(memory)) match = true;
  129. }
  130. if( waitForData(memory,"+RDII") ) ending_connection(memory);
  131. if( waitForData(memory,"+RDDSCNF=0") ) parse_brothers(memory,i);
  132. if( waitForData(memory,"+RSDSCNF=0") ) parse_device(memory);
  133. if( waitForData(memory,"+RCCRCNF") ) get_MTU(memory);
  134. if( match ){
  135. free(memory);
  136. memory=NULL;
  137. return 0;
  138. }
  139. if( withAnswer )
  140. {
  141. if( i>0 ){
  142. free(memory);
  143. memory=NULL;
  144. return 1;
  145. }
  146. else{
  147. free(memory);
  148. memory=NULL;
  149. return 2;
  150. }
  151. }
  152. else
  153. {
  154. if( i>0 ){
  155. free(memory);
  156. memory=NULL;
  157. return 3;
  158. }
  159. else{
  160. free(memory);
  161. memory=NULL;
  162. return 4;
  163. }
  164. }
  165. }
  166. uint8_t WaspBT::pin_request(uint8_t* data, uint8_t pin_en)
  167. {
  168. char command[50];
  169. uint8_t length=0;
  170. i=0;
  171. while(bt_pin[i]!='\0') i++;
  172. length=i;
  173. if(length<10) sprintf(command,"%s0%d,%s",BT_AT_PIN_REQUEST,length,bt_pin);
  174. else if(length>=10) sprintf(command,"%s%d,%s",BT_AT_PIN_REQUEST,length,bt_pin);
  175. printData(command);
  176. if(pin_en==1) return parse_data("+RSDSCNF=0");
  177. if(pin_en==2) return parse_data("+RCCRCNF");
  178. else if(!pin_en) return parse_data("+RSLE");
  179. }
  180. uint8_t WaspBT::accept_connection(uint8_t* data)
  181. {
  182. char command[50];
  183. sprintf(command,"%s1",BT_AT_ACCEPT_CONN);
  184. printData(command);
  185. return parse_data("OK");
  186. }
  187. uint8_t WaspBT::data_request(uint8_t* data)
  188. {
  189. uint16_t i=0;
  190. uint16_t j=0;
  191. uint8_t k=0;
  192. uint16_t init=0;
  193. j=waitForData(data,"+RDAI");
  194. while(data[j]!=',') j++;
  195. j++;
  196. while(data[j]!='\r' && i<BT_MAX_DATA){
  197. data_received[i]=data[j];
  198. i++;
  199. j++;
  200. }
  201. printNewline(1);
  202. if(i<BT_MAX_DATA) data_received[i]='\0';
  203. else data_received[BT_MAX_DATA-1]='\0';
  204. return 0;
  205. }
  206. void WaspBT::ending_connection(uint8_t* data)
  207. {
  208. active_connection=0;
  209. }
  210. void WaspBT::parse_brothers(uint8_t* data, uint16_t number_of_data)
  211. {
  212. uint8_t i=0;
  213. uint16_t j=0;
  214. uint8_t k=0;
  215. uint8_t end_line=0;
  216. i=0;
  217. while(i<number_of_data){
  218. if(data[i]=='\n') end_line++;
  219. i++;
  220. }
  221. devices_found=end_line-1;
  222. if(devices_found>BT_MAX_DEVICES) devices_found=BT_MAX_DEVICES;
  223. i=0;
  224. while( i<(end_line-1) && i<BT_MAX_DEVICES )
  225. {
  226. while(data[j]!='=' && j<number_of_data) j++;
  227. j++;
  228. for(k=0;k<12;k++)
  229. {
  230. discovered_devices[i].mac_address[k]=data[j];
  231. j++;
  232. }
  233. j++;
  234. k=0;
  235. while(data[j]!=',' && k<18)
  236. {
  237. discovered_devices[i].name[k]=data[j];
  238. j++;
  239. k++;
  240. }
  241. discovered_devices[i].name[k]='\0';
  242. while(data[j]!=',' && j<number_of_data) j++;
  243. j++;
  244. k=0;
  245. while(data[j]!='\r' && k<6)
  246. {
  247. discovered_devices[i].CoD[k]=data[j];
  248. j++;
  249. k++;
  250. }
  251. discovered_devices[i].CoD[k]='\0';
  252. i++;
  253. k=0;
  254. }
  255. }
  256. void WaspBT::parse_device(uint8_t* data)
  257. {
  258. uint16_t j=0;
  259. uint8_t k=0;
  260. if( waitForData(data,"+RSDSRES=") ){
  261. while(data[j]!='=') j++;
  262. j++;
  263. while(data[j]!=',' && k<16)
  264. {
  265. device_service_name[k]=data[j];
  266. j++;
  267. k++;
  268. }
  269. j++;
  270. device_service_name[k]='\0';
  271. device_service_channel[0]=data[j];
  272. device_service_channel[1]=data[j+1];
  273. }
  274. }
  275. void WaspBT::get_MTU(uint8_t* data)
  276. {
  277. uint8_t i=0;
  278. uint16_t j=0;
  279. uint8_t k=0;
  280. while(data[j]!='=') j++;
  281. j++;
  282. connection_mtu[0]=serialRead(0);
  283. connection_mtu[1]=serialRead(0);
  284. connection_mtu[2]=serialRead(0);
  285. serialFlush(1);
  286. }
  287. void WaspBT::printData(char* data)
  288. {
  289. uint8_t uart=0;
  290. printString(data,uart);
  291. printByte('\r',uart);
  292. printByte('\n',uart);
  293. }
  294. // Constructors ////////////////////////////////////////////////////////////////
  295. WaspBT::WaspBT()
  296. {
  297. i=0;
  298. while(BT_PIN[i]!='\0'){
  299. bt_pin[i]=BT_PIN[i];
  300. i++;
  301. }
  302. auto_accept=BT_AUTO_ACC;
  303. active_connection=0;
  304. devices_found=0;
  305. }
  306. // Public Methods //////////////////////////////////////////////////////////////
  307. void WaspBT::ON()
  308. {
  309. uint8_t answer=0;
  310. beginSerial(XBEE_RATE, 0);
  311. pinMode(XBEE_PW,OUTPUT);
  312. digitalWrite(XBEE_PW,HIGH);
  313. // Waiting for the answer 'ROK'
  314. answer=parse_data("ROK");
  315. if(answer) flag |= BT_ERROR_ON;
  316. }
  317. void WaspBT::OFF()
  318. {
  319. closeSerial(0);
  320. pinMode(XBEE_PW,OUTPUT);
  321. digitalWrite(XBEE_PW,LOW);
  322. }
  323. // Returns '0' when the functions are right, '>0' otherwise
  324. uint8_t WaspBT::init()
  325. {
  326. uint8_t error = 0;
  327. first=1;
  328. if(setSecurity(BT_SECURITY_PREDEFINED,bt_pin)) error++;
  329. if(setServiceParameters(BT_SERVICE_NAME,BT_SERVICE_CHANNEL,BT_SERVICE_COD)) error++;
  330. if(setPublicName(BT_PUBLIC_NAME)) error++;
  331. if(setAutoAccept(BT_AUTO_ACC)) error++;
  332. if(setDiscoveryOptions(BT_DISCOVERABLE)) error++;
  333. return error;
  334. }
  335. // Returns '0' if no error, '>0' otherwise
  336. uint8_t WaspBT::setSecurity(uint8_t mode, char* pin)
  337. {
  338. char command[50];
  339. uint8_t length=0;
  340. uint8_t error=0;
  341. i=0;
  342. while(pin[i]!='\0'){
  343. bt_pin[i]=pin[i];
  344. i++;
  345. }
  346. length=i;
  347. if(!first) reset();
  348. if(length<10) sprintf(command,"%s%d,1,1,0%d,%s",BT_AT_SECURITY,mode,length,pin);
  349. else if(length>=10) sprintf(command,"%s%d,1,1,%d,%s",BT_AT_SECURITY,mode,length,pin);
  350. printData(command);
  351. first=0;
  352. error=parse_data("OK");
  353. if(error) flag |= BT_ERROR_SECURITY;
  354. return error;
  355. }
  356. // Returns '0' if no error, '>0' otherwise
  357. uint8_t WaspBT::setPublicName(char* name)
  358. {
  359. char command[50];
  360. uint8_t length=0;
  361. uint8_t error=0;
  362. i=0;
  363. while(name[i]!='\0') i++;
  364. length=i;
  365. if(length<10) sprintf(command,"%s0%d,%s",BT_AT_PUBLIC_NAME,length,name);
  366. else if(length>=10) sprintf(command,"%s%d,%s",BT_AT_PUBLIC_NAME,length,name);
  367. printData(command);
  368. error=parse_data("OK");
  369. if(error) flag |= BT_ERROR_NAME;
  370. return error;
  371. }
  372. // Returns '0' if no error, '>0' otherwise
  373. uint8_t WaspBT::setAutoAccept(uint8_t mode)
  374. {
  375. char command[50];
  376. uint8_t error=0;
  377. auto_accept=mode;
  378. sprintf(command,"%s%d",BT_AT_AUTO_ACCEPT,mode);
  379. printData(command);
  380. error=parse_data("OK");
  381. if(error) flag |= BT_ERROR_ACCEPT;
  382. return error;
  383. }
  384. // Returns '0' if no error, '>0' otherwise
  385. uint8_t WaspBT::setDiscoveryOptions(uint8_t option)
  386. {
  387. char command[50];
  388. uint8_t length=0;
  389. uint8_t error=0;
  390. sprintf(command,"%s%d",BT_AT_DISCOV_OPT,option);
  391. printData(command);
  392. error=parse_data("OK");
  393. if(error) flag |= BT_ERROR_DISC_OPT;
  394. return error;
  395. }
  396. uint8_t WaspBT::readData()
  397. {
  398. return parse_data();
  399. }
  400. uint8_t WaspBT::setServiceParameters(char* name, uint8_t channel, char* cod)
  401. {
  402. char command[50];
  403. uint8_t length=0;
  404. uint8_t error=0;
  405. i=0;
  406. while(name[i]!='\0') i++;
  407. length=i;
  408. if(length<10 && channel<10) sprintf(command,"%s1101,0%d,%s,0%d,%s",BT_AT_SERVICE_PAR,length,name,channel,cod);
  409. else if(length>=10 && channel<10) sprintf(command,"%s1101,%d,%s,0%d,%s",BT_AT_SERVICE_PAR,length,name,channel,cod);
  410. else if(length<10 && channel>=10) sprintf(command,"%s1101,0%d,%s,%d,%s",BT_AT_SERVICE_PAR,length,name,channel,cod);
  411. else if(length>=10 && channel>=10) sprintf(command,"%s1101,%d,%s,%d,%s",BT_AT_SERVICE_PAR,length,name,channel,cod);
  412. printData(command);
  413. error=parse_data("OK");
  414. if(error) flag |= BT_ERROR_SERVICE;
  415. return error;
  416. }
  417. // Returns '0' if no error, '>0' otherwise
  418. uint8_t WaspBT::reset()
  419. {
  420. uint8_t error=0;
  421. printData(BT_AT_RESET);
  422. error=parse_data("ROK");
  423. if(error) flag |= BT_ERROR_RESET;
  424. return error;
  425. }
  426. // Returns '0' if no error, '>0' otherwise
  427. uint8_t WaspBT::scanNetwork()
  428. {
  429. char command[50];
  430. uint8_t error=0;
  431. sprintf(command,"%s%d",BT_AT_DISCOVER,0);
  432. printData(command);
  433. if(parse_data("OK")) return 1;
  434. error=parse_data("+RDDSCNF=0");
  435. if(error) flag |= BT_ERROR_SCAN;
  436. return error;
  437. }
  438. uint8_t WaspBT::discoverDevice(char* mac, char* profile)
  439. {
  440. char command[50];
  441. uint8_t error=0;
  442. sprintf(command,"%s%s,%s",BT_AT_DISCOVER_DEV,mac,profile);
  443. printData(command);
  444. if(parse_data("OK")) return 1;
  445. error=parse_data("+RSDSCNF=0");
  446. if(error) flag |= BT_ERROR_DISC;
  447. return error;
  448. }
  449. uint8_t WaspBT::createConnection(char* mac,char* channel)
  450. {
  451. char command[50];
  452. uint8_t error=0;
  453. sprintf(command,"%s%s,%s",BT_AT_CONNECT,mac,channel);
  454. printData(command);
  455. if(parse_data("OK")){
  456. flag |= BT_ERROR_CONNECTING;
  457. return 1;
  458. }
  459. error=parse_data("+RCCRCNF");
  460. if(error) flag |= BT_ERROR_CONNECTING;
  461. else active_connection=1;
  462. return error;
  463. }
  464. uint8_t WaspBT::getOwnMac()
  465. {
  466. printData(BT_AT_OWN_MAC);
  467. if(!parse_data("+RRBDRES")){
  468. i=0;
  469. while(i<12){
  470. own_mac[i]=serialRead(0);
  471. i++;
  472. }
  473. serialFlush(1);
  474. return 0;
  475. }
  476. flag |= BT_ERROR_MAC;
  477. return 1;
  478. }
  479. uint8_t WaspBT::removeTrustedDevice(char* mac)
  480. {
  481. char command[50];
  482. uint8_t error=0;
  483. sprintf(command,"%s%s",BT_AT_DELETE_TD,mac);
  484. printData(command);
  485. error=parse_data("OK");
  486. if(error) flag |= BT_ERROR_REMOVING_TD;
  487. return error;
  488. }
  489. uint8_t WaspBT::sendData(char* data)
  490. {
  491. uint16_t length=0;
  492. uint8_t error=0;
  493. i=0;
  494. while(data[i]!='\0') i++;
  495. length=i;
  496. char command[20+length];
  497. if(length<10) sprintf(command,"%s00%d,%s",BT_AT_SEND_DATA,length,data);
  498. else if(length<100 && length>10) sprintf(command,"%s0%d,%s",BT_AT_SEND_DATA,length,data);
  499. else sprintf(command,"%s%d,%s",BT_AT_SEND_DATA,length,data);
  500. printData(command);
  501. error=parse_data("OK");
  502. delay(300);
  503. if(error) flag |= BT_ERROR_SENDING_DATA;
  504. return error;
  505. }
  506. uint8_t WaspBT::removeConnection()
  507. {
  508. printData(BT_AT_DISCONNECT);
  509. if(!parse_data("OK"))
  510. {
  511. getOwnMac();
  512. return 0;
  513. }
  514. flag |= BT_ERROR_REMOVING_CONNECTION;
  515. return 1;
  516. }
  517. uint8_t WaspBT::createStreamConnection()
  518. {
  519. uint8_t error=0;
  520. printData(BT_AT_STREAM_CONN);
  521. error=parse_data("OK");
  522. if(error) flag |= BT_ERROR_STREAM;
  523. return error;
  524. }
  525. WaspBT BT=WaspBT();