PageRenderTime 70ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 1ms

/WaspXBeeCore.cpp

https://github.com/mencey/waspmote-api
C++ | 5619 lines | 4512 code | 344 blank | 763 comment | 716 complexity | 1a38e9b24757c429f426623e786533f9 MD5 | raw file
  1. /*
  2. * Copyright (C) 2009 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.13
  17. * Design: David Gascón
  18. * Implementation: Alberto Bielsa
  19. */
  20. #ifndef __WPROGRAM_H__
  21. #include "WaspClasses.h"
  22. #endif
  23. #ifndef __WASPXBEECONSTANTS_H__
  24. #include "WaspXBeeConstants.h"
  25. #endif
  26. char get_own_mac_low[] = "7E00040852534C06";
  27. char get_own_mac_high[] = "7E0004085253480A";
  28. char set_own_net_address[] = "7E000608524D59000000";
  29. char get_own_net_address[] = "7E000408524D59FF";
  30. char set_baudrate[] = "7E0005085242440000";
  31. char set_api_mode[] = "7E0005085241500000";
  32. char set_api_options[] = "7E00050852414F0000";
  33. char set_pan[] = "7E000608524944000000";
  34. char set_pan_zb[] = "7E000C08524944000000000000000000";
  35. char get_pan[] = "7E00040852494418";
  36. char set_sleep_mode_xbee[] = "7E00050852534D0000";
  37. char get_sleep_mode_xbee[] = "7E00040852534D05";
  38. char set_awake_time[] = "7E000608525354000000";
  39. char set_awake_time_DM[] = "7E00070852535400000000";
  40. char set_sleep_time[] = "7E000608525350000000";
  41. char set_sleep_time_DM[] = "7E00070852535000000000";
  42. char set_channel[] = "7E0005085243480000";
  43. char get_channel[] = "7E0004085243481A";
  44. char get_NI[] = "7E000408524E490E";
  45. char set_scanning_time[] = "7E000508524E540000";
  46. char set_scanning_time_DM[] = "7E000608524E54000000";
  47. char get_scanning_time[] = "7E000408524E5403";
  48. char set_discov_options[] = "7E000508524E4F0000";
  49. char get_discov_options[] = "7E000408524E4F08";
  50. char write_values[] = "7E000408525752FC";
  51. char set_scanning_channel[] = "7E000608525343000000";
  52. char get_scanning_channel[] = "7E0004085253430F";
  53. char get_duration_energy[] = "7E0004085253440E";
  54. char set_link_key[] = "7E001408524B590000000000000000000000000000000000";
  55. char set_encryption[] = "7E0005085245450000";
  56. char set_power_level[] = "7E00050852504C0000";
  57. char get_RSSI[] = "7E0004085244421F";
  58. char get_hard_version[] = "7E00040852485607";
  59. char get_soft_version[] = "7E000408525652FD";
  60. char set_RSSI_time[] = "7E0005085252500000";
  61. char get_RSSI_time[] = "7E00040852525003";
  62. char apply_changes[] = "7E00040852414321";
  63. char reset_xbee[] = "7E0004085246520D";
  64. char reset_defaults_xbee[] = "7E0004085252450E";
  65. char set_sleep_options_xbee[] = "7E00050852534F0000";
  66. char get_sleep_options_xbee[] = "7E00040852534F03";
  67. char scan_network[] = "7E000408524E4413";
  68. extern char set_duration_energy[];
  69. extern char set_duration_energy_ZB[];
  70. /*
  71. Function: Initializes all the global variables that will be used later
  72. Returns: Nothing
  73. Parameters:
  74. protocol_used: Protocol the XBee is using
  75. frequency: Frequency the XBee is running on
  76. model_used: Model of XBee used
  77. */
  78. void WaspXBeeCore::init(uint8_t protocol_used, uint8_t frequency, uint8_t model_used)
  79. {
  80. protocol=protocol_used;
  81. freq=frequency;
  82. model=model_used;
  83. totalFragmentsReceived=0;
  84. pendingPackets=0;
  85. pos=0;
  86. discoveryOptions=0x00;
  87. if(protocol==XBEE_802_15_4)
  88. {
  89. awakeTime[0]=AWAKE_TIME_802_15_4_H;
  90. awakeTime[1]=AWAKE_TIME_802_15_4_L;
  91. sleepTime[0]=SLEEP_TIME_802_15_4_H;
  92. sleepTime[1]=SLEEP_TIME_802_15_4_L;
  93. scanTime[0]=SCAN_TIME_802_15_4;
  94. scanChannels[0]=SCAN_CHANNELS_802_15_4_H;
  95. scanChannels[1]=SCAN_CHANNELS_802_15_4_L;
  96. encryptMode=ENCRYPT_MODE_802_15_4;
  97. powerLevel=POWER_LEVEL_802_15_4;
  98. timeRSSI=TIME_RSSI_802_15_4;
  99. sleepOptions=SLEEP_OPTIONS_802_15_4;
  100. }
  101. if(protocol==ZIGBEE)
  102. {
  103. awakeTime[0]=AWAKE_TIME_ZIGBEE_H;
  104. awakeTime[1]=AWAKE_TIME_ZIGBEE_L;
  105. sleepTime[0]=SLEEP_TIME_ZIGBEE_H;
  106. sleepTime[1]=SLEEP_TIME_ZIGBEE_L;
  107. scanTime[0]=SCAN_TIME_ZIGBEE;
  108. scanChannels[0]=SCAN_CHANNELS_ZIGBEE_H;
  109. scanChannels[1]=SCAN_CHANNELS_ZIGBEE_L;
  110. timeEnergyChannel=TIME_ENERGY_CHANNEL_ZIGBEE;
  111. encryptMode=ENCRYPT_MODE_ZIGBEE;
  112. powerLevel=POWER_LEVEL_ZIGBEE;
  113. timeRSSI=TIME_RSSI_ZIGBEE;
  114. sleepOptions=SLEEP_OPTIONS_ZIGBEE;
  115. }
  116. if(protocol==DIGIMESH)
  117. {
  118. awakeTime[0]=AWAKE_TIME_DIGIMESH_H;
  119. awakeTime[1]=AWAKE_TIME_DIGIMESH_M;
  120. awakeTime[2]=AWAKE_TIME_DIGIMESH_L;
  121. sleepTime[0]=SLEEP_TIME_DIGIMESH_H;
  122. sleepTime[1]=SLEEP_TIME_DIGIMESH_M;
  123. sleepTime[2]=SLEEP_TIME_DIGIMESH_L;
  124. scanTime[0]=SCAN_TIME_DIGIMESH_H;
  125. scanTime[1]=SCAN_TIME_DIGIMESH_L;
  126. encryptMode=ENCRYPT_MODE_DIGIMESH;
  127. powerLevel=POWER_LEVEL_DIGIMESH;
  128. timeRSSI=TIME_RSSI_DIGIMESH;
  129. sleepOptions=SLEEP_OPTIONS_DIGIMESH;
  130. }
  131. data_length=0;
  132. it=0;
  133. start=0;
  134. finish=0;
  135. add_type=0;
  136. mode=0;
  137. frag_length=0;
  138. TIME1=0;
  139. nextIndex1=0;
  140. frameNext=0;
  141. replacementPolicy=XBEE_OUT;
  142. indexNotModified=1;
  143. error_AT=2;
  144. error_RX=2;
  145. error_TX=2;
  146. clearFinishArray();
  147. clearCommand();
  148. apsEncryption=0;
  149. }
  150. /*
  151. Function: Get the 32 lower bits of my MAC address
  152. Returns: Integer that determines if there has been any error
  153. error=2 --> The command has not been executed
  154. error=1 --> There has been an error while executing the command
  155. error=0 --> The command has been executed with no errors
  156. Values: When it is executed stores the returned value by SL command in the global
  157. "sourceMacLow[4]" variable
  158. */
  159. uint8_t WaspXBeeCore::getOwnMacLow()
  160. {
  161. int8_t error=2;
  162. error_AT=2;
  163. gen_data(get_own_mac_low);
  164. error=gen_send(get_own_mac_low);
  165. if(error==0)
  166. {
  167. for(it=0;it<4;it++)
  168. {
  169. sourceMacLow[it]=data[it];
  170. }
  171. }
  172. return error;
  173. }
  174. /*
  175. Function: Get the 32 higher bits of my MAC address
  176. Returns: Integer that determines if there has been any error
  177. error=2 --> The command has not been executed
  178. error=1 --> There has been an error while executing the command
  179. error=0 --> The command has been executed with no errors
  180. Values: When it is executed stores the returned value by SH in the global
  181. "sourceMacHigh[4]" variable
  182. */
  183. uint8_t WaspXBeeCore::getOwnMacHigh()
  184. {
  185. int8_t error=2;
  186. error_AT=2;
  187. gen_data(get_own_mac_high);
  188. error=gen_send(get_own_mac_high);
  189. if(error==0)
  190. {
  191. for(it=0;it<4;it++)
  192. {
  193. sourceMacHigh[it]=data[it];
  194. }
  195. }
  196. return error;
  197. }
  198. /*
  199. Function: Get the 64 bits of my MAC address
  200. Returns: Integer that determines if there has been any error
  201. error=2 --> The command has not been executed
  202. error=1 --> There has been an error while executing the command
  203. error=0 --> The command has been executed with no errors
  204. Values: Executes functions getOwnMacLow() and getOwnMacHigh()
  205. */
  206. uint8_t WaspXBeeCore::getOwnMac()
  207. {
  208. int8_t error=2;
  209. error=getOwnMacLow();
  210. if(error==0)
  211. {
  212. error=getOwnMacHigh();
  213. }
  214. return error;
  215. }
  216. /*
  217. Function: Set the 16b network address
  218. Returns: Integer that determines if there has been any error
  219. error=2 --> The command has not been executed
  220. error=1 --> There has been an error while executing the command
  221. error=0 --> The command has been executed with no errors
  222. error=-1 --> Forbidden command in this protocol
  223. Parameters:
  224. NA_H : Higher byte of Network Address (0x00-0xFF)
  225. NA_L : Lower byte of Network Address (0x00-0xFF)
  226. Values: Stores in global "sourceNA[2]" variable the 16b address set by the user
  227. */
  228. uint8_t WaspXBeeCore::setOwnNetAddress(uint8_t NA_H, uint8_t NA_L)
  229. {
  230. int8_t error=2;
  231. if(protocol==XBEE_802_15_4)
  232. {
  233. error_AT=2;
  234. gen_data(set_own_net_address,NA_H,NA_L);
  235. gen_checksum(set_own_net_address);
  236. error=gen_send(set_own_net_address);
  237. }
  238. else
  239. {
  240. error_AT=-1;
  241. error=-1;
  242. }
  243. if(!error)
  244. {
  245. sourceNA[0]=NA_H;
  246. sourceNA[1]=NA_L;
  247. }
  248. return error;
  249. }
  250. /*
  251. Function: Get the 16b network address
  252. Returns: Integer that determines if there has been any error
  253. error=2 --> The command has not been executed
  254. error=1 --> There has been an error while executing the command
  255. error=0 --> The command has been executed with no errors
  256. error=-1 --> Forbidden command in this protocol
  257. Values: Stores in global "sourceNA[2]" variable the returned 16b network address
  258. by MY command
  259. */
  260. uint8_t WaspXBeeCore::getOwnNetAddress()
  261. {
  262. int8_t error=2;
  263. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) )
  264. {
  265. error_AT=2;
  266. gen_data(get_own_net_address);
  267. error=gen_send(get_own_net_address);
  268. }
  269. else
  270. {
  271. error_AT=-1;
  272. error=-1;
  273. }
  274. if(!error)
  275. {
  276. sourceNA[0]=data[0];
  277. sourceNA[1]=data[1];
  278. }
  279. return error;
  280. }
  281. /*
  282. Function: Set Baudrate to use
  283. Returns: Integer that determines if there has been any error
  284. error=2 --> The command has not been executed
  285. error=1 --> There has been an error while executing the command
  286. error=0 --> The command has been executed with no errors
  287. error=-1 --> Forbidden command in this protocol
  288. Parameters:
  289. baud_rate: integer that contains the baudrate
  290. Values: Stores in global "baudrate" variable the baudrate
  291. */
  292. uint8_t WaspXBeeCore::setBaudrate(uint8_t baud_rate)
  293. {
  294. int8_t error=2;
  295. error_AT=2;
  296. gen_data(set_baudrate,baud_rate);
  297. gen_checksum(set_baudrate);
  298. error=gen_send(set_baudrate);
  299. if(!error)
  300. {
  301. baudrate=baud_rate;
  302. }
  303. return error;
  304. }
  305. /*
  306. Function: Set API values
  307. Returns: Integer that determines if there has been any error
  308. error=2 --> The command has not been executed
  309. error=1 --> There has been an error while executing the command
  310. error=0 --> The command has been executed with no errors
  311. error=-1 --> Forbidden command in this protocol
  312. Parameters:
  313. api_value: integer that contains the api value
  314. Values: Stores in global "apiValue" variable the baudrate
  315. */
  316. uint8_t WaspXBeeCore::setAPI(uint8_t api_value)
  317. {
  318. int8_t error=2;
  319. error_AT=2;
  320. gen_data(set_api_mode,api_value);
  321. gen_checksum(set_api_mode);
  322. error=gen_send(set_api_mode);
  323. if(!error)
  324. {
  325. apiValue=api_value;
  326. }
  327. return error;
  328. }
  329. /*
  330. Function: Set API options. Enable ZIgBee Application Layer Addressing
  331. Returns: Integer that determines if there has been any error
  332. error=2 --> The command has not been executed
  333. error=1 --> There has been an error while executing the command
  334. error=0 --> The command has been executed with no errors
  335. error=-1 --> Forbidden command in this protocol
  336. Parameters:
  337. api_options: integer that contains the baudrate
  338. */
  339. uint8_t WaspXBeeCore::setAPIoptions(uint8_t api_options)
  340. {
  341. int8_t error=2;
  342. if( (protocol!=XBEE_802_15_4) )
  343. {
  344. error_AT=2;
  345. gen_data(set_api_options,api_options);
  346. gen_checksum(set_api_options);
  347. error=gen_send(set_api_options);
  348. }
  349. else
  350. {
  351. error_AT=-1;
  352. error=-1;
  353. }
  354. return error;
  355. }
  356. /*
  357. Function: Set the network identifier
  358. Returns: Integer that determines if there has been any error
  359. error=2 --> The command has not been executed
  360. error=1 --> There has been an error while executing the command
  361. error=0 --> The command has been executed with no errors
  362. Parameters:
  363. PANID: Array of integers than contains the 16b or 64b PAN ID
  364. Values: Stores in global "PAN_ID" variable the recent set PAN ID value
  365. */
  366. uint8_t WaspXBeeCore::setPAN(uint8_t* PANID)
  367. {
  368. int8_t error=2;
  369. if( (protocol==XBEE_802_15_4) || (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  370. {
  371. error_AT=2;
  372. gen_data(set_pan,PANID);
  373. gen_checksum(set_pan);
  374. error=gen_send(set_pan);
  375. }
  376. if(protocol==ZIGBEE)
  377. {
  378. error_AT=2;
  379. gen_data(set_pan_zb,PANID);
  380. gen_checksum(set_pan_zb);
  381. error=gen_send(set_pan_zb);
  382. }
  383. if(!error)
  384. {
  385. if( (protocol==XBEE_802_15_4) || (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  386. {
  387. for(it=0;it<2;it++)
  388. {
  389. PAN_ID[it]=PANID[it];
  390. }
  391. }
  392. if(protocol==ZIGBEE)
  393. {
  394. for(it=0;it<8;it++)
  395. {
  396. PAN_ID[it]=PANID[it];
  397. }
  398. }
  399. }
  400. return error;
  401. }
  402. /*
  403. Function: Get Network ID
  404. Returns: Integer that determines if there has been any error
  405. error=2 --> The command has not been executed
  406. error=1 --> There has been an error while executing the command
  407. error=0 --> The command has been executed with no errors
  408. Values: Stores in global "error" variable any error happened while execution
  409. Stores in global "PAN_ID" variable the 16b or 64b network PAN ID
  410. */
  411. uint8_t WaspXBeeCore::getPAN()
  412. {
  413. int8_t error=2;
  414. error_AT=2;
  415. gen_data(get_pan);
  416. if( protocol==ZIGBEE ) error=gen_send(get_pan);
  417. else error=gen_send(get_pan);
  418. if(!error)
  419. {
  420. if( (protocol==XBEE_802_15_4) || (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  421. {
  422. for(it=0;it<2;it++)
  423. {
  424. PAN_ID[it]=data[it];
  425. delay(20);
  426. }
  427. }
  428. if(protocol==ZIGBEE)
  429. {
  430. for(it=0;it<8;it++)
  431. {
  432. PAN_ID[it]=data[it];
  433. delay(20);
  434. }
  435. }
  436. }
  437. return error;
  438. }
  439. /*
  440. Function: Set the module to the sleep mode specified.
  441. Returns: Integer that determines if there has been any error
  442. error=2 --> The command has not been executed
  443. error=1 --> There has been an error while executing the command
  444. error=0 --> The command has been executed with no errors
  445. Values: Stores the returned value by SM command in the global "sleepMode" variable
  446. Parameters:
  447. sleep: Defines the sleep mode to use by the XBee (0-5)
  448. */
  449. uint8_t WaspXBeeCore::setSleepMode(uint8_t sleep)
  450. {
  451. int8_t error=2;
  452. error_AT=2;
  453. gen_data(set_sleep_mode_xbee,sleep);
  454. gen_checksum(set_sleep_mode_xbee);
  455. error=gen_send(set_sleep_mode_xbee);
  456. if(!error)
  457. {
  458. sleepMode=sleep;
  459. }
  460. return error;
  461. }
  462. /*
  463. Function: Get the XBee mode
  464. Returns: Integer that determines if there has been any error
  465. error=2 --> The command has not been executed
  466. error=1 --> There has been an error while executing the command
  467. error=0 --> The command has been executed with no errors
  468. Values: Stores the XBee mode in the global "sleepMode" variable
  469. */
  470. uint8_t WaspXBeeCore::getSleepMode()
  471. {
  472. int8_t error=2;
  473. error_AT=2;
  474. gen_data(get_sleep_mode_xbee);
  475. error=gen_send(get_sleep_mode_xbee);
  476. if(error==0)
  477. {
  478. sleepMode=data[0];
  479. }
  480. return error;
  481. }
  482. /*
  483. Function: Set the time the module has to be idle before start sleeping
  484. Returns: Integer that determines if there has been any error
  485. error=2 --> The command has not been executed
  486. error=1 --> There has been an error while executing the command
  487. error=0 --> The command has been executed with no errors
  488. Values: Change the ST parameter in XBee module
  489. Stores in global "awakeTime" the value of this time
  490. Parameters:
  491. awake: Array of integers that specifies the time to be awake before sleep
  492. */
  493. uint8_t WaspXBeeCore::setAwakeTime(uint8_t* awake)
  494. {
  495. int8_t error=2;
  496. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) )
  497. {
  498. error_AT=2;
  499. gen_data(set_awake_time,awake);
  500. gen_checksum(set_awake_time);
  501. error=gen_send(set_awake_time);
  502. }
  503. if( (protocol==DIGIMESH) || (protocol==XBEE_900) )
  504. {
  505. error_AT=2;
  506. gen_data(set_awake_time_DM,awake);
  507. gen_checksum(set_awake_time_DM);
  508. error=gen_send(set_awake_time_DM);
  509. }
  510. if(!error)
  511. {
  512. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) )
  513. {
  514. awakeTime[0]=awake[0];
  515. awakeTime[1]=awake[1];
  516. }
  517. if( (protocol==DIGIMESH) || (protocol==XBEE_900) )
  518. {
  519. awakeTime[0]=awake[0];
  520. awakeTime[1]=awake[1];
  521. awakeTime[2]=awake[2];
  522. }
  523. }
  524. return error;
  525. }
  526. /*
  527. Function: Set the cyclic sleeping time of the node
  528. Returns: Integer that determines if there has been any error
  529. error=2 --> The command has not been executed
  530. error=1 --> There has been an error while executing the command
  531. error=0 --> The command has been executed with no errors
  532. Values: Change the SP parameter in the XBee module
  533. Stores in global "sleepTime" the value of this time
  534. Parameters:
  535. sleep: Array of Integers that specifies the amount of time the module spends sleeping
  536. */
  537. uint8_t WaspXBeeCore::setSleepTime(uint8_t* sleep)
  538. {
  539. int8_t error=2;
  540. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) )
  541. {
  542. error_AT=2;
  543. gen_data(set_sleep_time,sleep);
  544. gen_checksum(set_sleep_time);
  545. error=gen_send(set_sleep_time);
  546. }
  547. if( (protocol==DIGIMESH) || (protocol==XBEE_900) )
  548. {
  549. error_AT=2;
  550. gen_data(set_sleep_time_DM,sleep);
  551. gen_checksum(set_sleep_time_DM);
  552. error=gen_send(set_sleep_time_DM);
  553. }
  554. if(!error)
  555. {
  556. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_868) )
  557. {
  558. sleepTime[0]=sleep[0];
  559. sleepTime[1]=sleep[1];
  560. }
  561. if( (protocol==DIGIMESH) || (protocol==XBEE_900) )
  562. {
  563. sleepTime[0]=sleep[0];
  564. sleepTime[1]=sleep[1];
  565. sleepTime[2]=sleep[2];
  566. }
  567. }
  568. return error;
  569. }
  570. /*
  571. Function: Set the channel frequency where the module is going to work
  572. Returns: Integer that determines if there has been any error
  573. error=2 --> The command has not been executed
  574. error=1 --> There has been an error while executing the command
  575. error=0 --> The command has been executed with no errors
  576. error=-1 --> Forbidden command for this protocol
  577. Values: Stores the selected channel in the global "channel" variable
  578. Parameters:
  579. _channel: Channel used to transmit (0x0B-0x1A)
  580. */
  581. uint8_t WaspXBeeCore::setChannel(uint8_t _channel)
  582. {
  583. int8_t error=2;
  584. if( (protocol==XBEE_802_15_4) || (protocol==DIGIMESH) || (protocol==XBEE_900) )
  585. {
  586. error_AT=2;
  587. gen_data(set_channel,_channel);
  588. gen_checksum(set_channel);
  589. error=gen_send(set_channel);
  590. }
  591. else
  592. {
  593. error_AT=-1;
  594. error=-1;
  595. }
  596. if(!error)
  597. {
  598. channel=_channel;
  599. }
  600. return error;
  601. }
  602. /*
  603. Function: Get the actual frequency channel
  604. Returns: Integer that determines if there has been any error
  605. error=2 --> The command has not been executed
  606. error=1 --> There has been an error while executing the command
  607. error=0 --> The command has been executed with no errors
  608. Values: Stores the frequency channel in the global "channel" variable
  609. */
  610. uint8_t WaspXBeeCore::getChannel()
  611. {
  612. int8_t error=2;
  613. error_AT=2;
  614. gen_data(get_channel);
  615. error=gen_send(get_channel);
  616. if(!error)
  617. {
  618. channel=data[0];
  619. }
  620. return error;
  621. }
  622. /*
  623. Function: Set the Node Indentifier
  624. Returns: Integer that determines if there has been any error
  625. error=2 --> The command has not been executed
  626. error=1 --> There has been an error while executing the command
  627. error=0 --> The command has been executed with no errors
  628. Values: Change the NI to the selected in the function
  629. The NI must be a 20 character max string
  630. Stores the given NI in the global "nodeID" variable
  631. Parameters:
  632. node: string that specifies the node indentifier
  633. */
  634. uint8_t WaspXBeeCore::setNodeIdentifier(char* node)
  635. {
  636. uint8_t* NI = (uint8_t*) calloc(30,sizeof(uint8_t)); //{0x7E, 0x00, 0x00, 0x08, 0x52, 0x4E, 0x49, 0x02};
  637. NI[0]=0x7E;
  638. NI[1]=0x00;
  639. NI[3]=0x08;
  640. NI[4]=0x52;
  641. NI[5]=0x4E;
  642. NI[6]=0x49;
  643. uint8_t num_NI;
  644. int8_t error=2;
  645. uint8_t* ByteIN = (uint8_t*) calloc(20,sizeof(uint8_t));
  646. uint8_t counter=0;
  647. uint8_t counter3=0;
  648. uint8_t est=1;
  649. uint8_t frame_ID=NI[4];
  650. uint8_t end=0;
  651. uint16_t interval=WAIT_TIME;
  652. uint8_t checksum=0;
  653. uint8_t numberBytes=9;
  654. uint8_t status=0;
  655. uint8_t undesired=0;
  656. it=0;
  657. error_AT=2;
  658. while( (node[it]!='\0') )
  659. {
  660. NI[it+7]=uint8_t(node[it]);
  661. it++;
  662. }
  663. NI[2]=4+it;
  664. for(it=3;it<(7+(NI[2]-4));it++)
  665. {
  666. checksum=checksum+NI[it];
  667. }
  668. while( (checksum>255))
  669. {
  670. checksum=checksum-256;
  671. }
  672. checksum=255-checksum;
  673. NI[7+NI[2]-4]=checksum;
  674. while(counter<(8+NI[2]-4))
  675. {
  676. XBee.print(NI[counter], BYTE);
  677. counter++;
  678. }
  679. counter=0;
  680. clearCommand();
  681. command[5]=0x4E;
  682. command[6]=0x49;
  683. error=parse_message(command);
  684. if(error==0)
  685. {
  686. for(it=0;it<NI[2]-4;it++)
  687. {
  688. nodeID[it]=node[it];
  689. }
  690. }
  691. free(NI);
  692. free(ByteIN);
  693. NI=NULL;
  694. ByteIN=NULL;
  695. return error;
  696. }
  697. /*
  698. Function: Get the Node Identifier
  699. Returns: Integer that determines if there has been any error
  700. error=2 --> The command has not been executed
  701. error=1 --> There has been an error while executing the command
  702. error=0 --> The command has been executed with no errors
  703. Values: Stores the NI in the global "nodeID" variable
  704. */
  705. uint8_t WaspXBeeCore::getNodeIdentifier()
  706. {
  707. int8_t error=2;
  708. error_AT=2;
  709. gen_data(get_NI);
  710. error=gen_send(get_NI);
  711. if(!error)
  712. {
  713. for(it=0;it<data_length;it++)
  714. {
  715. nodeID[it]=char(data[it]);
  716. }
  717. }
  718. return error;
  719. }
  720. /*
  721. Function: Scans for brothers in the same channel and same PAN ID
  722. Returns: Integer that determines if there has been any error
  723. error=2 --> The command has not been executed
  724. error=1 --> There has been an error while executing the command
  725. error=0 --> The command has been executed with no errors
  726. Values: Stores given info (SH,SL,MY,RSSI,NI) in global array "scannedBrothers" variable
  727. Stores in global "totalScannedBrothers" the number of found brothers
  728. */
  729. uint8_t WaspXBeeCore::scanNetwork()
  730. {
  731. uint8_t error=2;
  732. error_AT=2;
  733. totalScannedBrothers=0;
  734. gen_data(scan_network);
  735. error=gen_send(scan_network);
  736. return error;
  737. }
  738. /*
  739. Function: Scans for brothers in the same channel and same PAN ID
  740. Returns: Integer that determines if there has been any error
  741. error=2 --> The command has not been executed
  742. error=1 --> There has been an error while executing the command
  743. error=0 --> The command has been executed with no errors
  744. Values: Stores given info (SH,SL,MY,RSSI,NI) in global array "scannedBrothers" variable
  745. Stores in global "totalScannedBrothers" the number of founded brothers
  746. Parameters:
  747. node: 20-byte max string containing NI of the node to search
  748. */
  749. uint8_t WaspXBeeCore::scanNetwork(char* node)
  750. {
  751. uint8_t* ND = (uint8_t*) calloc(30,sizeof(uint8_t)); //{0x7E, 0x00, 0x04, 0x08, 0x52, 0x4E, 0x44, 0x13};
  752. ND[0]=0x7E;
  753. ND[1]=0x00;
  754. ND[3]=0x08;
  755. ND[4]=0x52;
  756. ND[5]=0x4E;
  757. ND[6]=0x44;
  758. uint8_t num_ND;
  759. int8_t error=2;
  760. uint8_t* ByteIN = (uint8_t*) calloc(20,sizeof(uint8_t));
  761. uint8_t cont=1;
  762. uint8_t cont2=0;
  763. uint8_t counter=0;
  764. uint8_t counter3=0;
  765. uint8_t est=1;
  766. uint8_t frame_ID=ND[4];
  767. uint8_t end=0;
  768. uint16_t interval=WAIT_TIME2;
  769. uint16_t length=0;
  770. uint16_t aux=0;
  771. uint8_t existsNI=0;
  772. uint8_t length_NI=0;
  773. uint16_t checksum=0;
  774. uint8_t finish=0;
  775. error_AT=2;
  776. totalScannedBrothers=0;
  777. if( (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  778. {
  779. interval=14000;
  780. }
  781. it=0;
  782. while( (node[it]!='\0') )
  783. {
  784. ND[it+7]=uint8_t(node[it]);
  785. it++;
  786. }
  787. ND[2]=4+it;
  788. for(it=3;it<(7+(ND[2]-4));it++)
  789. {
  790. checksum=checksum+ND[it];
  791. }
  792. while( (checksum>255))
  793. {
  794. checksum=checksum-256;
  795. }
  796. checksum=255-checksum;
  797. ND[7+ND[2]-4]=checksum;
  798. while(counter<(8+ND[2]-4))
  799. {
  800. XBee.print(ND[counter], BYTE);
  801. counter++;
  802. }
  803. counter=0;
  804. clearCommand();
  805. command[5]=ND[5];
  806. command[6]=ND[6];
  807. error=parse_message(command);
  808. free(ND);
  809. free(ByteIN);
  810. ND=NULL;
  811. ByteIN=NULL;
  812. return error;
  813. }
  814. /*
  815. Function: Defines the amount of time the scanNetwork() function is scanning
  816. Returns: Integer that determines if there has been any error
  817. error=2 --> The command has not been executed
  818. error=1 --> There has been an error while executing the command
  819. error=0 --> The command has been executed with no errors
  820. Values: Changes the NT command
  821. Stores in global "scanTime" variable the recent set time
  822. Parameters:
  823. time: amount of time ND is scanning for brothers (0x01-0xFC)
  824. */
  825. uint8_t WaspXBeeCore::setScanningTime(uint8_t* time)
  826. {
  827. int8_t error=2;
  828. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_900) )
  829. {
  830. error_AT=2;
  831. gen_data(set_scanning_time,time);
  832. gen_checksum(set_scanning_time);
  833. error=gen_send(set_scanning_time);
  834. }
  835. if( (protocol==DIGIMESH) || (protocol==XBEE_868) )
  836. {
  837. error_AT=2;
  838. gen_data(set_scanning_time_DM,time);
  839. gen_checksum(set_scanning_time_DM);
  840. error=gen_send(set_scanning_time_DM);
  841. }
  842. if(!error)
  843. {
  844. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) || (protocol==XBEE_900) )
  845. {
  846. scanTime[0]=time[0];
  847. }
  848. if( (protocol==DIGIMESH) || (protocol==XBEE_868) )
  849. {
  850. scanTime[0]=time[0];
  851. scanTime[1]=time[1];
  852. }
  853. }
  854. return error;
  855. }
  856. /*
  857. Function: Get the Scanning Time
  858. Returns: Integer that determines if there has been any error
  859. error=2 --> The command has not been executed
  860. error=1 --> There has been an error while executing the command
  861. error=0 --> The command has been executed with no errors
  862. Values: Stores in global "error" variable any error happened while execution
  863. Stores in global "scanTime" the value of scanning time
  864. */
  865. uint8_t WaspXBeeCore::getScanningTime()
  866. {
  867. int8_t error=2;
  868. error_AT=2;
  869. gen_data(get_scanning_time);
  870. if( (protocol==DIGIMESH) || (protocol==XBEE_868) || (protocol==ZIGBEE) || (protocol==XBEE_900) ) error=gen_send(get_scanning_time);
  871. else error=gen_send(get_scanning_time);
  872. if(!error)
  873. {
  874. if( (protocol==XBEE_802_15_4) )
  875. {
  876. scanTime[0]=data[0];
  877. }
  878. if( (protocol==ZIGBEE) || (protocol==XBEE_900) )
  879. {
  880. scanTime[0]=data[1];
  881. }
  882. if( (protocol==DIGIMESH) || (protocol==XBEE_868) )
  883. {
  884. scanTime[0]=data[0];
  885. scanTime[1]=data[1];
  886. }
  887. }
  888. return error;
  889. }
  890. /*
  891. Function: Set the options value for the network discovery command
  892. Returns: Integer that determines if there has been any error
  893. error=2 --> The command has not been executed
  894. error=1 --> There has been an error while executing the command
  895. error=0 --> The command has been executed with no errors
  896. Values: Change the NO command
  897. Parameters:
  898. options: chosen option (0x00-0x03)
  899. */
  900. uint8_t WaspXBeeCore::setDiscoveryOptions(uint8_t options)
  901. {
  902. int8_t error=2;
  903. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) )
  904. {
  905. error_AT=2;
  906. gen_data(set_discov_options,options);
  907. gen_checksum(set_discov_options);
  908. error=gen_send(set_discov_options);
  909. }
  910. else
  911. {
  912. error_AT=-1;
  913. error=-1;
  914. }
  915. if(!error)
  916. {
  917. discoveryOptions=options;
  918. }
  919. return error;
  920. }
  921. /*
  922. Function: Get the options value for the network discovery command
  923. Returns: Integer that determines if there has been any error
  924. error=2 --> The command has not been executed
  925. error=1 --> There has been an error while executing the command
  926. error=0 --> The command has been executed with no errors
  927. Values: Executes the NO command. Stores in global "discoveryOptions" variable the options
  928. */
  929. uint8_t WaspXBeeCore::getDiscoveryOptions()
  930. {
  931. int8_t error=2;
  932. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) )
  933. {
  934. error_AT=2;
  935. gen_data(get_discov_options);
  936. error=gen_send(get_discov_options);
  937. }
  938. else
  939. {
  940. error_AT=-1;
  941. error=-1;
  942. }
  943. if(error==0)
  944. {
  945. discoveryOptions=data[0];
  946. }
  947. return error;
  948. }
  949. /*
  950. Function: Performs a quick search.
  951. 802.15.4 : It keeps in DL the MY of the looked up NI brother
  952. ZIGBEE : Stores in global "paquete" naD,macDH,macDL from the searched device
  953. DIGIMESH: Stores in global "paquete" macDH,macDL from the searched device
  954. Returns: Integer that determines if there has been any error
  955. error=2 --> The command has not been executed
  956. error=1 --> There has been an error while executing the command
  957. error=0 --> The command has been executed with no errors
  958. Values: Executes DN command.
  959. Parameters:
  960. node: string that specifies the NI that identifies the searched brother
  961. length: length of that NI (0-20)
  962. */
  963. uint8_t WaspXBeeCore::nodeSearch(char* node, struct packetXBee* paq)
  964. {
  965. uint8_t* DN = (uint8_t*) calloc(30,sizeof(uint8_t)); //{0x7E, 0x00, 0x00, 0x08, 0x52, 0x44, 0x4E, 0xE3};
  966. DN[0]=0x7E;
  967. DN[1]=0x00;
  968. DN[3]=0x08;
  969. DN[4]=0x52;
  970. DN[5]=0x44;
  971. DN[6]=0x4E;
  972. uint8_t num_DN;
  973. int8_t error=2;
  974. uint8_t* ByteIN = (uint8_t*) calloc(25,sizeof(uint8_t));
  975. uint8_t counter=0;
  976. uint8_t counter3=0;
  977. uint8_t est=1;
  978. uint8_t frame_ID=DN[4];
  979. uint8_t end=0;
  980. uint16_t interval=2000;
  981. uint8_t checksum=0;
  982. uint8_t status=0;
  983. uint8_t undesired=0;
  984. error_AT=2;
  985. if(protocol==DIGIMESH)
  986. {
  987. interval=14000;
  988. }
  989. it=0;
  990. while( (node[it]!='\0') )
  991. {
  992. DN[it+7]=uint8_t(node[it]);
  993. it++;
  994. }
  995. DN[2]=4+it;
  996. for(it=3;it<(7+(DN[2]-4));it++)
  997. {
  998. checksum=checksum+DN[it];
  999. }
  1000. while( (checksum>255))
  1001. {
  1002. checksum=checksum-256;
  1003. }
  1004. checksum=255-checksum;
  1005. DN[7+DN[2]-4]=checksum;
  1006. while(counter<(8+DN[2]-4))
  1007. {
  1008. XBee.print(DN[counter], BYTE);
  1009. counter++;
  1010. }
  1011. counter=0;
  1012. clearCommand();
  1013. command[5]=0x44;
  1014. command[6]=0x4E;
  1015. error=parse_message(command);
  1016. if(error==0)
  1017. {
  1018. if( (protocol==ZIGBEE) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  1019. {
  1020. for(it=0;it<2;it++)
  1021. {
  1022. paq->naD[it]=data[it];
  1023. }
  1024. for(it=0;it<4;it++)
  1025. {
  1026. paq->macDH[it]=data[it+2];
  1027. }
  1028. for(it=0;it<4;it++)
  1029. {
  1030. paq->macDL[it]=data[it+6];
  1031. }
  1032. }
  1033. if(protocol==DIGIMESH)
  1034. {
  1035. for(it=0;it<4;it++)
  1036. {
  1037. paq->macDH[it]=data[it];
  1038. }
  1039. for(it=0;it<4;it++)
  1040. {
  1041. paq->macDL[it]=data[it+4];
  1042. }
  1043. }
  1044. }
  1045. free(DN);
  1046. free(ByteIN);
  1047. DN=NULL;
  1048. ByteIN=NULL;
  1049. return error;
  1050. }
  1051. /*
  1052. Function: Write the current parameters to a non volatil memory
  1053. Returns: Integer that determines if there has been any error
  1054. error=2 --> The command has not been executed
  1055. error=1 --> There has been an error while executing the command
  1056. error=0 --> The command has been executed with no errors
  1057. Values: Executes the WR command
  1058. */
  1059. uint8_t WaspXBeeCore::writeValues()
  1060. {
  1061. int8_t error=2;
  1062. error_AT=2;
  1063. gen_data(write_values);
  1064. error=gen_send(write_values);
  1065. return error;
  1066. }
  1067. /*
  1068. Function: Specifies the list of channels to scan when performing an energy scan
  1069. Returns: Integer that determines if there has been any error
  1070. error=2 --> The command has not been executed
  1071. error=1 --> There has been an error while executing the command
  1072. error=0 --> The command has been executed with no errors
  1073. error=-1 --> Forbidden command for this protocol
  1074. Values: Change the SC command. Stores in global "scanChannels" variable the list of channels
  1075. Parameters:
  1076. channel_H: higher byte of list of channels (0x00-0xFF)
  1077. channel_L: lower byte of list of channels (0x00-0xFF
  1078. */
  1079. uint8_t WaspXBeeCore::setScanningChannels(uint8_t channel_H, uint8_t channel_L)
  1080. {
  1081. int8_t error=2;
  1082. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) )
  1083. {
  1084. error_AT=2;
  1085. gen_data(set_scanning_channel,channel_H,channel_L);
  1086. gen_checksum(set_scanning_channel);
  1087. error=gen_send(set_scanning_channel);
  1088. }
  1089. else
  1090. {
  1091. error_AT=-1;
  1092. error=-1;
  1093. }
  1094. if(error==0)
  1095. {
  1096. scanChannels[0]=channel_H;
  1097. scanChannels[1]=channel_L;
  1098. }
  1099. return error;
  1100. }
  1101. /*
  1102. Function: Get the list of channels to scan when performing an energy scan
  1103. Returns: Integer that determines if there has been any error
  1104. error=2 --> The command has not been executed
  1105. error=1 --> There has been an error while executing the command
  1106. error=0 --> The command has been executed with no errors
  1107. error=-1 --> Forbidden command for this protocol
  1108. Values: Stores in global "scanChannels" variable the scanning channel list
  1109. */
  1110. uint8_t WaspXBeeCore::getScanningChannels()
  1111. {
  1112. int8_t error=2;
  1113. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) )
  1114. {
  1115. error_AT=2;
  1116. gen_data(get_scanning_channel);
  1117. error=gen_send(get_scanning_channel);
  1118. }
  1119. else
  1120. {
  1121. error_AT=-1;
  1122. error=-1;
  1123. }
  1124. if(error==0)
  1125. {
  1126. for(it=0;it<2;it++)
  1127. {
  1128. scanChannels[it]=data[it];
  1129. }
  1130. }
  1131. return error;
  1132. }
  1133. /*
  1134. Function: It sets the time the energy scan will be performed
  1135. Returns: Integer that determines if there has been any error
  1136. error=2 --> The command has not been executed
  1137. error=1 --> There has been an error while executing the command
  1138. error=0 --> The command has been executed with no errors
  1139. error=-1 --> Forbidden command for this protocol
  1140. Values: Change the ED command. Stores in global "energyChannel" variable the energy in each channel
  1141. Parameters:
  1142. duration: amount of time that the energy scan will be performed (0-6)
  1143. */
  1144. uint8_t WaspXBeeCore::setDurationEnergyChannels(uint8_t duration)
  1145. {
  1146. int8_t error=2;
  1147. if( (protocol==XBEE_802_15_4) )
  1148. {
  1149. error_AT=2;
  1150. gen_data(set_duration_energy,duration);
  1151. gen_checksum(set_duration_energy);
  1152. error=gen_send(set_duration_energy);
  1153. }
  1154. else if( (protocol==ZIGBEE) )
  1155. {
  1156. error_AT=2;
  1157. gen_data(set_duration_energy_ZB,duration);
  1158. gen_checksum(set_duration_energy_ZB);
  1159. error=gen_send(set_duration_energy_ZB);
  1160. }
  1161. else
  1162. {
  1163. error_AT=-1;
  1164. error=-1;
  1165. }
  1166. if(error==0)
  1167. {
  1168. if(protocol==XBEE_802_15_4)
  1169. {
  1170. for(it=0;it<data_length;it++)
  1171. {
  1172. energyChannel[it]=data[it];
  1173. }
  1174. }
  1175. if(protocol==ZIGBEE)
  1176. {
  1177. timeEnergyChannel=data[0];
  1178. }
  1179. }
  1180. return error;
  1181. }
  1182. /*
  1183. Function: It gets the time the energy scan will be performed
  1184. Returns: Integer that determines if there has been any error
  1185. error=2 --> The command has not been executed
  1186. error=1 --> There has been an error while executing the command
  1187. error=0 --> The command has been executed with no errors
  1188. error=-1 --> Forbidden command for this protocol
  1189. Values: Change the SD command. Stores in global "timeEnergyChannel" variable the time the energy
  1190. scan will be performed
  1191. */
  1192. uint8_t WaspXBeeCore::getDurationEnergyChannels()
  1193. {
  1194. int8_t error=2;
  1195. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) )
  1196. {
  1197. error_AT=2;
  1198. gen_data(get_duration_energy);
  1199. error=gen_send(get_duration_energy);
  1200. }
  1201. else
  1202. {
  1203. error_AT=-1;
  1204. error=-1;
  1205. }
  1206. if(!error)
  1207. {
  1208. timeEnergyChannel=data[0];
  1209. }
  1210. return error;
  1211. }
  1212. /*
  1213. Function: Sets the encryption key to be used in the 128b AES algorithm
  1214. Returns: Integer that determines if there has been any error
  1215. error=2 --> The command has not been executed
  1216. error=1 --> There has been an error while executing the command
  1217. error=0 --> The command has been executed with no errors
  1218. Values: Change the KY command. Stores in global "linkKey" variable the key has been set
  1219. Parameters:
  1220. key: 16 byte array of chars that specifies the 128b AES key
  1221. */
  1222. uint8_t WaspXBeeCore::setLinkKey(char* key)
  1223. {
  1224. int8_t error=2;
  1225. error_AT=2;
  1226. gen_data(set_link_key,key);
  1227. gen_checksum(set_link_key);
  1228. error=gen_send(set_link_key);
  1229. if(!error)
  1230. {
  1231. for(it=0;it<16;it++)
  1232. {
  1233. linkKey[it]=char(key[it]);
  1234. }
  1235. }
  1236. return error;
  1237. }
  1238. /*
  1239. Function: Sets the encryption mode on/off
  1240. Returns: Integer that determines if there has been any error
  1241. error=2 --> The command has not been executed
  1242. error=1 --> There has been an error while executing the command
  1243. error=0 --> The command has been executed with no errors
  1244. Values: Change the EE command. Stores in global "encryptMode" variable the encryption mode
  1245. Parameters:
  1246. mode: on/off the encryption mode (1/0)
  1247. */
  1248. uint8_t WaspXBeeCore::encryptionMode(uint8_t mode)
  1249. {
  1250. int8_t error=2;
  1251. error_AT=2;
  1252. gen_data(set_encryption,mode);
  1253. gen_checksum(set_encryption);
  1254. error=gen_send(set_encryption);
  1255. if(!error)
  1256. {
  1257. encryptMode=mode;
  1258. }
  1259. return error;
  1260. }
  1261. /*
  1262. Function: Select the power level at which the RF module transmits
  1263. Returns: Integer that determines if there has been any error
  1264. error=2 --> The command has not been executed
  1265. error=1 --> There has been an error while executing the command
  1266. error=0 --> The command has been executed with no errors
  1267. Values: Change the PL command. Stores in global "powerLevel" the power level at which RF tx
  1268. Parameters:
  1269. value: power level of transmission (0-4)
  1270. */
  1271. uint8_t WaspXBeeCore::setPowerLevel(uint8_t value)
  1272. {
  1273. int8_t error=2;
  1274. if(protocol!=XBEE_900)
  1275. {
  1276. error_AT=2;
  1277. gen_data(set_power_level,value);
  1278. gen_checksum(set_power_level);
  1279. error=gen_send(set_power_level);
  1280. }
  1281. if(!error)
  1282. {
  1283. powerLevel=value;
  1284. }
  1285. return error;
  1286. }
  1287. /*
  1288. Function: Get the Received Signal Strength Indicator of the last received packet
  1289. Returns: Returns: Integer that determines if there has been any error
  1290. error=2 --> The command has not been executed
  1291. error=1 --> There has been an error while executing the command
  1292. error=0 --> The command has been executed with no errors
  1293. Values: Stores in global "valueRSSI" variable the RSSI value of last received packet
  1294. */
  1295. uint8_t WaspXBeeCore::getRSSI()
  1296. {
  1297. int8_t error=2;
  1298. uint8_t* ByteIN = (uint8_t*) calloc(40,sizeof(uint8_t));
  1299. uint8_t i=0;
  1300. if( (protocol == XBEE_802_15_4 ) || (protocol==ZIGBEE) )
  1301. {
  1302. error_AT=2;
  1303. gen_data(get_RSSI);
  1304. error=gen_send(get_RSSI);
  1305. }
  1306. else if( (protocol== DIGIMESH) || (protocol==XBEE_868) || (protocol==XBEE_900) )
  1307. {
  1308. delay(2000);
  1309. XBee.print("+++");
  1310. delay(2000);
  1311. XBee.flush();
  1312. XBee.println("atdb");
  1313. delay(1000);
  1314. error_AT=2;
  1315. while(XBee.available()>0)
  1316. {
  1317. ByteIN[i]=XBee.read();
  1318. error=0;
  1319. i++;
  1320. error_AT=0;
  1321. }
  1322. i=0;
  1323. XBee.println("atcn");
  1324. delay(1000);
  1325. valueRSSI[0]=Utils.str2hex(ByteIN);
  1326. }
  1327. if(error==0)
  1328. {
  1329. if( (protocol==XBEE_802_15_4) || (protocol==ZIGBEE) )
  1330. {
  1331. valueRSSI[0]=data[0];
  1332. }
  1333. }
  1334. free(ByteIN);
  1335. ByteIN=NULL;
  1336. return error;
  1337. }
  1338. /*
  1339. Function: Get the Harware Version
  1340. Returns: Returns: Integer that determines if there has been any error
  1341. error=2 --> The command has not been executed
  1342. error=1 --> There has been an error while executing the command
  1343. error=0 --> The command has been executed with no errors
  1344. Values: Stores in global "hardVersion" variable the Hardware Version
  1345. */
  1346. uint8_t WaspXBeeCore::getHardVersion()
  1347. {
  1348. int8_t error=2;
  1349. error_AT=2;
  1350. gen_data(get_hard_version);
  1351. error=gen_send(get_hard_version);
  1352. if(!error)
  1353. {
  1354. hardVersion[0]=data[0];
  1355. hardVersion[1]=data[1];
  1356. }
  1357. return error;
  1358. }
  1359. /*
  1360. Function: Get the version of the firmware
  1361. Returns: Integer that determines if there has been any error
  1362. error=2 --> The command has not been executed
  1363. error=1 --> There has been an error while executing the command
  1364. error=0 --> The command has been executed with no errors
  1365. Values: Stores in global "softVersion" variable the firmware version
  1366. */
  1367. uint8_t WaspXBeeCore::getSoftVersion()
  1368. {
  1369. int8_t error=2;
  1370. error_AT=2;
  1371. gen_data(get_soft_version);
  1372. error=gen_send(get_soft_version);
  1373. if(error==0)
  1374. {
  1375. softVersion[0]=data[0];
  1376. softVersion[1]=data[1];
  1377. }
  1378. return error;
  1379. }
  1380. /*
  1381. Function: Set the RSSI time
  1382. Returns: Integer that determines if there has been any error
  1383. error=2 --> The command has not been executed
  1384. error=1 --> There has been an error while executing the command
  1385. error=0 --> The command has been executed with no errors
  1386. Values: Change the RP command. Stores in global "timeRSSI" variable the RSSI time
  1387. Parameters:
  1388. time: amount of time to do the pwm (0x00-0xFF)
  1389. */
  1390. uint8_t WaspXBeeCore::setRSSItime(uint8_t time)
  1391. {
  1392. int8_t error=2;
  1393. error_AT=2;
  1394. gen_data(set_RSSI_time,time);
  1395. gen_checksum(set_RSSI_time);
  1396. error=gen_send(set_RSSI_time);
  1397. if(!error)
  1398. {
  1399. timeRSSI=time;
  1400. }
  1401. return error;
  1402. }
  1403. /*
  1404. Function: Get the RSSI time
  1405. Returns: Integer that determines if there has been any error
  1406. error=2 --> The command has not been executed
  1407. error=1 --> There has been an error while executing the command
  1408. error=0 --> The command has been executed with no errors
  1409. Values: Stores in global "timeRSSI" variable the RSSI time
  1410. */
  1411. uint8_t WaspXBeeCore::getRSSItime()
  1412. {
  1413. int8_t error=2;
  1414. error_AT=2;
  1415. gen_data(get_RSSI_time);
  1416. error=gen_send(get_RSSI_time);
  1417. if(!error)
  1418. {
  1419. timeRSSI=data[0];
  1420. }
  1421. return error;
  1422. }
  1423. /*
  1424. Function: Immediately applies new settings without exiting command mode
  1425. Returns: Integer that determines if there has been any error
  1426. error=2 --> The command has not been executed
  1427. error=1 --> There has been an error while executing the command
  1428. error=0 --> The command has been executed with no errors
  1429. Values: Executes the AC command
  1430. */
  1431. uint8_t WaspXBeeCore::applyChanges()
  1432. {
  1433. int8_t error=2;
  1434. error_AT=2;
  1435. gen_data(apply_changes);
  1436. error=gen_send(apply_changes);
  1437. return error;
  1438. }
  1439. /*
  1440. Function: Reset the XBee Firmware
  1441. Returns: Integer that determines if there has been any error
  1442. error=2 --> The command has not been executed
  1443. error=1 --> There has been an error while executing the command
  1444. error=0 --> The command has been executed with no errors
  1445. Values: Executes the FR command
  1446. */
  1447. uint8_t WaspXBeeCore::reset()
  1448. {
  1449. int8_t error=2;
  1450. error_AT=2;
  1451. gen_data(reset_xbee);
  1452. error=gen_send(reset_xbee);
  1453. return error;
  1454. }
  1455. /*
  1456. Function: Set the parameteres to the factory defaults
  1457. Returns: Integer that determines if there has been any error
  1458. error=2 --> The command has not been executed
  1459. error=1 --> There has been an error while executing the command
  1460. error=0 --> The command has been executed with no errors
  1461. Values: Executes the RE command
  1462. */
  1463. uint8_t WaspXBeeCore::resetDefaults()
  1464. {
  1465. int8_t error=2;
  1466. error_AT=2;
  1467. gen_data(reset_defaults_xbee);
  1468. error=gen_send(reset_defaults_xbee);
  1469. return error;
  1470. }
  1471. /*
  1472. Function: Configure options for sleep
  1473. Returns: Integer that determines if there has been any error
  1474. error=2 --> The command has not been executed
  1475. error=1 --> There has been an error while executing the command
  1476. error=0 --> The command has been executed with no errors
  1477. error=-1 --> Forbidden command for this protocol
  1478. Values: Change the SO command. Stores in global "sleepOptions" variable the options
  1479. Parameters:
  1480. soption: options for sleep (0x00-0xFF)
  1481. */
  1482. uint8_t WaspXBeeCore::setSleepOptions(uint8_t soption)
  1483. {
  1484. int8_t error=2;
  1485. if( (protocol==ZIGBEE) || (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  1486. {
  1487. error_AT=2;
  1488. gen_data(set_sleep_options_xbee,soption);
  1489. gen_checksum(set_sleep_options_xbee);
  1490. error=gen_send(set_sleep_options_xbee);
  1491. }
  1492. else
  1493. {
  1494. error_AT=-1;
  1495. error=-1;
  1496. }
  1497. if(!error)
  1498. {
  1499. sleepOptions=soption;
  1500. }
  1501. return error;
  1502. }
  1503. /*
  1504. Function: Reads the options for sleep
  1505. Returns: Integer that determines if there has been any error
  1506. error=2 --> The command has not been executed
  1507. error=1 --> There has been an error while executing the command
  1508. error=0 --> The command has been executed with no errors
  1509. error=-1 --> Forbidden command for this protocol
  1510. Values: Executes the SO command. Stores in global "sleepOptions" variable the options
  1511. */
  1512. uint8_t WaspXBeeCore::getSleepOptions()
  1513. {
  1514. int8_t error=2;
  1515. if( (protocol==ZIGBEE) || (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  1516. {
  1517. error_AT=2;
  1518. gen_data(get_sleep_options_xbee);
  1519. error=gen_send(get_sleep_options_xbee);
  1520. }
  1521. else
  1522. {
  1523. error_AT=-1;
  1524. error=-1;
  1525. }
  1526. if(!error)
  1527. {
  1528. sleepOptions=data[0];
  1529. }
  1530. return error;
  1531. }
  1532. /*
  1533. Function: Transparent function. The user introduces an AT command within a string and the function executes it without knowing its meaning
  1534. Returns: Integer that determines if there has been any error
  1535. error=2 --> The command has not been executed
  1536. error=1 --> There has been an error while executing the command
  1537. error=0 --> The command has been executed with no errors
  1538. Parameters:
  1539. atcommand : String to specify the AT command to execute
  1540. */
  1541. uint8_t WaspXBeeCore::sendCommandAT(char* atcommand)
  1542. {
  1543. uint8_t* AT = (uint8_t*) calloc(30,sizeof(uint8_t));// {0x7E, 0x00, 0x00, 0x08, 0x52, 0x00, 0x00, 0x00};
  1544. AT[0]=0x7E;
  1545. AT[1]=0x00;
  1546. AT[3]=0x08;
  1547. AT[4]=0x52;
  1548. uint8_t num_AT=0;
  1549. int8_t error=2;
  1550. uint8_t it2=0;
  1551. uint8_t* ByteIN = (uint8_t*) calloc(120,sizeof(uint8_t));
  1552. uint8_t counter=0;
  1553. uint8_t counter3=0;
  1554. uint8_t est=1;
  1555. uint8_t frame_ID=AT[4];
  1556. uint8_t end=0;
  1557. uint16_t interval=WAIT_TIME;
  1558. uint8_t checksum=0;
  1559. uint16_t length=0;
  1560. it=0;
  1561. error_AT=2;
  1562. while( atcommand[it2]!='#' )
  1563. {
  1564. if( it>=2 )
  1565. {
  1566. if( atcommand[it2+1]!='#' )
  1567. {
  1568. AT[it+5]=Utils.converter(atcommand[2*(it-1)],atcommand[2*(it-1)+1]);
  1569. it2+=2;
  1570. }
  1571. else
  1572. {
  1573. switch( atcommand[it2] )
  1574. {
  1575. case '0': AT[it+5]=0;
  1576. break;
  1577. case '1': AT[it+5]=1;
  1578. break;
  1579. case '2': AT[it+5]=2;
  1580. break;
  1581. case '3': AT[it+5]=3;
  1582. break;
  1583. case '4': AT[it+5]=4;
  1584. break;
  1585. case '5': AT[it+5]=5;
  1586. break;
  1587. case '6': AT[it+5]=6;
  1588. break;
  1589. case '7': AT[it+5]=7;
  1590. break;
  1591. case '8': AT[it+5]=8;
  1592. break;
  1593. case '9': AT[it+5]=9;
  1594. break;
  1595. case 'A': AT[it+5]='A';
  1596. break;
  1597. case 'B': AT[it+5]='B';
  1598. break;
  1599. case 'C': AT[it+5]='C';
  1600. break;
  1601. case 'D': AT[it+5]='D';
  1602. break;
  1603. case 'E': AT[it+5]='E';
  1604. break;
  1605. case 'F': AT[it+5]='F';
  1606. break;
  1607. }
  1608. it2++;
  1609. }
  1610. }
  1611. else
  1612. {
  1613. AT[it+5]=atcommand[it];
  1614. it2++;
  1615. }
  1616. it++;
  1617. }
  1618. length=it;
  1619. AT[2]=2+length;
  1620. for(it=3;it<(5+length);it++)
  1621. {
  1622. checksum=checksum+AT[it];
  1623. }
  1624. while( (checksum>255))
  1625. {
  1626. checksum=checksum-256;
  1627. }
  1628. checksum=255-checksum;
  1629. AT[5+length]=checksum;
  1630. while(counter<(6+length))
  1631. {
  1632. XBee.print(AT[counter], BYTE);
  1633. counter++;
  1634. }
  1635. counter=0;
  1636. clearCommand();
  1637. command[5]=AT[5];
  1638. command[6]=AT[6];
  1639. data_length=0;
  1640. error=parse_message(command);
  1641. if(error==0)
  1642. {
  1643. if(data_length>0)
  1644. {
  1645. for(it=0;it<data_length;it++)
  1646. {
  1647. commandAT[it]=data[it];
  1648. delay(20);
  1649. }
  1650. }
  1651. else
  1652. {
  1653. commandAT[0]=0x4F;
  1654. commandAT[1]=0x4B;
  1655. }
  1656. }
  1657. free(AT);
  1658. AT=NULL;
  1659. free(ByteIN);
  1660. ByteIN=NULL;
  1661. return error;
  1662. }
  1663. /*
  1664. Function: Connect XBee, activating switch in Waspmote
  1665. Returns: Integer that determines if there has been any error
  1666. error=2 --> The command has not been executed
  1667. error=1 --> There has been an error while executing the command
  1668. error=0 --> The command has been executed with no errors
  1669. */
  1670. uint8_t WaspXBeeCore::ON()
  1671. {
  1672. uint8_t error=2;
  1673. XBee.begin();
  1674. XBee.setMode(XBEE_ON);
  1675. if( protocol== ZIGBEE || protocol==XBEE_868 ) delay(500);
  1676. else delay(50);
  1677. error=0;
  1678. XBee_ON=1;
  1679. return error;
  1680. }
  1681. /*
  1682. Function: disconnects XBee, switching it off and closing the UART
  1683. Returns: Integer that determines if there has been any error
  1684. error=2 --> The command has not been executed
  1685. error=1 --> There has been an error while executing the command
  1686. error=0 --> The command has been executed with no errors
  1687. */
  1688. uint8_t WaspXBeeCore::OFF()
  1689. {
  1690. uint8_t error=2;
  1691. XBee.close();
  1692. XBee.setMode(XBEE_OFF);
  1693. error=0;
  1694. XBee_ON=0;
  1695. return error;
  1696. }
  1697. /*
  1698. Function: Set XBee to sleep, asserting PIN 9
  1699. Returns: Integer that determines if there has been any error
  1700. error=2 --> The command has not been executed
  1701. error=1 --> There has been an error while executing the command
  1702. error=0 --> The command has been executed with no errors
  1703. */
  1704. uint8_t WaspXBeeCore::sleep()
  1705. {
  1706. uint8_t error=2;
  1707. pinMode(XBEE_SLEEP, OUTPUT);
  1708. digitalWrite(XBEE_SLEEP,HIGH);
  1709. XBee.close();
  1710. error=0;
  1711. return error;
  1712. }
  1713. /*
  1714. Function: Wake up XBee, de-asserting PIN 9
  1715. Returns: Integer that determines if there has been any error
  1716. error=2 --> The command has not been executed
  1717. error=1 --> There has been an error while executing the command
  1718. error=0 --> The command has been executed with no errors
  1719. */
  1720. uint8_t WaspXBeeCore::wake()
  1721. {
  1722. uint8_t error=2;
  1723. pinMode(XBEE_SLEEP, OUTPUT);
  1724. digitalWrite(XBEE_SLEEP,LOW);
  1725. XBee.begin();
  1726. delay(50);
  1727. error=0;
  1728. return error;
  1729. }
  1730. /*
  1731. Function: Send a packet from one XBee to another XBee in API mode
  1732. Returns: Integer that determines if there has been any error
  1733. error=2 --> The command has not been executed
  1734. error=1 --> There has been an error while executing the command
  1735. error=0 --> The command has been executed with no errors
  1736. Parameters:
  1737. packet : A struct of packetXBee type
  1738. */
  1739. uint8_t WaspXBeeCore::sendXBeePriv(struct packetXBee* packet)
  1740. {
  1741. uint8_t* TX = (uint8_t*) calloc(120,sizeof(uint8_t));
  1742. uint8_t counter=0;
  1743. uint8_t counter3=0;
  1744. uint8_t num_TX=0;
  1745. uint8_t checksum=0;
  1746. uint8_t est=1;
  1747. uint8_t end=0;
  1748. uint16_t interval=2000;
  1749. long previous=0;
  1750. uint16_t aux=0;
  1751. uint16_t aux2=0;
  1752. uint8_t protegido=0;
  1753. uint8_t a=5;
  1754. uint8_t tipo=0;
  1755. uint8_t estado=1;
  1756. int8_t error=2;
  1757. uint8_t* ByteIN = (uint8_t*) calloc(20,sizeof(uint8_t));
  1758. uint8_t numberBytes=0;
  1759. uint8_t status=0;
  1760. uint8_t undesired=0;
  1761. uint8_t old_netAddress[2];
  1762. uint8_t net_Address_changed = 0;
  1763. clearCommand();
  1764. error_TX=2;
  1765. for(it=0;it<120;it++)
  1766. {
  1767. TX[it]=0;
  1768. }
  1769. TX[0]=0x7E;
  1770. TX[1]=0x00;
  1771. TX[4]=packet->packetID; // frame ID
  1772. it=0;
  1773. error_AT=2;
  1774. if(protocol==XBEE_802_15_4)
  1775. {
  1776. if(packet->mode==BROADCAST)
  1777. {
  1778. tipo=15;
  1779. TX[3]=0x00;
  1780. previous=millis();
  1781. error_AT=2;
  1782. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  1783. {
  1784. estado=getOwnNetAddress();
  1785. }
  1786. old_netAddress[0]=sourceNA[0];
  1787. old_netAddress[1]=sourceNA[1];
  1788. previous=millis();
  1789. error_AT=2;
  1790. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  1791. {
  1792. estado=setOwnNetAddress(0xFF,0xFF);
  1793. net_Address_changed = 1;
  1794. }
  1795. error=2;
  1796. while(a<13) // destination address
  1797. {
  1798. for(it=0;it<4;it++)
  1799. {
  1800. TX[a]=0x00;
  1801. a++;
  1802. }
  1803. for(it=0;it<2;it++)
  1804. {
  1805. TX[a]=0x00;
  1806. a++;
  1807. }
  1808. for(it=0;it<2;it++)
  1809. {
  1810. TX[a]=0xFF;
  1811. a++;
  1812. }
  1813. }
  1814. TX[13]=0x00;
  1815. TX[14]=packet->packetID;
  1816. TX[15]=packet->numFragment;
  1817. it=0;
  1818. gen_frame(packet,TX,16);
  1819. TX[2]=11+packet->frag_length; // fragment length
  1820. for(it=3;it<(TX[2]+3);it++) // calculating checksum
  1821. {
  1822. checksum=checksum+TX[it];
  1823. }
  1824. while((checksum>255))
  1825. {
  1826. checksum=checksum-256;
  1827. }
  1828. checksum=255-checksum;
  1829. TX[packet->frag_length+14]=checksum; // setting checksum
  1830. }
  1831. if(packet->mode==UNICAST)
  1832. {
  1833. if(packet->address_type==_64B)
  1834. {
  1835. tipo=15;
  1836. TX[3]=0x00;
  1837. while(a<13) // destination address
  1838. {
  1839. for(it=0;it<4;it++)
  1840. {
  1841. TX[a]=packet->macDH[it];
  1842. a++;
  1843. }
  1844. for(it=0;it<4;it++)
  1845. {
  1846. TX[a]=packet->macDL[it];
  1847. a++;
  1848. }
  1849. }
  1850. previous=millis();
  1851. error_AT=2;
  1852. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  1853. {
  1854. estado=getOwnNetAddress();
  1855. }
  1856. old_netAddress[0]=sourceNA[0];
  1857. old_netAddress[1]=sourceNA[1];
  1858. previous=millis();
  1859. error_AT=2;
  1860. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  1861. {
  1862. estado=setOwnNetAddress(0xFF,0xFF);
  1863. net_Address_changed = 1;
  1864. }
  1865. error=2;
  1866. TX[13]=0x00;
  1867. TX[14]=packet->packetID;
  1868. TX[15]=packet->numFragment;
  1869. it=0;
  1870. gen_frame(packet,TX,16);
  1871. TX[2]=11+packet->frag_length; // fragment length
  1872. for(it=3;it<(TX[2]+3);it++) // calculating checksum
  1873. {
  1874. checksum=checksum+TX[it];
  1875. }
  1876. while((checksum>255))
  1877. {
  1878. checksum=checksum-256;
  1879. }
  1880. checksum=255-checksum;
  1881. TX[packet->frag_length+14]=checksum; // setting checksum
  1882. }
  1883. if(packet->address_type==_16B)
  1884. {
  1885. tipo=9;
  1886. TX[3]=0x01;
  1887. TX[5]=packet->naD[0];
  1888. TX[6]=packet->naD[1];
  1889. TX[7]=0x00;
  1890. TX[8]=packet->packetID;
  1891. TX[9]=packet->numFragment;
  1892. it=0;
  1893. gen_frame(packet,TX,10);
  1894. TX[2]=5+packet->frag_length; // fragment length
  1895. for(it=3;it<(TX[2]+3);it++) // calculating checksum
  1896. {
  1897. checksum=checksum+TX[it];
  1898. }
  1899. while((checksum>255))
  1900. {
  1901. checksum=checksum-256;
  1902. }
  1903. checksum=255-checksum;
  1904. TX[packet->frag_length+8]=checksum; // setting checksum
  1905. }
  1906. }
  1907. if(packet->mode==SYNC)
  1908. {
  1909. tipo=15;
  1910. TX[3]=0x00;
  1911. if(packet->opt==1) // Broadcast
  1912. {
  1913. previous=millis();
  1914. error_AT=2;
  1915. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  1916. {
  1917. estado=getOwnNetAddress();
  1918. }
  1919. old_netAddress[0]=sourceNA[0];
  1920. old_netAddress[1]=sourceNA[1];
  1921. previous=millis();
  1922. error_AT=2;
  1923. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  1924. {
  1925. estado=setOwnNetAddress(0xFF,0xFF);
  1926. if( (error_AT==1) || (error_AT==2) )
  1927. {
  1928. TIME1=millis();
  1929. delay(100);
  1930. }
  1931. net_Address_changed = 1;
  1932. }
  1933. error=2;
  1934. while(a<13) // destination address
  1935. {
  1936. for(it=0;it<4;it++)
  1937. {
  1938. TX[a]=0x00;
  1939. a++;
  1940. }
  1941. for(it=0;it<2;it++)
  1942. {
  1943. TX[a]=0x00;
  1944. a++;
  1945. }
  1946. for(it=0;it<2;it++)
  1947. {
  1948. TX[a]=0xFF;
  1949. a++;
  1950. }
  1951. }
  1952. }
  1953. else if(packet->opt==0) // UNICAST 64B
  1954. {
  1955. while(a<13) // destination address
  1956. {
  1957. for(it=0;it<4;it++)
  1958. {
  1959. TX[a]=packet->macDH[it];
  1960. a++;
  1961. }
  1962. for(it=0;it<4;it++)
  1963. {
  1964. TX[a]=packet->macDL[it];
  1965. a++;
  1966. }
  1967. }
  1968. previous=millis();
  1969. error_AT=2;
  1970. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  1971. {
  1972. estado=getOwnNetAddress();
  1973. }
  1974. old_netAddress[0]=sourceNA[0];
  1975. old_netAddress[1]=sourceNA[1];
  1976. previous=millis();
  1977. error_AT=2;
  1978. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  1979. {
  1980. estado=setOwnNetAddress(0xFF,0xFF);
  1981. net_Address_changed = 1;
  1982. }
  1983. }
  1984. TX[13]=0x00;
  1985. TX[14]=packet->packetID;
  1986. TX[15]=packet->numFragment;
  1987. it=0;
  1988. gen_frame(packet,TX,16);
  1989. TX[2]=11+packet->frag_length; // fragment length
  1990. for(it=3;it<(TX[2]+3);it++) // calculating checksum
  1991. {
  1992. checksum=checksum+TX[it];
  1993. }
  1994. while((checksum>255))
  1995. {
  1996. checksum=checksum-256;
  1997. }
  1998. checksum=255-checksum;
  1999. TX[packet->frag_length+14]=checksum; // setting checksum
  2000. }
  2001. // AP = 2
  2002. gen_frame_ap2(packet,TX,protegido,tipo);
  2003. // Frame OK
  2004. counter=0;
  2005. while(counter<(packet->frag_length+tipo+protegido))
  2006. {
  2007. XBee.print(TX[counter], BYTE);
  2008. counter++;
  2009. }
  2010. counter=0;
  2011. command[0]=0xFF;
  2012. error=parse_message(command);
  2013. packet->deliv_status=delivery_status;
  2014. if( net_Address_changed )
  2015. {
  2016. error_AT=2;
  2017. previous=millis();
  2018. while( ((error_AT==1) || (error_AT==2)) && (millis()-previous<5000) )
  2019. {
  2020. estado=setOwnNetAddress(old_netAddress[0],old_netAddress[1]);
  2021. }
  2022. }
  2023. }
  2024. if( (protocol==ZIGBEE) || (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  2025. {
  2026. if( (packet->mode==BROADCAST) || (packet->mode==UNICAST) )
  2027. {
  2028. if(protocol==XBEE_868)
  2029. {
  2030. if(packet->frag_length>241)
  2031. {
  2032. TX[1]=0x01;
  2033. aux=packet->frag_length+14;
  2034. aux=aux-256;
  2035. if(aux>9)
  2036. {
  2037. switch(aux)
  2038. {
  2039. case 10: TX[2]=0x0A;
  2040. break;
  2041. case 11: TX[2]=0x0B;
  2042. break;
  2043. case 12: TX[2]=0x0C;
  2044. break;
  2045. case 13: TX[2]=0x0D;
  2046. break;
  2047. case 14: TX[2]=0x0E;
  2048. break;
  2049. }
  2050. }
  2051. else
  2052. {
  2053. TX[2]=aux;
  2054. }
  2055. }
  2056. else
  2057. {
  2058. TX[1]=0x00;
  2059. TX[2]=14+packet->frag_length;
  2060. }
  2061. }
  2062. else
  2063. {
  2064. TX[2]=14+packet->frag_length; // fragment length
  2065. }
  2066. aux=0;
  2067. TX[3]=0x10; // frame ID
  2068. tipo=18;
  2069. if(packet->mode==BROADCAST)
  2070. {
  2071. while(a<13) // destination address
  2072. {
  2073. for(it=0;it<4;it++)
  2074. {
  2075. TX[a]=0x00;
  2076. a++;
  2077. }
  2078. for(it=0;it<2;it++)
  2079. {
  2080. TX[a]=0x00;
  2081. a++;
  2082. }
  2083. for(it=0;it<2;it++)
  2084. {
  2085. TX[a]=0xFF;
  2086. a++;
  2087. }
  2088. }
  2089. TX[13]=0xFF;
  2090. TX[14]=0xFE;
  2091. }
  2092. if(packet->mode==UNICAST)
  2093. {
  2094. while(a<13) // destination address
  2095. {
  2096. for(it=0;it<4;it++)
  2097. {
  2098. TX[a]=packet->macDH[it];
  2099. a++;
  2100. }
  2101. for(it=0;it<4;it++)
  2102. {
  2103. TX[a]=packet->macDL[it];
  2104. a++;
  2105. }
  2106. }
  2107. if (packet->MY_known==1) // destination network address
  2108. {
  2109. for(it=0;it<2;it++)
  2110. {
  2111. TX[it+13]=packet->naD[it];
  2112. }
  2113. }
  2114. else
  2115. {
  2116. TX[13]=0xFF;
  2117. TX[14]=0xFE;
  2118. }
  2119. }
  2120. if(protocol==XBEE_868)
  2121. {
  2122. TX[13]=0xFF;
  2123. TX[14]=0xFE;
  2124. }
  2125. TX[15]=hops;
  2126. if( apsEncryption) TX[16]=0x20;
  2127. else TX[16]=packet->opt;
  2128. TX[17]=packet->packetID;
  2129. TX[18]=packet->numFragment;
  2130. it=0;
  2131. gen_frame(packet,TX,19);
  2132. for(it=3;it<(TX[2]+3);it++) // calculating checksum
  2133. {
  2134. checksum=checksum+TX[it];
  2135. }
  2136. while((checksum>255))
  2137. {
  2138. checksum=checksum-256;
  2139. }
  2140. checksum=255-checksum;
  2141. TX[packet->frag_length+17]=checksum; // setting checksum
  2142. }
  2143. else // Cluster Type
  2144. {
  2145. if( (protocol==ZIGBEE) || (protocol==XBEE_868) )
  2146. {
  2147. if(protocol==XBEE_868)
  2148. {
  2149. if(packet->frag_length>235)
  2150. {
  2151. TX[1]=0x01;
  2152. aux=packet->frag_length+20;
  2153. aux=aux-256;
  2154. if(aux>9)
  2155. {
  2156. switch(aux)
  2157. {
  2158. case 10: TX[2]=0x0A;
  2159. break;
  2160. case 11: TX[2]=0x0B;
  2161. break;
  2162. case 12: TX[2]=0x0C;
  2163. break;
  2164. case 13: TX[2]=0x0D;
  2165. break;
  2166. case 14: TX[2]=0x0E;
  2167. break;
  2168. case 15: TX[2]=0x0F;
  2169. break;
  2170. case 16: TX[2]=0x10;
  2171. break;
  2172. case 17: TX[2]=0x11;
  2173. break;
  2174. case 18: TX[2]=0x12;
  2175. break;
  2176. case 19: TX[2]=0x13;
  2177. break;
  2178. case 20: TX[2]=0x14;
  2179. break;
  2180. }
  2181. }
  2182. else
  2183. {
  2184. TX[2]=aux;
  2185. }
  2186. }
  2187. else
  2188. {
  2189. TX[1]=0x00;
  2190. TX[2]=20+packet->frag_length;
  2191. }
  2192. }
  2193. else
  2194. {
  2195. TX[2]=20+packet->frag_length; // fragment length
  2196. }
  2197. TX[3]=0x11; // frame ID
  2198. tipo=24;
  2199. while(a<13) // destination address
  2200. {
  2201. for(it=0;it<4;it++)
  2202. {
  2203. TX[a]=packet->macDH[it];
  2204. a++;
  2205. }
  2206. for(it=0;it<4;it++)
  2207. {
  2208. TX[a]=packet->macDL[it];
  2209. a++;
  2210. }
  2211. }
  2212. if (packet->MY_known==1) // destination network address
  2213. {
  2214. for(it=0;it<2;it++)
  2215. {
  2216. TX[it+13]=packet->naD[it];
  2217. }
  2218. }
  2219. else
  2220. {
  2221. TX[13]=0xFF;
  2222. TX[14]=0xFE;
  2223. }
  2224. TX[15]=packet->SD;
  2225. TX[16]=packet->DE;
  2226. TX[17]=packet->CID[0];
  2227. TX[18]=packet->CID[1];
  2228. TX[19]=packet->PID[0];
  2229. TX[20]=packet->PID[1];
  2230. TX[21]=hops;
  2231. if( apsEncryption) TX[22]=0x20;
  2232. else TX[22]=packet->opt;
  2233. TX[23]=packet->packetID;
  2234. TX[24]=packet->numFragment;
  2235. it=0;
  2236. gen_frame(packet,TX,25);
  2237. for(it=3;it<(TX[2]+3);it++) // calculating checksum
  2238. {
  2239. checksum=checksum+TX[it];
  2240. }
  2241. while((checksum>255))
  2242. {
  2243. checksum=checksum-256;
  2244. }
  2245. checksum=255-checksum;
  2246. TX[packet->frag_length+23]=checksum; // setting checksum
  2247. }
  2248. else // DIGIMESH or XBEE_900
  2249. {
  2250. TX[2]=20+packet->frag_length; // fragment length
  2251. TX[3]=0x11; // frame ID
  2252. tipo=24;
  2253. while(a<13) // destination address
  2254. {
  2255. for(it=0;it<4;it++)
  2256. {
  2257. TX[a]=packet->macDH[it];
  2258. a++;
  2259. }
  2260. for(it=0;it<4;it++)
  2261. {
  2262. TX[a]=packet->macDL[it];
  2263. a++;
  2264. }
  2265. }
  2266. if (packet->MY_known==1) // destination network address
  2267. {
  2268. for(it=0;it<2;it++)
  2269. {
  2270. TX[it+13]=packet->naD[it];
  2271. }
  2272. }
  2273. else
  2274. {
  2275. TX[13]=0xFF;
  2276. TX[14]=0xFE;
  2277. }
  2278. TX[15]=packet->SD;
  2279. TX[16]=packet->DE;
  2280. TX[17]=0x00;
  2281. TX[18]=packet->CID[0];
  2282. TX[19]=packet->PID[0];
  2283. TX[20]=packet->PID[1];
  2284. TX[21]=hops;
  2285. TX[22]=packet->opt;
  2286. TX[23]=packet->packetID;
  2287. TX[24]=packet->numFragment;
  2288. it=0;
  2289. gen_frame(packet,TX,25);
  2290. for(it=3;it<(TX[2]+3);it++) // calculating checksum
  2291. {
  2292. checksum=checksum+TX[it];
  2293. }
  2294. while((checksum>255))
  2295. {
  2296. checksum=checksum-256;
  2297. }
  2298. checksum=255-checksum;
  2299. TX[packet->frag_length+23]=checksum; // setting checksum
  2300. }
  2301. }
  2302. // AP = 2
  2303. gen_frame_ap2(packet,TX,protegido,tipo);
  2304. // Frame OK
  2305. while(counter<(packet->frag_length+tipo+protegido))
  2306. {
  2307. XBee.print(TX[counter], BYTE);
  2308. counter++;
  2309. }
  2310. counter=0;
  2311. command[0]=0xFE;
  2312. error=parse_message(command);
  2313. packet->deliv_status=delivery_status;
  2314. packet->discov_status=discovery_status;
  2315. packet->true_naD[0]=true_naD[0];
  2316. packet->true_naD[1]=true_naD[1];
  2317. packet->retries=retries_sending;
  2318. }
  2319. free(TX);
  2320. free(ByteIN);
  2321. TX=NULL;
  2322. ByteIN=NULL;
  2323. return error;
  2324. }
  2325. /*
  2326. Function: Send a packet from one XBee to another XBee in API mode
  2327. Returns: Integer that determines if there has been any error
  2328. error=2 --> The command has not been executed
  2329. error=1 --> There has been an error while executing the command
  2330. error=0 --> The command has been executed with no errors
  2331. Parameters:
  2332. packet : A struct of packetXBee type
  2333. */
  2334. uint8_t WaspXBeeCore::sendXBee(struct packetXBee* packet)
  2335. {
  2336. uint8_t counter=0;
  2337. uint8_t counter3=0;
  2338. uint8_t checksum=0;
  2339. uint8_t est=1;
  2340. uint8_t final=0;
  2341. uint8_t end=0;
  2342. uint16_t interval=2000;
  2343. uint8_t protegido=0;
  2344. uint8_t unico=0;
  2345. uint8_t tipo=0;
  2346. uint8_t estado=1;
  2347. uint8_t estadoSend=0;
  2348. uint8_t maxPayload=0;
  2349. uint8_t numPackets=0;
  2350. uint8_t maxPackets=0;
  2351. uint16_t lastPacket=0;
  2352. uint16_t aux3=0;
  2353. int8_t error=2;
  2354. uint8_t firstPacket=1;
  2355. uint16_t maxData=0;
  2356. uint16_t counter1=0;
  2357. uint8_t type=0;
  2358. uint8_t header=0;
  2359. it=0;
  2360. //FIXME Add max payloads for Cluster type
  2361. if(protocol==XBEE_802_15_4)
  2362. {
  2363. if(encryptMode==0)
  2364. {
  2365. maxPayload=100;
  2366. }
  2367. else
  2368. {
  2369. if(packet->mode==BROADCAST)
  2370. {
  2371. maxPayload=95;
  2372. }
  2373. else
  2374. {
  2375. if(packet->address_type==_16B)
  2376. {
  2377. maxPayload=98;
  2378. }
  2379. else
  2380. {
  2381. maxPayload=94;
  2382. }
  2383. }
  2384. }
  2385. }
  2386. if(protocol==ZIGBEE)
  2387. {
  2388. if(encryptMode==0)
  2389. {
  2390. if(packet->mode==BROADCAST)
  2391. {
  2392. maxPayload=92;
  2393. }
  2394. else
  2395. {
  2396. maxPayload=84;
  2397. }
  2398. }
  2399. else
  2400. {
  2401. if(packet->mode==BROADCAST)
  2402. {
  2403. if(apsEncryption) maxPayload=70;
  2404. else maxPayload=74;
  2405. }
  2406. else
  2407. {
  2408. if(apsEncryption) maxPayload=62;
  2409. else maxPayload=66;
  2410. }
  2411. }
  2412. }
  2413. if( (protocol==DIGIMESH) )
  2414. {
  2415. maxPayload=73;
  2416. }
  2417. if( (protocol==XBEE_900) )
  2418. {
  2419. if(encryptMode) maxPayload=80;
  2420. else maxPayload=100;
  2421. }
  2422. if(protocol==XBEE_868)
  2423. {
  2424. maxPayload=100;
  2425. }
  2426. switch(packet->typeSourceID)
  2427. {
  2428. case MY_TYPE: type=2;
  2429. break;
  2430. case MAC_TYPE: type=8;
  2431. break;
  2432. case NI_TYPE: while(packet->niO[it]!='#'){
  2433. counter1++;
  2434. it++;
  2435. }
  2436. type=counter1+1;
  2437. break;
  2438. default: break;
  2439. }
  2440. header=3+firstPacket+type;
  2441. aux3=packet->data_length;
  2442. if((aux3+header)<=maxPayload)
  2443. {
  2444. lastPacket=aux3+header;
  2445. numPackets=1;
  2446. }
  2447. else
  2448. {
  2449. while((aux3+header)>maxPayload)
  2450. {
  2451. numPackets++;
  2452. aux3=aux3-maxPayload+header;
  2453. firstPacket=0;
  2454. header=3+firstPacket+type;
  2455. if((aux3+header)<=maxPayload)
  2456. {
  2457. lastPacket=aux3+header;
  2458. numPackets++;
  2459. }
  2460. }
  2461. }
  2462. maxPackets=numPackets;
  2463. while(estadoSend!=1)
  2464. {
  2465. while(numPackets>0)
  2466. {
  2467. packet->numFragment=numPackets;
  2468. if(numPackets==1) // last fragment
  2469. {
  2470. packet->frag_length=lastPacket;
  2471. }
  2472. else
  2473. {
  2474. packet->frag_length=maxPayload;
  2475. }
  2476. if(numPackets==maxPackets)
  2477. {
  2478. start=0;
  2479. firstPacket=1;
  2480. header=3+firstPacket+type;
  2481. packet->endFragment=1;
  2482. }
  2483. else
  2484. {
  2485. start=finish+1;
  2486. firstPacket=0;
  2487. header=3+firstPacket+type;
  2488. packet->endFragment=0;
  2489. }
  2490. if(numPackets==1)
  2491. {
  2492. finish=packet->data_length-1;
  2493. }
  2494. else
  2495. {
  2496. finish=start+packet->frag_length-header-1;
  2497. }
  2498. frag_length=packet->frag_length;
  2499. error=sendXBeePriv(packet);
  2500. if(error==0)
  2501. {
  2502. numPackets--;
  2503. if(numPackets==0)
  2504. {
  2505. estadoSend=1;
  2506. }
  2507. else delay(50);
  2508. }
  2509. else
  2510. {
  2511. numPackets=0;
  2512. estadoSend=1;
  2513. }
  2514. }
  2515. }
  2516. return error;
  2517. }
  2518. /*
  2519. Function: Send a packet from one XBee to another XBee in API mode
  2520. Returns: Integer that determines if there has been any error
  2521. error=2 --> The command has not been executed
  2522. error=1 --> There has been an error while executing the command
  2523. error=0 --> The command has been executed with no errors
  2524. */
  2525. int8_t WaspXBeeCore::send(uint8_t* address, char* data)
  2526. {
  2527. char macDest[16];
  2528. Utils.hex2str(address, macDest);
  2529. return send(macDest,data);
  2530. }
  2531. /*
  2532. Function: Send a packet from one XBee to another XBee in API mode
  2533. Returns: Integer that determines if there has been any error
  2534. error=2 --> The command has not been executed
  2535. error=1 --> There has been an error while executing the command
  2536. error=0 --> The command has been executed with no errors
  2537. */
  2538. int8_t WaspXBeeCore::send(char* address, char* data)
  2539. {
  2540. uint8_t maxPayload = 0;
  2541. uint8_t i=0;
  2542. uint8_t j=0;
  2543. char aux[2];
  2544. uint8_t error=2;
  2545. uint8_t destination[8];
  2546. uint8_t maxData = 0;
  2547. uint8_t checksum = 0;
  2548. uint8_t tipo = 0;
  2549. switch( protocol )
  2550. {
  2551. case XBEE_802_15_4 : if( !encryptMode ) maxPayload = 100;
  2552. else
  2553. {
  2554. if( !strcmp(address,"000000000000FFFF") ) maxPayload = 95;
  2555. else maxPayload = 94;
  2556. }
  2557. tipo = 15;
  2558. break;
  2559. case ZIGBEE : if( !encryptMode )
  2560. {
  2561. if( !strcmp(address,"000000000000FFFF") ) maxPayload = 92;
  2562. else maxPayload = 84;
  2563. }
  2564. else
  2565. {
  2566. if( !strcmp(address,"000000000000FFFF") ) maxPayload = 74;
  2567. else maxPayload = 66;
  2568. }
  2569. tipo = 18;
  2570. break;
  2571. case DIGIMESH : tipo = 18;
  2572. maxPayload = 73;
  2573. break;
  2574. case XBEE_900 : tipo = 18;
  2575. if(encryptMode) maxPayload=80;
  2576. else maxPayload=100;
  2577. break;
  2578. case XBEE_868 : tipo = 18;
  2579. maxPayload = 100;
  2580. break;
  2581. }
  2582. while( data[i]!='\0' )
  2583. {
  2584. maxData++;
  2585. i++;
  2586. }
  2587. i=0;
  2588. if( maxData > maxPayload )
  2589. {
  2590. error_TX = 2;
  2591. return -1;
  2592. }
  2593. while(j<8)
  2594. {
  2595. aux[i-j*2]=address[i];
  2596. aux[(i-j*2)+1]=address[i+1];
  2597. destination[j]=Utils.str2hex(aux);
  2598. i+=2;
  2599. j++;
  2600. }
  2601. uint8_t* command = (uint8_t*) calloc(130,sizeof(uint8_t));
  2602. if(command==NULL){
  2603. return -1;
  2604. }
  2605. switch( protocol )
  2606. {
  2607. case XBEE_802_15_4 : command[0] = 0x7E;
  2608. command[1] = 0x00;
  2609. command[2] = maxData+11;
  2610. command[3] = 0x00;
  2611. command[4] = 0x01;
  2612. for(it=0;it<8;it++) command[it+5]=destination[it];
  2613. command[13]=0x00;
  2614. for(it=0;it<maxData;it++) command[it+14]=data[it];
  2615. for(it=3;it<(maxData+14);it++)
  2616. {
  2617. checksum=checksum+command[it];
  2618. }
  2619. while( (checksum>255))
  2620. {
  2621. checksum=checksum-256;
  2622. }
  2623. checksum=255-checksum;
  2624. command[14+maxData]=checksum;
  2625. break;
  2626. case DIGIMESH :
  2627. case XBEE_900 :
  2628. case XBEE_868 :
  2629. case ZIGBEE : command[0] = 0x7E;
  2630. command[1] = 0x00;
  2631. command[2] = maxData+14;
  2632. command[3] = 0x10;
  2633. command[4] = 0x01;
  2634. for(it=0;it<8;it++) command[it+5]=destination[it];
  2635. command[13]=0xFF;
  2636. command[14]=0xFE;
  2637. command[15]=0x00;
  2638. command[16]=0x00;
  2639. for(it=0;it<maxData;it++) command[it+17]=data[it];
  2640. for(it=3;it<(maxData+17);it++)
  2641. {
  2642. checksum=checksum+command[it];
  2643. }
  2644. while( (checksum>255))
  2645. {
  2646. checksum=checksum-256;
  2647. }
  2648. checksum=255-checksum;
  2649. command[17+maxData]=checksum;
  2650. break;
  2651. }
  2652. it=0;
  2653. while(it<(maxData+tipo))
  2654. {
  2655. XBee.print(command[it], BYTE);
  2656. it++;
  2657. }
  2658. if( protocol==XBEE_802_15_4 ) command[0]=0xFF;
  2659. else if( protocol==ZIGBEE || protocol==DIGIMESH || protocol==XBEE_900 || protocol==XBEE_868) command[0]=0xFE;
  2660. error=parse_message(command);
  2661. free(command);
  2662. command=NULL;
  2663. return error;
  2664. }
  2665. /*
  2666. Function: Treats any data from the XBee UART
  2667. Returns: Integer that determines if there has been any error
  2668. error=2 --> The command has not been executed
  2669. error=1 --> There has been an error while executing the command
  2670. error=0 --> The command has been executed with no errors
  2671. */
  2672. int8_t WaspXBeeCore::treatData()
  2673. {
  2674. command[0]=0xEE;
  2675. return parse_message(command);
  2676. }
  2677. /*
  2678. Function: Free the outcoming data buffer in the XBee
  2679. */
  2680. uint8_t WaspXBeeCore::freeXBee()
  2681. {
  2682. uint8_t temp=0;
  2683. uint8_t error=2;
  2684. while(XBee.available()>0)
  2685. {
  2686. temp=XBee.read();
  2687. error=0;
  2688. }
  2689. return error;
  2690. }
  2691. /*
  2692. Function: Synchronizes two nodes in a PAN
  2693. */
  2694. uint8_t WaspXBeeCore::synchronization(struct packetXBee* paq)
  2695. {
  2696. uint8_t estado=2;
  2697. int i=0;
  2698. char* number = (char*) alloca(10);
  2699. long previous2=0;
  2700. int syncro=0;
  2701. TIME1=millis();
  2702. long TIME3=3000;
  2703. long TIME2=0;
  2704. long TIME4=0;
  2705. long TIME5=0;
  2706. i=Utils.long2array(TIME3,number);
  2707. i=0;
  2708. paq->data[i]=char(35);
  2709. paq->data[i+1]=char(35);
  2710. while( (number[i]) != 35 )
  2711. {
  2712. paq->data[i+2]=number[i];
  2713. i++;
  2714. }
  2715. paq->data[i+2]=char(35);
  2716. paq->data_length=i+3;
  2717. estado=sendXBee(paq);
  2718. TIME1=millis()-TIME1;
  2719. delay(TIME3-TIME1);
  2720. digitalWrite(XBEE_SLEEP,HIGH); // Dormimos el XBee
  2721. free(number);
  2722. return estado;
  2723. }
  2724. /* FUnction: Sets to 'paq' the destination address and data
  2725. */
  2726. uint8_t WaspXBeeCore::setDestinationParams(packetXBee* paq, uint8_t* address, char* data, uint8_t type, uint8_t off_type)
  2727. {
  2728. char macDest[16];
  2729. Utils.hex2str(address, macDest);
  2730. return setDestinationParams(paq,macDest,data,type,off_type);
  2731. }
  2732. /* FUnction: Sets to 'paq' the destination address and data
  2733. */
  2734. uint8_t WaspXBeeCore::setDestinationParams(packetXBee* paq, uint8_t* address, int data, uint8_t type, uint8_t off_type)
  2735. {
  2736. char macDest[16];
  2737. Utils.hex2str(address, macDest);
  2738. return setDestinationParams(paq,macDest,data,type,off_type);
  2739. }
  2740. /* FUnction: Sets to 'paq' the destination address and data
  2741. */
  2742. uint8_t WaspXBeeCore::setDestinationParams(packetXBee* paq, char* address, char* data, uint8_t type, uint8_t off_type)
  2743. {
  2744. uint8_t destination[8];
  2745. uint8_t i=0;
  2746. uint8_t j=0;
  2747. char aux[2];
  2748. if( off_type==DATA_ABSOLUTE )
  2749. {
  2750. if( type==MAC_TYPE )
  2751. {
  2752. while(j<8)
  2753. {
  2754. aux[i-j*2]=address[i];
  2755. aux[(i-j*2)+1]=address[i+1];
  2756. destination[j]=Utils.str2hex(aux);
  2757. i+=2;
  2758. j++;
  2759. }
  2760. for(uint8_t a=0;a<4;a++)
  2761. {
  2762. paq->macDH[a]=destination[a];
  2763. }
  2764. for(uint8_t b=0;b<4;b++)
  2765. {
  2766. paq->macDL[b]=destination[b+4];
  2767. }
  2768. paq->address_type=_64B;
  2769. }
  2770. if( type==MY_TYPE )
  2771. {
  2772. while(j<2)
  2773. {
  2774. aux[i-j*2]=address[i];
  2775. aux[(i-j*2)+1]=address[i+1];
  2776. destination[j]=Utils.str2hex(aux);
  2777. i+=2;
  2778. j++;
  2779. }
  2780. paq->naD[0]=destination[0];
  2781. paq->naD[1]=destination[1];
  2782. paq->address_type=_16B;
  2783. }
  2784. data_ind=0;
  2785. }
  2786. while( *data!='\0' )
  2787. {
  2788. paq->data[data_ind]=*data++;
  2789. data_ind++;
  2790. if( data_ind>=MAX_DATA ) break;
  2791. }
  2792. paq->data_length=data_ind;
  2793. return 1;
  2794. }
  2795. /* FUnction: Sets to 'paq' the destination address and data
  2796. */
  2797. uint8_t WaspXBeeCore::setDestinationParams(packetXBee* paq, char* address, int data, uint8_t type, uint8_t off_type)
  2798. {
  2799. uint8_t destination[8];
  2800. uint8_t i=0;
  2801. uint8_t j=0;
  2802. char aux[2];
  2803. char numb[10];
  2804. if( off_type==DATA_ABSOLUTE )
  2805. {
  2806. if( type==MAC_TYPE )
  2807. {
  2808. while(j<8)
  2809. {
  2810. aux[i-j*2]=address[i];
  2811. aux[(i-j*2)+1]=address[i+1];
  2812. destination[j]=Utils.str2hex(aux);
  2813. i+=2;
  2814. j++;
  2815. }
  2816. for(uint8_t a=0;a<4;a++)
  2817. {
  2818. paq->macDH[a]=destination[a];
  2819. }
  2820. for(uint8_t a=0;a<4;a++)
  2821. {
  2822. paq->macDL[a]=destination[a+4];
  2823. }
  2824. paq->address_type=_64B;
  2825. }
  2826. if( type==MY_TYPE )
  2827. {
  2828. while(j<2)
  2829. {
  2830. aux[i-j*2]=address[i];
  2831. aux[(i-j*2)+1]=address[i+1];
  2832. destination[j]=Utils.str2hex(aux);
  2833. i+=2;
  2834. j++;
  2835. }
  2836. paq->naD[0]=destination[0];
  2837. paq->naD[1]=destination[1];
  2838. paq->address_type=_16B;
  2839. }
  2840. data_ind=0;
  2841. }
  2842. i=0;
  2843. Utils.long2array(data,numb);
  2844. while( numb[i]!='\0' )
  2845. {
  2846. paq->data[data_ind]=numb[i]++;
  2847. data_ind++;
  2848. i++;
  2849. if( data_ind>=MAX_DATA ) break;
  2850. }
  2851. paq->data_length=data_ind;
  2852. }
  2853. /* FUnction: Sets to 'paq' the destination address and data
  2854. */
  2855. uint8_t WaspXBeeCore::setOriginParams(packetXBee* paq, uint8_t type)
  2856. {
  2857. return setOriginParams(paq,"",type);
  2858. }
  2859. /* FUnction: Sets to 'paq' the destination address and data
  2860. */
  2861. uint8_t WaspXBeeCore::setOriginParams(packetXBee* paq, char* address, uint8_t type)
  2862. {
  2863. uint8_t origin[8];
  2864. uint8_t i=0;
  2865. uint8_t j=0;
  2866. char aux[2];
  2867. char ni[20];
  2868. if( type==MAC_TYPE )
  2869. {
  2870. if(Utils.sizeOf(address)<5)
  2871. {
  2872. getOwnMac();
  2873. for(uint8_t a=0;a<4;a++)
  2874. {
  2875. paq->macOH[a]=sourceMacHigh[a];
  2876. }
  2877. for(uint8_t b=0;b<4;b++)
  2878. {
  2879. paq->macOL[b]=sourceMacLow[b];
  2880. }
  2881. }
  2882. else
  2883. {
  2884. while(j<8)
  2885. {
  2886. aux[i-j*2]=address[i];
  2887. aux[(i-j*2)+1]=address[i+1];
  2888. origin[j]=Utils.str2hex(aux);
  2889. i+=2;
  2890. j++;
  2891. }
  2892. for(uint8_t a=0;a<4;a++)
  2893. {
  2894. paq->macOH[a]=origin[a];
  2895. }
  2896. for(uint8_t b=0;b<4;b++)
  2897. {
  2898. paq->macOL[b]=origin[b+4];
  2899. }
  2900. }
  2901. paq->typeSourceID=MAC_TYPE;
  2902. }
  2903. if( type==MY_TYPE )
  2904. {
  2905. if(Utils.sizeOf(address)<2)
  2906. {
  2907. getOwnNetAddress();
  2908. for(uint8_t a=0;a<2;a++)
  2909. {
  2910. paq->naO[a]=sourceNA[a];
  2911. }
  2912. }
  2913. else
  2914. {
  2915. while(j<2)
  2916. {
  2917. aux[i-j*2]=address[i];
  2918. aux[(i-j*2)+1]=address[i+1];
  2919. origin[j]=Utils.str2hex(aux);
  2920. i+=2;
  2921. j++;
  2922. }
  2923. paq->naO[0]=origin[0];
  2924. paq->naO[1]=origin[1];
  2925. }
  2926. paq->typeSourceID=MY_TYPE;
  2927. }
  2928. i=0;
  2929. if( type==NI_TYPE )
  2930. {
  2931. while( *address!='\0' )
  2932. {
  2933. paq->niO[i]=*address++;
  2934. i++;
  2935. }
  2936. paq->niO[i]='#';
  2937. paq->typeSourceID=NI_TYPE;
  2938. }
  2939. return 1;
  2940. }
  2941. /*
  2942. Function: Treats and parses the read bytes wich are a message sent by a remote XBee
  2943. Returns: Integer that determines if there has been any error
  2944. error=2 --> The command has not been executed
  2945. error=1 --> There has been an error while executing the command
  2946. error=0 --> The command has been executed with no errors
  2947. error=-1 --> No more memory available
  2948. Values: Stores in global "packet_finished" array the received message
  2949. */
  2950. int8_t WaspXBeeCore::readXBee(uint8_t* data)
  2951. {
  2952. uint16_t counter=0;
  2953. uint8_t checksum=0;
  2954. uint8_t estado=1;
  2955. uint16_t length=0;
  2956. uint16_t cont=1;
  2957. uint16_t aux=0;
  2958. uint16_t aux2=0;
  2959. uint8_t aux3=0;
  2960. uint16_t counter3=0;
  2961. uint8_t est=1;
  2962. uint8_t end=0;
  2963. uint16_t interval=WAIT_TIME_READ;
  2964. uint8_t primero=0;
  2965. int8_t error=2;
  2966. uint8_t num_read=0;
  2967. uint16_t cont3=0;
  2968. uint8_t header=0;
  2969. uint16_t temp=0;
  2970. int16_t temp2=0;
  2971. uint16_t temp3=0;
  2972. uint8_t samePacket=0;
  2973. uint8_t comp=0;
  2974. uint8_t numFragments;
  2975. uint8_t index1=0;
  2976. uint8_t index2=0;
  2977. long time=0;
  2978. uint8_t finishIndex=0;
  2979. uint16_t counter1=0;
  2980. it=0;
  2981. uint8_t checksum_read=0;
  2982. if( indexNotModified )
  2983. {
  2984. for(it=0;it<MAX_FINISH_PACKETS;it++)
  2985. {
  2986. if( pendingFragments[it]==NULL ) break;
  2987. }
  2988. nextIndex1=it;
  2989. }
  2990. it=0;
  2991. #if DEBUG
  2992. XBee.println("");
  2993. XBee.println("-----------------------------------------------------");
  2994. XBee.print("Pending Packets: ");
  2995. XBee.println(pendingPackets,DEC);
  2996. #endif
  2997. temp=0;
  2998. if( protocol!=XBEE_802_15_4 && data_length<12 ) return 1;
  2999. if( protocol==XBEE_802_15_4 && add_type==_16B && data_length<5 ) return 1;
  3000. if( protocol==XBEE_802_15_4 && add_type==_64B && data_length<11 ) return 1;
  3001. while(temp<MAX_FINISH_PACKETS) // miramos si ya tenemos fragmentos de este paquete global
  3002. {
  3003. #if DEBUG
  3004. XBee.println("Posible fragmento de paquete existente");
  3005. #endif
  3006. it=0;
  3007. temp2=0;
  3008. temp3=0;
  3009. if( pendingFragments[temp]->time > 0 )
  3010. {
  3011. if(protocol==XBEE_802_15_4)
  3012. {
  3013. if(add_type==_16B)
  3014. {
  3015. if( (data[4]) == pendingFragments[temp]->packetID )
  3016. {
  3017. if((data[6])==35)
  3018. {
  3019. temp2=1;
  3020. }
  3021. else
  3022. {
  3023. temp2=0;
  3024. }
  3025. temp3=data[6+temp2];
  3026. it=0;
  3027. switch(temp3)
  3028. {
  3029. case MY_TYPE: if(pendingFragments[temp]->naO[0]==data[7+temp2])
  3030. {
  3031. if(pendingFragments[temp]->naO[1]==data[8+temp2])
  3032. {
  3033. samePacket=1;
  3034. }
  3035. }
  3036. break;
  3037. case 1: for(it=0;it<4;it++)
  3038. {
  3039. if(pendingFragments[temp]->macOH[it]!=data[7+temp2+it])
  3040. {
  3041. comp=1;
  3042. break;
  3043. }
  3044. }
  3045. for(it=0;it<4;it++)
  3046. {
  3047. if(pendingFragments[temp]->macOL[it]!=data[11+temp2+it])
  3048. {
  3049. comp=1;
  3050. break;
  3051. }
  3052. }
  3053. if(comp==0)
  3054. {
  3055. samePacket=1;
  3056. }
  3057. break;
  3058. case 2: while(pendingFragments[temp]->niO[it]!=35)
  3059. {
  3060. if(pendingFragments[temp]->niO[it]!=data[7+it+temp2])
  3061. {
  3062. comp=1;
  3063. break;
  3064. }
  3065. it++;
  3066. }
  3067. if(comp==0)
  3068. {
  3069. samePacket=1;
  3070. }
  3071. break;
  3072. }
  3073. if(samePacket==1) // Fragmento del mismo paquete
  3074. {
  3075. index1=temp;
  3076. temp=MAX_FINISH_PACKETS;
  3077. if(temp2==1)
  3078. {
  3079. pendingFragments[index1]->totalFragments=data[5];
  3080. }
  3081. pendingFragments[index1]->recFragments++;
  3082. pendingFragments[index1]->RSSI=pendingFragments[index1]->RSSI+data[2];
  3083. index2=data[5]-1;
  3084. if( index2>= MAX_FRAG_PACKETS ){
  3085. freeIndexMatrix(index1);
  3086. return -1;
  3087. }
  3088. }
  3089. }
  3090. }
  3091. else if(add_type==_64B)
  3092. {
  3093. if((data[10])==pendingFragments[temp]->packetID)
  3094. {
  3095. if((data[12])==35)
  3096. {
  3097. temp2=1;
  3098. }
  3099. else
  3100. {
  3101. temp2=0;
  3102. }
  3103. temp3=data[12+temp2];
  3104. it=0;
  3105. switch(temp3)
  3106. {
  3107. case MY_TYPE: if(pendingFragments[temp]->naO[0]==data[13+temp2])
  3108. {
  3109. if(pendingFragments[temp]->naO[1]==data[14+temp2])
  3110. {
  3111. samePacket=1;
  3112. }
  3113. }
  3114. break;
  3115. case 1: for(it=0;it<4;it++)
  3116. {
  3117. if(pendingFragments[temp]->macOH[it]!=data[13+temp2+it])
  3118. {
  3119. comp=1;
  3120. break;
  3121. }
  3122. }
  3123. for(it=0;it<4;it++)
  3124. {
  3125. if(pendingFragments[temp]->macOL[it]!=data[17+temp2+it])
  3126. {
  3127. comp=1;
  3128. break;
  3129. }
  3130. }
  3131. if(comp==0)
  3132. {
  3133. samePacket=1;
  3134. }
  3135. break;
  3136. case 2: while(pendingFragments[temp]->niO[it]!=35)
  3137. {
  3138. if(pendingFragments[temp]->niO[it]!=data[13+it+temp2])
  3139. {
  3140. comp=1;
  3141. break;
  3142. }
  3143. it++;
  3144. }
  3145. if(comp==0)
  3146. {
  3147. samePacket=1;
  3148. }
  3149. break;
  3150. }
  3151. if(samePacket==1) // Fragmento del mismo paquete
  3152. {
  3153. #if DEBUG
  3154. XBee.println("Fragmento de paquete existente");
  3155. #endif
  3156. index1=temp;
  3157. temp=MAX_FINISH_PACKETS;
  3158. if(temp2==1)
  3159. {
  3160. pendingFragments[index1]->totalFragments=data[11];
  3161. }
  3162. pendingFragments[index1]->recFragments++;
  3163. pendingFragments[index1]->RSSI=pendingFragments[index1]->RSSI+data[8];
  3164. index2=data[11]-1;
  3165. if( index2>= MAX_FRAG_PACKETS ){
  3166. freeIndexMatrix(index1);
  3167. return -1;
  3168. }
  3169. #if DEBUG
  3170. XBee.print("Index1: ");
  3171. XBee.println(index1,DEC);
  3172. XBee.print("Index2: ");
  3173. XBee.println(index2,DEC);
  3174. #endif
  3175. }
  3176. }
  3177. }
  3178. }
  3179. else if( (protocol==DIGIMESH) || (protocol==ZIGBEE) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  3180. {
  3181. if(mode==UNICAST)
  3182. {
  3183. if((data[11])==pendingFragments[temp]->packetID)
  3184. {
  3185. if((data[13])==35)
  3186. {
  3187. temp2=1;
  3188. }
  3189. else
  3190. {
  3191. temp2=0;
  3192. }
  3193. temp3=data[13+temp2];
  3194. it=0;
  3195. switch(temp3)
  3196. {
  3197. case MY_TYPE: if(pendingFragments[temp]->naO[0]==data[14+temp2])
  3198. {
  3199. if(pendingFragments[temp]->naO[1]==data[15+temp2])
  3200. {
  3201. samePacket=1;
  3202. }
  3203. }
  3204. break;
  3205. case 1: for(it=0;it<4;it++)
  3206. {
  3207. if(pendingFragments[temp]->macOH[it]!=data[14+temp2+it])
  3208. {
  3209. comp=1;
  3210. break;
  3211. }
  3212. }
  3213. for(it=0;it<4;it++)
  3214. {
  3215. if(pendingFragments[temp]->macOL[it]!=data[18+temp2+it])
  3216. {
  3217. comp=1;
  3218. break;
  3219. }
  3220. }
  3221. if(comp==0)
  3222. {
  3223. samePacket=1;
  3224. }
  3225. break;
  3226. case 2: while(pendingFragments[temp]->niO[it]!=35)
  3227. {
  3228. if(pendingFragments[temp]->niO[it]!=data[14+it+temp2])
  3229. {
  3230. comp=1;
  3231. break;
  3232. }
  3233. it++;
  3234. }
  3235. if(comp==0)
  3236. {
  3237. samePacket=1;
  3238. }
  3239. break;
  3240. }
  3241. if(samePacket==1) // Fragmento del mismo paquete
  3242. {
  3243. index1=temp;
  3244. #if DEBUG
  3245. XBee.println("Fragmento de paquete existente");
  3246. #endif
  3247. temp=MAX_FINISH_PACKETS;
  3248. if(temp2==1)
  3249. {
  3250. pendingFragments[index1]->totalFragments=data[12];
  3251. }
  3252. pendingFragments[index1]->recFragments++;
  3253. index2=data[12]-1;
  3254. #if DEBUG
  3255. XBee.print("Index1: ");
  3256. XBee.println(index1,DEC);
  3257. XBee.print("Index2: ");
  3258. XBee.println(index2,DEC);
  3259. #endif
  3260. if( index2>= MAX_FRAG_PACKETS ){
  3261. freeIndexMatrix(index1);
  3262. return -1;
  3263. }
  3264. }
  3265. }
  3266. }
  3267. else if(mode==CLUSTER)
  3268. {
  3269. if((data[17])==pendingFragments[temp]->packetID)
  3270. {
  3271. if((data[19])==35)
  3272. {
  3273. temp2=1;
  3274. }
  3275. else
  3276. {
  3277. temp2=0;
  3278. }
  3279. temp3=data[19+temp2];
  3280. it=0;
  3281. switch(temp3)
  3282. {
  3283. case MY_TYPE: if(pendingFragments[temp]->naO[0]==data[20+temp2])
  3284. {
  3285. if(pendingFragments[temp]->naO[1]==data[21+temp2])
  3286. {
  3287. samePacket=1;
  3288. }
  3289. }
  3290. break;
  3291. case 1: for(it=0;it<4;it++)
  3292. {
  3293. if(pendingFragments[temp]->macOH[it]!=data[20+temp2+it])
  3294. {
  3295. comp=1;
  3296. break;
  3297. }
  3298. }
  3299. for(it=0;it<4;it++)
  3300. {
  3301. if(pendingFragments[temp]->macOL[it]!=data[24+temp2+it])
  3302. {
  3303. comp=1;
  3304. break;
  3305. }
  3306. }
  3307. if(comp==0)
  3308. {
  3309. samePacket=1;
  3310. }
  3311. break;
  3312. case 2: while(pendingFragments[temp]->niO[it]!=35)
  3313. {
  3314. if(pendingFragments[temp]->niO[it]!=data[20+it+temp2])
  3315. {
  3316. comp=1;
  3317. break;
  3318. }
  3319. it++;
  3320. }
  3321. if(comp==0)
  3322. {
  3323. samePacket=1;
  3324. }
  3325. break;
  3326. }
  3327. if(samePacket==1) // Fragmento del mismo paquete
  3328. {
  3329. index1=temp;
  3330. temp=MAX_FINISH_PACKETS;
  3331. if(temp2==1)
  3332. {
  3333. pendingFragments[index1]->totalFragments=data[18];
  3334. }
  3335. pendingFragments[index1]->recFragments++;
  3336. index2=data[18]-1;
  3337. if( index2>= MAX_FRAG_PACKETS ){
  3338. freeIndexMatrix(index1);
  3339. return -1;
  3340. }
  3341. }
  3342. }
  3343. }
  3344. }
  3345. }
  3346. temp++;
  3347. }
  3348. it=0;
  3349. if(samePacket==0) // Fragmento de un paquete nuevo
  3350. {
  3351. #if DEBUG
  3352. XBee.println("Fragmento de paquete nuevo");
  3353. #endif
  3354. index1=nextIndex1;
  3355. indexNotModified=1;
  3356. if( pendingPackets>= MAX_FINISH_PACKETS ){
  3357. freeIndex();
  3358. index1=nextIndex1;
  3359. }
  3360. pendingPackets++;
  3361. pendingFragments[index1] = (index*) calloc(1,sizeof(index));
  3362. if(pendingFragments[index1]==NULL){
  3363. freeAll();
  3364. return -1;
  3365. }
  3366. if(protocol==XBEE_802_15_4)
  3367. {
  3368. if(add_type==_16B)
  3369. {
  3370. #if DEBUG
  3371. XBee.println("Entro en 16B");
  3372. XBee.println(pendingFragments[index1]->packetID,HEX);
  3373. XBee.println(pendingFragments[index1]->time,DEC);
  3374. #endif
  3375. pendingFragments[index1]->address_typeS=add_type;
  3376. pendingFragments[index1]->packetID=data[4];
  3377. pendingFragments[index1]->time=millis();
  3378. for(it=0;it<2;it++)
  3379. {
  3380. pendingFragments[index1]->naS[it]=data[it];
  3381. #if DEBUG
  3382. XBee.print(pendingFragments[index1]->naS[it],HEX);
  3383. #endif
  3384. }
  3385. if((data[6])==35)
  3386. {
  3387. temp2=1;
  3388. }
  3389. else
  3390. {
  3391. temp2=0;
  3392. }
  3393. pendingFragments[index1]->typeSourceID=data[6+temp2];
  3394. it=0;
  3395. switch(pendingFragments[index1]->typeSourceID)
  3396. {
  3397. case MY_TYPE: pendingFragments[index1]->naO[0]=data[7+temp2];
  3398. pendingFragments[index1]->naO[1]=data[8+temp2];
  3399. break;
  3400. case MAC_TYPE: for(it=0;it<4;it++)
  3401. {
  3402. pendingFragments[index1]->macOH[it]=data[7+it+temp2];
  3403. }
  3404. for(it=0;it<4;it++)
  3405. {
  3406. pendingFragments[index1]->macOL[it]=data[11+it+temp2];
  3407. }
  3408. break;
  3409. case NI_TYPE: while(data[7+temp2+it]!=35)
  3410. {
  3411. pendingFragments[index1]->niO[it]=char(data[7+it+temp2]);
  3412. it++;
  3413. if(it>20)
  3414. {
  3415. break;
  3416. }
  3417. }
  3418. pendingFragments[index1]->niO[it]=char(35);
  3419. break;
  3420. }
  3421. if(temp2==1)
  3422. {
  3423. pendingFragments[index1]->totalFragments=data[5];
  3424. }
  3425. pendingFragments[index1]->recFragments=1;
  3426. index2=data[5]-1;
  3427. if( index2>= MAX_FRAG_PACKETS ){
  3428. freeIndexMatrix(index1);
  3429. return -1;
  3430. }
  3431. pendingFragments[index1]->RSSI=data[2];
  3432. pendingFragments[index1]->opt=data[3];
  3433. if( (pendingFragments[index1]->opt==0x01) || (pendingFragments[index1]->opt==0x02) )
  3434. {
  3435. pendingFragments[index1]->mode=BROADCAST;
  3436. }
  3437. else
  3438. {
  3439. pendingFragments[index1]->mode=UNICAST;
  3440. }
  3441. }
  3442. else if(add_type==_64B)
  3443. {
  3444. pendingFragments[index1]->address_typeS=add_type;
  3445. pendingFragments[index1]->packetID=data[10];
  3446. pendingFragments[index1]->time=millis();
  3447. #if DEBUG
  3448. XBee.println("Entro en 64B");
  3449. XBee.println(pendingFragments[index1]->packetID,HEX);
  3450. XBee.println(pendingFragments[index1]->time,DEC);
  3451. #endif
  3452. for(it=0;it<4;it++)
  3453. {
  3454. pendingFragments[index1]->macSH[it]=data[it];
  3455. #if DEBUG
  3456. XBee.print(pendingFragments[index1]->macSH[it],HEX);
  3457. #endif
  3458. }
  3459. for(it=0;it<4;it++)
  3460. {
  3461. pendingFragments[index1]->macSL[it]=data[it+4];
  3462. #if DEBUG
  3463. XBee.print(pendingFragments[index1]->macSL[it],HEX);
  3464. #endif
  3465. }
  3466. if((data[12])==35)
  3467. {
  3468. temp2=1;
  3469. }
  3470. else
  3471. {
  3472. temp2=0;
  3473. }
  3474. pendingFragments[index1]->typeSourceID=data[12+temp2];
  3475. #if DEBUG
  3476. XBee.println("");
  3477. XBee.println(pendingFragments[index1]->typeSourceID,DEC);
  3478. #endif
  3479. it=0;
  3480. switch(pendingFragments[index1]->typeSourceID)
  3481. {
  3482. case MY_TYPE: pendingFragments[index1]->naO[0]=data[13+temp2];
  3483. pendingFragments[index1]->naO[1]=data[14+temp2];
  3484. #if DEBUG
  3485. XBee.println(pendingFragments[index1]->naO[0],HEX);
  3486. XBee.println(pendingFragments[index1]->naO[1],HEX);
  3487. #endif
  3488. break;
  3489. case MAC_TYPE: for(it=0;it<4;it++)
  3490. {
  3491. pendingFragments[index1]->macOH[it]=data[13+it+temp2];
  3492. }
  3493. for(it=0;it<4;it++)
  3494. {
  3495. pendingFragments[index1]->macOL[it]=data[17+it+temp2];
  3496. }
  3497. break;
  3498. case NI_TYPE: while(data[13+temp2+it]!=35)
  3499. {
  3500. pendingFragments[index1]->niO[it]=char(data[13+it+temp2]);
  3501. #if DEBUG
  3502. XBee.print(pendingFragments[index1]->niO[it],BYTE);
  3503. #endif
  3504. it++;
  3505. if(it>20)
  3506. {
  3507. break;
  3508. }
  3509. }
  3510. pendingFragments[index1]->niO[it]=char(35);
  3511. break;
  3512. }
  3513. pendingFragments[index1]->RSSI=data[8];
  3514. pendingFragments[index1]->opt=data[9];
  3515. if( (pendingFragments[index1]->opt==0x01) || (pendingFragments[index1]->opt==0x02) )
  3516. {
  3517. pendingFragments[index1]->mode=BROADCAST;
  3518. }
  3519. else
  3520. {
  3521. pendingFragments[index1]->mode=UNICAST;
  3522. }
  3523. if(temp2==1)
  3524. {
  3525. pendingFragments[index1]->totalFragments=data[11];
  3526. }
  3527. pendingFragments[index1]->recFragments=1;
  3528. index2=data[11]-1;
  3529. if( index2>= MAX_FRAG_PACKETS ){
  3530. freeIndexMatrix(index1);
  3531. return -1;
  3532. }
  3533. #if DEBUG
  3534. XBee.print("Index1: ");
  3535. XBee.println(index1,DEC);
  3536. XBee.print("Index2: ");
  3537. XBee.println(index2,DEC);
  3538. #endif
  3539. }
  3540. }
  3541. else if( (protocol==DIGIMESH) || (protocol==ZIGBEE) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  3542. {
  3543. if(mode==UNICAST)
  3544. {
  3545. pendingFragments[index1]->packetID=data[11];
  3546. pendingFragments[index1]->time=millis();
  3547. if((data[13])==35)
  3548. {
  3549. temp2=1;
  3550. }
  3551. else
  3552. {
  3553. temp2=0;
  3554. }
  3555. pendingFragments[index1]->typeSourceID=data[13+temp2];
  3556. it=0;
  3557. switch(pendingFragments[index1]->typeSourceID)
  3558. {
  3559. case MY_TYPE: pendingFragments[index1]->naO[0]=data[14+temp2];
  3560. pendingFragments[index1]->naO[1]=data[15+temp2];
  3561. aux3=2;
  3562. break;
  3563. case MAC_TYPE: for(it=0;it<4;it++)
  3564. {
  3565. pendingFragments[index1]->macOH[it]=data[14+it+temp2];
  3566. }
  3567. for(it=0;it<4;it++)
  3568. {
  3569. pendingFragments[index1]->macOL[it]=data[18+it+temp2];
  3570. }
  3571. aux3=8;
  3572. break;
  3573. case NI_TYPE: while(data[14+temp2+it]!=35)
  3574. {
  3575. pendingFragments[index1]->niO[it]=char(data[14+it+temp2]);
  3576. it++;
  3577. aux3++;
  3578. if(it>20)
  3579. {
  3580. break;
  3581. }
  3582. }
  3583. pendingFragments[index1]->niO[it]=char(35);
  3584. break;
  3585. }
  3586. if(temp2==1)
  3587. {
  3588. pendingFragments[index1]->totalFragments=data[12];
  3589. }
  3590. pendingFragments[index1]->recFragments=1;
  3591. index2=data[12]-1;
  3592. if( index2>= MAX_FRAG_PACKETS ){
  3593. freeIndexMatrix(index1);
  3594. return -1;
  3595. }
  3596. for(it=0;it<4;it++)
  3597. {
  3598. pendingFragments[index1]->macSH[it]=data[it];
  3599. }
  3600. for(it=0;it<4;it++)
  3601. {
  3602. pendingFragments[index1]->macSL[it]=data[it+4];
  3603. }
  3604. for(it=0;it<2;it++)
  3605. {
  3606. pendingFragments[index1]->naS[it]=data[it+8];
  3607. }
  3608. pendingFragments[index1]->mode=UNICAST;
  3609. pendingFragments[index1]->opt=data[10];
  3610. if(pendingFragments[index1]->opt==0x02)
  3611. {
  3612. pendingFragments[index1]->mode=BROADCAST;
  3613. }
  3614. #if DEBUG
  3615. XBee.print("Index1: ");
  3616. XBee.println(index1,DEC);
  3617. XBee.print("Index2: ");
  3618. XBee.println(index2,DEC);
  3619. #endif
  3620. }
  3621. else if(mode==CLUSTER)
  3622. {
  3623. pendingFragments[index1]->packetID=data[17];
  3624. pendingFragments[index1]->time=millis();
  3625. if((data[19])==35)
  3626. {
  3627. temp2=1;
  3628. }
  3629. else
  3630. {
  3631. temp2=0;
  3632. }
  3633. pendingFragments[index1]->typeSourceID=data[19+temp2];
  3634. it=0;
  3635. switch(pendingFragments[index1]->typeSourceID)
  3636. {
  3637. case MY_TYPE: pendingFragments[index1]->naO[0]=data[20+temp2];
  3638. pendingFragments[index1]->naO[1]=data[21+temp2];
  3639. aux3=2;
  3640. break;
  3641. case MAC_TYPE: for(it=0;it<4;it++)
  3642. {
  3643. pendingFragments[index1]->macOH[it]=data[20+it+temp2];
  3644. }
  3645. for(it=0;it<4;it++)
  3646. {
  3647. pendingFragments[index1]->macOL[it]=data[24+it+temp2];
  3648. }
  3649. aux3=8;
  3650. break;
  3651. case NI_TYPE: while(data[20+temp2+it]!=35)
  3652. {
  3653. pendingFragments[index1]->niO[it]=char(data[20+it+temp2]);
  3654. it++;
  3655. aux3++;
  3656. if(it>20)
  3657. {
  3658. break;
  3659. }
  3660. }
  3661. pendingFragments[index1]->niO[it]=char(35);
  3662. break;
  3663. }
  3664. if(temp2==1)
  3665. {
  3666. pendingFragments[index1]->totalFragments=data[18];
  3667. }
  3668. pendingFragments[index1]->recFragments=1;
  3669. index2=data[18]-1;
  3670. if( index2>= MAX_FRAG_PACKETS ){
  3671. freeIndexMatrix(index1);
  3672. return -1;
  3673. }
  3674. for(it=0;it<4;it++)
  3675. {
  3676. pendingFragments[index1]->macSH[it]=data[it];
  3677. }
  3678. for(it=0;it<4;it++)
  3679. {
  3680. pendingFragments[index1]->macSL[it]=data[it+4];
  3681. }
  3682. for(it=0;it<2;it++)
  3683. {
  3684. pendingFragments[index1]->naS[it]=data[it+8];
  3685. }
  3686. pendingFragments[index1]->mode=CLUSTER;
  3687. pendingFragments[index1]->SD=data[10];
  3688. pendingFragments[index1]->DE=data[11];
  3689. for(it=0;it<2;it++)
  3690. {
  3691. pendingFragments[index1]->CID[it]=data[it+12];
  3692. }
  3693. for(it=0;it<2;it++)
  3694. {
  3695. pendingFragments[index1]->PID[it]=data[it+14];
  3696. }
  3697. pendingFragments[index1]->opt=data[16];
  3698. if(pendingFragments[index1]->opt==0x02)
  3699. {
  3700. pendingFragments[index1]->mode=BROADCAST;
  3701. }
  3702. }
  3703. }
  3704. }
  3705. samePacket=0;
  3706. packet_fragments[index1][index2] = (matrix*) calloc(1,sizeof(matrix));
  3707. if(packet_fragments[index1][index2]==NULL){
  3708. freeAll();
  3709. return -1;
  3710. }
  3711. if(protocol==XBEE_802_15_4)
  3712. {
  3713. if(add_type==_16B)
  3714. {
  3715. packet_fragments[index1][index2]->numFragment=data[5];
  3716. if(data[6]==35)
  3717. {
  3718. packet_fragments[index1][index2]->endFragment=1;
  3719. }
  3720. else
  3721. {
  3722. packet_fragments[index1][index2]->endFragment=0;
  3723. }
  3724. aux2=packet_fragments[index1][index2]->endFragment;
  3725. it=0;
  3726. cont3=0;
  3727. switch(pendingFragments[index1]->typeSourceID)
  3728. {
  3729. case MY_TYPE: cont3=2;
  3730. break;
  3731. case MAC_TYPE: cont3=8;
  3732. break;
  3733. case NI_TYPE: while(data[7+aux2+it]!=35)
  3734. {
  3735. it++;
  3736. cont3++;
  3737. }
  3738. cont3++;
  3739. break;
  3740. }
  3741. header=4+3+aux2+cont3;
  3742. if( header>data_length ) data_length=header;
  3743. packet_fragments[index1][index2]->frag_length=data_length-header;
  3744. #if DEBUG
  3745. XBee.println("");
  3746. XBee.print("data_length: ");
  3747. XBee.println(data_length,DEC);
  3748. XBee.print("header: ");
  3749. XBee.println(header,DEC);
  3750. XBee.print("aux2: ");
  3751. XBee.println(aux2,DEC);
  3752. XBee.print("cont3: ");
  3753. XBee.println(cont3,DEC);
  3754. XBee.println(packet_fragments[index1][index2]->frag_length,DEC);
  3755. #endif
  3756. for(it=0;it<packet_fragments[index1][index2]->frag_length;it++)
  3757. {
  3758. packet_fragments[index1][index2]->data[it]=char(data[it+header]);
  3759. #if DEBUG
  3760. XBee.print(packet_fragments[index1][index2]->data[it],BYTE);
  3761. #endif
  3762. }
  3763. }
  3764. if(add_type==_64B)
  3765. {
  3766. packet_fragments[index1][index2]->numFragment=data[11];
  3767. if(data[12]==35)
  3768. {
  3769. packet_fragments[index1][index2]->endFragment=1;
  3770. }
  3771. else
  3772. {
  3773. packet_fragments[index1][index2]->endFragment=0;
  3774. }
  3775. aux2=packet_fragments[index1][index2]->endFragment;
  3776. it=0;
  3777. cont3=0;
  3778. switch(pendingFragments[index1]->typeSourceID)
  3779. {
  3780. case MY_TYPE: cont3=2;
  3781. break;
  3782. case MAC_TYPE: cont3=8;
  3783. break;
  3784. case NI_TYPE: while(data[13+aux2+it]!=35)
  3785. {
  3786. it++;
  3787. cont3++;
  3788. }
  3789. cont3++;
  3790. break;
  3791. }
  3792. header=10+3+aux2+cont3;
  3793. if( header>data_length ) data_length=header;
  3794. packet_fragments[index1][index2]->frag_length=data_length-header;
  3795. #if DEBUG
  3796. XBee.println("");
  3797. XBee.print("data_length: ");
  3798. XBee.println(data_length,DEC);
  3799. XBee.print("header: ");
  3800. XBee.println(header,DEC);
  3801. XBee.print("aux2: ");
  3802. XBee.println(aux2,DEC);
  3803. XBee.print("cont3: ");
  3804. XBee.println(cont3,DEC);
  3805. XBee.println(packet_fragments[index1][index2]->frag_length,DEC);
  3806. #endif
  3807. for(it=0;it<packet_fragments[index1][index2]->frag_length;it++)
  3808. {
  3809. packet_fragments[index1][index2]->data[it]=char(data[it+header]);
  3810. #if DEBUG
  3811. XBee.print(packet_fragments[index1][index2]->data[it],BYTE);
  3812. #endif
  3813. }
  3814. }
  3815. }
  3816. if( (protocol==ZIGBEE) || (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  3817. {
  3818. if(mode==UNICAST)
  3819. {
  3820. packet_fragments[index1][index2]->numFragment=data[12];
  3821. if(data[13]==35)
  3822. {
  3823. packet_fragments[index1][index2]->endFragment=1;
  3824. }
  3825. else
  3826. {
  3827. packet_fragments[index1][index2]->endFragment=0;
  3828. }
  3829. aux2=packet_fragments[index1][index2]->endFragment;
  3830. it=0;
  3831. cont3=0;
  3832. switch(pendingFragments[index1]->typeSourceID)
  3833. {
  3834. case MY_TYPE: cont3=2;
  3835. break;
  3836. case MAC_TYPE: cont3=8;
  3837. break;
  3838. case NI_TYPE: while(data[14+aux2+it]!=35)
  3839. {
  3840. it++;
  3841. cont3++;
  3842. }
  3843. cont3++;
  3844. break;
  3845. }
  3846. header=11+3+aux2+cont3;
  3847. if( header>data_length ) data_length=header;
  3848. packet_fragments[index1][index2]->frag_length=data_length-header;
  3849. #if DEBUG
  3850. XBee.println("");
  3851. XBee.print("data_length: ");
  3852. XBee.println(data_length,DEC);
  3853. XBee.print("header: ");
  3854. XBee.println(header,DEC);
  3855. XBee.print("aux2: ");
  3856. XBee.println(aux2,DEC);
  3857. XBee.print("cont3: ");
  3858. XBee.println(cont3,DEC);
  3859. XBee.println(packet_fragments[index1][index2]->frag_length,DEC);
  3860. #endif
  3861. for(it=0;it<packet_fragments[index1][index2]->frag_length;it++)
  3862. {
  3863. packet_fragments[index1][index2]->data[it]=char(data[it+header]);
  3864. }
  3865. }
  3866. else if(mode==CLUSTER)
  3867. {
  3868. packet_fragments[index1][index2]->numFragment=data[18];
  3869. if(data[19]==35)
  3870. {
  3871. packet_fragments[index1][index2]->endFragment=1;
  3872. }
  3873. else
  3874. {
  3875. packet_fragments[index1][index2]->endFragment=0;
  3876. }
  3877. aux2=packet_fragments[index1][index2]->endFragment;
  3878. it=0;
  3879. cont3=0;
  3880. switch(pendingFragments[index1]->typeSourceID)
  3881. {
  3882. case MY_TYPE: cont3=2;
  3883. break;
  3884. case MAC_TYPE: cont3=8;
  3885. break;
  3886. case NI_TYPE: while(data[23+aux2+it]!=35)
  3887. {
  3888. it++;
  3889. cont3++;
  3890. }
  3891. cont3++;
  3892. break;
  3893. }
  3894. header=17+3+aux2+cont3;
  3895. if( header>data_length ) data_length=header;
  3896. packet_fragments[index1][index2]->frag_length=data_length-header;
  3897. for(it=0;it<packet_fragments[index1][index2]->frag_length;it++)
  3898. {
  3899. packet_fragments[index1][index2]->data[it]=char(data[it+header]);
  3900. }
  3901. }
  3902. }
  3903. totalFragmentsReceived++;
  3904. if(totalFragmentsReceived==MAX_FRAG_PACKETS)
  3905. {
  3906. totalFragmentsReceived=0;
  3907. }
  3908. if(pendingFragments[index1]->recFragments==pendingFragments[index1]->totalFragments)
  3909. {
  3910. pendingFragments[index1]->complete=1;
  3911. }
  3912. temp=0;
  3913. temp2=0;
  3914. temp3=0;
  3915. aux=0;
  3916. while(temp<MAX_FINISH_PACKETS)
  3917. {
  3918. it=0;
  3919. time=millis();
  3920. if( (pendingFragments[temp]!=NULL) )
  3921. {
  3922. if ( (pendingFragments[temp]->time>0) )
  3923. {
  3924. if( ((time-pendingFragments[temp]->time)<=TIMEOUT) )
  3925. {
  3926. if ((pendingFragments[temp]->time>0) ) // se mira el contenido
  3927. {
  3928. if(pendingFragments[temp]->complete==1)
  3929. {
  3930. nextIndex1=temp;
  3931. indexNotModified=0;
  3932. pos++;
  3933. finishIndex=getFinishIndex();
  3934. if( pos>=MAX_FINISH_PACKETS ){
  3935. switch( replacementPolicy )
  3936. {
  3937. case XBEE_FIFO: finishIndex=getIndexFIFO();
  3938. break;
  3939. case XBEE_LIFO: finishIndex=getIndexLIFO();
  3940. break;
  3941. case XBEE_OUT: freeIndexMatrix(temp);
  3942. return -1;
  3943. break;
  3944. }
  3945. }
  3946. packet_finished[finishIndex] = (packetXBee*) calloc(1,sizeof(packetXBee));
  3947. if(packet_finished[finishIndex]==NULL){
  3948. freeIndexMatrix(temp);
  3949. return -1;
  3950. }
  3951. else pendingPackets--;
  3952. packet_finished[finishIndex]->time=pendingFragments[temp]->time;
  3953. packet_finished[finishIndex]->packetID=pendingFragments[temp]->packetID;
  3954. packet_finished[finishIndex]->address_typeS=pendingFragments[temp]->address_typeS;
  3955. packet_finished[finishIndex]->mode=pendingFragments[temp]->mode;
  3956. if(protocol==XBEE_802_15_4)
  3957. {
  3958. if(packet_finished[finishIndex]->address_typeS==_64B)
  3959. {
  3960. for(it=0;it<4;it++)
  3961. {
  3962. packet_finished[finishIndex]->macSH[it]=pendingFragments[temp]->macSH[it];
  3963. }
  3964. for(it=0;it<4;it++)
  3965. {
  3966. packet_finished[finishIndex]->macSL[it]=pendingFragments[temp]->macSL[it];
  3967. }
  3968. }
  3969. else if(packet_finished[finishIndex]->address_typeS==_16B)
  3970. {
  3971. packet_finished[finishIndex]->naS[0]=pendingFragments[temp]->naS[0];
  3972. packet_finished[finishIndex]->naS[1]=pendingFragments[temp]->naS[1];
  3973. }
  3974. }
  3975. else
  3976. {
  3977. for(it=0;it<4;it++)
  3978. {
  3979. packet_finished[finishIndex]->macSH[it]=pendingFragments[temp]->macSH[it];
  3980. }
  3981. for(it=0;it<4;it++)
  3982. {
  3983. packet_finished[finishIndex]->macSL[it]=pendingFragments[temp]->macSL[it];
  3984. }
  3985. packet_finished[finishIndex]->naS[0]=pendingFragments[temp]->naS[0];
  3986. packet_finished[finishIndex]->naS[1]=pendingFragments[temp]->naS[1];
  3987. }
  3988. aux=(pendingFragments[temp]->RSSI)/(pendingFragments[temp]->totalFragments);
  3989. packet_finished[finishIndex]->RSSI=aux;
  3990. packet_finished[finishIndex]->typeSourceID=pendingFragments[temp]->typeSourceID;
  3991. switch(packet_finished[finishIndex]->typeSourceID)
  3992. {
  3993. case MY_TYPE: packet_finished[finishIndex]->naO[0]=pendingFragments[temp]->naO[0];
  3994. packet_finished[finishIndex]->naO[1]=pendingFragments[temp]->naO[1];
  3995. break;
  3996. case MAC_TYPE: for(it=0;it<4;it++)
  3997. {
  3998. packet_finished[finishIndex]->macOH[it]=pendingFragments[temp]->macOH[it];
  3999. }
  4000. for(it=0;it<4;it++)
  4001. {
  4002. packet_finished[finishIndex]->macOL[it]=pendingFragments[temp]->macOL[it];
  4003. }
  4004. break;
  4005. case NI_TYPE: it=0;
  4006. do
  4007. {
  4008. packet_finished[finishIndex]->niO[it]=pendingFragments[temp]->niO[it];
  4009. it++;
  4010. } while(pendingFragments[temp]->niO[it]!=35);
  4011. packet_finished[finishIndex]->niO[it]=char(35);
  4012. break;
  4013. }
  4014. temp2=(pendingFragments[temp]->totalFragments)-1;
  4015. aux=0;
  4016. temp3=0;
  4017. while(temp2>=0)
  4018. {
  4019. for(it=0;it<packet_fragments[temp][temp2]->frag_length;it++)
  4020. {
  4021. packet_finished[finishIndex]->data[it+temp3]=packet_fragments[temp][temp2]->data[it];
  4022. aux++;
  4023. }
  4024. temp3=packet_fragments[temp][temp2]->frag_length+temp3;
  4025. temp2--;
  4026. }
  4027. packet_finished[finishIndex]->data_length=aux;
  4028. if(mode==CLUSTER)
  4029. {
  4030. packet_finished[finishIndex]->SD=pendingFragments[temp]->SD;
  4031. packet_finished[finishIndex]->DE=pendingFragments[temp]->DE;
  4032. packet_finished[finishIndex]->CID[0]=pendingFragments[temp]->CID[0];
  4033. packet_finished[finishIndex]->CID[1]=pendingFragments[temp]->CID[1];
  4034. packet_finished[finishIndex]->PID[0]=pendingFragments[temp]->PID[0];
  4035. packet_finished[finishIndex]->PID[1]=pendingFragments[temp]->PID[1];
  4036. }
  4037. // Vaciamos el index
  4038. for(it=0;it<MAX_FRAG_PACKETS;it++)
  4039. {
  4040. free(packet_fragments[temp][it]);
  4041. packet_fragments[temp][it]=NULL;
  4042. }
  4043. pendingFragments[temp]->time=0;
  4044. free(pendingFragments[temp]);
  4045. pendingFragments[temp]=NULL;
  4046. }
  4047. else if(pendingFragments[temp]->totalFragments==pendingFragments[temp]->recFragments)
  4048. {
  4049. for(it=0;it<MAX_FRAG_PACKETS;it++)
  4050. {
  4051. free(packet_fragments[temp][it]);
  4052. packet_fragments[temp][it]=NULL;
  4053. }
  4054. pendingFragments[temp]->time=0;
  4055. free(pendingFragments[temp]);
  4056. pendingFragments[temp]=NULL;
  4057. pendingPackets--;
  4058. nextIndex1=temp;
  4059. indexNotModified=0;
  4060. }
  4061. }
  4062. }
  4063. else // se borra la fila de la matriz y el correspondiente al vector indexador
  4064. {
  4065. for(it=0;it<MAX_FRAG_PACKETS;it++)
  4066. {
  4067. free(packet_fragments[temp][it]);
  4068. packet_fragments[temp][it]=NULL;
  4069. }
  4070. pendingFragments[temp]->time=0;
  4071. free(pendingFragments[temp]);
  4072. pendingFragments[temp]=NULL;
  4073. pendingPackets--;
  4074. nextIndex1=temp;
  4075. indexNotModified=0;
  4076. }
  4077. }
  4078. }
  4079. temp++;
  4080. }
  4081. temp=0;
  4082. return 0;
  4083. }
  4084. /*
  4085. Function: Generates the API frame to send to the XBee module
  4086. Parameters:
  4087. data : The string that contains part of the API frame
  4088. param : The param to set
  4089. Returns: Nothing
  4090. Values: Stores in 'command' variable the API frame to send to the XBee module
  4091. */
  4092. void WaspXBeeCore::gen_data(const char* data, uint8_t param)
  4093. {
  4094. uint8_t inc=0;
  4095. uint8_t inc2=0;
  4096. clearCommand();
  4097. it=0;
  4098. while(data[it] != '\0') {
  4099. inc++;
  4100. it++;
  4101. }
  4102. inc/=2;
  4103. while(inc2<inc){
  4104. command[inc2]=Utils.converter(data[2*inc2],data[2*inc2+1]);
  4105. inc2++;
  4106. }
  4107. command[inc-2]=param;
  4108. }
  4109. /*
  4110. Function: Generates the API frame to send to the XBee module
  4111. Parameters:
  4112. data : The string that contains part of the API frame
  4113. Returns: Nothing
  4114. Values: Stores in 'command' variable the API frame to send to the XBee module
  4115. */
  4116. void WaspXBeeCore::gen_data(const char* data)
  4117. {
  4118. uint8_t inc=0;
  4119. uint8_t inc2=0;
  4120. clearCommand();
  4121. it=0;
  4122. while(data[it] != '\0') {
  4123. inc++;
  4124. it++;
  4125. }
  4126. inc/=2;
  4127. while(inc2<inc){
  4128. command[inc2]=Utils.converter(data[2*inc2],data[2*inc2+1]);
  4129. inc2++;
  4130. }
  4131. }
  4132. /*
  4133. Function: Generates the API frame to send to the XBee module
  4134. Parameters:
  4135. data : The string that contains part of the API frame
  4136. param1 : The param to set
  4137. param2 : The param to set
  4138. Returns: Nothing
  4139. Values: Stores in 'command' variable the API frame to send to the XBee module
  4140. */
  4141. void WaspXBeeCore::gen_data(const char* data, uint8_t param1, uint8_t param2)
  4142. {
  4143. uint8_t inc=0;
  4144. uint8_t inc2=0;
  4145. clearCommand();
  4146. it=0;
  4147. while(data[it] != '\0') {
  4148. inc++;
  4149. it++;
  4150. }
  4151. inc/=2;
  4152. while(inc2<inc){
  4153. command[inc2]=Utils.converter(data[2*inc2],data[2*inc2+1]);
  4154. inc2++;
  4155. }
  4156. command[inc-3]=param1;
  4157. command[inc-2]=param2;
  4158. }
  4159. /*
  4160. Function: Generates the API frame to send to the XBee module
  4161. Parameters:
  4162. data : The string that contains part of the API frame
  4163. param : The param to set
  4164. Returns: Nothing
  4165. Values: Stores in 'command' variable the API frame to send to the XBee module
  4166. */
  4167. void WaspXBeeCore::gen_data(const char* data, uint8_t* param)
  4168. {
  4169. uint8_t inc=0;
  4170. uint8_t inc2=0;
  4171. clearCommand();
  4172. it=0;
  4173. while(data[it] != '\0') {
  4174. inc++;
  4175. it++;
  4176. }
  4177. inc/=2;
  4178. while(inc2<inc){
  4179. command[inc2]=Utils.converter(data[2*inc2],data[2*inc2+1]);
  4180. inc2++;
  4181. }
  4182. if(inc>11)
  4183. {
  4184. for(it=0;it<8;it++)
  4185. {
  4186. command[inc-9+it]=param[it];
  4187. }
  4188. }
  4189. else if(inc==11)
  4190. {
  4191. for(it=0;it<3;it++)
  4192. {
  4193. command[inc-4+it]=param[it];
  4194. }
  4195. }
  4196. else if(inc==10)
  4197. {
  4198. for(it=0;it<2;it++)
  4199. {
  4200. command[inc-3+it]=param[it];
  4201. }
  4202. }
  4203. else command[inc-2]=param[0];
  4204. }
  4205. /*
  4206. Function: Generates the API frame to send to the XBee module
  4207. Parameters:
  4208. data : The string that contains part of the API frame
  4209. param : The param to set
  4210. Returns: Nothing
  4211. Values: Stores in 'command' variable the API frame to send to the XBee module
  4212. */
  4213. void WaspXBeeCore::gen_data(const char* data, char* param)
  4214. {
  4215. gen_data(data,(uint8_t*) param);
  4216. }
  4217. /*
  4218. Function: Generates the checksum API frame to send to the XBee module
  4219. Parameters:
  4220. data : The string that contains part of the API frame
  4221. Returns: Nothing
  4222. Values: Stores in 'command' variable the checksum API frame to send to the XBee module
  4223. */
  4224. uint8_t WaspXBeeCore::gen_checksum(const char* data)
  4225. {
  4226. uint8_t inc=0;
  4227. uint8_t inc2=0;
  4228. uint8_t checksum=0;
  4229. it=0;
  4230. while(data[it] != '\0') {
  4231. inc++;
  4232. it++;
  4233. }
  4234. inc/=2;
  4235. for(it=3;it<inc;it++)
  4236. {
  4237. checksum=checksum+command[it];
  4238. }
  4239. while( (checksum>255))
  4240. {
  4241. checksum=checksum-256;
  4242. }
  4243. checksum=255-checksum;
  4244. command[inc-1]=checksum;
  4245. return checksum;
  4246. }
  4247. /*
  4248. Function: Sends the API frame stored in 'command' variable to the XBee module
  4249. Parameters:
  4250. data : The string that contains part of the API frame
  4251. Returns: Integer that determines if there has been any error
  4252. error=2 --> The command has not been executed
  4253. error=1 --> There has been an error while executing the command
  4254. error=0 --> The command has been executed with no errors
  4255. */
  4256. uint8_t WaspXBeeCore::gen_send(const char* data)
  4257. {
  4258. uint8_t inc=0;
  4259. uint8_t inc2=0;
  4260. uint8_t checksum=0;
  4261. uint8_t counter3=0;
  4262. uint8_t undesired=0;
  4263. uint8_t status=0;
  4264. uint8_t num_max=0;
  4265. int8_t error_int=2;
  4266. uint8_t est=1;
  4267. uint8_t frame_ID=data[4];
  4268. it=0;
  4269. while(data[it] != '\0') {
  4270. inc++;
  4271. it++;
  4272. }
  4273. inc/=2;
  4274. while(inc2<inc)
  4275. {
  4276. XBee.print(command[inc2], BYTE);
  4277. inc2++;
  4278. }
  4279. inc2=0;
  4280. error_int=parse_message(command);
  4281. return error_int;
  4282. }
  4283. /*
  4284. Function: Generates the API frame when a TX is done
  4285. Parameters:
  4286. _packet : the packetXBee structure where the data to send is stored
  4287. TX_array : the array where the API frame is stored
  4288. start_pos : starting position in API frame
  4289. Returns: Nothing
  4290. */
  4291. void WaspXBeeCore::gen_frame(struct packetXBee* _packet, uint8_t* TX_array, uint8_t start_pos)
  4292. {
  4293. uint16_t counter1=0;
  4294. if(_packet->endFragment==1)
  4295. {
  4296. TX_array[start_pos]=0x23;
  4297. switch(_packet->typeSourceID)
  4298. {
  4299. case MY_TYPE: TX_array[start_pos+1]=_packet->typeSourceID;
  4300. TX_array[start_pos+2]=_packet->naO[0];
  4301. TX_array[start_pos+3]=_packet->naO[1];
  4302. for(it=0;it<(finish-start+1);it++) // data
  4303. {
  4304. TX_array[it+start_pos+4]=uint8_t(_packet->data[it+start]);
  4305. }
  4306. break;
  4307. case MAC_TYPE: TX_array[start_pos+1]=_packet->typeSourceID;
  4308. for(it=0;it<4;it++)
  4309. {
  4310. TX_array[start_pos+2+it]=_packet->macOH[it];
  4311. }
  4312. for(it=0;it<4;it++)
  4313. {
  4314. TX_array[start_pos+6+it]=_packet->macOL[it];
  4315. }
  4316. for(it=0;it<(finish-start+1);it++) // data
  4317. {
  4318. TX_array[it+start_pos+10]=uint8_t(_packet->data[it+start]);
  4319. }
  4320. break;
  4321. case NI_TYPE: TX_array[start_pos+1]=_packet->typeSourceID;
  4322. while(_packet->niO[it]!='#'){
  4323. counter1++;
  4324. it++;
  4325. }
  4326. counter1++;
  4327. for(it=0;it<counter1;it++)
  4328. {
  4329. TX_array[start_pos+2+it]=uint8_t(_packet->niO[it]);
  4330. }
  4331. for(it=0;it<(finish-start+1);it++) // data
  4332. {
  4333. TX_array[it+start_pos+2+counter1]=uint8_t(_packet->data[it+start]);
  4334. }
  4335. break;
  4336. default: break;
  4337. }
  4338. }
  4339. else
  4340. {
  4341. switch(_packet->typeSourceID)
  4342. {
  4343. case MY_TYPE: TX_array[start_pos]=_packet->typeSourceID;
  4344. TX_array[start_pos+1]=_packet->naO[0];
  4345. TX_array[start_pos+2]=_packet->naO[1];
  4346. for(it=0;it<(finish-start+1);it++) // data
  4347. {
  4348. TX_array[it+start_pos+3]=uint8_t(_packet->data[it+start]);
  4349. }
  4350. break;
  4351. case MAC_TYPE: TX_array[start_pos]=_packet->typeSourceID;
  4352. for(it=0;it<4;it++)
  4353. {
  4354. TX_array[start_pos+1+it]=_packet->macOH[it];
  4355. }
  4356. for(it=0;it<4;it++)
  4357. {
  4358. TX_array[start_pos+5+it]=_packet->macOL[it];
  4359. }
  4360. for(it=0;it<(finish-start+1);it++) // data
  4361. {
  4362. TX_array[it+start_pos+9]=uint8_t(_packet->data[it+start]);
  4363. }
  4364. break;
  4365. case NI_TYPE: TX_array[start_pos]=_packet->typeSourceID;
  4366. while(_packet->niO[it]!='#'){
  4367. counter1++;
  4368. it++;
  4369. }
  4370. counter1++;
  4371. for(it=0;it<counter1;it++)
  4372. {
  4373. TX_array[start_pos+1+it]=uint8_t(_packet->niO[it]);
  4374. }
  4375. for(it=0;it<(finish-start+1);it++) // data
  4376. {
  4377. TX_array[it+start_pos+1+counter1]=uint8_t(_packet->data[it+start]);
  4378. }
  4379. break;
  4380. default: break;
  4381. }
  4382. }
  4383. }
  4384. /*
  4385. Function: Generates the eschaped API frame when a TX is done
  4386. Parameters:
  4387. _packet : the packetXBee structure where the data to send is stored
  4388. TX_array : the array where the API frame is stored
  4389. protect : specifies the number of chars that had been eschaped
  4390. type : specifies the type of send
  4391. Returns: Nothing
  4392. */
  4393. void WaspXBeeCore::gen_frame_ap2(struct packetXBee* _packet, uint8_t* TX_array, uint8_t &protect, uint8_t type)
  4394. {
  4395. uint8_t a=1;
  4396. uint8_t final=0;
  4397. uint8_t unico=0;
  4398. uint16_t aux=0;
  4399. uint16_t aux2=0;
  4400. while(a<(_packet->frag_length+type+protect))
  4401. {
  4402. if( (TX_array[a]==17) && (unico==0) )
  4403. {
  4404. TX_array[a]=49;
  4405. protect++;
  4406. aux=TX_array[a];
  4407. TX_array[a]=125;
  4408. uint16_t l=a-1;
  4409. while(final==0)
  4410. {
  4411. aux2=TX_array[l+2];
  4412. TX_array[l+2]=aux;
  4413. if( ((l+3)>=(_packet->frag_length+type+protect)) )
  4414. {
  4415. final=1;
  4416. break;
  4417. }
  4418. aux=TX_array[l+3];
  4419. TX_array[l+3]=aux2;
  4420. if( ((l+4)>=(_packet->frag_length+type+protect)) )
  4421. {
  4422. final=1;
  4423. break;
  4424. }
  4425. l++;
  4426. l++;
  4427. }
  4428. final=0;
  4429. unico=1;
  4430. }
  4431. if( (TX_array[a]==19) && (unico==0) )
  4432. {
  4433. TX_array[a]=51;
  4434. protect++;
  4435. aux=TX_array[a];
  4436. TX_array[a]=125;
  4437. uint16_t l=a-1;
  4438. while(final==0)
  4439. {
  4440. aux2=TX_array[l+2];
  4441. TX_array[l+2]=aux;
  4442. if( ((l+3)>=(_packet->frag_length+type+protect)) )
  4443. {
  4444. final=1;
  4445. break;
  4446. }
  4447. aux=TX_array[l+3];
  4448. TX_array[l+3]=aux2;
  4449. if( ((l+4)>=(_packet->frag_length+type+protect)) )
  4450. {
  4451. final=1;
  4452. break;
  4453. }
  4454. l++;
  4455. l++;
  4456. }
  4457. final=0;
  4458. unico=1;
  4459. }
  4460. if( (TX_array[a]==126) && (unico==0) )
  4461. {
  4462. TX_array[a]=94;
  4463. protect++;
  4464. aux=TX_array[a];
  4465. TX_array[a]=125;
  4466. uint16_t l=a-1;
  4467. while(final==0)
  4468. {
  4469. aux2=TX_array[l+2];
  4470. TX_array[l+2]=aux;
  4471. if( ((l+3)>=(_packet->frag_length+type+protect)) )
  4472. {
  4473. final=1;
  4474. break;
  4475. }
  4476. aux=TX_array[l+3];
  4477. TX_array[l+3]=aux2;
  4478. if( ((l+4)>=(_packet->frag_length+type+protect)) )
  4479. {
  4480. final=1;
  4481. break;
  4482. }
  4483. l++;
  4484. l++;
  4485. }
  4486. final=0;
  4487. unico=1;
  4488. }
  4489. if( (TX_array[a]==125) && (unico==0) )
  4490. {
  4491. TX_array[a]=93;
  4492. protect++;
  4493. aux=TX_array[a];
  4494. TX_array[a]=125;
  4495. uint16_t l=a-1;
  4496. while(final==0)
  4497. {
  4498. aux2=TX_array[l+2];
  4499. TX_array[l+2]=aux;
  4500. if( ((l+3)>=(_packet->frag_length+type+protect)) )
  4501. {
  4502. final=1;
  4503. break;
  4504. }
  4505. aux=TX_array[l+3];
  4506. TX_array[l+3]=aux2;
  4507. if( ((l+4)>=(_packet->frag_length+type+protect)) )
  4508. {
  4509. final=1;
  4510. break;
  4511. }
  4512. l++;
  4513. l++;
  4514. }
  4515. final=0;
  4516. unico=1;
  4517. }
  4518. a++;
  4519. unico=0;
  4520. }
  4521. }
  4522. /*
  4523. Function: Parses the answer received by the XBee module, calling the appropriate function
  4524. Parameters:
  4525. frame : an array that contains the API frame that is expected to receive answer from if it is an AT command
  4526. Returns: Integer that determines if there has been any error
  4527. error=2 --> The command has not been executed
  4528. error=1 --> There has been an error while executing the command
  4529. error=0 --> The command has been executed with no errors
  4530. */
  4531. int8_t WaspXBeeCore::parse_message(uint8_t* frame)
  4532. {
  4533. uint8_t* memory = (uint8_t*) calloc(MAX_PARSE,sizeof(uint8_t));
  4534. if( memory==NULL ){
  4535. XBee.flush();
  4536. return -1;
  4537. }
  4538. uint16_t i=0;
  4539. long previous=millis();
  4540. long previous2=millis();
  4541. uint8_t num_mes=0;
  4542. uint8_t num_esc=0;
  4543. uint16_t num_data=0;
  4544. uint16_t length_mes=0;
  4545. uint16_t length_prev=0;
  4546. int8_t error=2;
  4547. long interval=50;
  4548. long intervalMAX=40000;
  4549. uint8_t good_frame=0;
  4550. uint8_t maxFrame=30;
  4551. long auxiliar = 0;
  4552. // If a frame was truncated before, we set the first byte
  4553. if( frameNext ){
  4554. frameNext=0;
  4555. memory[0]=0x7E;
  4556. i=1;
  4557. num_mes=1;
  4558. }
  4559. // If it is a TX we have a different behaviour
  4560. if( frame[0]==0xFF ){
  4561. error_TX=txStatusResponse(memory);
  4562. free(memory);
  4563. memory=NULL;
  4564. return error_TX;
  4565. }
  4566. else if( frame[0]==0xFE ){
  4567. error_TX=txZBStatusResponse(memory);
  4568. free(memory);
  4569. memory=NULL;
  4570. return error_TX;
  4571. }
  4572. // If a RX we reduce the interval
  4573. if( frame[0]==0xEE ){
  4574. interval=5;
  4575. maxFrame=109;
  4576. }
  4577. // Check if a ED is performed
  4578. if( frame[5]==0x45 && frame[6]==0x44 && protocol==XBEE_802_15_4 ) interval=3000;
  4579. // Check if a DN is performed
  4580. if( frame[5]==0x44 && frame[6]==0x4E ) interval=1000;
  4581. // Check if a ND is performed
  4582. if( frame[5]==0x4E && frame[6]==0x44 ){
  4583. interval=20000;
  4584. if(protocol==DIGIMESH) interval=40000;
  4585. else if( (protocol==XBEE_900) || (protocol==XBEE_868) )
  4586. {
  4587. interval=14000;
  4588. }
  4589. }
  4590. // Read data from XBee meanwhile data is available
  4591. previous2=millis();
  4592. previous=millis();
  4593. while( ((millis()-previous)<interval) && ((millis()-previous2)<intervalMAX) && i<MAX_PARSE && !frameNext )
  4594. {
  4595. if(XBee.available())
  4596. {
  4597. memory[i]=XBee.read();
  4598. i++;
  4599. if(memory[i-1]==0x7E){
  4600. if( (MAX_PARSE-i) < maxFrame ) frameNext=1;
  4601. else num_mes++;
  4602. }
  4603. previous=millis();
  4604. }
  4605. if( millis()-previous < 0 ) previous=millis();
  4606. if( millis()-previous2 < 0 ) previous2=millis();
  4607. }
  4608. num_data=i;
  4609. i=1;
  4610. // If some corrupted frame has appeared we jump it
  4611. if( memory[0]!=0x7E ) num_mes++;
  4612. // Parse the received messages from the XBee
  4613. while( num_mes>0 )
  4614. {
  4615. while( memory[i]!=0x7E && i<num_data ) i++;
  4616. length_mes=i-length_prev;
  4617. // If some char has been eschaped, it must be converted before parsing it
  4618. for( it=0;it<length_mes;it++ )
  4619. {
  4620. if( memory[it+length_prev]==0x7D ) num_esc++;
  4621. }
  4622. if( num_esc ) des_esc(memory,length_mes,i-length_mes);
  4623. switch( memory[(i-length_mes)+3] )
  4624. {
  4625. case 0x88 : error=atCommandResponse(memory,frame,length_mes-num_esc+length_prev,i-length_mes);
  4626. error_AT=error;
  4627. break;
  4628. case 0x8A : error=modemStatusResponse(memory,length_mes-num_esc+length_prev,i-length_mes);
  4629. break;
  4630. case 0x80 : error=rxData(memory,length_mes-num_esc+length_prev,i-length_mes);
  4631. error_RX=error;
  4632. break;
  4633. case 0x81 : error=rxData(memory,length_mes-num_esc+length_prev,i-length_mes);
  4634. error_RX=error;
  4635. break;
  4636. case 0x90 : error=rxData(memory,length_mes-num_esc+length_prev,i-length_mes);
  4637. error_RX=error;
  4638. break;
  4639. case 0x91 : error=rxData(memory,length_mes-num_esc+length_prev,i-length_mes);
  4640. error_RX=error;
  4641. break;
  4642. default : break;
  4643. }
  4644. num_mes--;
  4645. length_prev=i;
  4646. i++;
  4647. num_esc=0;
  4648. if(!error) good_frame++;
  4649. }
  4650. free(memory);
  4651. memory=NULL;
  4652. if(good_frame) return 0;
  4653. else return error;
  4654. }
  4655. /*
  4656. Function: Generates the correct API frame from an eschaped one
  4657. Parameters:
  4658. data_in : The string that contains the eschaped API frame
  4659. end : the end of the frame
  4660. start : the start of the frame
  4661. Returns: Nothing
  4662. */
  4663. void WaspXBeeCore::des_esc(uint8_t* data_in, uint16_t end, uint16_t start)
  4664. {
  4665. uint16_t i=0;
  4666. uint16_t aux=0;
  4667. while( i<end )
  4668. {
  4669. while( data_in[start+i]!=0x7D && i<end ) i++;
  4670. if( i<end )
  4671. {
  4672. aux=i+1;
  4673. switch( data_in[start+i+1] )
  4674. {
  4675. case 0x31 : data_in[start+i]=0x11;
  4676. break;
  4677. case 0x33 : data_in[start+i]=0x13;
  4678. break;
  4679. case 0x5E : data_in[start+i]=0x7E;
  4680. break;
  4681. case 0x5D : data_in[start+i]=0x7D;
  4682. break;
  4683. }
  4684. i++;
  4685. end--;
  4686. while( i<(end) ){
  4687. data_in[start+i]=data_in[start+i+1];
  4688. i++;
  4689. }
  4690. i=aux;
  4691. }
  4692. }
  4693. }
  4694. /*
  4695. Function: Parses the AT command answer received by the XBee module
  4696. Parameters:
  4697. data_in : the answer received by the module
  4698. frame : an array that contains the API frame that is expected to receive answer from if it is an AT command
  4699. end : the end of the frame
  4700. start : the start of the frame
  4701. Returns: Integer that determines if there has been any error
  4702. error=2 --> The command has not been executed
  4703. error=1 --> There has been an error while executing the command
  4704. error=0 --> The command has been executed with no errors
  4705. */
  4706. uint8_t WaspXBeeCore::atCommandResponse(uint8_t* data_in, uint8_t* frame, uint16_t end, uint16_t start)
  4707. {
  4708. // Check the checksum
  4709. if(checkChecksum(data_in,end,start)) return 1;
  4710. // Check the AT Command Response is from the command expected
  4711. if( data_in[start+5]!=frame[5] || data_in[start+6]!=frame[6] ) return 1;
  4712. // Check if there is data in the AT Command Response frame
  4713. if( (end-start)==9 ){
  4714. if( data_in[start+7]==0 ) return 0;
  4715. else return 1;
  4716. }
  4717. if( data_in[start+7]!=0 ) return 1;
  4718. // Store the data in the response frame
  4719. for(it=0;it<(end-start-9);it++)
  4720. {
  4721. data[it]=data_in[8+it+start];
  4722. }
  4723. // Check if a ND is performed
  4724. data_length=end-start-9;
  4725. if( frame[5]==0x4E && frame[6]==0x44 ){
  4726. if( data_length>1 ) totalScannedBrothers++;
  4727. treatScan();
  4728. }
  4729. return 0;
  4730. }
  4731. /*
  4732. Function: Parses the Modem Status message received by the XBee module
  4733. Parameters:
  4734. data_in : the answer received by the module
  4735. end : the end of the frame
  4736. start : the start of the frame
  4737. Returns: Integer that determines if there has been any error
  4738. error=2 --> The command has not been executed
  4739. error=1 --> There has been an error while executing the command
  4740. error=0 --> The command has been executed with no errors
  4741. */
  4742. uint8_t WaspXBeeCore::modemStatusResponse(uint8_t* data_in, uint16_t end, uint16_t start)
  4743. {
  4744. // Check the checksum
  4745. if(checkChecksum(data_in,end,start)) return 1;
  4746. modem_status=data_in[start+4];
  4747. return 0;
  4748. }
  4749. /*
  4750. Function: Parses the TX Status message received by the XBee module
  4751. Parameters:
  4752. data_in : the answer received by the module
  4753. end : the end of the frame
  4754. start : the start of the frame
  4755. Returns: Integer that determines if there has been any error
  4756. error=2 --> The command has not been executed
  4757. error=1 --> There has been an error while executing the command
  4758. error=0 --> The command has been executed with no errors
  4759. */
  4760. uint8_t WaspXBeeCore::txStatusResponse(uint8_t* ByteIN)
  4761. {
  4762. long previous=millis();
  4763. uint16_t numberBytes=7;
  4764. uint8_t end=0;
  4765. uint16_t counter3=0;
  4766. uint8_t undesired=0;
  4767. uint8_t status=0;
  4768. uint16_t num_TX=0;
  4769. uint8_t num_esc=0;
  4770. int16_t interval=2000;
  4771. uint8_t num_mes=0;
  4772. uint16_t i=1;
  4773. uint16_t length_mes=0;
  4774. uint16_t length_prev=0;
  4775. uint8_t maxFrame=110;
  4776. error_TX=2;
  4777. if( frameNext )
  4778. {
  4779. ByteIN[0]=0x7E;
  4780. counter3=1;
  4781. num_mes=1;
  4782. frameNext=0;
  4783. }
  4784. while( end==0 && !frameNext )
  4785. {
  4786. if(XBee.available()>0)
  4787. {
  4788. ByteIN[counter3]=XBee.read();
  4789. counter3++;
  4790. previous=millis();
  4791. if(ByteIN[counter3-1]==0x7E){
  4792. if( (MAX_PARSE-counter3) < maxFrame ) frameNext=1;
  4793. else num_mes++;
  4794. }
  4795. if( (counter3==1) && (ByteIN[counter3-1]!=0x7E) ) counter3=0;
  4796. if( counter3>=MAX_PARSE ) end=1;
  4797. if( (counter3==4+status*6+undesired) && (undesired!=1) ) //FIXME
  4798. {
  4799. if( (ByteIN[counter3-1]!= 0x89) && (ByteIN[counter3-1]!=0x8A) ){
  4800. undesired=1;
  4801. numberBytes+=3;
  4802. }
  4803. }
  4804. if( undesired==1 ) numberBytes++;
  4805. if( (ByteIN[counter3-1]==0x7D) && (!undesired) )
  4806. {
  4807. numberBytes++;
  4808. }
  4809. if( (ByteIN[counter3-1]==0x8A) && (counter3==(4+status*6)) )
  4810. {
  4811. numberBytes+=6;
  4812. status++;
  4813. }
  4814. if( (ByteIN[counter3-1]==0x7E) && (undesired==1) )
  4815. {
  4816. numberBytes--;
  4817. undesired=numberBytes-7;
  4818. }
  4819. if(counter3==numberBytes)
  4820. {
  4821. end=1;
  4822. }
  4823. }
  4824. if( millis()-previous < 0 ) previous=millis();
  4825. if( (millis()-previous) > interval )
  4826. {
  4827. end=1;
  4828. XBee.flush();
  4829. }
  4830. }
  4831. num_TX=counter3;
  4832. counter3=0;
  4833. // If some corrupted frame has appeared we jump it
  4834. if( ByteIN[0]!=0x7E ) num_mes++;
  4835. // Parse the received messages from the XBee
  4836. while( num_mes>0 )
  4837. {
  4838. while( ByteIN[i]!=0x7E && i<num_TX ) i++;
  4839. length_mes=i-length_prev;
  4840. // If some char has been eschaped, it must be converted before parsing it
  4841. for( it=0;it<length_mes;it++)
  4842. {
  4843. if( ByteIN[it+length_prev]==0x7D ) num_esc++;
  4844. }
  4845. if( num_esc ) des_esc(ByteIN,length_mes,i-length_mes);
  4846. switch( ByteIN[(i-length_mes)+3] )
  4847. {
  4848. case 0x8A : modemStatusResponse(ByteIN,length_mes-num_esc+length_prev,i-length_mes);
  4849. break;
  4850. case 0x80 : error_RX=rxData(ByteIN,length_mes-num_esc+length_prev,i-length_mes);
  4851. break;
  4852. case 0x81 : error_RX=rxData(ByteIN,length_mes-num_esc+length_prev,i-length_mes);
  4853. break;
  4854. case 0x89 : delivery_status=ByteIN[i-length_mes+5];
  4855. if( delivery_status==0 ) error_TX=0;
  4856. else error_TX=1;
  4857. break;
  4858. default : break;
  4859. }
  4860. num_mes--;
  4861. length_prev=i;
  4862. i++;
  4863. num_esc=0;
  4864. }
  4865. return error_TX;
  4866. }
  4867. /*
  4868. Function: Parses the ZB TX Status message received by the XBee module
  4869. Parameters:
  4870. data_in : the answer received by the module
  4871. end : the end of the frame
  4872. start : the start of the frame
  4873. Returns: Integer that determines if there has been any error
  4874. error=2 --> The command has not been executed
  4875. error=1 --> There has been an error while executing the command
  4876. error=0 --> The command has been executed with no errors
  4877. */
  4878. uint8_t WaspXBeeCore::txZBStatusResponse(uint8_t* ByteIN)
  4879. {
  4880. long previous=millis();
  4881. uint16_t numberBytes=11;
  4882. uint8_t end=0;
  4883. uint16_t counter3=0;
  4884. uint8_t undesired=0;
  4885. uint8_t status=0;
  4886. uint16_t num_TX=0;
  4887. uint8_t num_esc=0;
  4888. int16_t interval=2000;
  4889. uint8_t num_mes=0;
  4890. uint16_t i=1;
  4891. uint16_t length_mes=0;
  4892. uint16_t length_prev=0;
  4893. uint8_t maxFrame=110;
  4894. error_TX=2;
  4895. if( frameNext )
  4896. {
  4897. ByteIN[0]=0x7E;
  4898. counter3=1;
  4899. num_mes=1;
  4900. frameNext=0;
  4901. }
  4902. while( end==0 && !frameNext )
  4903. {
  4904. if(XBee.available()>0)
  4905. {
  4906. ByteIN[counter3]=XBee.read();
  4907. counter3++;
  4908. previous=millis();
  4909. if(ByteIN[counter3-1]==0x7E){
  4910. if( (MAX_PARSE-counter3) < maxFrame ) frameNext=1;
  4911. else num_mes++;
  4912. }
  4913. if( (counter3==1) && (ByteIN[counter3-1]!=0x7E) ) counter3=0;
  4914. if( counter3>=MAX_PARSE ) end=1;
  4915. if( (counter3==4+status*6+undesired) && (undesired!=1) ) //FIXME
  4916. {
  4917. if( (ByteIN[counter3-1]!= 0x8B) && (ByteIN[counter3-1]!=0x8A) ){
  4918. undesired=1;
  4919. numberBytes+=3;
  4920. }
  4921. }
  4922. if( undesired==1 ) numberBytes++;
  4923. if( (ByteIN[counter3-1]==0x7D) && (!undesired) )
  4924. {
  4925. numberBytes++;
  4926. }
  4927. if( (ByteIN[counter3-1]==0x8A) && (counter3==(4+status*6)) )
  4928. {
  4929. numberBytes+=6;
  4930. status++;
  4931. }
  4932. if( (ByteIN[counter3-1]==0x7E) && (undesired==1) )
  4933. {
  4934. numberBytes--;
  4935. undesired=numberBytes-7;
  4936. }
  4937. if(counter3==numberBytes)
  4938. {
  4939. end=1;
  4940. }
  4941. }
  4942. if( millis()-previous < 0 ) previous=millis();
  4943. if( (millis()-previous) > interval )
  4944. {
  4945. end=1;
  4946. XBee.flush();
  4947. }
  4948. }
  4949. num_TX=counter3;
  4950. counter3=0;
  4951. // If some corrupted frame has appeared we jump it
  4952. if( ByteIN[0]!=0x7E ) num_mes++;
  4953. // Parse the received messages from the XBee
  4954. while( num_mes>0 )
  4955. {
  4956. while( ByteIN[i]!=0x7E && i<num_TX ) i++;
  4957. length_mes=i-length_prev;
  4958. // If some char has been eschaped, it must be converted before parsing it
  4959. for( it=0;it<length_mes;it++)
  4960. {
  4961. if( ByteIN[it+length_prev]==0x7D ) num_esc++;
  4962. }
  4963. if( num_esc ) des_esc(ByteIN,length_mes,i-length_mes);
  4964. switch( ByteIN[(i-length_mes)+3] )
  4965. {
  4966. case 0x8A : modemStatusResponse(ByteIN,length_mes-num_esc+length_prev,i-length_mes);
  4967. break;
  4968. case 0x90 : error_RX=rxData(ByteIN,length_mes-num_esc+length_prev,i-length_mes);
  4969. break;
  4970. case 0x91 : error_RX=rxData(ByteIN,length_mes-num_esc+length_prev,i-length_mes);
  4971. break;
  4972. case 0x8B : true_naD[0]=ByteIN[i-length_mes+5];
  4973. true_naD[1]=ByteIN[i-length_mes+6];
  4974. retries_sending=ByteIN[i-length_mes+7];
  4975. discovery_status=ByteIN[i-length_mes+9];
  4976. delivery_status=ByteIN[i-length_mes+8];
  4977. if( delivery_status==0 ) error_TX=0;
  4978. else error_TX=1;
  4979. break;
  4980. default : break;
  4981. }
  4982. num_mes--;
  4983. length_prev=i;
  4984. i++;
  4985. num_esc=0;
  4986. }
  4987. return error_TX;
  4988. }
  4989. /*
  4990. Function: Parses the RX Data message received by the XBee module
  4991. Parameters:
  4992. data_in : the answer received by the module
  4993. end : the end of the frame
  4994. start : the start of the frame
  4995. Returns: Integer that determines if there has been any error
  4996. error=2 --> The command has not been executed
  4997. error=1 --> There has been an error while executing the command
  4998. error=0 --> The command has been executed with no errors
  4999. */
  5000. int8_t WaspXBeeCore::rxData(uint8_t* data_in, uint16_t end, uint16_t start)
  5001. {
  5002. uint8_t* byteIN = (uint8_t*) calloc(120,sizeof(uint8_t));
  5003. int8_t error=2;
  5004. // Check the checksum
  5005. if(checkChecksum(data_in,end,start)){
  5006. free(byteIN);
  5007. byteIN=NULL;
  5008. return 1;
  5009. }
  5010. // Copy the data
  5011. data_length=0;
  5012. for(it=4+start;it<end-1;it++)
  5013. {
  5014. byteIN[it-4-start]=data_in[it];
  5015. data_length++;
  5016. }
  5017. switch( data_in[start+3] )
  5018. {
  5019. case 0x80 : add_type=_64B;
  5020. break;
  5021. case 0x81 : add_type=_16B;
  5022. break;
  5023. case 0x90 : mode=UNICAST;
  5024. break;
  5025. case 0x91 : mode=CLUSTER;
  5026. break;
  5027. }
  5028. error=readXBee(byteIN);
  5029. free(byteIN);
  5030. byteIN=NULL;
  5031. return error;
  5032. }
  5033. /*
  5034. Function: Parses the ND message received by the XBee module
  5035. Values: Stores in 'scannedBrothers' variable the data extracted from the answer
  5036. */
  5037. void WaspXBeeCore::treatScan()
  5038. {
  5039. uint8_t cont2=0;
  5040. uint8_t length_NI=data_length-19;
  5041. if(protocol==XBEE_802_15_4)
  5042. {
  5043. cont2=totalScannedBrothers-1;
  5044. for(it=0;it<2;it++)
  5045. {
  5046. scannedBrothers[cont2].MY[it]=data[it];
  5047. }
  5048. for(it=0;it<4;it++)
  5049. {
  5050. scannedBrothers[cont2].SH[it]=data[it+2];
  5051. }
  5052. for(it=0;it<4;it++)
  5053. {
  5054. scannedBrothers[cont2].SL[it]=data[it+6];
  5055. }
  5056. scannedBrothers[cont2].RSSI=data[10];
  5057. if (data_length>12)
  5058. {
  5059. for(it=0;it<(data_length-12);it++)
  5060. {
  5061. scannedBrothers[cont2].NI[it]=char(data[it+11]);
  5062. }
  5063. }
  5064. }
  5065. if( (protocol==ZIGBEE) || (protocol==DIGIMESH) || (protocol==XBEE_900) || (protocol==XBEE_868) )
  5066. {
  5067. cont2=totalScannedBrothers-1;
  5068. for(it=0;it<2;it++)
  5069. {
  5070. scannedBrothers[cont2].MY[it]=data[it];
  5071. }
  5072. for(it=0;it<4;it++)
  5073. {
  5074. scannedBrothers[cont2].SH[it]=data[it+2];
  5075. }
  5076. for(it=0;it<4;it++)
  5077. {
  5078. scannedBrothers[cont2].SL[it]=data[it+6];
  5079. }
  5080. for(it=0;it<length_NI;it++)
  5081. {
  5082. scannedBrothers[cont2].NI[it]=char(data[it+10]);
  5083. }
  5084. for(it=0;it<2;it++)
  5085. {
  5086. scannedBrothers[cont2].PMY[it]=data[it+length_NI+11];
  5087. }
  5088. scannedBrothers[cont2].DT=data[length_NI+13];
  5089. scannedBrothers[cont2].ST=data[length_NI+14];
  5090. for(it=0;it<2;it++)
  5091. {
  5092. scannedBrothers[cont2].PID[it]=data[it+length_NI+15];
  5093. }
  5094. for(it=0;it<2;it++)
  5095. {
  5096. scannedBrothers[cont2].MID[it]=data[it+length_NI+17];
  5097. }
  5098. }
  5099. }
  5100. /*
  5101. Function: Checks the checksum is good
  5102. Parameters:
  5103. data_in : the answer received by the module
  5104. end : the end of the frame
  5105. start : the start of the frame
  5106. Returns: Integer that determines if there has been any error
  5107. error=2 --> The command has not been executed
  5108. error=1 --> There has been an error while executing the command
  5109. error=0 --> The command has been executed with no errors
  5110. */
  5111. uint8_t WaspXBeeCore::checkChecksum(uint8_t* data_in, uint16_t end, uint16_t start)
  5112. {
  5113. uint16_t checksum=0;
  5114. for(it=3+start;it<end;it++)
  5115. {
  5116. checksum=checksum+data_in[it];
  5117. }
  5118. if( (checksum==255) ) return 0;
  5119. checksum%=256;
  5120. if( checksum!=255 ) return 1;
  5121. return 0;
  5122. }
  5123. /*
  5124. Function: Clears the variable 'command'
  5125. */
  5126. void WaspXBeeCore::clearCommand()
  5127. {
  5128. for(it=0;it<30;it++)
  5129. {
  5130. command[it]=0;
  5131. }
  5132. }
  5133. /*
  5134. Function: It frees a position in index array
  5135. */
  5136. void WaspXBeeCore::freeIndex()
  5137. {
  5138. uint16_t counter1=0;
  5139. nextIndex1=0;
  5140. while( counter1<MAX_FINISH_PACKETS )
  5141. {
  5142. for(it=counter1;it<(MAX_FINISH_PACKETS-1);it++)
  5143. {
  5144. if( pendingFragments[counter1]->time < pendingFragments[it+1]->time ) nextIndex1++;
  5145. else break;
  5146. }
  5147. if( nextIndex1==(MAX_FINISH_PACKETS-1) ){
  5148. nextIndex1=counter1;
  5149. counter1=MAX_FINISH_PACKETS;
  5150. }
  5151. else nextIndex1=counter1+1;
  5152. counter1++;
  5153. }
  5154. for(it=0;it<MAX_FRAG_PACKETS;it++)
  5155. {
  5156. free(packet_fragments[nextIndex1][it]);
  5157. packet_fragments[nextIndex1][it]=NULL;
  5158. }
  5159. pendingFragments[nextIndex1]->time=0;
  5160. free(pendingFragments[nextIndex1]);
  5161. pendingFragments[nextIndex1]=NULL;
  5162. pendingPackets--;
  5163. indexNotModified=0;
  5164. }
  5165. /*
  5166. Function: It frees index array and matrix
  5167. */
  5168. void WaspXBeeCore::freeAll()
  5169. {
  5170. uint8_t temp=0;
  5171. for(temp=0;temp<MAX_FINISH_PACKETS;temp++)
  5172. {
  5173. for(it=0;it<MAX_FRAG_PACKETS;it++)
  5174. {
  5175. free(packet_fragments[temp][it]);
  5176. packet_fragments[temp][it]=NULL;
  5177. }
  5178. pendingFragments[temp]->time=0;
  5179. free(pendingFragments[temp]);
  5180. pendingFragments[temp]=NULL;
  5181. }
  5182. pendingPackets=0;
  5183. nextIndex1=0;
  5184. indexNotModified=0;
  5185. }
  5186. /*
  5187. Function: It gets the next index where store the finished packet
  5188. */
  5189. uint8_t WaspXBeeCore::getFinishIndex()
  5190. {
  5191. for(it=0;it<MAX_FINISH_PACKETS;it++)
  5192. {
  5193. if( packet_finished[it]==NULL ) break;
  5194. }
  5195. return it;
  5196. }
  5197. /*
  5198. Function: It clears the finished packets array
  5199. */
  5200. void WaspXBeeCore::clearFinishArray()
  5201. {
  5202. for(it=0;it<MAX_FINISH_PACKETS;it++)
  5203. {
  5204. free(packet_finished[it]);
  5205. packet_finished[it]=NULL;
  5206. }
  5207. }
  5208. /*
  5209. Function: It gets the index in 'packet_finished' where store the new packet, according to a FIFO policy
  5210. */
  5211. uint8_t WaspXBeeCore::getIndexFIFO()
  5212. {
  5213. uint8_t position=0;
  5214. uint16_t counter1=0;
  5215. while( counter1<MAX_FINISH_PACKETS )
  5216. {
  5217. for(it=counter1;it<(MAX_FINISH_PACKETS-1);it++)
  5218. {
  5219. if( packet_finished[counter1]->time < packet_finished[it+1]->time ) position++;
  5220. else break;
  5221. }
  5222. if( position==(MAX_FINISH_PACKETS-1) ){
  5223. position=counter1;
  5224. counter1=MAX_FINISH_PACKETS;
  5225. }
  5226. else position=counter1+1;
  5227. counter1++;
  5228. }
  5229. free(packet_finished[position]);
  5230. packet_finished[position]=NULL;
  5231. return position;
  5232. }
  5233. /*
  5234. Function: It gets the index in 'packet_finished' where store the new packet, according to a LIFO policy
  5235. */
  5236. uint8_t WaspXBeeCore::getIndexLIFO()
  5237. {
  5238. uint8_t position=0;
  5239. uint16_t counter1=0;
  5240. while( counter1<MAX_FINISH_PACKETS )
  5241. {
  5242. for(it=counter1;it<(MAX_FINISH_PACKETS-1);it++)
  5243. {
  5244. if( packet_finished[counter1]->time > packet_finished[it+1]->time ) position++;
  5245. else break;
  5246. }
  5247. if( position==(MAX_FINISH_PACKETS-1) ){
  5248. position=counter1;
  5249. counter1=MAX_FINISH_PACKETS;
  5250. }
  5251. else position=counter1+1;
  5252. counter1++;
  5253. }
  5254. free(packet_finished[position]);
  5255. packet_finished[position]=NULL;
  5256. return position;
  5257. }
  5258. /*
  5259. Function: It frees the index array and the matrix row corresponding to the position is sent as an input parameter
  5260. */
  5261. void WaspXBeeCore::freeIndexMatrix(uint8_t position)
  5262. {
  5263. for(it=0;it<MAX_FRAG_PACKETS;it++)
  5264. {
  5265. free(packet_fragments[position][it]);
  5266. packet_fragments[position][it]=NULL;
  5267. }
  5268. pendingFragments[position]->time=0;
  5269. free(pendingFragments[position]);
  5270. pendingFragments[position]=NULL;
  5271. pendingPackets--;
  5272. }
  5273. WaspXBeeCore xbee = WaspXBeeCore();