Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: Wifly.cpp
- Revision:
- 0:27e403b8981e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Wifly.cpp Sat Apr 28 21:09:44 2012 +0000 @@ -0,0 +1,436 @@ +#include "mbed.h" +#include "Wifly.h" +#include <string> + +// #define DEBUG + + +Wifly::Wifly( PinName tx, PinName rx, PinName _reset, char * ssid, char * ip, char * netmask, int channel, int baudrate): + wifi(tx, rx), reset_pin(_reset) { + wifi.baud(baudrate); + wifi.format(8, Serial::None, 1); + adhoc = true; + strcpy(this->ssid, ssid); + strcpy(this->ip, ip); + strcpy(this->netmask, netmask); + this->channel = channel; + last_char = '\0'; + reset(); +} + + +void Wifly::handler_rx(void) { + char read = wifi.getc(); + if(read == 'q') { + attach_img(true); + gettingImg = true; + last_char = read; + } else if(read == 'g'){ + attach_cmd(true); + } else { + buf_wifly.queue(read); + } + //call user callback + rx.call(); +} + +void Wifly::handler_img(void) { + char read = wifi.getc(); + // printf("%c", read); + if (read == '*') { + gettingImg = false; + gotImg = true; + attach_img(false); + attach_rx(true); + } + img_buffer.queue(read); + // printf("%d",img_buffer.available()); + if (img_buffer.isFull()) { + write_img(); + } +} + +void Wifly::handler_cmd(void) { + char read = wifi.getc(); + if (cmd_buffer.queue(read)) { + attach_rx(true); + } +} + +void Wifly::attach_rx(bool null) { + if (!null) { + wifi.attach(NULL); + } else { + wifi.attach(this, &Wifly::handler_rx); + } +} + +void Wifly::write_img(void) { + printf("\n\rWriting Image\n\r"); + fp = fopen("/local/pic.bmp", "a"); + char a, c; + while (!img_buffer.isEmpty()) { + img_buffer.dequeue((uint8_t *) &c); + a = (char_to_num(c)<<4) & 0xf0; + img_buffer.dequeue((uint8_t *) &c); + a |= char_to_num(c) & 0x0f; + printf("%x",a); + fwrite(&a, 1, sizeof(char), fp); + } + fpos_t pos; + fgetpos(fp,&pos); + fclose(fp); + wifi.printf("Did it!"); +} + +void Wifly::attach_img(bool null) { + printf("img "); + if (!null) { + wifi.attach(NULL); + if (!img_buffer.isEmpty()) { + write_img(); + } + printf("end\n\r"); + } else { + printf("start\n\r"); + remove("/local/pic.bmp"); + img_buffer.clear(); + wifi.attach(this, &Wifly::handler_img); + } +} + +void Wifly::attach_cmd(bool null) { + if (!null) + wifi.attach(NULL); + else + wifi.attach(this, &Wifly::handler_cmd); +} + +bool Wifly::send(char * str, char * ACK, char * res) { + char read; + size_t found = string::npos; + string checking; + Timer tmr; + +#ifdef DEBUG + printf("will send: %s\r\n",str); +#endif + + + attach_rx(false); + if (!strcmp(ACK, "NO")) { + wifi.printf("%s", str); + } else { + //We flush the buffer + while (wifi.readable()){ + wifi.getc(); + } + + tmr.start(); + wifi.printf("%s", str); + + while (1) { + if (tmr.read() > 3) { + //We flush the buffer + while (wifi.readable()) + wifi.getc(); +#ifdef DEBUG + printf("check: %s\r\n", checking.c_str()); +#endif + attach_rx(true); + return false; + } else if (wifi.readable()) { + read = wifi.getc(); + if ( read != '\r' && read != '\n') { + checking += read; + found = checking.find(ACK); + if (found != string::npos) { + wait(0.01); + + //We flush the buffer + while (wifi.readable()) + wifi.getc(); + + break; + } + } + } + } +#ifdef DEBUG + printf("check: %s\r\n", checking.c_str()); +#endif + attach_rx(true); + return true; + } + + //the user wants the result from the command (ACK == "NO", res != NULL) + if ( res != NULL) { + int i = 0; + Timer timeout; + timeout.start(); + while (1) { + if (timeout.read() > 3) { + read = NULL; + return false; + } else { + if (tmr.read_ms() > 500) { + res[i] = 0; +#ifdef DEBUG + printf("user str: %s\r\n", res); +#endif + attach_rx(true); + return true; + } + if (wifi.readable()) { + tmr.start(); + read = wifi.getc(); + if ( read != '\r' && read != '\n') { + res[i++] = read; + } + } + } + } + } + attach_rx(true); + return true; +} + +bool Wifly::attach_interrupt(char cmd, void (*func)(Command *), int num) { + return cmd_buffer.attach_interrupt(cmd, func, num); +} + +bool Wifly::hasCmd() { + return cmd_buffer.available(); +} + +Command * Wifly::getCmd() { + Command * c = NULL; + if (cmd_buffer.available()){ + c = cmd_buffer.dequeue(); + } + return c; +} + +bool Wifly::sendCmd(Command * c){ + char str[4 + 5*9]; + str[0] = 'g'; + str[1] = '0'; + str[2] = num_to_char(c->cmd); + str[3] = ' '; + switch(c->cmd){ + case 7: + for (int i=0; i < 5; i++) { + long_to_str(str + 4 + 9*i, c->l[i]); + } + str[4 + 5*9 - 1] = '\0'; + return send(str); + case 9: + for (int i=0; i < 2; i++) { + long_to_str(str + 4 + 9*i, c->l[i]); + } + str[4 + 2*9 - 1] = '\0'; + return send(str); + case 8: + default: + for (int i=0; i < 5; i++) { + long_to_str(str + 4 + 9*i, c->l[i]); + str[12 + 9 * i] = ' '; + } + str[4 + 5*9 - 1] = '\0'; + return send(str); + } +} + +bool Wifly::createAdhocNetwork() { + if (adhoc) { + char cmd[50]; + + if (!cmdMode()) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: Failed to enter cmd mode. Retrying...\r\n"); +#endif + if (!cmdMode()) { + #ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: Cannot enter cmd mode.\r\n"); +#endif + exit(); + return false; + } + } + + if (!send("set w j 4\r", "AOK")) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: cannot set join 4\r\n"); +#endif + exit(); + return false; + } + + //no echo + if (!send("set u m 1\r", "AOK")) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: cannot set no echo\r\n"); +#endif + exit(); + return false; + } + + //ssid + sprintf(cmd, "set w s %s\r", ssid); + if (!send(cmd, "AOK")) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: cannot set ssid\r\n"); +#endif + exit(); + return false; + } + + sprintf(cmd, "set w c %d\r", channel); + if (!send(cmd, "AOK")) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: cannot set channel\r\n"); +#endif + exit(); + return false; + } + + sprintf(cmd, "set i a %s\r", ip); + if (!send(cmd, "AOK")) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: cannot set ip address\r\n"); +#endif + exit(); + return false; + } + + sprintf(cmd, "set i n %s\r", netmask); + if (!send(cmd, "AOK")) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: cannot set netmask\r\n"); +#endif + exit(); + return false; + } + + if (!send("set i d 0\r", "AOK")) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: cannot set dhcp off\r\n"); +#endif + exit(); + return false; + } + + if (!send("save\r", "Stor")) { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: cannot save\r\n"); +#endif + exit(); + return false; + } + + flush(); + + send("reboot\r", "NO"); +#ifdef DEBUG + printf("\r\ncreating an adhoc\r\nnetwork: %s\r\nip: %s\r\nnetmask: %s\r\nchannel: %d\r\n\r\n", ssid, ip, netmask, channel); +#endif + + wait(0.1); + flush(); + return true; + } else { +#ifdef DEBUG + printf("Wifly::CreateAdhocNetwork: You didn't choose the right constructor for creating an adhoc mode!\r\n"); +#endif + return false; + } +} + +void Wifly::flush() { + while (readable()) + getc(); +} + +bool Wifly::cmdMode() { + if (!send("$$$", "CMD")) { +#ifdef DEBUG + printf("Wifly::cmdMode: cannot enter in cmd mode\r\n"); +#endif + return false; + } + return true; +} + +void Wifly::reset() { + reset_pin = 0; + wait(0.2); + reset_pin = 1; + wait(0.2); +} + +void Wifly::putc(char c) { + while (!wifi.writeable()); + wifi.putc(c); +} + +bool Wifly::read(char * str) { + int length = buf_wifly.available(); + if (length == 0) + return false; + for (int i = 0; i < length; i++) + buf_wifly.dequeue((uint8_t *)&str[i]); + str[length] = 0; + return true; +} + +bool Wifly::exit() { + return send("exit\r", "EXIT"); +} + + +int Wifly::readable() { + return buf_wifly.available(); +} + +char Wifly::getc() { + char c; + while (!buf_wifly.available()); + buf_wifly.dequeue((uint8_t *)&c); + return c; +} + +char Wifly::num_to_char(char n) { + if(n <= 9) { + return n + '0'; + } else if (n >= 0xa && n <= 0xf) { + return n + 'a' - 0xa; + } else { + return 0; + } +} + +void Wifly::long_to_str(char * str, long n) { + for (int i = 0; i < 8; i += 2) { + str[i+1] = num_to_char(n & 0x0f); + n = n >> 4; + str[i] = num_to_char(n & 0x0f); + n = n >> 4; + } +} + +void Wifly::float_to_str(char * str, float f) { + long_to_str(str, (long) f); +} + +// Return 0xf if char is invalid +char Wifly::char_to_num(char c) { + if(c >= '0' && c <= '9') { + return c - '0'; + } else if(c >= 'a' && c <= 'f') { + return c - 'a' + 0xa; + } else if(c >= 'A' && c <= 'F') { + return c - 'A' + 0xa; + } else { + return 0xf; + } +}