1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495 |
- /*
- RedFly Lib for Arduino
- by Watterott electronic (www.watterott.com)
- */
- #include <inttypes.h>
- #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
- # include <avr/io.h>
- # include <avr/pgmspace.h>
- # include <util/delay.h>
- #else
- # include <chip.h>
- # include <itoa.h>
- #endif
- #if ARDUINO >= 100
- # include "Arduino.h"
- #else
- # include "WProgram.h"
- #endif
- #include "digitalWriteFast.h"
- #include "RedFlyCommands.h"
- #include "RedFly.h"
- #include "RedFlyClient.h"
- #include "RedFlyServer.h"
- #include "RedFlyNBNS.h"
- #define RX_PIN UART_RX_PIN //0
- #define TX_PIN UART_TX_PIN //1
- #define RST_PIN 2
- #define CS_PIN 3
- #define RST_DISABLE() digitalWriteFast(RST_PIN, HIGH)
- #define RST_ENABLE() digitalWriteFast(RST_PIN, LOW)
- #define CS_DISABLE() digitalWriteFast(CS_PIN, HIGH)
- #define CS_ENABLE() digitalWriteFast(CS_PIN, LOW)
- #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
- # if defined(UBRRH) && defined(UBRRL)
- # define _UCSRA_ UCSRA
- # define _RXC_ RXC
- # define _UCSRC_ UCSRC
- # define _USBS_ USBS
- # define _SERIAL_ Serial
- # elif defined(UBRR0H) && !defined(UBRR0L)
- # define _UCSRA_ UCSR1A
- # define _RXC_ RXC1
- # define _UCSRC_ UCSR1C
- # define _USBS_ USBS1
- # define _SERIAL_ Serial1
- # else
- # define _UCSRA_ UCSR0A
- # define _RXC_ RXC0
- # define _UCSRC_ UCSR0C
- # define _USBS_ USBS0
- # define _SERIAL_ Serial
- # endif
- #else
- # define _SERIAL_ Serial
- # define _USART_ USART0
- #endif
- REDFLY RedFly;
- //-------------------- Constructor/Destructor --------------------
- REDFLY::REDFLY(void)
- {
- return;
- }
- REDFLY::~REDFLY(void)
- {
- return;
- }
- //-------------------- Public --------------------
- uint8_t REDFLY::init(uint32_t br, uint8_t pwr)
- {
- uint8_t ret=0xFF, i;
- uint32_t ms;
- //init pins
- #ifdef CS_PIN
- pinMode(CS_PIN, OUTPUT);
- CS_DISABLE(); //deselect
- #endif
- #ifdef RST_PIN
- pinMode(RST_PIN, OUTPUT);
- RST_ENABLE(); //reset on
- #endif
- #ifdef TX_PIN
- pinMode(TX_PIN, OUTPUT);
- digitalWrite(TX_PIN, HIGH);
- #endif
- #ifdef RX_PIN
- pinMode(RX_PIN, INPUT);
- digitalWrite(RX_PIN, HIGH); //pull-up on
- #endif
- //reset vars
- memset(ipaddr, 0, sizeof(ipaddr));
- memset(buffer, 0, sizeof(buffer));
- //set serial port config
- baudrate = br;
- setbaudrate(br);
- //enable module communication
- enable();
- //reset module
- RST_ENABLE();
- delay_10ms(5); //wait 50ms
- RST_DISABLE();
- //auto baud rate detection
- delay_10ms(11); //wait 110ms for module boot-up
- for(i=4; i!=0; i--) //try 4 times
- {
- write(0x1C); //transmit 0x1C
- for(ms=millis(); (millis()-ms) < 200;) //wait 200ms for response
- {
- if(available())
- {
- if(read() == 0x55) //wait for 0x55
- {
- write(0x55); //transmit 0x55
- delay_10ms(10); //wait 100ms
- //skip firmware upgrade question at power on
- write('n');
- write('\n');
- ret = 0xFE;
- i = 1; //break 1st for loop
- break; //break 2nd for loop
- }
- }
- }
- }
- delay_10ms(20); //wait 200ms for booting
- //get firmware version and set config
- // if(ret == 0xFE)
- // {
- for(i=3; i!=0; i--) //try 3 times
- {
- flush();
- if(cmd(PSTR(CMD_FWVERSION)) == 0)
- {
- //cmd(PSTR(CMD_RESET)); //soft reset
- cmd(PSTR(CMD_BAND BAND24));
- cmd(PSTR(CMD_INIT));
- tx_power = pwr;
- ret = 0;
- break;
- }
- delay_10ms(10);
- }
- // }
- if(ret)
- {
- disable();
- }
- return ret;
- }
- uint8_t REDFLY::init(uint8_t pwr) { return init(REDFLY_BAUDRATE, pwr); }
- uint8_t REDFLY::init(void) { return init(REDFLY_BAUDRATE, HIGH_POWER); }
- void REDFLY::enable(void) //select module
- {
- flush(); //clear buffers
- setbaudrate(baudrate);
- read_state = 0;
- CS_ENABLE();
- return;
- }
- void REDFLY::disable(void) //deselect module
- {
- flush(); //clear buffers
- read_state = 0;
- CS_DISABLE();
- return;
- }
- uint8_t REDFLY::getversion(char *ver) //return module firmware version
- {
- uint8_t ret;
- for(uint8_t i=3; i!=0; i--) //try 3 times
- {
- memset(buffer, 0, sizeof(buffer));
- ret = cmd(buffer, sizeof(buffer), PSTR(CMD_FWVERSION)); //OKa.b.c
- if(ret == 0)
- {
- //buffer[0] = 'O', buffer[1] = 'K'
- memcpy(&ver[0], &buffer[2], 5);
- ver[5] = 0;
- return 0;
- }
- }
- return ret;
- }
- uint8_t REDFLY::getmac(uint8_t *mac) //return module MAC address
- {
- uint8_t ret;
- for(uint8_t i=3; i!=0; i--) //try 3 times
- {
- memset(buffer, 0, sizeof(buffer));
- ret = cmd(buffer, sizeof(buffer), PSTR(CMD_MAC)); //OKabcdef
- if(ret == 0)
- {
- memcpy(&mac[0], &buffer[2], 6); //buffer[0] = 'O', buffer[1] = 'K'
- return 0;
- }
- }
- return ret;
- }
- uint8_t REDFLY::getlocalip(uint8_t *ip) //return module IP address
- {
- if(ipaddr[0])
- {
- memcpy(ip, ipaddr, 4);
- return 0;
- }
- return 1;
- }
- uint8_t REDFLY::getip(char *host, uint8_t *ip) //return IP addr from host/domain
- {
- uint8_t ret;
- for(uint8_t i=3; i!=0; i--) //try 3 times
- {
- wdt_reset();
- memset(buffer, 0, sizeof(buffer));
- ret = cmd(buffer, sizeof(buffer), PSTR(CMD_DNSGET), (uint8_t*)host, strlen(host)); //OKx...
- if(ret == 0)
- {
- if(buffer[2]) //IP received?
- {
- memcpy(&ip[0], &buffer[3], 4);
- return 0;
- }
- }
- }
- return ret;
- }
- #define NTP_PORT (123)
- #define NTP_PACKETLEN (48)
- #define NTP_FLAGOFFSET (0)
- #define NTP_TIMEOFFSET (40)
- uint32_t REDFLY::gettime(uint8_t *server, uint16_t port)
- {
- uint8_t buf[64]; //min. NTP_PACKETLEN
- uint32_t time=0UL, ms;
- uint8_t hNTP, sock, buf_len, *ptr;
- uint16_t rd, len;
-
- if(port == 0)
- {
- port = NTP_PORT;
- }
- //open connection to server
- hNTP = socketConnect(PROTO_UDP, server, port, port);
- if(hNTP != INVALID_SOCKET)
- {
- //send NTP request
- memset(buf, 0, NTP_PACKETLEN);
- buf[NTP_FLAGOFFSET] = (0<<6)|(1<<3)|(3<<0); //NTP flags: LI=0 | VN=1 | Mode=3 -> Client
- if(socketSend(hNTP, buf, NTP_PACKETLEN) == 0)
- {
- //get data
- ptr = buf;
- buf_len = 0;
- for(ms=millis(); (millis()-ms) < 3000;) //wait max. 3s
- {
- sock = hNTP;
- rd = socketRead(&sock, &len, ptr, sizeof(buf)-buf_len);
- if((rd != 0) && (rd != 0xFFFF)) //0xFFFF = connection closed
- {
- ptr += rd;
- buf_len += rd;
- }
- if(buf_len && (len == 0)) //all data received?
- {
- break;
- }
- }
- //check data
- if((buf_len >= NTP_PACKETLEN) && ((buf[NTP_FLAGOFFSET]&0x07) == 4)) //NTP flags: Mode=4 -> Server
- {
- //time = (uint32_t)*((uint32_t*)&buf[NTP_TIMEOFFSET]);
- time = (((uint32_t)buf[NTP_TIMEOFFSET+0])<<24)|
- (((uint32_t)buf[NTP_TIMEOFFSET+1])<<16)|
- (((uint32_t)buf[NTP_TIMEOFFSET+2])<< 8)|
- (((uint32_t)buf[NTP_TIMEOFFSET+3])<< 0); //swap32
- time -= 2208988800UL; //sub seconds 1900-1970
- }
- }
- socketClose(hNTP);
- }
- return time;
- }
- uint32_t REDFLY::gettime(uint8_t *server){ return gettime(server, 0); };
- uint8_t REDFLY::getrssi(void) //return signal strength for current connection
- {
- for(uint8_t i=3; i!=0; i--) //try 3 times
- {
- memset(buffer, 0, sizeof(buffer));
- if(cmd(buffer, sizeof(buffer), PSTR(CMD_RSSI)) == 0) //OKx
- {
- return buffer[2];
- }
- }
- return 0;
- }
- uint8_t REDFLY::getbssid(char *ssid, uint8_t *mac) //return SSID and MAC, call after scan()
- {
- uint8_t ret;
- memset(buffer, 0, sizeof(buffer));
-
- ret = cmd(buffer, sizeof(buffer), PSTR(CMD_BSSID));
- if(ret == 0) //successful
- {
- //buffer[0] = 'O', buffer[1] = 'K'
- memcpy(ssid, &buffer[2], 32); //SSID
- ssid[32] = 0; //32+1
- memcpy(&mac[0], &buffer[34], 6); //MAC
- }
- else
- {
- ssid[0] = 0;
- }
- return ret;
- }
- uint8_t REDFLY::gettype(char *ssid, uint8_t *type) //return SSID and network type (0=Ad-hoc, 1=Infrastructure), call after scan()
- {
- uint8_t ret;
- memset(buffer, 0, sizeof(buffer));
-
- ret = cmd(buffer, sizeof(buffer), PSTR(CMD_NWTYPE));
- if(ret == 0) //successful
- {
- //buffer[0] = 'O', buffer[1] = 'K'
- memcpy(ssid, &buffer[2], 32); //SSID
- ssid[32] = 0; //32+1
- *type = buffer[34]; //type
- }
- else
- {
- ssid[0] = 0;
- }
- return ret;
- }
- uint8_t REDFLY::scan(void)
- {
- cmd(PSTR(CMD_NUMSCAN "0")); //return all results on scan command
- return cmd(PSTR(CMD_SCAN "0"));
- }
- uint8_t REDFLY::scan(uint8_t chn, char *ssid, uint8_t *mode, uint8_t *rssi) //chn 0 = all
- {
- uint8_t ret, len;
- memset(buffer, 0, sizeof(buffer));
- cmd(PSTR(CMD_NUMSCAN "1")); //return only one result on scan command
- if(ssid[0] != 0) //scan for ssid
- {
- uitoa(chn, (char*)&buffer[0]); //chn
- len = strlen((char*)buffer);
- strcat_P((char*)&buffer[len], PSTR(",")); //,
- len = strlen((char*)buffer);
- strcat((char*)&buffer[len], ssid); //ssid
- ret = cmd(buffer, sizeof(buffer), PSTR(CMD_SCAN), (char*)buffer);
- }
- else
- {
- ret = cmd(buffer, sizeof(buffer), PSTR(CMD_SCAN), chn);
- }
- if(ret == 0) //scan successful
- {
- memcpy(ssid, &buffer[2], 32); //SSID
- ssid[32] = 0; //32+1
- if(mode)
- {
- *mode = buffer[34];
- }
- if(rssi)
- {
- *rssi = buffer[35];
- }
- }
- else
- {
- if(rssi)
- {
- *rssi = 0;
- }
- }
- return ret;
- }
- uint8_t REDFLY::scan(char *ssid, uint8_t *mode, uint8_t *rssi) { return scan(0, ssid, mode, rssi); }
- uint8_t REDFLY::scan(char *ssid) { return scan(0, ssid, 0, 0); }
- uint8_t REDFLY::nextscan(char *ssid, uint8_t *mode, uint8_t *rssi)
- {
- uint8_t ret;
- memset(buffer, 0, sizeof(buffer));
- ret = cmd(buffer, sizeof(buffer), PSTR(CMD_NEXTSCAN));
- if(ret == 0) //scan successful
- {
- memcpy(ssid, &buffer[2], 32); //SSID
- ssid[32] = 0; //32+1
- if(mode)
- {
- *mode = buffer[34];
- }
- if(rssi)
- {
- *rssi = buffer[35];
- }
- }
- else
- {
- if(rssi)
- {
- *rssi = 0;
- }
- }
- return ret;
- }
- uint8_t REDFLY::nextscan(char *ssid) { nextscan(ssid, 0, 0); }
- uint8_t REDFLY::join(char *ssid, char *key, uint8_t net, uint8_t chn, uint8_t authmode)
- {
- uint8_t ret=0;
- //network
- switch(net)
- {
- case INFRASTRUCTURE:
- cmd(PSTR(CMD_NETWORK "INFRASTRUCTURE"));
- break;
- case IBSS_JOINER:
- if(key)
- {
- cmd(PSTR(CMD_NETWORK "IBSS_SEC,0,0"));
- }
- else
- {
- cmd(PSTR(CMD_NETWORK "IBSS,0,0"));
- }
- break;
- case IBSS_CREATOR:
- if(key)
- {
- cmd(PSTR(CMD_NETWORK "IBSS_SEC,1,"), chn);
- }
- else
- {
- cmd(PSTR(CMD_NETWORK "IBSS,1,"), chn);
- }
- break;
- }
- //authentication mode
- if(authmode <= 4)
- {
- cmd(PSTR(CMD_AUTHMODE), authmode);
- }
- //key
- if(key)
- {
- cmd(PSTR(CMD_PSK), key);
- }
- //join
- switch(tx_power)
- {
- //auto data rate
- case LOW_POWER: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW)); break;
- case MED_POWER: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW)); break;
- case HIGH_POWER: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW)); break;
- //1Mbps
- case LOW_POWER_1M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW1M)); break;
- case MED_POWER_1M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW1M)); break;
- case HIGH_POWER_1M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW1M)); break;
- //2Mbps
- case LOW_POWER_2M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW2M)); break;
- case MED_POWER_2M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW2M)); break;
- case HIGH_POWER_2M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW2M)); break;
- //11Mbps
- case LOW_POWER_11M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW11M)); break;
- case MED_POWER_11M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW11M)); break;
- case HIGH_POWER_11M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW11M)); break;
- //12Mbps
- case LOW_POWER_12M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW12M)); break;
- case MED_POWER_12M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW12M)); break;
- case HIGH_POWER_12M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW12M)); break;
- //24Mbps
- case LOW_POWER_24M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW24M)); break;
- case MED_POWER_24M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW24M)); break;
- case HIGH_POWER_24M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW24M)); break;
- //54Mbps
- case LOW_POWER_54M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_LOWPW54M)); break;
- case MED_POWER_54M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_MEDPW54M)); break;
- case HIGH_POWER_54M: ret = cmd(PSTR(CMD_JOIN), ssid, PSTR(JOIN_HIGHPW54M)); break;
- }
- return ret;
- }
- uint8_t REDFLY::join(char *ssid, char *key, uint8_t net, uint8_t chn) { return join(ssid, key, net, chn, 0xFF); } //IBSS_CREATOR
- uint8_t REDFLY::join(char *ssid, uint8_t net, uint8_t chn) { return join(ssid, 0, net, chn, 0xFF); } //IBSS_CREATOR
- uint8_t REDFLY::join(char *ssid, char *key, uint8_t net) { return join(ssid, key, net, 0, 0xFF); } //INFRASTRUCTURE or IBSS_JOINER
- uint8_t REDFLY::join(char *ssid, uint8_t net) { return join(ssid, 0, net, 0, 0xFF); } //INFRASTRUCTURE or IBSS_JOINER
- uint8_t REDFLY::join(char *ssid, char *key) { return join(ssid, key, INFRASTRUCTURE, 0, 0xFF); } //INFRASTRUCTURE
- uint8_t REDFLY::join(char *ssid) { return join(ssid, 0, INFRASTRUCTURE, 0, 0xFF); } //INFRASTRUCTURE
- uint8_t REDFLY::disconnect(void)
- {
- socketReset();
- memset(ipaddr, 0, sizeof(ipaddr));
- return cmd(PSTR(CMD_DISCONN));
- }
- uint8_t REDFLY::begin(uint8_t dhcp, uint8_t *ip, uint8_t *dns, uint8_t *gateway, uint8_t *netmask)
- {
- uint8_t len;
- //reset sockets and IP addr
- socketReset();
- memset(ipaddr, 0, sizeof(ipaddr));
- memset(buffer, 0, sizeof(buffer));
- //dhcp or auto ip
- if(dhcp == 2) //Auto-IP
- {
- if(cmd(buffer, sizeof(buffer), PSTR(CMD_IPCONF IPCONF_AUTOIP)) == 0) //OKMACaddrIPaddrSUBNETGateway
- {
- memcpy(&ipaddr[0], &buffer[8], 4);
- return 0;
- }
- return 2;
- }
- else if(dhcp) //DHCP
- {
- if(cmd(buffer, sizeof(buffer), PSTR(CMD_IPCONF IPCONF_DHCP)) == 0) //OKMACaddrIPaddrSUBNETGateway
- {
- memcpy(&ipaddr[0], &buffer[8], 4);
- return 0;
- }
- return 1;
- }
- //static ip settings
- if(dns)
- {
- iptoa(dns, (char*)&buffer[0]);
- cmd(PSTR(CMD_DNSSERVER), (char*)buffer); //set DNS server (FW >= 4.3.0 required)
- }
- if(ip)
- {
- iptoa(ip, (char*)buffer);
- memcpy(ipaddr, ip, 4);
- }
- else
- {
- strcat_P((char*)buffer, PSTR("192.168.0.1"));
- ipaddr[0] = 192;
- ipaddr[1] = 168;
- ipaddr[2] = 0;
- ipaddr[3] = 1;
- }
- if(netmask)
- {
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- iptoa(netmask, (char*)&buffer[len]);
- }
- else
- {
- strcat_P((char*)buffer, PSTR(",255.255.255.0"));
- }
- if(gateway)
- {
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- iptoa(gateway, (char*)&buffer[len]);
- }
- return cmd(PSTR(CMD_IPCONF "0,"), (char*)buffer); //xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy,zzz.zzz.zzz.zzz
- }
- uint8_t REDFLY::begin(uint8_t *ip, uint8_t *dns, uint8_t *gateway, uint8_t *netmask) { return begin( 0, ip, dns, gateway, netmask); }
- uint8_t REDFLY::begin(uint8_t *ip, uint8_t *dns, uint8_t *gateway) { return begin( 0, ip, dns, gateway, 0); }
- uint8_t REDFLY::begin(uint8_t *ip, uint8_t *dns) { return begin( 0, ip, dns, 0, 0); }
- uint8_t REDFLY::begin(uint8_t *ip) { return begin( 0, ip, 0, 0, 0); }
- uint8_t REDFLY::begin(uint8_t dhcp) { return begin(dhcp, 0, 0, 0, 0); }
- uint8_t REDFLY::begin(void) { return begin( 1, 0, 0, 0, 0); }
-
- uint8_t REDFLY::socketConnect(uint8_t proto, uint8_t *ip, uint16_t port, uint16_t lport)
- {
- uint8_t ret=INVALID_SOCKET, len;
- //ip
- iptoa(ip, (char*)buffer);
- //port
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- uitoa(port, (char*)&buffer[len]);
- //local port
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- uitoa(lport, (char*)&buffer[len]);
- if(proto == PROTO_MCAST) //Multicast
- {
- proto = SOCKET_MCAST;
- if(cmd(buffer, 8, PSTR(CMD_MCAST), (char*)buffer) == 0) //xxx.xxx.xxx.xxx,aaaaa,bbbbb
- {
- ret = buffer[2]; //OKx
- }
- }
- else if(proto == PROTO_TCP) //TCP
- {
- proto = SOCKET_TCP;
- if(cmd(buffer, 8, PSTR(CMD_TCP), (char*)buffer) == 0) //xxx.xxx.xxx.xxx,aaaaa,bbbbb
- {
- ret = buffer[2]; //OKx
- }
- }
- else //UDP
- {
- proto = SOCKET_UDP;
- if(cmd(buffer, 8, PSTR(CMD_UDP), (char*)buffer) == 0) //xxx.xxx.xxx.xxx,aaaaa,bbbbb
- {
- ret = buffer[2]; //OKx
- }
- }
- if(ret != INVALID_SOCKET) //handle okay -> save socket handle and type
- {
- for(uint8_t i=0; i<MAX_SOCKETS; i++)
- {
- if(socket_state[i].handle == INVALID_SOCKET)
- {
- socket_state[i].handle = ret;
- socket_state[i].state = proto;
- break;
- }
- }
- }
- return ret;
- }
- uint8_t REDFLY::socketConnect(uint8_t proto, uint8_t *ip, uint16_t port)
- {
- static uint16_t lport=1024;
- if(++lport > 2048)
- {
- lport = 1024;
- }
- return socketConnect(proto, ip, port, lport);
- }
- uint8_t REDFLY::socketListen(uint8_t proto, uint16_t lport)
- {
- uint8_t ret=INVALID_SOCKET;
- //local port
- uitoa(lport, (char*)&buffer[0]);
- if(proto == PROTO_TCP) //TCP
- {
- proto = SOCKET_TCP;
- if(cmd(buffer, sizeof(buffer), PSTR(CMD_LTCP), (char*)buffer) == 0)
- {
- ret = buffer[2]; //OKx
- }
- }
- else //UDP
- {
- proto = SOCKET_UDP;
- if(cmd(buffer, sizeof(buffer), PSTR(CMD_LUDP), (char*)buffer) == 0)
- {
- ret = buffer[2]; //OKx
- }
- }
- if(ret != INVALID_SOCKET) //handle okay -> save socket handle and type
- {
- for(uint8_t i=0; i<MAX_SOCKETS; i++)
- {
- if(socket_state[i].handle == INVALID_SOCKET)
- {
- socket_state[i].handle = ret;
- socket_state[i].state = proto;
- break;
- }
- }
- }
- return ret;
- }
- uint8_t REDFLY::socketClose(uint8_t socket)
- {
- uint8_t ret=0;
- while(available()) //check for new data, if socket already closed?
- {
- uint8_t sock=INVALID_SOCKET;
- uint16_t len=0;
- socketRead(&sock, &len, 0, 0, 0, 0);
- if(sock == socket)
- {
- while(len) //clear buffer
- {
- uint8_t b[8];
- sock = socket;
- socketRead(&sock, &len, 0, 0, b, 8);
- }
- }
- else
- {
- break;
- }
- }
- //close socket if opened
- if(socket != INVALID_SOCKET)
- {
- for(uint8_t i=0; i<MAX_SOCKETS; i++)
- {
- if(socket_state[i].handle == socket)
- {
- socket_state[i].handle = INVALID_SOCKET;
- socket_state[i].state = SOCKET_CLOSED;
- for(i=3; i!=0; i--) //try 3 times
- {
- ret = cmd(PSTR(CMD_CLS), socket);
- if((ret == 0) || (ret == 0xFE)) //(0xFE = socket already closed)
- {
- ret = 0;
- break;
- }
- }
- break;
- }
- }
- }
- return ret;
- }
- uint8_t REDFLY::socketClosed(uint8_t socket)
- {
- if(available()) //check for new data, if socket closed?
- {
- uint8_t sock=INVALID_SOCKET;
- uint16_t len=0;
- socketRead(&sock, &len, 0, 0, 0, 0);
- }
- if(socket != INVALID_SOCKET)
- {
- for(uint8_t i=0; i<MAX_SOCKETS; i++)
- {
- if(socket_state[i].handle == socket) //socket found
- {
- return 0;
- }
- }
- }
- return 1;
- }
- uint8_t REDFLY::socketStatus(uint8_t socket)
- {
- if(available()) //check for new data, if socket closed?
- {
- uint8_t sock=INVALID_SOCKET;
- uint16_t len=0;
- socketRead(&sock, &len, 0, 0, 0, 0);
- }
- for(uint8_t i=0; i<MAX_SOCKETS; i++)
- {
- if(socket_state[i].handle == socket)
- {
- return cmd(PSTR(CMD_CTCP), socket);
- }
- }
- return 0xFF;
- }
- uint8_t REDFLY::socketState(uint8_t socket)
- {
- for(uint8_t i=0; i<MAX_SOCKETS; i++)
- {
- if(socket_state[i].handle == socket)
- {
- return socket_state[i].state;
- }
- }
- return SOCKET_CLOSED;
- }
- uint8_t REDFLY::socketSend(uint8_t socket, uint8_t *stream, uint16_t size, uint8_t *ip, uint16_t port)
- {
- uint8_t len;
- //socket
- uitoa(socket, (char*)buffer);
- //size
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- uitoa(size, (char*)&buffer[len]);
- //ip
- if(ip && (socketState(socket) == SOCKET_UDP))
- {
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- iptoa(ip, (char*)&buffer[len]);
- }
- else
- {
- strcat_P((char*)buffer, PSTR(",0"));
- }
- //port
- if(port && (socketState(socket) == SOCKET_UDP))
- {
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- uitoa(port, (char*)&buffer[len]);
- }
- else
- {
- strcat_P((char*)buffer, PSTR(",0"));
- }
- //data
- strcat_P((char*)buffer, PSTR(","));
- return cmd(PSTR(CMD_SEND), (char*)buffer, stream, size); //x,xxxx,xxx.xxx.xxx.xxx,xxxxx,
- }
- uint8_t REDFLY::socketSend(uint8_t socket, char *stream, uint8_t *ip, uint16_t port)
- {
- return socketSend(socket, (uint8_t*)stream, strlen(stream), ip, port);
- }
- uint8_t REDFLY::socketSendPGM(uint8_t socket, PGM_P stream, uint8_t *ip, uint16_t port)
- {
- uint8_t len;
- uint16_t size = strlen_P(stream);
- //socket
- uitoa(socket, (char*)buffer);
- //size
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- uitoa(size, (char*)&buffer[len]);
- //ip
- if(ip && (socketState(socket) == SOCKET_UDP))
- {
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- iptoa(ip, (char*)&buffer[len]);
- }
- else
- {
- strcat_P((char*)buffer, PSTR(",0"));
- }
- //port
- if(port && (socketState(socket) == SOCKET_UDP))
- {
- strcat_P((char*)buffer, PSTR(","));
- len = strlen((char*)buffer);
- uitoa(port, (char*)&buffer[len]);
- }
- else
- {
- strcat_P((char*)buffer, PSTR(",0"));
- }
- //data
- strcat_P((char*)buffer, PSTR(","));
- return cmd(PSTR(CMD_SEND), (char*)buffer, stream); //x,xxxx,xxx.xxx.xxx.xxx,xxxxx,
- }
- uint8_t REDFLY::socketSend(uint8_t socket, uint8_t *stream, uint16_t size)
- {
- return socketSend(socket, stream, size, 0, 0);
- }
- uint8_t REDFLY::socketSend(uint8_t socket, char *stream)
- {
- return socketSend(socket, (uint8_t*)stream, strlen(stream), 0, 0);
- }
- uint8_t REDFLY::socketSendPGM(uint8_t socket, PGM_P stream)
- {
- return socketSendPGM(socket, stream, 0, 0);
- }
- uint8_t REDFLY::socketSend(uint8_t socket, int val)
- {
- char buf[8];
- itoa(val, buf, 10);
- return socketSend(socket, (uint8_t*)buf, strlen(buf), 0, 0);
- }
- uint16_t REDFLY::socketRead(uint8_t *socket, uint16_t *len, uint8_t *ip, uint16_t *port, uint8_t *dst, uint16_t dst_size)
- {
- uint8_t stop=0;
- uint16_t rd=0;
- static uint8_t last_socket=INVALID_SOCKET;
- static uint16_t last_len=0;
- static uint8_t buf[8], pos=0;
- static uint16_t udp_port=0;
- static uint8_t udp_ip[4];
- if(read_state == 2) //we are currently reading data
- {
- if((*socket != INVALID_SOCKET) && (*socket != last_socket)) //abort if not searched socket
- {
- return 0;
- }
- if(dst_size == 0) //only get len and socket
- {
- *socket = last_socket;
- *len = last_len;
- return 0;
- }
- }
- do
- {
- switch(read_state)
- {
- case 0: //restart searching
- read_state = 1;
- last_socket = INVALID_SOCKET;
- last_len = 0;
- pos = 0;
- udp_port = 0;
- udp_ip[0] = 0;
- udp_ip[1] = 0;
- udp_ip[2] = 0;
- udp_ip[3] = 0;
- case 1: //search
- while((pos<8) && available())
- {
- buf[pos++] = read();
- }
- if(pos >= 8)
- {
- if((buf[0] == 'R') && \
- (buf[1] == 'S') && \
- (buf[2] == 'I') && \
- (buf[3] == '_') && \
- (buf[4] == 'R') && \
- (buf[5] == 'E') && \
- (buf[6] == 'A') && \
- (buf[7] == 'D')) //RSI_READ
- {
- last_socket = readwait();
- last_len = readwait();
- last_len |= readwait()<<8;
- if((last_socket == INVALID_SOCKET) || (last_len == 0))
- {
- read_state = 0;
- last_socket = INVALID_SOCKET;
- last_len = 0;
- break;
- }
- read_state = 2;
- //get IP and port on UDP connection
- if(socketState(last_socket) == SOCKET_UDP)
- {
- udp_ip[0] = readwait();
- udp_ip[1] = readwait();
- udp_ip[2] = readwait();
- udp_ip[3] = readwait();
- udp_port = readwait();
- udp_port |= readwait()<<8;
- }
- if((*socket != INVALID_SOCKET) && (*socket != last_socket)) //abort if not searched socket
- {
- return 0;
- }
- if(dst_size == 0)
- {
- stop = 1; //break loop
- }
- }
- else if((buf[0] == 'S') && \
- (buf[1] == 'I') && \
- (buf[2] == '_') && \
- (buf[3] == 'C') && \
- (buf[4] == 'L') && \
- (buf[5] == 'O') && \
- (buf[6] == 'S') && \
- (buf[7] == 'E')) //SI_CLOSE
- {
- last_socket = readwait();
- readwait(); readwait(); //trailing \r\n
- last_len = 0;
- rd = 0xFFFF;
- read_state = 0;
- stop = 1; //break loop
- for(uint8_t i=0; i<MAX_SOCKETS; i++)
- {
- if(socket_state[i].handle == last_socket)
- {
- socket_state[i].handle = INVALID_SOCKET;
- socket_state[i].state = SOCKET_CLOSED;
- break;
- }
- }
- }
- else
- {
- //move one byte
- pos = 7;
- buf[0] = buf[1];
- buf[1] = buf[2];
- buf[2] = buf[3];
- buf[3] = buf[4];
- buf[4] = buf[5];
- buf[5] = buf[6];
- buf[6] = buf[7];
- }
- }
- break;
- case 2: //receive
- *dst = readwait();
- dst_size--;
- rd++;
- if(--last_len == 0)
- {
- readwait(); readwait(); //trailing \r\n
- read_state = 0;
- stop = 1; //break loop
- }
- else if(dst_size == 0)
- {
- stop = 1; //break loop
- }
- break;
- }
- }while(available() && (stop == 0));
- *socket = last_socket;
- *len = last_len;
- if(ip && udp_ip[0])
- {
- ip[0] = udp_ip[0];
- ip[1] = udp_ip[1];
- ip[2] = udp_ip[2];
- ip[3] = udp_ip[3];
- }
- if(port && udp_port)
- {
- *port = udp_port;
- }
- return rd;
- }
- uint16_t REDFLY::socketRead(uint8_t *socket, uint16_t *len, uint8_t *dst, uint16_t dst_size) //TCP connection
- {
- return socketRead(socket, len, 0, 0, dst, dst_size);
- }
- void REDFLY::socketReset(void)
- {
- read_state = 0;
- for(uint8_t i=0; i<MAX_SOCKETS; i++)
- {
- socket_state[i].handle = INVALID_SOCKET;
- socket_state[i].state = SOCKET_CLOSED;
- }
- flush();
- return;
- }
- //-------------------- Private --------------------
- 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)
- {
- uint8_t c, i;
- uint32_t ms;
- uint32_t timeout;
- uint8_t buf[8]; //ERRORx
- if(read_state == 2) //currently receiving data?
- {
- return 0xFF;
- }
- else if(available()) //check for new data
- {
- uint8_t sock=INVALID_SOCKET;
- uint16_t len=0;
- socketRead(&sock, &len, 0, 0, 0, 0);
- if(len != 0) //rx data found
- {
- return 0xFF;
- }
- }
- //send p1 command
- c = pgm_read_byte(p1++);
- while(c != 0)
- {
- write(c);
- c = pgm_read_byte(p1++);
- }
- //send v1 parameter 1
- if(v1)
- {
- while(*v1)
- {
- write(*v1++);
- }
- }
- //send p2 parameter 2
- if(p2)
- {
- c = pgm_read_byte(p2++);
- while(c != 0)
- {
- if(c == 0xDB) //0xDB -> 0xDB 0xDD
- {
- write(0xDB);
- write(0xDD);
- c = pgm_read_byte(p2++);
- }
- else if((c == 0x0D) && (pgm_read_byte(p2) == 0x0A)) //\r\n -> 0xDB 0xDC
- {
- write(0xDB);
- write(0xDC);
- p2++;
- c = pgm_read_byte(p2++);
- }
- else
- {
- write(c);
- c = pgm_read_byte(p2++);
- }
- }
- }
- //send v2 parameter 3
- if(v2_size)
- {
- while(v2_size)
- {
- if(v2[0] == 0xDB) //0xDB -> 0xDB 0xDD
- {
- write(0xDB);
- write(0xDD);
- v2++; v2_size--;
- }
- else if((v2[0] == 0x0D) && (v2[1] == 0x0A) && (v2_size >= 2)) //\r\n -> 0xDB 0xDC
- {
- write(0xDB);
- write(0xDC);
- v2+=2; v2_size-=2;
- }
- else
- {
- write(*v2++);
- v2_size--;
- }
- }
- }
- //flush rx and tx buffer
- flush_nowait();
- //send end characters of command
- write('\r');
- write('\n');
- //read response
- timeout = 10000; //default timeout: 10s
- if(dst_size == 0) //dont save response
- {
- buf[0] = 0;
- buf[5] = 0;
- for(i=0, ms=millis(); (millis()-ms) < timeout;)
- {
- if(available())
- {
- c = read();
- if(i < 8)
- {
- buf[i++] = c;
- if((buf[0] != 'O') && (buf[0] != 'E')) //OK or ERROR
- {
- i = 0;
- }
- }
- ms = millis();
- timeout = 3; //3 ms timeout
- }
- }
- }
- else //save response to dst
- {
- dst[0] = 0;
- dst[5] = 0;
- for(i=0, ms=millis(); (millis()-ms) < timeout;)
- {
- if(available())
- {
- c = read();
- if(i < dst_size)
- {
- dst[i++] = c;
- if((dst[0] != 'O') && (dst[0] != 'E')) //OK or ERROR
- {
- i = 0;
- }
- }
- ms = millis();
- timeout = 3; //3 ms timeout
- }
- }
- buf[0] = dst[0];
- buf[1] = dst[1];
- buf[5] = dst[5];
- }
- //check response
- if((buf[0] == 'O') && (buf[1] == 'K'))
- {
- return 0; //OK
- }
- else if((buf[0] == 'E') && (buf[1] == 'R') && (buf[5] != 0) && (buf[5] != '\r'))
- {
- return buf[5]; //ERROR code
- }
- return 0xFF;
- }
- uint8_t REDFLY::cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, int16_t val)
- {
- char buf[8];
- itoa(val, buf, 10);
- return cmd(dst, dst_size, p1, buf, 0, 0, 0);
- }
- 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); }
- 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); }
- uint8_t REDFLY::cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1) { return cmd(dst, dst_size, p1, 0, 0, 0, 0); }
- uint8_t REDFLY::cmd( PGM_P p1, char *v1, PGM_P p2) { return cmd( 0, 0, p1, v1, p2, 0, 0); }
- 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); }
- uint8_t REDFLY::cmd( PGM_P p1, char *v1) { return cmd( 0, 0, p1, v1, 0, 0, 0); }
- uint8_t REDFLY::cmd( PGM_P p1, int16_t v1) { return cmd( 0, 0, p1, v1 ); }
- uint8_t REDFLY::cmd( PGM_P p1) { return cmd( 0, 0, p1, 0, 0, 0, 0); }
- void REDFLY::flush(void)
- {
- uint32_t ms;
- //clear tx buffer
- _SERIAL_.flush();
- //clear rx buffer
- #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
- for(ms=millis(); ((_UCSRA_&(1<<_RXC_)) || available()) && ((millis()-ms) < 50);) //50ms
- #else
- for(ms=millis(); available() && ((millis()-ms) < 50);) //50ms
- #endif
- {
- read();
- }
- delay_10ms(1);
- return;
- }
- void REDFLY::flush_nowait(void)
- {
- //clear tx buffer
- _SERIAL_.flush();
- //clear rx buffer
- for(int len=available(); len!=0; len--)
- {
- read();
- }
- return;
- }
- int REDFLY::available(void)
- {
- return _SERIAL_.available();
- }
- uint8_t REDFLY::readwait(void) //serial read
- {
- while(!available());
- return (uint8_t)_SERIAL_.read();
- }
- uint8_t REDFLY::read(void) //serial read
- {
- return _SERIAL_.read();
- }
- void REDFLY::write(uint8_t c) //serial write
- {
- _SERIAL_.write(c);
- return;
- }
- void REDFLY::setbaudrate(uint32_t br) //set serial baudrate and config (8n2)
- {
- if(br < 9600)
- {
- br = 9600;
- }
- else if(br > 3686400)
- {
- br = 3686400;
- }
- _SERIAL_.begin(br);
- //8 N 2
- #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
- _UCSRC_ |= (1<<_USBS_);
- #else
- _USART_->US_MR |= US_MR_NBSTOP_2_BIT;
- //_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;
- #endif
- return;
- }
- char* REDFLY::iptoa(uint8_t *ip, char *s) //convert ip to string
- {
- sprintf_P(s, PSTR("%i.%i.%i.%i"), ip[0], ip[1], ip[2], ip[3]);
- return s;
- }
- char* REDFLY::uitoa(uint16_t val, char *s) //convert unsigned int to string
- {
- sprintf_P(s, PSTR("%u"), val);
- return s;
- }
- void REDFLY::delay_10ms(uint8_t ms) //delay of 10ms * x
- {
- for(; ms!=0; ms--)
- {
- #if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
- _delay_ms(10);
- #else
- delay(10);
- #endif
- }
- return;
- }
|