RedFly.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494
  1. /*
  2. RedFly Lib for Arduino
  3. by Watterott electronic (www.watterott.com)
  4. */
  5. #include <inttypes.h>
  6. #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
  7. # include <avr/io.h>
  8. # include <avr/pgmspace.h>
  9. # include <util/delay.h>
  10. #else
  11. # include <chip.h>
  12. # include <itoa.h>
  13. #endif
  14. #if ARDUINO >= 100
  15. # include "Arduino.h"
  16. #else
  17. # include "WProgram.h"
  18. #endif
  19. #include "digitalWriteFast.h"
  20. #include "RedFlyCommands.h"
  21. #include "RedFly.h"
  22. #include "RedFlyClient.h"
  23. #include "RedFlyServer.h"
  24. #include "RedFlyNBNS.h"
  25. #define RX_PIN UART_RX_PIN //0
  26. #define TX_PIN UART_TX_PIN //1
  27. #define RST_PIN 2
  28. #define CS_PIN 3
  29. #define RST_DISABLE() digitalWriteFast(RST_PIN, HIGH)
  30. #define RST_ENABLE() digitalWriteFast(RST_PIN, LOW)
  31. #define CS_DISABLE() digitalWriteFast(CS_PIN, HIGH)
  32. #define CS_ENABLE() digitalWriteFast(CS_PIN, LOW)
  33. #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
  34. # if defined(UBRRH) && defined(UBRRL)
  35. # define _UCSRA_ UCSRA
  36. # define _RXC_ RXC
  37. # define _UCSRC_ UCSRC
  38. # define _USBS_ USBS
  39. # define _SERIAL_ Serial
  40. # elif defined(UBRR0H) && !defined(UBRR0L)
  41. # define _UCSRA_ UCSR1A
  42. # define _RXC_ RXC1
  43. # define _UCSRC_ UCSR1C
  44. # define _USBS_ USBS1
  45. # define _SERIAL_ Serial1
  46. # else
  47. # define _UCSRA_ UCSR0A
  48. # define _RXC_ RXC0
  49. # define _UCSRC_ UCSR0C
  50. # define _USBS_ USBS0
  51. # define _SERIAL_ Serial
  52. # endif
  53. #else
  54. # define _SERIAL_ Serial
  55. # define _USART_ USART0
  56. #endif
  57. REDFLY RedFly;
  58. //-------------------- Constructor/Destructor --------------------
  59. REDFLY::REDFLY(void)
  60. {
  61. return;
  62. }
  63. REDFLY::~REDFLY(void)
  64. {
  65. return;
  66. }
  67. //-------------------- Public --------------------
  68. uint8_t REDFLY::init(uint32_t br, uint8_t pwr)
  69. {
  70. uint8_t ret=0xFF, i;
  71. uint32_t ms;
  72. //init pins
  73. #ifdef CS_PIN
  74. pinMode(CS_PIN, OUTPUT);
  75. CS_DISABLE(); //deselect
  76. #endif
  77. #ifdef RST_PIN
  78. pinMode(RST_PIN, OUTPUT);
  79. RST_ENABLE(); //reset on
  80. #endif
  81. #ifdef TX_PIN
  82. pinMode(TX_PIN, OUTPUT);
  83. digitalWrite(TX_PIN, HIGH);
  84. #endif
  85. #ifdef RX_PIN
  86. pinMode(RX_PIN, INPUT);
  87. digitalWrite(RX_PIN, HIGH); //pull-up on
  88. #endif
  89. //reset vars
  90. memset(ipaddr, 0, sizeof(ipaddr));
  91. memset(buffer, 0, sizeof(buffer));
  92. //set serial port config
  93. baudrate = br;
  94. setbaudrate(br);
  95. //enable module communication
  96. enable();
  97. //reset module
  98. RST_ENABLE();
  99. delay_10ms(5); //wait 50ms
  100. RST_DISABLE();
  101. //auto baud rate detection
  102. delay_10ms(11); //wait 110ms for module boot-up
  103. for(i=4; i!=0; i--) //try 4 times
  104. {
  105. write(0x1C); //transmit 0x1C
  106. for(ms=millis(); (millis()-ms) < 200;) //wait 200ms for response
  107. {
  108. if(available())
  109. {
  110. if(read() == 0x55) //wait for 0x55
  111. {
  112. write(0x55); //transmit 0x55
  113. delay_10ms(10); //wait 100ms
  114. //skip firmware upgrade question at power on
  115. write('n');
  116. write('\n');
  117. ret = 0xFE;
  118. i = 1; //break 1st for loop
  119. break; //break 2nd for loop
  120. }
  121. }
  122. }
  123. }
  124. delay_10ms(20); //wait 200ms for booting
  125. //get firmware version and set config
  126. // if(ret == 0xFE)
  127. // {
  128. for(i=3; i!=0; i--) //try 3 times
  129. {
  130. flush();
  131. if(cmd(PSTR(CMD_FWVERSION)) == 0)
  132. {
  133. //cmd(PSTR(CMD_RESET)); //soft reset
  134. cmd(PSTR(CMD_BAND BAND24));
  135. cmd(PSTR(CMD_INIT));
  136. tx_power = pwr;
  137. ret = 0;
  138. break;
  139. }
  140. delay_10ms(10);
  141. }
  142. // }
  143. if(ret)
  144. {
  145. disable();
  146. }
  147. return ret;
  148. }
  149. uint8_t REDFLY::init(uint8_t pwr) { return init(REDFLY_BAUDRATE, pwr); }
  150. uint8_t REDFLY::init(void) { return init(REDFLY_BAUDRATE, HIGH_POWER); }
  151. void REDFLY::enable(void) //select module
  152. {
  153. flush(); //clear buffers
  154. setbaudrate(baudrate);
  155. read_state = 0;
  156. CS_ENABLE();
  157. return;
  158. }
  159. void REDFLY::disable(void) //deselect module
  160. {
  161. flush(); //clear buffers
  162. read_state = 0;
  163. CS_DISABLE();
  164. return;
  165. }
  166. uint8_t REDFLY::getversion(char *ver) //return module firmware version
  167. {
  168. uint8_t ret;
  169. for(uint8_t i=3; i!=0; i--) //try 3 times
  170. {
  171. memset(buffer, 0, sizeof(buffer));
  172. ret = cmd(buffer, sizeof(buffer), PSTR(CMD_FWVERSION)); //OKa.b.c
  173. if(ret == 0)
  174. {
  175. //buffer[0] = 'O', buffer[1] = 'K'
  176. memcpy(&ver[0], &buffer[2], 5);
  177. ver[5] = 0;
  178. return 0;
  179. }
  180. }
  181. return ret;
  182. }
  183. uint8_t REDFLY::getmac(uint8_t *mac) //return module MAC address
  184. {
  185. uint8_t ret;
  186. for(uint8_t i=3; i!=0; i--) //try 3 times
  187. {
  188. memset(buffer, 0, sizeof(buffer));
  189. ret = cmd(buffer, sizeof(buffer), PSTR(CMD_MAC)); //OKabcdef
  190. if(ret == 0)
  191. {
  192. memcpy(&mac[0], &buffer[2], 6); //buffer[0] = 'O', buffer[1] = 'K'
  193. return 0;
  194. }
  195. }
  196. return ret;
  197. }
  198. uint8_t REDFLY::getlocalip(uint8_t *ip) //return module IP address
  199. {
  200. if(ipaddr[0])
  201. {
  202. memcpy(ip, ipaddr, 4);
  203. return 0;
  204. }
  205. return 1;
  206. }
  207. uint8_t REDFLY::getip(char *host, uint8_t *ip) //return IP addr from host/domain
  208. {
  209. uint8_t ret;
  210. for(uint8_t i=3; i!=0; i--) //try 3 times
  211. {
  212. memset(buffer, 0, sizeof(buffer));
  213. ret = cmd(buffer, sizeof(buffer), PSTR(CMD_DNSGET), (uint8_t*)host, strlen(host)); //OKx...
  214. if(ret == 0)
  215. {
  216. if(buffer[2]) //IP received?
  217. {
  218. memcpy(&ip[0], &buffer[3], 4);
  219. return 0;
  220. }
  221. }
  222. }
  223. return ret;
  224. }
  225. #define NTP_PORT (123)
  226. #define NTP_PACKETLEN (48)
  227. #define NTP_FLAGOFFSET (0)
  228. #define NTP_TIMEOFFSET (40)
  229. uint32_t REDFLY::gettime(uint8_t *server, uint16_t port)
  230. {
  231. uint8_t buf[64]; //min. NTP_PACKETLEN
  232. uint32_t time=0UL, ms;
  233. uint8_t hNTP, sock, buf_len, *ptr;
  234. uint16_t rd, len;
  235. if(port == 0)
  236. {
  237. port = NTP_PORT;
  238. }
  239. //open connection to server
  240. hNTP = socketConnect(PROTO_UDP, server, port, port);
  241. if(hNTP != INVALID_SOCKET)
  242. {
  243. //send NTP request
  244. memset(buf, 0, NTP_PACKETLEN);
  245. buf[NTP_FLAGOFFSET] = (0<<6)|(1<<3)|(3<<0); //NTP flags: LI=0 | VN=1 | Mode=3 -> Client
  246. if(socketSend(hNTP, buf, NTP_PACKETLEN) == 0)
  247. {
  248. //get data
  249. ptr = buf;
  250. buf_len = 0;
  251. for(ms=millis(); (millis()-ms) < 3000;) //wait max. 3s
  252. {
  253. sock = hNTP;
  254. rd = socketRead(&sock, &len, ptr, sizeof(buf)-buf_len);
  255. if((rd != 0) && (rd != 0xFFFF)) //0xFFFF = connection closed
  256. {
  257. ptr += rd;
  258. buf_len += rd;
  259. }
  260. if(buf_len && (len == 0)) //all data received?
  261. {
  262. break;
  263. }
  264. }
  265. //check data
  266. if((buf_len >= NTP_PACKETLEN) && ((buf[NTP_FLAGOFFSET]&0x07) == 4)) //NTP flags: Mode=4 -> Server
  267. {
  268. //time = (uint32_t)*((uint32_t*)&buf[NTP_TIMEOFFSET]);
  269. time = (((uint32_t)buf[NTP_TIMEOFFSET+0])<<24)|
  270. (((uint32_t)buf[NTP_TIMEOFFSET+1])<<16)|
  271. (((uint32_t)buf[NTP_TIMEOFFSET+2])<< 8)|
  272. (((uint32_t)buf[NTP_TIMEOFFSET+3])<< 0); //swap32
  273. time -= 2208988800UL; //sub seconds 1900-1970
  274. }
  275. }
  276. socketClose(hNTP);
  277. }
  278. return time;
  279. }
  280. uint32_t REDFLY::gettime(uint8_t *server){ return gettime(server, 0); };
  281. uint8_t REDFLY::getrssi(void) //return signal strength for current connection
  282. {
  283. for(uint8_t i=3; i!=0; i--) //try 3 times
  284. {
  285. memset(buffer, 0, sizeof(buffer));
  286. if(cmd(buffer, sizeof(buffer), PSTR(CMD_RSSI)) == 0) //OKx
  287. {
  288. return buffer[2];
  289. }
  290. }
  291. return 0;
  292. }
  293. uint8_t REDFLY::getbssid(char *ssid, uint8_t *mac) //return SSID and MAC, call after scan()
  294. {
  295. uint8_t ret;
  296. memset(buffer, 0, sizeof(buffer));
  297. ret = cmd(buffer, sizeof(buffer), PSTR(CMD_BSSID));
  298. if(ret == 0) //successful
  299. {
  300. //buffer[0] = 'O', buffer[1] = 'K'
  301. memcpy(ssid, &buffer[2], 32); //SSID
  302. ssid[32] = 0; //32+1
  303. memcpy(&mac[0], &buffer[34], 6); //MAC
  304. }
  305. else
  306. {
  307. ssid[0] = 0;
  308. }
  309. return ret;
  310. }
  311. uint8_t REDFLY::gettype(char *ssid, uint8_t *type) //return SSID and network type (0=Ad-hoc, 1=Infrastructure), call after scan()
  312. {
  313. uint8_t ret;
  314. memset(buffer, 0, sizeof(buffer));
  315. ret = cmd(buffer, sizeof(buffer), PSTR(CMD_NWTYPE));
  316. if(ret == 0) //successful
  317. {
  318. //buffer[0] = 'O', buffer[1] = 'K'
  319. memcpy(ssid, &buffer[2], 32); //SSID
  320. ssid[32] = 0; //32+1
  321. *type = buffer[34]; //type
  322. }
  323. else
  324. {
  325. ssid[0] = 0;
  326. }
  327. return ret;
  328. }
  329. uint8_t REDFLY::scan(void)
  330. {
  331. cmd(PSTR(CMD_NUMSCAN "0")); //return all results on scan command
  332. return cmd(PSTR(CMD_SCAN "0"));
  333. }
  334. uint8_t REDFLY::scan(uint8_t chn, char *ssid, uint8_t *mode, uint8_t *rssi) //chn 0 = all
  335. {
  336. uint8_t ret, len;
  337. memset(buffer, 0, sizeof(buffer));
  338. cmd(PSTR(CMD_NUMSCAN "1")); //return only one result on scan command
  339. if(ssid[0] != 0) //scan for ssid
  340. {
  341. uitoa(chn, (char*)&buffer[0]); //chn
  342. len = strlen((char*)buffer);
  343. strcat_P((char*)&buffer[len], PSTR(",")); //,
  344. len = strlen((char*)buffer);
  345. strcat((char*)&buffer[len], ssid); //ssid
  346. ret = cmd(buffer, sizeof(buffer), PSTR(CMD_SCAN), (char*)buffer);
  347. }
  348. else
  349. {
  350. ret = cmd(buffer, sizeof(buffer), PSTR(CMD_SCAN), chn);
  351. }
  352. if(ret == 0) //scan successful
  353. {
  354. memcpy(ssid, &buffer[2], 32); //SSID
  355. ssid[32] = 0; //32+1
  356. if(mode)
  357. {
  358. *mode = buffer[34];
  359. }
  360. if(rssi)
  361. {
  362. *rssi = buffer[35];
  363. }
  364. }
  365. else
  366. {
  367. if(rssi)
  368. {
  369. *rssi = 0;
  370. }
  371. }
  372. return ret;
  373. }
  374. uint8_t REDFLY::scan(char *ssid, uint8_t *mode, uint8_t *rssi) { return scan(0, ssid, mode, rssi); }
  375. uint8_t REDFLY::scan(char *ssid) { return scan(0, ssid, 0, 0); }
  376. uint8_t REDFLY::nextscan(char *ssid, uint8_t *mode, uint8_t *rssi)
  377. {
  378. uint8_t ret;
  379. memset(buffer, 0, sizeof(buffer));
  380. ret = cmd(buffer, sizeof(buffer), PSTR(CMD_NEXTSCAN));
  381. if(ret == 0) //scan successful
  382. {
  383. memcpy(ssid, &buffer[2], 32); //SSID
  384. ssid[32] = 0; //32+1
  385. if(mode)
  386. {
  387. *mode = buffer[34];
  388. }
  389. if(rssi)
  390. {
  391. *rssi = buffer[35];
  392. }
  393. }
  394. else
  395. {
  396. if(rssi)
  397. {
  398. *rssi = 0;
  399. }
  400. }
  401. return ret;
  402. }
  403. uint8_t REDFLY::nextscan(char *ssid) { nextscan(ssid, 0, 0); }
  404. uint8_t REDFLY::join(char *ssid, char *key, uint8_t net, uint8_t chn, uint8_t authmode)
  405. {
  406. uint8_t ret=0;
  407. //network
  408. switch(net)
  409. {
  410. case INFRASTRUCTURE:
  411. cmd(PSTR(CMD_NETWORK "INFRASTRUCTURE"));
  412. break;
  413. case IBSS_JOINER:
  414. if(key)
  415. {
  416. cmd(PSTR(CMD_NETWORK "IBSS_SEC,0,0"));
  417. }
  418. else
  419. {
  420. cmd(PSTR(CMD_NETWORK "IBSS,0,0"));
  421. }
  422. break;
  423. case IBSS_CREATOR:
  424. if(key)
  425. {
  426. cmd(PSTR(CMD_NETWORK "IBSS_SEC,1,"), chn);
  427. }
  428. else
  429. {
  430. cmd(PSTR(CMD_NETWORK "IBSS,1,"), chn);
  431. }
  432. break;
  433. }
  434. //authentication mode
  435. if(authmode <= 4)
  436. {
  437. cmd(PSTR(CMD_AUTHMODE), authmode);
  438. }
  439. //key
  440. if(key)
  441. {
  442. cmd(PSTR(CMD_PSK), key);
  443. }
  444. //join
  445. switch(tx_power)
  446. {
  447. //auto data rate
  448. case LOW_POWER: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW)); break;
  449. case MED_POWER: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW)); break;
  450. case HIGH_POWER: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW)); break;
  451. //1Mbps
  452. case LOW_POWER_1M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW1M)); break;
  453. case MED_POWER_1M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW1M)); break;
  454. case HIGH_POWER_1M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW1M)); break;
  455. //2Mbps
  456. case LOW_POWER_2M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW2M)); break;
  457. case MED_POWER_2M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW2M)); break;
  458. case HIGH_POWER_2M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW2M)); break;
  459. //11Mbps
  460. case LOW_POWER_11M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW11M)); break;
  461. case MED_POWER_11M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW11M)); break;
  462. case HIGH_POWER_11M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW11M)); break;
  463. //12Mbps
  464. case LOW_POWER_12M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW12M)); break;
  465. case MED_POWER_12M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW12M)); break;
  466. case HIGH_POWER_12M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW12M)); break;
  467. //24Mbps
  468. case LOW_POWER_24M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW24M)); break;
  469. case MED_POWER_24M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW24M)); break;
  470. case HIGH_POWER_24M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW24M)); break;
  471. //54Mbps
  472. case LOW_POWER_54M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW54M)); break;
  473. case MED_POWER_54M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW54M)); break;
  474. case HIGH_POWER_54M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW54M)); break;
  475. }
  476. return ret;
  477. }
  478. uint8_t REDFLY::join(char *ssid, char *key, uint8_t net, uint8_t chn) { return join(ssid, key, net, chn, 0xFF); } //IBSS_CREATOR
  479. uint8_t REDFLY::join(char *ssid, uint8_t net, uint8_t chn) { return join(ssid, 0, net, chn, 0xFF); } //IBSS_CREATOR
  480. uint8_t REDFLY::join(char *ssid, char *key, uint8_t net) { return join(ssid, key, net, 0, 0xFF); } //INFRASTRUCTURE or IBSS_JOINER
  481. uint8_t REDFLY::join(char *ssid, uint8_t net) { return join(ssid, 0, net, 0, 0xFF); } //INFRASTRUCTURE or IBSS_JOINER
  482. uint8_t REDFLY::join(char *ssid, char *key) { return join(ssid, key, INFRASTRUCTURE, 0, 0xFF); } //INFRASTRUCTURE
  483. uint8_t REDFLY::join(char *ssid) { return join(ssid, 0, INFRASTRUCTURE, 0, 0xFF); } //INFRASTRUCTURE
  484. uint8_t REDFLY::disconnect(void)
  485. {
  486. socketReset();
  487. memset(ipaddr, 0, sizeof(ipaddr));
  488. return cmd(PSTR(CMD_DISCONN));
  489. }
  490. uint8_t REDFLY::begin(uint8_t dhcp, uint8_t *ip, uint8_t *dns, uint8_t *gateway, uint8_t *netmask)
  491. {
  492. uint8_t len;
  493. //reset sockets and IP addr
  494. socketReset();
  495. memset(ipaddr, 0, sizeof(ipaddr));
  496. memset(buffer, 0, sizeof(buffer));
  497. //dhcp or auto ip
  498. if(dhcp == 2) //Auto-IP
  499. {
  500. if(cmd(buffer, sizeof(buffer), PSTR(CMD_IPCONF IPCONF_AUTOIP)) == 0) //OKMACaddrIPaddrSUBNETGateway
  501. {
  502. memcpy(&ipaddr[0], &buffer[8], 4);
  503. return 0;
  504. }
  505. return 2;
  506. }
  507. else if(dhcp) //DHCP
  508. {
  509. if(cmd(buffer, sizeof(buffer), PSTR(CMD_IPCONF IPCONF_DHCP)) == 0) //OKMACaddrIPaddrSUBNETGateway
  510. {
  511. memcpy(&ipaddr[0], &buffer[8], 4);
  512. return 0;
  513. }
  514. return 1;
  515. }
  516. //static ip settings
  517. if(dns)
  518. {
  519. iptoa(dns, (char*)&buffer[0]);
  520. cmd(PSTR(CMD_DNSSERVER), (char*)buffer); //set DNS server (FW >= 4.3.0 required)
  521. }
  522. if(ip)
  523. {
  524. iptoa(ip, (char*)buffer);
  525. memcpy(ipaddr, ip, 4);
  526. }
  527. else
  528. {
  529. strcat_P((char*)buffer, PSTR("192.168.0.1"));
  530. ipaddr[0] = 192;
  531. ipaddr[1] = 168;
  532. ipaddr[2] = 0;
  533. ipaddr[3] = 1;
  534. }
  535. if(netmask)
  536. {
  537. strcat_P((char*)buffer, PSTR(","));
  538. len = strlen((char*)buffer);
  539. iptoa(netmask, (char*)&buffer[len]);
  540. }
  541. else
  542. {
  543. strcat_P((char*)buffer, PSTR(",255.255.255.0"));
  544. }
  545. if(gateway)
  546. {
  547. strcat_P((char*)buffer, PSTR(","));
  548. len = strlen((char*)buffer);
  549. iptoa(gateway, (char*)&buffer[len]);
  550. }
  551. return cmd(PSTR(CMD_IPCONF "0,"), (char*)buffer); //xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy,zzz.zzz.zzz.zzz
  552. }
  553. uint8_t REDFLY::begin(uint8_t *ip, uint8_t *dns, uint8_t *gateway, uint8_t *netmask) { return begin( 0, ip, dns, gateway, netmask); }
  554. uint8_t REDFLY::begin(uint8_t *ip, uint8_t *dns, uint8_t *gateway) { return begin( 0, ip, dns, gateway, 0); }
  555. uint8_t REDFLY::begin(uint8_t *ip, uint8_t *dns) { return begin( 0, ip, dns, 0, 0); }
  556. uint8_t REDFLY::begin(uint8_t *ip) { return begin( 0, ip, 0, 0, 0); }
  557. uint8_t REDFLY::begin(uint8_t dhcp) { return begin(dhcp, 0, 0, 0, 0); }
  558. uint8_t REDFLY::begin(void) { return begin( 1, 0, 0, 0, 0); }
  559. uint8_t REDFLY::socketConnect(uint8_t proto, uint8_t *ip, uint16_t port, uint16_t lport)
  560. {
  561. uint8_t ret=INVALID_SOCKET, len;
  562. //ip
  563. iptoa(ip, (char*)buffer);
  564. //port
  565. strcat_P((char*)buffer, PSTR(","));
  566. len = strlen((char*)buffer);
  567. uitoa(port, (char*)&buffer[len]);
  568. //local port
  569. strcat_P((char*)buffer, PSTR(","));
  570. len = strlen((char*)buffer);
  571. uitoa(lport, (char*)&buffer[len]);
  572. if(proto == PROTO_MCAST) //Multicast
  573. {
  574. proto = SOCKET_MCAST;
  575. if(cmd(buffer, 8, PSTR(CMD_MCAST), (char*)buffer) == 0) //xxx.xxx.xxx.xxx,aaaaa,bbbbb
  576. {
  577. ret = buffer[2]; //OKx
  578. }
  579. }
  580. else if(proto == PROTO_TCP) //TCP
  581. {
  582. proto = SOCKET_TCP;
  583. if(cmd(buffer, 8, PSTR(CMD_TCP), (char*)buffer) == 0) //xxx.xxx.xxx.xxx,aaaaa,bbbbb
  584. {
  585. ret = buffer[2]; //OKx
  586. }
  587. }
  588. else //UDP
  589. {
  590. proto = SOCKET_UDP;
  591. if(cmd(buffer, 8, PSTR(CMD_UDP), (char*)buffer) == 0) //xxx.xxx.xxx.xxx,aaaaa,bbbbb
  592. {
  593. ret = buffer[2]; //OKx
  594. }
  595. }
  596. if(ret != INVALID_SOCKET) //handle okay -> save socket handle and type
  597. {
  598. for(uint8_t i=0; i<MAX_SOCKETS; i++)
  599. {
  600. if(socket_state[i].handle == INVALID_SOCKET)
  601. {
  602. socket_state[i].handle = ret;
  603. socket_state[i].state = proto;
  604. break;
  605. }
  606. }
  607. }
  608. return ret;
  609. }
  610. uint8_t REDFLY::socketConnect(uint8_t proto, uint8_t *ip, uint16_t port)
  611. {
  612. static uint16_t lport=1024;
  613. if(++lport > 2048)
  614. {
  615. lport = 1024;
  616. }
  617. return socketConnect(proto, ip, port, lport);
  618. }
  619. uint8_t REDFLY::socketListen(uint8_t proto, uint16_t lport)
  620. {
  621. uint8_t ret=INVALID_SOCKET;
  622. //local port
  623. uitoa(lport, (char*)&buffer[0]);
  624. if(proto == PROTO_TCP) //TCP
  625. {
  626. proto = SOCKET_TCP;
  627. if(cmd(buffer, sizeof(buffer), PSTR(CMD_LTCP), (char*)buffer) == 0)
  628. {
  629. ret = buffer[2]; //OKx
  630. }
  631. }
  632. else //UDP
  633. {
  634. proto = SOCKET_UDP;
  635. if(cmd(buffer, sizeof(buffer), PSTR(CMD_LUDP), (char*)buffer) == 0)
  636. {
  637. ret = buffer[2]; //OKx
  638. }
  639. }
  640. if(ret != INVALID_SOCKET) //handle okay -> save socket handle and type
  641. {
  642. for(uint8_t i=0; i<MAX_SOCKETS; i++)
  643. {
  644. if(socket_state[i].handle == INVALID_SOCKET)
  645. {
  646. socket_state[i].handle = ret;
  647. socket_state[i].state = proto;
  648. break;
  649. }
  650. }
  651. }
  652. return ret;
  653. }
  654. uint8_t REDFLY::socketClose(uint8_t socket)
  655. {
  656. uint8_t ret=0;
  657. while(available()) //check for new data, if socket already closed?
  658. {
  659. uint8_t sock=INVALID_SOCKET;
  660. uint16_t len=0;
  661. socketRead(&sock, &len, 0, 0, 0, 0);
  662. if(sock == socket)
  663. {
  664. while(len) //clear buffer
  665. {
  666. uint8_t b[8];
  667. sock = socket;
  668. socketRead(&sock, &len, 0, 0, b, 8);
  669. }
  670. }
  671. else
  672. {
  673. break;
  674. }
  675. }
  676. //close socket if opened
  677. if(socket != INVALID_SOCKET)
  678. {
  679. for(uint8_t i=0; i<MAX_SOCKETS; i++)
  680. {
  681. if(socket_state[i].handle == socket)
  682. {
  683. socket_state[i].handle = INVALID_SOCKET;
  684. socket_state[i].state = SOCKET_CLOSED;
  685. for(i=3; i!=0; i--) //try 3 times
  686. {
  687. ret = cmd(PSTR(CMD_CLS), socket);
  688. if((ret == 0) || (ret == 0xFE)) //(0xFE = socket already closed)
  689. {
  690. ret = 0;
  691. break;
  692. }
  693. }
  694. break;
  695. }
  696. }
  697. }
  698. return ret;
  699. }
  700. uint8_t REDFLY::socketClosed(uint8_t socket)
  701. {
  702. if(available()) //check for new data, if socket closed?
  703. {
  704. uint8_t sock=INVALID_SOCKET;
  705. uint16_t len=0;
  706. socketRead(&sock, &len, 0, 0, 0, 0);
  707. }
  708. if(socket != INVALID_SOCKET)
  709. {
  710. for(uint8_t i=0; i<MAX_SOCKETS; i++)
  711. {
  712. if(socket_state[i].handle == socket) //socket found
  713. {
  714. return 0;
  715. }
  716. }
  717. }
  718. return 1;
  719. }
  720. uint8_t REDFLY::socketStatus(uint8_t socket)
  721. {
  722. if(available()) //check for new data, if socket closed?
  723. {
  724. uint8_t sock=INVALID_SOCKET;
  725. uint16_t len=0;
  726. socketRead(&sock, &len, 0, 0, 0, 0);
  727. }
  728. for(uint8_t i=0; i<MAX_SOCKETS; i++)
  729. {
  730. if(socket_state[i].handle == socket)
  731. {
  732. return cmd(PSTR(CMD_CTCP), socket);
  733. }
  734. }
  735. return 0xFF;
  736. }
  737. uint8_t REDFLY::socketState(uint8_t socket)
  738. {
  739. for(uint8_t i=0; i<MAX_SOCKETS; i++)
  740. {
  741. if(socket_state[i].handle == socket)
  742. {
  743. return socket_state[i].state;
  744. }
  745. }
  746. return SOCKET_CLOSED;
  747. }
  748. uint8_t REDFLY::socketSend(uint8_t socket, uint8_t *stream, uint16_t size, uint8_t *ip, uint16_t port)
  749. {
  750. uint8_t len;
  751. //socket
  752. uitoa(socket, (char*)buffer);
  753. //size
  754. strcat_P((char*)buffer, PSTR(","));
  755. len = strlen((char*)buffer);
  756. uitoa(size, (char*)&buffer[len]);
  757. //ip
  758. if(ip && (socketState(socket) == SOCKET_UDP))
  759. {
  760. strcat_P((char*)buffer, PSTR(","));
  761. len = strlen((char*)buffer);
  762. iptoa(ip, (char*)&buffer[len]);
  763. }
  764. else
  765. {
  766. strcat_P((char*)buffer, PSTR(",0"));
  767. }
  768. //port
  769. if(port && (socketState(socket) == SOCKET_UDP))
  770. {
  771. strcat_P((char*)buffer, PSTR(","));
  772. len = strlen((char*)buffer);
  773. uitoa(port, (char*)&buffer[len]);
  774. }
  775. else
  776. {
  777. strcat_P((char*)buffer, PSTR(",0"));
  778. }
  779. //data
  780. strcat_P((char*)buffer, PSTR(","));
  781. return cmd(PSTR(CMD_SEND), (char*)buffer, stream, size); //x,xxxx,xxx.xxx.xxx.xxx,xxxxx,
  782. }
  783. uint8_t REDFLY::socketSend(uint8_t socket, char *stream, uint8_t *ip, uint16_t port)
  784. {
  785. return socketSend(socket, (uint8_t*)stream, strlen(stream), ip, port);
  786. }
  787. uint8_t REDFLY::socketSendPGM(uint8_t socket, PGM_P stream, uint8_t *ip, uint16_t port)
  788. {
  789. uint8_t len;
  790. uint16_t size = strlen_P(stream);
  791. //socket
  792. uitoa(socket, (char*)buffer);
  793. //size
  794. strcat_P((char*)buffer, PSTR(","));
  795. len = strlen((char*)buffer);
  796. uitoa(size, (char*)&buffer[len]);
  797. //ip
  798. if(ip && (socketState(socket) == SOCKET_UDP))
  799. {
  800. strcat_P((char*)buffer, PSTR(","));
  801. len = strlen((char*)buffer);
  802. iptoa(ip, (char*)&buffer[len]);
  803. }
  804. else
  805. {
  806. strcat_P((char*)buffer, PSTR(",0"));
  807. }
  808. //port
  809. if(port && (socketState(socket) == SOCKET_UDP))
  810. {
  811. strcat_P((char*)buffer, PSTR(","));
  812. len = strlen((char*)buffer);
  813. uitoa(port, (char*)&buffer[len]);
  814. }
  815. else
  816. {
  817. strcat_P((char*)buffer, PSTR(",0"));
  818. }
  819. //data
  820. strcat_P((char*)buffer, PSTR(","));
  821. return cmd(PSTR(CMD_SEND), (char*)buffer, stream); //x,xxxx,xxx.xxx.xxx.xxx,xxxxx,
  822. }
  823. uint8_t REDFLY::socketSend(uint8_t socket, uint8_t *stream, uint16_t size)
  824. {
  825. return socketSend(socket, stream, size, 0, 0);
  826. }
  827. uint8_t REDFLY::socketSend(uint8_t socket, char *stream)
  828. {
  829. return socketSend(socket, (uint8_t*)stream, strlen(stream), 0, 0);
  830. }
  831. uint8_t REDFLY::socketSendPGM(uint8_t socket, PGM_P stream)
  832. {
  833. return socketSendPGM(socket, stream, 0, 0);
  834. }
  835. uint8_t REDFLY::socketSend(uint8_t socket, int val)
  836. {
  837. char buf[8];
  838. itoa(val, buf, 10);
  839. return socketSend(socket, (uint8_t*)buf, strlen(buf), 0, 0);
  840. }
  841. uint16_t REDFLY::socketRead(uint8_t *socket, uint16_t *len, uint8_t *ip, uint16_t *port, uint8_t *dst, uint16_t dst_size)
  842. {
  843. uint8_t stop=0;
  844. uint16_t rd=0;
  845. static uint8_t last_socket=INVALID_SOCKET;
  846. static uint16_t last_len=0;
  847. static uint8_t buf[8], pos=0;
  848. static uint16_t udp_port=0;
  849. static uint8_t udp_ip[4];
  850. if(read_state == 2) //we are currently reading data
  851. {
  852. if((*socket != INVALID_SOCKET) && (*socket != last_socket)) //abort if not searched socket
  853. {
  854. return 0;
  855. }
  856. if(dst_size == 0) //only get len and socket
  857. {
  858. *socket = last_socket;
  859. *len = last_len;
  860. return 0;
  861. }
  862. }
  863. do
  864. {
  865. switch(read_state)
  866. {
  867. case 0: //restart searching
  868. read_state = 1;
  869. last_socket = INVALID_SOCKET;
  870. last_len = 0;
  871. pos = 0;
  872. udp_port = 0;
  873. udp_ip[0] = 0;
  874. udp_ip[1] = 0;
  875. udp_ip[2] = 0;
  876. udp_ip[3] = 0;
  877. case 1: //search
  878. while((pos<8) && available())
  879. {
  880. buf[pos++] = read();
  881. }
  882. if(pos >= 8)
  883. {
  884. if((buf[0] == 'R') && \
  885. (buf[1] == 'S') && \
  886. (buf[2] == 'I') && \
  887. (buf[3] == '_') && \
  888. (buf[4] == 'R') && \
  889. (buf[5] == 'E') && \
  890. (buf[6] == 'A') && \
  891. (buf[7] == 'D')) //RSI_READ
  892. {
  893. last_socket = readwait();
  894. last_len = readwait();
  895. last_len |= readwait()<<8;
  896. if((last_socket == INVALID_SOCKET) || (last_len == 0))
  897. {
  898. read_state = 0;
  899. last_socket = INVALID_SOCKET;
  900. last_len = 0;
  901. break;
  902. }
  903. read_state = 2;
  904. //get IP and port on UDP connection
  905. if(socketState(last_socket) == SOCKET_UDP)
  906. {
  907. udp_ip[0] = readwait();
  908. udp_ip[1] = readwait();
  909. udp_ip[2] = readwait();
  910. udp_ip[3] = readwait();
  911. udp_port = readwait();
  912. udp_port |= readwait()<<8;
  913. }
  914. if((*socket != INVALID_SOCKET) && (*socket != last_socket)) //abort if not searched socket
  915. {
  916. return 0;
  917. }
  918. if(dst_size == 0)
  919. {
  920. stop = 1; //break loop
  921. }
  922. }
  923. else if((buf[0] == 'S') && \
  924. (buf[1] == 'I') && \
  925. (buf[2] == '_') && \
  926. (buf[3] == 'C') && \
  927. (buf[4] == 'L') && \
  928. (buf[5] == 'O') && \
  929. (buf[6] == 'S') && \
  930. (buf[7] == 'E')) //SI_CLOSE
  931. {
  932. last_socket = readwait();
  933. readwait(); readwait(); //trailing \r\n
  934. last_len = 0;
  935. rd = 0xFFFF;
  936. read_state = 0;
  937. stop = 1; //break loop
  938. for(uint8_t i=0; i<MAX_SOCKETS; i++)
  939. {
  940. if(socket_state[i].handle == last_socket)
  941. {
  942. socket_state[i].handle = INVALID_SOCKET;
  943. socket_state[i].state = SOCKET_CLOSED;
  944. break;
  945. }
  946. }
  947. }
  948. else
  949. {
  950. //move one byte
  951. pos = 7;
  952. buf[0] = buf[1];
  953. buf[1] = buf[2];
  954. buf[2] = buf[3];
  955. buf[3] = buf[4];
  956. buf[4] = buf[5];
  957. buf[5] = buf[6];
  958. buf[6] = buf[7];
  959. }
  960. }
  961. break;
  962. case 2: //receive
  963. *dst = readwait();
  964. dst_size--;
  965. rd++;
  966. if(--last_len == 0)
  967. {
  968. readwait(); readwait(); //trailing \r\n
  969. read_state = 0;
  970. stop = 1; //break loop
  971. }
  972. else if(dst_size == 0)
  973. {
  974. stop = 1; //break loop
  975. }
  976. break;
  977. }
  978. }while(available() && (stop == 0));
  979. *socket = last_socket;
  980. *len = last_len;
  981. if(ip && udp_ip[0])
  982. {
  983. ip[0] = udp_ip[0];
  984. ip[1] = udp_ip[1];
  985. ip[2] = udp_ip[2];
  986. ip[3] = udp_ip[3];
  987. }
  988. if(port && udp_port)
  989. {
  990. *port = udp_port;
  991. }
  992. return rd;
  993. }
  994. uint16_t REDFLY::socketRead(uint8_t *socket, uint16_t *len, uint8_t *dst, uint16_t dst_size) //TCP connection
  995. {
  996. return socketRead(socket, len, 0, 0, dst, dst_size);
  997. }
  998. void REDFLY::socketReset(void)
  999. {
  1000. read_state = 0;
  1001. for(uint8_t i=0; i<MAX_SOCKETS; i++)
  1002. {
  1003. socket_state[i].handle = INVALID_SOCKET;
  1004. socket_state[i].state = SOCKET_CLOSED;
  1005. }
  1006. flush();
  1007. return;
  1008. }
  1009. //-------------------- Private --------------------
  1010. uint8_t REDFLY::cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, char *v1, PGM_P p2, uint8_t *v2, uint16_t v2_size)
  1011. {
  1012. uint8_t c, i;
  1013. uint32_t ms;
  1014. uint32_t timeout;
  1015. uint8_t buf[8]; //ERRORx
  1016. if(read_state == 2) //currently receiving data?
  1017. {
  1018. return 0xFF;
  1019. }
  1020. else if(available()) //check for new data
  1021. {
  1022. uint8_t sock=INVALID_SOCKET;
  1023. uint16_t len=0;
  1024. socketRead(&sock, &len, 0, 0, 0, 0);
  1025. if(len != 0) //rx data found
  1026. {
  1027. return 0xFF;
  1028. }
  1029. }
  1030. //send p1 command
  1031. c = pgm_read_byte(p1++);
  1032. while(c != 0)
  1033. {
  1034. write(c);
  1035. c = pgm_read_byte(p1++);
  1036. }
  1037. //send v1 parameter 1
  1038. if(v1)
  1039. {
  1040. while(*v1)
  1041. {
  1042. write(*v1++);
  1043. }
  1044. }
  1045. //send p2 parameter 2
  1046. if(p2)
  1047. {
  1048. c = pgm_read_byte(p2++);
  1049. while(c != 0)
  1050. {
  1051. if(c == 0xDB) //0xDB -> 0xDB 0xDD
  1052. {
  1053. write(0xDB);
  1054. write(0xDD);
  1055. c = pgm_read_byte(p2++);
  1056. }
  1057. else if((c == 0x0D) && (pgm_read_byte(p2) == 0x0A)) //\r\n -> 0xDB 0xDC
  1058. {
  1059. write(0xDB);
  1060. write(0xDC);
  1061. p2++;
  1062. c = pgm_read_byte(p2++);
  1063. }
  1064. else
  1065. {
  1066. write(c);
  1067. c = pgm_read_byte(p2++);
  1068. }
  1069. }
  1070. }
  1071. //send v2 parameter 3
  1072. if(v2_size)
  1073. {
  1074. while(v2_size)
  1075. {
  1076. if(v2[0] == 0xDB) //0xDB -> 0xDB 0xDD
  1077. {
  1078. write(0xDB);
  1079. write(0xDD);
  1080. v2++; v2_size--;
  1081. }
  1082. else if((v2[0] == 0x0D) && (v2[1] == 0x0A) && (v2_size >= 2)) //\r\n -> 0xDB 0xDC
  1083. {
  1084. write(0xDB);
  1085. write(0xDC);
  1086. v2+=2; v2_size-=2;
  1087. }
  1088. else
  1089. {
  1090. write(*v2++);
  1091. v2_size--;
  1092. }
  1093. }
  1094. }
  1095. //flush rx and tx buffer
  1096. flush_nowait();
  1097. //send end characters of command
  1098. write('\r');
  1099. write('\n');
  1100. //read response
  1101. timeout = 10000; //default timeout: 10s
  1102. if(dst_size == 0) //dont save response
  1103. {
  1104. buf[0] = 0;
  1105. buf[5] = 0;
  1106. for(i=0, ms=millis(); (millis()-ms) < timeout;)
  1107. {
  1108. if(available())
  1109. {
  1110. c = read();
  1111. if(i < 8)
  1112. {
  1113. buf[i++] = c;
  1114. if((buf[0] != 'O') && (buf[0] != 'E')) //OK or ERROR
  1115. {
  1116. i = 0;
  1117. }
  1118. }
  1119. ms = millis();
  1120. timeout = 3; //3 ms timeout
  1121. }
  1122. }
  1123. }
  1124. else //save response to dst
  1125. {
  1126. dst[0] = 0;
  1127. dst[5] = 0;
  1128. for(i=0, ms=millis(); (millis()-ms) < timeout;)
  1129. {
  1130. if(available())
  1131. {
  1132. c = read();
  1133. if(i < dst_size)
  1134. {
  1135. dst[i++] = c;
  1136. if((dst[0] != 'O') && (dst[0] != 'E')) //OK or ERROR
  1137. {
  1138. i = 0;
  1139. }
  1140. }
  1141. ms = millis();
  1142. timeout = 3; //3 ms timeout
  1143. }
  1144. }
  1145. buf[0] = dst[0];
  1146. buf[1] = dst[1];
  1147. buf[5] = dst[5];
  1148. }
  1149. //check response
  1150. if((buf[0] == 'O') && (buf[1] == 'K'))
  1151. {
  1152. return 0; //OK
  1153. }
  1154. else if((buf[0] == 'E') && (buf[1] == 'R') && (buf[5] != 0) && (buf[5] != '\r'))
  1155. {
  1156. return buf[5]; //ERROR code
  1157. }
  1158. return 0xFF;
  1159. }
  1160. uint8_t REDFLY::cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, int16_t val)
  1161. {
  1162. char buf[8];
  1163. itoa(val, buf, 10);
  1164. return cmd(dst, dst_size, p1, buf, 0, 0, 0);
  1165. }
  1166. uint8_t REDFLY::cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, uint8_t *v2, uint16_t v2_size) { return cmd(dst, dst_size, p1, 0, 0, v2, v2_size); }
  1167. uint8_t REDFLY::cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, char *v1) { return cmd(dst, dst_size, p1, v1, 0, 0, 0); }
  1168. uint8_t REDFLY::cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1) { return cmd(dst, dst_size, p1, 0, 0, 0, 0); }
  1169. uint8_t REDFLY::cmd( PGM_P p1, char *v1, PGM_P p2) { return cmd( 0, 0, p1, v1, p2, 0, 0); }
  1170. uint8_t REDFLY::cmd( PGM_P p1, char *v1, uint8_t *v2, uint16_t v2_size) { return cmd( 0, 0, p1, v1, 0, v2, v2_size); }
  1171. uint8_t REDFLY::cmd( PGM_P p1, char *v1) { return cmd( 0, 0, p1, v1, 0, 0, 0); }
  1172. uint8_t REDFLY::cmd( PGM_P p1, int16_t v1) { return cmd( 0, 0, p1, v1 ); }
  1173. uint8_t REDFLY::cmd( PGM_P p1) { return cmd( 0, 0, p1, 0, 0, 0, 0); }
  1174. void REDFLY::flush(void)
  1175. {
  1176. uint32_t ms;
  1177. //clear tx buffer
  1178. _SERIAL_.flush();
  1179. //clear rx buffer
  1180. #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
  1181. for(ms=millis(); ((_UCSRA_&(1<<_RXC_)) || available()) && ((millis()-ms) < 50);) //50ms
  1182. #else
  1183. for(ms=millis(); available() && ((millis()-ms) < 50);) //50ms
  1184. #endif
  1185. {
  1186. read();
  1187. }
  1188. delay_10ms(1);
  1189. return;
  1190. }
  1191. void REDFLY::flush_nowait(void)
  1192. {
  1193. //clear tx buffer
  1194. _SERIAL_.flush();
  1195. //clear rx buffer
  1196. for(int len=available(); len!=0; len--)
  1197. {
  1198. read();
  1199. }
  1200. return;
  1201. }
  1202. int REDFLY::available(void)
  1203. {
  1204. return _SERIAL_.available();
  1205. }
  1206. uint8_t REDFLY::readwait(void) //serial read
  1207. {
  1208. while(!available());
  1209. return (uint8_t)_SERIAL_.read();
  1210. }
  1211. uint8_t REDFLY::read(void) //serial read
  1212. {
  1213. return _SERIAL_.read();
  1214. }
  1215. void REDFLY::write(uint8_t c) //serial write
  1216. {
  1217. _SERIAL_.write(c);
  1218. return;
  1219. }
  1220. void REDFLY::setbaudrate(uint32_t br) //set serial baudrate and config (8n2)
  1221. {
  1222. if(br < 9600)
  1223. {
  1224. br = 9600;
  1225. }
  1226. else if(br > 3686400)
  1227. {
  1228. br = 3686400;
  1229. }
  1230. _SERIAL_.begin(br);
  1231. //8 N 2
  1232. #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
  1233. _UCSRC_ |= (1<<_USBS_);
  1234. #else
  1235. _USART_->US_MR |= US_MR_NBSTOP_2_BIT;
  1236. //_USART_->US_MR = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL;
  1237. #endif
  1238. return;
  1239. }
  1240. char* REDFLY::iptoa(uint8_t *ip, char *s) //convert ip to string
  1241. {
  1242. sprintf_P(s, PSTR("%i.%i.%i.%i"), ip[0], ip[1], ip[2], ip[3]);
  1243. return s;
  1244. }
  1245. char* REDFLY::uitoa(uint16_t val, char *s) //convert unsigned int to string
  1246. {
  1247. sprintf_P(s, PSTR("%u"), val);
  1248. return s;
  1249. }
  1250. void REDFLY::delay_10ms(uint8_t ms) //delay of 10ms * x
  1251. {
  1252. for(; ms!=0; ms--)
  1253. {
  1254. #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
  1255. _delay_ms(10);
  1256. #else
  1257. delay(10);
  1258. #endif
  1259. }
  1260. return;
  1261. }