Browse Source

switched to platformIO

subDesTagesMitExtraKaese 4 years ago
parent
commit
c354bd49b6
52 changed files with 8378 additions and 89 deletions
  1. 7 0
      .gitignore
  2. 7 0
      .vscode/extensions.json
  3. 0 6
      data.txt
  4. 89 0
      ether.py
  5. 77 0
      gif.py
  6. BIN
      image.png
  7. 20 0
      include/config.hpp
  8. 29 0
      include/matrix.hpp
  9. 15 0
      include/redFlyClient.hpp
  10. 9 0
      include/serialClient.hpp
  11. 543 0
      lib/RedFly/README.md
  12. 1494 0
      lib/RedFly/RedFly.cpp
  13. 181 0
      lib/RedFly/RedFly.h
  14. 456 0
      lib/RedFly/RedFlyClient.cpp
  15. 63 0
      lib/RedFly/RedFlyClient.h
  16. 168 0
      lib/RedFly/RedFlyCommands.h
  17. 223 0
      lib/RedFly/RedFlyNBNS.cpp
  18. 33 0
      lib/RedFly/RedFlyNBNS.h
  19. 392 0
      lib/RedFly/RedFlyServer.cpp
  20. 59 0
      lib/RedFly/RedFlyServer.h
  21. 356 0
      lib/RedFly/digitalWriteFast.h
  22. 182 0
      lib/RedFly/examples/Adhoc/Adhoc.ino
  23. 147 0
      lib/RedFly/examples/EchoTest/EchoTest.ino
  24. 31 0
      lib/RedFly/examples/FWupdate/FWupdate.ino
  25. 176 0
      lib/RedFly/examples/Infrastructure/Infrastructure.ino
  26. 174 0
      lib/RedFly/examples/NBNS/NBNS.ino
  27. 132 0
      lib/RedFly/examples/NTP/NTP.ino
  28. 317 0
      lib/RedFly/examples/Paint/Paint.ino
  29. 354 0
      lib/RedFly/examples/TwitterRSSReader/TwitterRSSReader.ino
  30. 175 0
      lib/RedFly/examples/TwitterTest/TwitterTest.ino
  31. 177 0
      lib/RedFly/examples/TwitterTest_Socket/TwitterTest_Socket.ino
  32. 308 0
      lib/RedFly/examples/TwitterWriter/TwitterWriter_Socket.ino
  33. 139 0
      lib/RedFly/examples/UDP/UDP.ino
  34. 119 0
      lib/RedFly/examples/WLANScan/WLANScan.ino
  35. 163 0
      lib/RedFly/examples/WebClient/WebClient.ino
  36. 34 83
      lib/RedFly/examples/WebClient_Socket/WebClient_Socket.ino
  37. 181 0
      lib/RedFly/examples/WebServer/WebServer.ino
  38. 390 0
      lib/RedFly/examples/WebServer2/WebServer2.ino
  39. 194 0
      lib/RedFly/examples/WebServer_Socket/WebServer_Socket.ino
  40. 58 0
      lib/RedFly/examples/WebServer_Socket/conn_test.htm
  41. 166 0
      lib/RedFly/examples/XivelyClient/XivelyClient.ino
  42. 13 0
      lib/RedFly/library.json
  43. 9 0
      lib/RedFly/library.properties
  44. 20 0
      platformio.ini
  45. 51 0
      redfly-led.py
  46. 96 0
      serial-led.py
  47. BIN
      src/cie.ods
  48. 11 0
      src/config.cpp
  49. 86 0
      src/main.cpp
  50. 80 0
      src/matrix.cpp
  51. 123 0
      src/redFlyClient.cpp
  52. 51 0
      src/serialClient.cpp

+ 7 - 0
.gitignore

@@ -0,0 +1,7 @@
+.pio
+.vscode/.browse.c_cpp.db*
+.vscode/c_cpp_properties.json
+.vscode/launch.json
+.vscode/ipch
+
+*.gif

+ 7 - 0
.vscode/extensions.json

@@ -0,0 +1,7 @@
+{
+    // See http://go.microsoft.com/fwlink/?LinkId=827846
+    // for the documentation about the extensions.json format
+    "recommendations": [
+        "platformio.platformio-ide"
+    ]
+}

+ 0 - 6
data.txt

@@ -1,6 +0,0 @@
-
-@$ h"’(#@,  " �(`4�n8@& `  " B"0'|3&`8  ( `# h"—(#‚  ( @ €! ’`<�@‚$! $`cC  €  '„1&  ‚ @, 
-€F"l"st F2�€B!0A€4`J%0I%x()R V(8$pJ!xDda)%`D"l"tt 1u +i@#@x s€t2@0e#lP bRV;0(!!FI!V$29‘2 
-@u h[’h An2@j!0)`|“j$PG%d4i3 J"0‡}2!d<J`H&`t h[wh “t`hjX!€$ rn<1@‚=!Bu`cBJ5€4 —D1!Jj“dB. 
-@t"("b` Ab3`f 0I`00*$0A%d4MB B*0$d"!d$N 9"`t"("q` 1t`hŠD"@d r`00@"5!‚u`pBJ5 =!$D!!JJ2dC" 
-@D <"— #†l2€J �(€1�.80f"x)kS B"X'|#&x9J`I!`C <"— #�H ;yX#@$ —€=€€’4"Bu`{“J5€4 'Ž!&Jdƒdb, 

+ 89 - 0
ether.py

@@ -0,0 +1,89 @@
+#!/bin/python3
+
+import socket
+import sys
+import time
+import math
+import requests
+from json.decoder import JSONDecodeError
+from PIL import Image, ImageDraw, ImageFont
+
+# Create a TCP/IP socket
+sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+
+server_address = ('0.0.0.0', 2020)
+print('binding {} port {}'.format(*server_address))
+sock.bind(server_address)
+
+
+N_ROWS = 5
+N_COLS = 10
+
+#font = ImageFont.truetype('5by5.ttf', 5)
+
+def req():
+  try:
+    response = requests.get('https://api.ethereumdb.com/v1/timeseries?pair=ETH-EUR&range=10mi&type=line')
+    json = response.json()
+    print(json[0]['price'])
+    return float(json[0]['price'])
+  except requests.ConnectionError:
+    print("connection error")
+  except JSONDecodeError:
+    print("decode error")
+  except KeyError:
+    print("key error")
+
+def render(txt):
+  image = Image.new("RGB", (len(txt)*4+4,N_ROWS), (0,0,0))
+  draw = ImageDraw.Draw(image)
+  draw.text((0, -1), txt, (255,255,255), font=font)
+  image.save('image.png')
+  return image
+
+def getBytes(price):
+  pixels = [0] * (N_ROWS * N_COLS)
+  digit = math.floor(math.log10(price))
+  for row in range(N_ROWS):
+    val = int(price / 10**(digit)) % 10
+    for col in range(N_COLS):
+      if col >= 9-val and col < 9:
+        pixels[row*N_COLS + col] = 15
+      elif digit == 0 and col == 9:
+        pixels[row*N_COLS + col] = 9
+    digit -= 1
+
+
+  pixels[49] = int(pixels[49]/2)
+  return bytes([0x41] + pixels)
+
+
+client_address = None
+oldPing = time.time()
+def send(pixels):
+  global oldPing, client_address, sock
+  if not client_address:
+    data, addr = sock.recvfrom(16)
+    print('received {} from {}'.format(data, addr))
+    client_address = addr
+  else:
+    sock.sendto(pixels, client_address)
+    if time.time() - oldPing > 30:
+      data, addr = sock.recvfrom(16)
+      print('received {} from {}'.format(data, addr))
+      client_address = addr
+      oldPing = time.time()
+
+while True:
+  try:
+    price = req()
+    pixels = getBytes(price)
+    for i in range(20):
+      send(pixels)
+      time.sleep(1)
+
+  except OSError:
+    print("os error")
+      
+print('closing socket')
+sock.close()

+ 77 - 0
gif.py

@@ -0,0 +1,77 @@
+#!/bin/python3
+
+import socket
+import sys
+import random
+import time
+import math
+from PIL import Image
+
+im = Image.open("wave.gif")
+N_ROWS = 5
+N_COLS = 10
+oldPing = time.time()
+
+# Create a TCP/IP socket
+sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+
+# Connect the socket to the port where the server is listening
+server_address = ('0.0.0.0', 2020)
+print('binding {} port {}'.format(*server_address))
+sock.bind(server_address)
+sock.settimeout(30)
+
+def getBytes(im):
+  x = im.load()
+  pixels = [0] * (N_ROWS * N_COLS)
+  for row in range(N_ROWS):
+    for col in range(N_COLS):
+      pixels[row*N_COLS + col] = int(int(x[col, row]/16) + random.random() * (x[col, row]-int(x[col, row])))
+
+  pixels[49] = int(pixels[49]/2)
+  return bytes([0x41] + pixels)
+
+frames = []
+try:
+  while 1:
+    im.seek(im.tell()+1)
+    im.thumbnail((N_COLS, N_ROWS), Image.ANTIALIAS)
+    pixels = getBytes(im)
+    frames.append(pixels)
+except EOFError:
+  pass
+
+client_address = None
+frameIndex = 0
+print('frame count:', len(frames))
+if not frames:
+  exit(1)
+
+
+try:
+  while True:
+    if not client_address:
+      try:
+        print('waiting...')
+        data, addr = sock.recvfrom(16)
+        print('received {} from {}'.format(data, addr))
+        client_address = addr
+      except socket.timeout:
+        pass
+    else:
+      sock.sendto(frames[frameIndex], client_address)
+      frameIndex = (frameIndex+1) % len(frames)
+      if time.time() - oldPing > 30:
+        try:
+          data, addr = sock.recvfrom(16)
+          print('received {} from {}'.format(data, addr))
+          client_address = addr
+          oldPing = time.time()
+        except socket.timeout:
+          client_address = None
+    time.sleep(1/40)
+except KeyboardInterrupt:
+  pass
+finally:
+    print('closing socket')
+    sock.close()

BIN
image.png


+ 20 - 0
include/config.hpp

@@ -0,0 +1,20 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <inttypes.h>
+#include <Arduino.h>
+#include <avr/wdt.h>
+#include <EEPROM.h>
+
+struct config_t {
+  char ssid[32];
+  char pass[32];
+  char host[32];
+  int port;
+};
+
+extern config_t config;
+void config_init();
+void config_save();
+
+#endif

+ 29 - 0
include/matrix.hpp

@@ -0,0 +1,29 @@
+#ifndef MATRIX_H
+#define MATRIX_H
+
+#include <inttypes.h>
+#include <Arduino.h>
+
+#define N_ROWS 5
+#define N_COLS 10
+
+struct row_t {
+  uint8_t bytes[N_COLS];
+};
+
+struct matrix_t {
+    union {
+    row_t rows[N_ROWS];
+    uint8_t bytes[sizeof(row_t) * N_ROWS];
+  };
+};
+
+extern matrix_t matrix;
+
+void matrix_init();
+void writeRow(const uint8_t& nRow, const uint16_t& values);
+void nextRow();
+
+extern uint16_t n;
+
+#endif

+ 15 - 0
include/redFlyClient.hpp

@@ -0,0 +1,15 @@
+#include <inttypes.h>
+#include <Arduino.h>
+#include <avr/wdt.h>
+
+#include <RedFly.h>
+#include <RedFlyClient.h>
+
+#include "matrix.hpp"
+#include "config.hpp"
+
+void debugout(const char* fmt, ...);
+//void debugMatrix(const matrix_t& matrix);
+int8_t connect();
+int8_t readUDP();
+void ping();

+ 9 - 0
include/serialClient.hpp

@@ -0,0 +1,9 @@
+#include <inttypes.h>
+#include <Arduino.h>
+#include <avr/wdt.h>
+
+#include "matrix.hpp"
+#include "config.hpp"
+
+
+int8_t readSerial();

+ 543 - 0
lib/RedFly/README.md

@@ -0,0 +1,543 @@
+# RedFly-Shield
+
+## FAQ
+
+### Howto update the Firmware?
+See the [Firmware Update Guide](https://github.com/watterott/RedFly-Shield/blob/master/fw/update_guide/README.md).
+
+### Which pins does the RedFly use?
+Used pins: D0, D1, D2, D3
+
+The RedFly also uses the first hardware serial port (data format 8N2) of the Arduino (D0+D1).
+If you want to use this serial port for other things then you have to disable the communication with the RedFly at first (see *enable()* and *disable()*).
+
+### Why I am getting errors when I send commands/data to the RedFly?
+When sending commands to the RedFly you always have to check that the serial input buffer doesn't contain data (see *socketRead()*, *client.read()* and *server.read()*).
+
+### The received data is not correct?
+If you have receiving problems, e.g. on a high data volume, then set a higher communication baud rate with the *init()* function.
+
+### A connection cannot be established to the RedFly?
+Check if your AP has a *client isolation* option and if it is disabled.
+Also some customers reported problems with AVM FritzBox routers as AP. In this case disable the automatic WiFi power managment and try with maximum WiFi power and fixed data rate.
+
+### The WiFi connection does not work (*join()* or *begin()* return an error)?
+In high power transmit mode an external power supply is recommended, because in some cases the USB port has not enough power.
+
+### The initialization of the WiFi module does not work (*init()* returns a value >0)?
+Try to update/re-flash the WiFi module firmware: [Firmware Update Guide](https://github.com/watterott/RedFly-Shield/tree/master/fw/update_guide)
+
+### What is the wireless range of the RedFly?
+The range varies depending on the environment (indoor, outdoor, other nearby WiFi networks).
+The indoor range is about 10-20 meters and the outdoor range is up to 200 meters.
+
+### What WiFi module is on the RedFly?
+It is a Redpine Signals RS9110-N-11-22 with UART interface.
+
+
+## Examples
+
+Examples can be found in the Arduino IDE under ```File -> Examples -> RedFly```.
+
+French description and additional functions:
+* http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.LibrairieRedFly
+* http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.MATERIELArduinoShieldWifiRedflyShield
+
+DHCP and DNS servers for RedFly:
+* http://notebook.kulchenko.com/embedded/dhcp-and-dns-servers-with-arduino
+* https://github.com/pkulchenko/DHCPLite
+
+
+## Libraries
+
+
+### RedFly
+
+    uint8_t init(uint32_t br, uint8_t pwr)
+    uint8_t init(uint8_t pwr) //br=9600
+    uint8_t init(void) //br=9600, pwr=HIGH_POWER
+* br - Baud rate: 9600, 19200, 38400, 57600, 115200, 200000, 230400, 460800, 921600, 1843200, 3686400 (only baud rates up to 230400 are support by Arduino @ 16MHz)
+* pwr - Transmitter power and data rate:
+  * LOW_POWER,     MED_POWER,     HIGH_POWER     (auto data rate)
+  * LOW_POWER_1M,  MED_POWER_1M,  HIGH_POWER_1M  (1Mbps data rate)
+  * LOW_POWER_2M,  MED_POWER_2M,  HIGH_POWER_2M  (2Mbps data rate)
+  * LOW_POWER_11M, MED_POWER_11M, HIGH_POWER_11M (11Mbps data rate)
+  * LOW_POWER_12M, MED_POWER_12M, HIGH_POWER_12M (12Mbps data rate)
+  * LOW_POWER_24M, MED_POWER_24M, HIGH_POWER_24M (24Mbps data rate)
+  * LOW_POWER_54M, MED_POWER_54M, HIGH_POWER_54M (54Mbps data rate)
+
+Initialize the WiFi module and set baud rate and transmitter power. Returns 0 if everything is okay.
+
+    void enable(void)
+Enable communication with the RedFly-Shield.
+Note: The function clears the serial input and output buffer.
+
+    void disable(void)
+Disable communication with the RedFly-Shield.
+Note: The function clears the serial input and output buffer.
+
+    uint8_t getversion(char *ver)
+* ver - Pointer to a buffer to receive the version
+
+Get the firmware version. The return value is 0 if the version is successfully copied to *ver*.
+
+    uint8_t getmac(uint8_t *mac)
+* mac - Pointer to a buffer to receive the address
+
+Get the MAC address of the WiFi module. The return value is 0 if the MAC is successfully copied to *mac*.
+
+    uint8_t getlocalip(uint8_t *ip)
+* ip - Pointer to a buffer to receive the address
+
+Get the IP address of the WiFi module. The return value is 0 if the IP is successfully copied to *ip*.
+
+    uint8_t getip(char *host, uint8_t *ip)
+* host - host name
+* ip - Pointer to a buffer to receive the IP address
+
+Returns 0 if the ip address of the searched host is succefully received. (FW >= 4.3.0 required)
+
+    uint32_t gettime(uint8_t *server, uint16_t port)
+    uint32_t gettime(uint8_t *server) //use port 123
+* server - IP address of NTP server
+* port - Port of NTP server
+
+Returns the seconds since 1970 or 0 (zero) on an error.
+
+    uint8_t getrssi(void)
+Returns the signal strengh (in dBm) of the current connection.
+
+    uint8_t getbssid(char *ssid, uint8_t *mac)
+* ssid - Pointer to a buffer to receive the SSID
+* mac - Pointer to a buffer to receive the MAC address
+
+Get the SSID and MAC of the scanned network. The return value is 0 if no error occurred.
+Note: Run this function direct after *scan()* or *nextscan()*.
+
+    uint8_t gettype(char *ssid, uint8_t *type)
+* ssid - Pointer to a buffer to receive the SSID
+* type - Pointer to a buffer to receive the type (0=Ad-hoc, 1=Infrastructure)
+
+Get the SSID and type of the scanned network. The return value is 0 if no error occurred.
+Note: Run this function direct after *scan()* or *nextscan()*.
+
+    uint8_t scan(uint8_t chn, char *ssid, uint8_t *mode, uint8_t *rssi)
+    uint8_t scan(char *ssid, uint8_t *mode, uint8_t *rssi)
+    uint8_t scan(char *ssid)
+    uint8_t scan(void)
+* chn - Channel (0=all channels)
+* ssid - Pointer to a buffer to receive the SSID (if set on function call, the module scans for networks with hidden SSID)
+* mode - Pointer to a buffer to receive the mode value 0=Open, 1=WPA, 2=WPA2, 3=WEP
+* rssi - Pointer to a buffer to receive the RSSI value (signal strengh)
+
+Scan for wireless networks and return SSID, Mode and RSSI. If the scanning was successful the return vaule is 0.
+Note: A scan cannot be started after joining a network.
+
+    uint8_t nextscan(char *ssid, uint8_t *mode, uint8_t *rssi)
+    uint8_t nextscan(char *ssid)
+* ssid - SSID
+* mode - Mode
+* rssi - RSSI
+
+Scan for next wireless networks and return SSID, Mode and RSSI. If the scanning was successful the return vaule is 0.
+Note: Run this function direct after *scan()* and a scan cannot be started after joining a network.
+
+    uint8_t join(char *ssid, char *key, uint8_t net, uint8_t chn, uint8_t authmode) //infrastructure or IBSS joiner / creator
+    uint8_t join(char *ssid, char *key, uint8_t net, uint8_t chn) //IBSS creator
+    uint8_t join(char *ssid, char *key, uint8_t net) //infrastructure or IBSS joiner
+    uint8_t join(char *ssid, uint8_t net, uint8_t chn) //IBSS creator
+    uint8_t join(char *ssid, uint8_t net) //infrastructure or IBSS joiner
+    uint8_t join(char *ssid, char *key) //infrastructure
+    uint8_t join(char *ssid) //infrastructure
+* ssid - SSID
+* key - Key / Password (max 31 characters, WEP-64bit: 10 hex digits and WEP-128bit: 26 hex digits)
+* net - Network: INFRASTRUCTURE, IBSS_JOINER, IBSS_CREATOR
+* chn - Channel: 0...14, 0=all channels
+* authmode - Auth mode: 0=Open Key, 1=Shared Key (only for WEP)
+
+Join wireless network. If everything is okay then the return value is 0.
+Note: *scan()* has to be called before this function for infrastructure and IBSS joiner networks. The maximum number of IBSS_JOINER devices (ad-hoc) is 4.
+
+    uint8_t disconnect(void)
+Disconnect / disassociate wireless connection.
+
+    uint8_t begin(uint8_t dhcp, uint8_t *ip, uint8_t *dns, uint8_t *gateway, uint8_t *netmask)
+    uint8_t begin(uint8_t *ip, uint8_t *dns, uint8_t *gateway, uint8_t *netmask)
+    uint8_t begin(uint8_t *ip, uint8_t *dns, uint8_t *gateway) //netmask=255.255.255.0
+    uint8_t begin(uint8_t *ip, uint8_t *dns) //netmask=255.255.255.0
+    uint8_t begin(uint8_t *ip) //netmask=255.255.255.0
+    uint8_t begin(uint8_t dhcp) //Use 1=DHCP or 2=Auto-IP to get IP config.
+    uint8_t begin(void) //Use DHCP to get IP config.
+* dhcp - 1=DHCP or 2=Auto-IP (only in infrastructure mode available, Auto-IP requires FW >= 4.3.0)
+* ip - IP address
+* dns - DNS server (FW >= 4.3.0 required)
+* gateway - Gateway address
+* netmask - Network mask
+
+Set IP configuration. If everything is okay then the return value is 0.
+
+    uint8_t socketConnect(uint8_t proto, uint8_t *ip, uint16_t port, uint16_t lport)
+    uint8_t socketConnect(uint8_t proto, uint8_t *ip, uint16_t port) //lport=1024
+* proto - Protocol: PROTO_TCP, PROTO_UDP, PROTO_MCAST (Multicast requires FW >= 4.3.0)
+* ip - Server IP address
+* port - Server port
+* lport - Local port
+
+Connect to server. Returns the socket handle or 0xFF on an error.
+
+    uint8_t socketListen(uint8_t proto, uint16_t lport)
+* proto - Protocol: PROTO_TCP, PROTO_UDP
+* lport - Local port
+
+Listen on port. Returns the socket handle or 0xFF on an error.
+Note: If you want to open multiply sockets with the same port number, you have to wait till the opened socket gets connected and then you can open a new socket with the same port number.
+
+__Example for using 2 sockets with the same port number:__
+```
+    uint8_t socket1=INVALID_SOCKET, socket2=INVALID_SOCKET; //socket handles
+    
+    void setup()
+    {
+      //init RedFly
+      //...
+      socket1 = RedFly.socketListen(PROTO_TCP, 123); //open 1st socket
+    }
+    
+    void loop()
+    {
+      uint8_t s=0xFF; //return data from all sockets
+      uint16_t len=0;
+      RedFly.socketRead(&s, &len, 0, 0, 0, 0);
+      if(len > 0) //data available?
+      {
+        if(s == socket1)
+        {
+          if(RedFly.socketClosed(socket2)) //check if 2nd socket is closed
+          {
+            socket2 = RedFly.socketListen(PROTO_TCP, 123); //open 2nd socket
+          }
+          //do something...
+        }
+        else if(s == socket2)
+        {
+          if(RedFly.socketClosed(socket1)) //check if 1st socket is closed
+          {
+            socket1 = RedFly.socketListen(PROTO_TCP, 123); //open 1st socket
+          }
+          //do something...
+        }
+      }
+    }
+```
+
+    uint8_t socketClose(uint8_t socket)
+* socket - Socket handle
+
+Close socket.
+
+    uint8_t socketClosed(uint8_t socket)
+* socket - Socket handle
+
+Is the socket closed? A return value >0 means that the socket is closed.
+
+    uint8_t socketStatus(uint8_t socket)
+* socket - Socket handle
+
+Get socket status from WiFi module (0xFF=error).
+
+    uint8_t socketState(uint8_t socket)
+* socket - Socket handle
+
+Get socket state (0x00=TCP, 0x01=UDP, 0x02=MCAST, 0xFF=closed).
+
+    uint8_t socketSend(uint8_t socket, uint8_t *stream, uint16_t size, uint8_t *ip, uint16_t port)
+    uint8_t socketSendPGM(uint8_t socket, PGM_P stream, uint8_t *ip, uint16_t port)
+    uint8_t socketSend(uint8_t socket, char *stream, uint8_t *ip, uint16_t port)
+    uint8_t socketSend(uint8_t socket, uint8_t *stream, uint16_t size)
+    uint8_t socketSendPGM(uint8_t socket, PGM_P stream)
+    uint8_t socketSend(uint8_t socket, char *stream)
+    uint8_t socketSend(uint8_t socket, int value)
+* socket - Socket handle
+* stream - Data
+* size - Data length
+* value - Data (int)
+* ip - Server IP address (only on UDP)
+* port - Server port (only on UDP)
+
+Send data on socket. The function returns 0 if everything is okay and 0xFF if there is new data in the input buffer (no data is sent).
+The *ip* and *port* parameters are only used on UDP connections.
+Note: The input buffer has to be empty before sending data (see *socketRead()*).
+
+    uint16_t socketRead(uint8_t *socket, uint16_t *len, uint8_t *ip, uint16_t *port, uint8_t *dst, uint16_t dst_size) //UDP connection
+    uint16_t socketRead(uint8_t *socket, uint16_t *len, uint8_t *dst, uint16_t dst_size)
+* socket - Socket handle (set from function or if set on function call, only return data from this socket)
+* len - Complete data length
+* ip - Server IP address (only UDP)
+* port - Server port (only UDP)
+* dst - Receive buffer
+* dst_size - Receive buffer length
+
+Read data. Returns data length in dst (0xFFFF=socket closed).
+
+__Example:__
+```
+    uint8_t socket=0xFF;   //0xFF = return data from all sockets, otherwise return only data from specialized socket
+    uint16_t len;          //complete data length, that is available
+    uint8_t ip[4];         //source IP, only on UDP connection
+    uint16_t port          //source port, only on UDP connection
+    uint8_t dst[64];       //destination buffer for the data
+    uint16_t d_size=64;    //size of destination buffer
+    uint16_t received_len; //data copied to destination buffer
+    received_len = RedFly.socketRead(&socket, &len, ip, &port, dst, d_size); //ip + port only on UDP connections
+    received_len = RedFly.socketRead(&socket, &len, dst, d_size);
+```
+
+#### Error codes
+```
+  -1 (0xFF) Waiting for the connection from peer.
+  -2 (0xFE) Socket not available.
+  -3 (0xFD) De-authentication from the Access Point.
+  -4 (0xFC) Illegal IP/Port parameters.
+  -5 (0xFB) TCP/IP configuration failure.
+  -6 (0xFA) Invalid socket.
+  -7 (0xF9) Association not done.
+  -8 (0xF8) Error in command.
+  -9 (0xF7) Error with byte stuffing for escape characters.
+ -10 (0xF6) IP Lease expired.
+ -11 (0xF5) TCP connection closed.
+ -12 (0xF4) Pre-Shared Key contains invalid characters (applicable in case of WEP).
+ -13 (0xF3) No Access Points present. This error is also issued if the security mode of the AP is different from the one supplied to the module in the "Authmode" command.
+ -14 (0xF2) 1. The "Init" command is sent more than once.
+            2. Flash access error for at_rsi_cfgenable command.
+            3. Returned for "Cfgget" command when the config save feature is not enabled.
+ -15 (0xF1) 1. The "Join" command is sent when module is already associated with an existing network.
+            2. Scan command is issued after the module has already associated with a network.
+            3. When there is a flash write failure for the "Cfgsave" command.
+            4. Module not in connected state (for "Cfgsave" command).
+ -16 (0xF0) DHCP Failure, DHCP Renewal not done by AP.
+ -17 (0xEF) Baud Rate not supported.
+ -18 (0xEE) Encryption mode not supported.
+ -19 (0xED) Invalid channel.
+ -20 (0xEC) "Snd" command is issued but there is no network in the remote terminal.
+ -21 (0xEB) Authentication failure.
+ -22 (0xEA) Re-join failure.
+ -23 (0xE9) Country information not found in probe response from AP during scan.
+ -24 (0xE8) Wrong PSK was supplied to the module.
+ -25 (0xE7) Invalid network type.
+ -26 (0xE6) Back ground scan cancelled.
+ -28 (0xE4) Unsupported bits are set in Feature Select bitmap.
+ -29 (0xE3) "Scan" command is issued before "Band" and "Init" commands.
+ -30 (0xE2) Tx data rate configured in module does not match the rates supported by the target AP.
+ -56 (0xC8) "Query RSSI" command issued in IBSS mode.
+ -55 (0xC9) For RSSI query in unassociated state.
+ -56 (0XC8) For rssi query in IBSS.
+ -58 (0xC6) Gives an error if memory limit exceeds for "Load" command to load tadm2 file.
+ -59 (0xC5) Unable to process command. The Host should stop sending commands to the module for some tens of millisecs.
+ -69 (0xBB) The reply did not contain an answer with an IP address.
+ -70 (0xBA) DNS class error.
+ -72 (0xB8) The number of queries is more than 1 or the number of replies is zero.
+ -73 (0xB7) The reply contained an error code.
+ -74 (0xB6) The reply was truncated or not a response to a standard query.
+ -75 (0xB5) The ID number of the reply did not match the ID number sent.
+ -85 (0xAB) No buffer was passed or the reply was too short.
+ -91 (0xA5) Invalid IP address passed or unable to send IGMP report.
+ -92 (0xA4) DNS response timed out.
+ -95 (0xA1) Unable to send data as ARP is not resolved.
+-100 (0x9C) DHCP handshake failure.
+-113 (0x8F) Unable to send data because of connectivity disruption (such as AP switched off abruptly).
+-121 (0x87) Error issued when trying to connect to a non-existent TCP server socket.
+-124 (0x84) Connection establishment failure.
+-127 (0x81) Socket already exists.
+-128 (0x80) Attempt to open more than 8 sockets.
+-131 (0x7D) "DHCP Mode" parameter in "Set IP parameters" command is set to a value other than 0 or 1.
+-211 (0x2D) This code is returned in the following scenario: An LTCP socket is opened in the module. The remote peer tries to connect to the socket using a client socket, by sending a SYN packet (according to TCP protocol). The module in turn responds with a SYN+ACK packet. The remote peer is now supposed to send an ACK packet. If this packet is missed or does not reach the module, the module retries sending the SYN+ACK packet 4 times, and if the maximum number of retries does not lead to reception of an ACK from the remote terminal, the module returns this error to the Host and closes the LTCP socket.
+   1 (0x01) Wireless configuration failure.
+  25 (0x19) Invalid value supplied as input in "Authmode" command.
+  51 (0x33) Keep alive timeout. On lack of activity over an existing TCP socket connection, the module sends out a Keep alive frame to the remote terminal. If there is no response, the module closes its TCP socket and sends out an asynchronous message "ERROR<Error_code=0x33>".
+  64 (0x40) Tx buffers are not available. The Host should stop sending data to the module for some tens of millisecs to relax the buffers
+  65 (0x41) A packet of size more than 1460 bytes (TCP) or more than 1472 bytes (UDP) is sent in "Snd" command.
+  66 (0x42) Zero TCP/UDP payload is sent from the module.
+```
+
+
+### RedFlyClient
+
+
+    RedFlyClient()
+    RedFlyClient(uint8_t socket)
+    RedFlyClient(uint8_t *ip, uint16_t port)
+    RedFlyClient(uint8_t *ip, uint16_t port, uint16_t lport)
+* socket - Socket handle
+* ip - Client ip to connect
+* port - Client port to connect
+* lport - Local port
+
+Create client.
+
+    void begin(void)
+    void beginUDP(void)
+    int connect(void)
+    int connectUDP(void)
+    int connect(uint8_t *ip, uint16_t port)
+    int connectUDP(uint8_t *ip, uint16_t port)
+    int connect(uint8_t *ip, uint16_t port, uint16_t lport)
+    int connectUDP(uint8_t *ip, uint16_t port, uint16_t lport)
+    int connect(char *host, uint16_t port)
+    int connectUDP(char *host, uint16_t port)
+* ip - Client ip to connect
+* port - Client port to connect
+* lport - Local port
+* host - Host name
+
+Start the TCP or UDP client. *connect()* returns 1 if everything is okay.
+
+    uint8_t connected(void)
+Is the Client connected? The return value is 1 if yes.
+
+    void stop(void)
+Stop the Client.
+
+    uint8_t status(void)
+Returns the Client status. 0 means an open connection.
+Note: The status will be directly read from the WiFi module.
+
+    uint8_t getsocket(void)
+Returns the socket handle for the connection.
+
+    int available(void)
+Returns the size/length of available data.
+
+    int read(void)
+Get the received data. On -1 an error occurred.
+
+    int read(uint8_t *s, size_t sz)
+* s - Destination buffer
+* sz - Buffer size
+
+Returns the received data len.
+
+    void flush(void)
+Flushes the receive buffer.
+
+    size_t write(uint8_t b)
+    size_t write(const char *s)
+    size_t write(const uint8_t *s, size_t sz)
+* b - Byte to write
+* s - String/Array to write
+* sz - Array size
+
+Write data to the connected device and return the number of written bytes.
+Note: The input buffer has to be empty before sending data (see *read()*).
+
+    size_t print(text)
+    size_t print(int, base)
+    size_t println(text)
+    size_t println(int, base)
+* text, int - String, Char, Integer, Long, Float (RAM)
+* base - DEC, HEX, OCT, BIN
+
+Print text/data from RAM.
+
+    size_t print_P(PGM_P s)
+    size_t println_P(PGM_P s)
+* s - Pointer to String/Array (Flash), example: PSTR("test"), further infos about using flash memory: http://www.nongnu.org/avr-libc/user-manual/pgmspace.html
+
+Print text/data from Flash.
+
+
+### RedFlyServer
+
+    RedFlyServer()
+    RedFlyServer(uint16_t port)
+* port - Server port for listening
+
+Create server.
+      
+    void begin(void)
+    void beginUDP(void)
+    int connect(void)
+    int connectUDP(void)
+    int connect(uint16_t port)
+    int connectUDP(uint16_t port)
+* port - Server port to start listening
+
+Start TCP or UDP server. *connect()* returns 1 if everything is okay.
+
+    uint8_t connected(void)
+Is the Server port open? The return value is 1 if yes.
+
+    void stop(void)
+Stop the Server.
+
+    uint8_t status(void)
+Returns the Server status. 0 means an open connection.
+Note: The status will be directly read from the WiFi module.
+
+    uint8_t getsocket(void)
+Returns the socket handle for the connection.
+
+    void getip(uint8_t *ip)
+* ip - IP address
+
+Returns the IP of the client on an UDP connection.
+      
+    uint16_t getport(void)
+Returns the port of the client on an UDP connection..
+
+    int available(void)
+Returns the size/length of available data.
+
+    int read(void)
+Get the received data. On -1 an error occurred.
+
+    int read(uint8_t *s, size_t sz)
+* s - Destination buffer
+* sz - Buffer size
+
+Returns the received data len.
+
+    void flush(void)
+Flushes the receive buffer.
+
+    size_t write(uint8_t b)
+    size_t write(const char *s)
+    size_t write(const uint8_t *s, size_t sz)
+* b - Byte to write
+* s - String/Array to write
+* sz - Array size
+
+Write data to the connected device and return the number of written bytes.
+Note: The input buffer has to be empty before sending data (see *read()*).
+
+    size_t print(text)
+    size_t print(int, base)
+    size_t println(text)
+    size_t println(int, base)
+* text, int - String, Char, Integer, Long, Float (RAM)
+* base - DEC, HEX, OCT, BIN
+
+Print text/data from RAM.
+
+    size_t print_P(PGM_P s)
+    size_t println_P(PGM_P s)
+* s - Pointer to String/Array (Flash), example: PSTR("test"), further infos about using flash memory: http://www.nongnu.org/avr-libc/user-manual/pgmspace.html
+
+Print text/data from Flash.
+
+
+### RedFlyNBNS
+
+    RedFlyNBNS()
+    RedFlyNBNS(char *name)
+* name - Device name
+      
+Create NBNS (NetBIOS Name Service).
+
+    void setName(char *name)
+    void setNamePGM(PGM_P name)
+* name - Device name (String/Array, Pointer to String/Array in Flash)
+
+Set device name.
+
+    uint8_t service(void)
+Service routine, run in *loop()*.

+ 1494 - 0
lib/RedFly/RedFly.cpp

@@ -0,0 +1,1494 @@
+/*
+  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
+  {
+    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;
+}

+ 181 - 0
lib/RedFly/RedFly.h

@@ -0,0 +1,181 @@
+#ifndef REDFLY_h
+#define REDFLY_h
+
+
+#include <inttypes.h>
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+# include <avr/pgmspace.h>
+#endif
+
+
+//default baud rate
+#define REDFLY_BAUDRATE (9600)
+
+//Tx power (init cmd)
+#define LOW_POWER       (0)
+#define MED_POWER       (1)
+#define HIGH_POWER      (2)
+#define LOW_POWER_1M    (3)
+#define MED_POWER_1M    (4)
+#define HIGH_POWER_1M   (5)
+#define LOW_POWER_2M    (6)
+#define MED_POWER_2M    (7)
+#define HIGH_POWER_2M   (8)
+#define LOW_POWER_11M   (9)
+#define MED_POWER_11M   (10)
+#define HIGH_POWER_11M  (11)
+#define LOW_POWER_12M   (12)
+#define MED_POWER_12M   (13)
+#define HIGH_POWER_12M  (14)
+#define LOW_POWER_24M   (15)
+#define MED_POWER_24M   (16)
+#define HIGH_POWER_24M  (17)
+#define LOW_POWER_54M   (18)
+#define MED_POWER_54M   (19)
+#define HIGH_POWER_54M  (20)
+
+//net type (join cmd)
+#define INFRASTRUCTURE  (0)
+#define IBSS_JOINER     (1)
+#define IBSS_CREATOR    (2)
+
+//protocol (socket cmds)
+#define PROTO_TCP       (0)
+#define PROTO_UDP       (1)
+#define PROTO_MCAST     (2)
+
+//max. sockets (WiFi module supports up to 8 sockets and FW 4.7.1 only 7 sockets)
+#define MAX_SOCKETS     (7)
+#define INVALID_SOCKET  (0xFF)
+
+//socket states
+#define SOCKET_TCP      PROTO_TCP
+#define SOCKET_UDP      PROTO_UDP
+#define SOCKET_MCAST    PROTO_MCAST
+#define SOCKET_CLOSED   (0xFF)
+
+#ifndef SWAP16
+#define SWAP16(x)       ((((x)&0x00FF)<<8)| \
+                         (((x)&0xFF00)>>8))
+#endif
+
+#ifndef SWAP32
+#define SWAP32(x)       ((((x)&0xFF000000UL)>>24)| \
+                         (((x)&0x00FF0000UL)>> 8)| \
+                         (((x)&0x0000FF00UL)<< 8)| \
+                         (((x)&0x000000FFUL)<<24))
+#endif
+
+
+typedef struct 
+{
+	uint8_t handle;
+	uint8_t state;
+} SOCKET_STATE;
+
+
+extern class REDFLY RedFly;
+
+class REDFLY
+{
+  public:
+    REDFLY(void);
+    ~REDFLY(void);
+
+    uint8_t init(uint32_t br, uint8_t pwr); //br=baudrate, pwr=tx_power
+    uint8_t init(uint8_t pwr);              //pwr=tx_power
+    uint8_t init(void);
+
+    void enable(void);
+    void disable(void);
+
+    uint8_t getversion(char *ver);
+    uint8_t getmac(uint8_t *mac); 
+    uint8_t getlocalip(uint8_t *ip);
+    uint8_t getip(char *host, uint8_t *ip);
+    uint32_t gettime(uint8_t *server, uint16_t port);
+    uint32_t gettime(uint8_t *server);
+    uint8_t getrssi(void);
+    uint8_t getbssid(char *ssid, uint8_t *mac);
+    uint8_t gettype(char *ssid, uint8_t *type);
+
+    uint8_t scan(void); 
+    uint8_t scan(uint8_t chn, char *ssid, uint8_t *mode, uint8_t *rssi);  //returns: ssid, mode, rssi
+    uint8_t scan(char *ssid, uint8_t *mode, uint8_t *rssi);               //returns: ssid, mode, rssi
+    uint8_t scan(char *ssid);                                             //returns: ssid
+    uint8_t nextscan(char *ssid, uint8_t *mode, uint8_t *rssi);           //returns: ssid, mode, rssi
+    uint8_t nextscan(char *ssid);                                         //returns: ssid
+
+    uint8_t join(char *ssid, char *key, uint8_t net, uint8_t chn, uint8_t authmode); //INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR
+    uint8_t join(char *ssid, char *key, uint8_t net, uint8_t chn); //IBSS_CREATOR
+    uint8_t join(char *ssid, uint8_t net, uint8_t chn);            //IBSS_CREATOR
+    uint8_t join(char *ssid, char *key, uint8_t net);              //INFRASTRUCTURE or IBSS_JOINER
+    uint8_t join(char *ssid, uint8_t net);                         //INFRASTRUCTURE or IBSS_JOINER
+    uint8_t join(char *ssid, char *key);                           //INFRASTRUCTURE
+    uint8_t join(char *ssid);                                      //INFRASTRUCTURE
+
+    uint8_t disconnect(void); //disassociate
+
+    uint8_t begin(uint8_t dhcp, uint8_t *ip, uint8_t *dns, uint8_t *gateway, uint8_t *netmask);
+    uint8_t begin(uint8_t *ip, uint8_t *dns, uint8_t *gateway, uint8_t *netmask); //dhcp off
+    uint8_t begin(uint8_t *ip, uint8_t *dns, uint8_t *gateway);                   //dhcp off
+    uint8_t begin(uint8_t *ip, uint8_t *dns);                                     //dhcp off
+    uint8_t begin(uint8_t *ip);                                                   //dhcp off
+    uint8_t begin(uint8_t dhcp);                                                  //dhcp or autoip
+    uint8_t begin(void);                                                          //dhcp on
+
+    uint8_t socketConnect(uint8_t proto, uint8_t *ip, uint16_t port, uint16_t lport); //ret 0xFF=error
+    uint8_t socketConnect(uint8_t proto, uint8_t *ip, uint16_t port); //ret 0xFF=error (lport=1024...2048)
+
+    uint8_t socketListen(uint8_t proto, uint16_t lport); //ret 0xFF=error
+
+    uint8_t socketClose(uint8_t socket);
+    uint8_t socketClosed(uint8_t socket); //0!=closed
+    uint8_t socketStatus(uint8_t socket); //ret 0xFF=error
+    uint8_t socketState(uint8_t socket); //ret 0xFF=closed
+
+    uint8_t socketSend(uint8_t socket, uint8_t *stream, uint16_t size, uint8_t *ip, uint16_t port); //ip+port only for UDP
+    uint8_t socketSend(uint8_t socket, char *stream, uint8_t *ip, uint16_t port); //ip+port only for UDP
+    uint8_t socketSendPGM(uint8_t socket, PGM_P stream, uint8_t *ip, uint16_t port); //ip+port only for UDP
+    uint8_t socketSend(uint8_t socket, uint8_t *stream, uint16_t size); //TCP
+    uint8_t socketSend(uint8_t socket, char *stream);                   //TCP
+    uint8_t socketSendPGM(uint8_t socket, PGM_P stream);                //TCP
+    uint8_t socketSend(uint8_t socket, int value);                      //TCP
+
+    uint16_t socketRead(uint8_t *socket, uint16_t *len, uint8_t *ip, uint16_t *port, uint8_t *dst, uint16_t dst_size); //ret 0xFFFF=closed
+    uint16_t socketRead(uint8_t *socket, uint16_t *len, uint8_t *dst, uint16_t dst_size);
+ 
+    void socketReset(void);
+
+  private:
+    uint8_t tx_power, read_state;
+    uint8_t buffer[48]; //min. 48 (receive and data buffer)
+    uint32_t baudrate;
+    uint8_t ipaddr[4];
+    SOCKET_STATE socket_state[MAX_SOCKETS];
+
+    uint8_t 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 cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, int16_t v1);
+    uint8_t cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, uint8_t *v2, uint16_t v2_size);
+    uint8_t cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, char *v1);
+    uint8_t cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1);
+    uint8_t cmd(PGM_P p1, char *v1, PGM_P p2);
+    uint8_t cmd(PGM_P p1, char *v1, uint8_t *v2, uint16_t v2_size);
+    uint8_t cmd(PGM_P p1, char *v1);
+    uint8_t cmd(PGM_P p1, int16_t v1);
+    uint8_t cmd(PGM_P p1);
+
+    void flush(void);
+    void flush_nowait(void);
+    int available(void);
+    uint8_t readwait(void);
+    uint8_t read(void);
+    void write(uint8_t c);
+    void setbaudrate(uint32_t br);
+    char* iptoa(uint8_t *ip, char *s);
+    char* uitoa(uint16_t val, char *s);
+    void delay_10ms(uint8_t ms);
+};
+
+
+#endif //REDFLY_h

+ 456 - 0
lib/RedFly/RedFlyClient.cpp

@@ -0,0 +1,456 @@
+#include <inttypes.h>
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+# include <avr/pgmspace.h>
+#endif
+#if ARDUINO >= 100
+# include "Arduino.h"
+#else
+# include "WProgram.h"
+#endif
+#include "RedFly.h"
+#include "RedFlyClient.h"
+
+
+#define MAX_ERRORS 10
+
+
+//-------------------- Constructor/Destructor --------------------
+
+
+RedFlyClient::RedFlyClient(void)
+{
+  c_port   = 0;
+  c_socket = INVALID_SOCKET;
+
+  return;
+}
+
+
+RedFlyClient::RedFlyClient(uint8_t socket)
+{
+  c_port   = 0;
+  c_socket = socket;
+
+  return;
+}
+
+
+RedFlyClient::RedFlyClient(uint8_t *ip, uint16_t port)
+{
+  c_ip[0]  = ip[0];
+  c_ip[1]  = ip[1];
+  c_ip[2]  = ip[2];
+  c_ip[3]  = ip[3];
+  c_port   = port;
+  c_socket = INVALID_SOCKET;
+
+  return;
+}
+
+
+RedFlyClient::RedFlyClient(uint8_t *ip, uint16_t port, uint16_t lport)
+{
+  c_ip[0]  = ip[0];
+  c_ip[1]  = ip[1];
+  c_ip[2]  = ip[2];
+  c_ip[3]  = ip[3];
+  c_port   = port;
+  c_lport  = lport;
+  c_socket = INVALID_SOCKET;
+
+  return;
+}
+
+
+RedFlyClient::~RedFlyClient(void)
+{
+  stop();
+
+  return;
+}
+
+
+//-------------------- Public --------------------
+
+
+void RedFlyClient::begin(void)
+{
+  connectSocket(PROTO_TCP);
+
+  return;
+}
+
+
+void RedFlyClient::beginUDP(void)
+{
+  connectSocket(PROTO_UDP);
+
+  return;
+}
+
+
+int RedFlyClient::connect(void)
+{
+  return connectSocket(PROTO_TCP);
+}
+
+
+int RedFlyClient::connectUDP(void)
+{
+  return connectSocket(PROTO_UDP);
+}
+
+
+int RedFlyClient::connect(uint8_t *ip, uint16_t port)
+{
+  c_ip[0] = ip[0];
+  c_ip[1] = ip[1];
+  c_ip[2] = ip[2];
+  c_ip[3] = ip[3];
+  c_port  = port;
+
+  return connectSocket(PROTO_TCP);
+}
+
+
+int RedFlyClient::connectUDP(uint8_t *ip, uint16_t port)
+{
+  c_ip[0] = ip[0];
+  c_ip[1] = ip[1];
+  c_ip[2] = ip[2];
+  c_ip[3] = ip[3];
+  c_port  = port;
+
+  return connectSocket(PROTO_UDP);
+}
+
+
+int RedFlyClient::connect(uint8_t *ip, uint16_t port, uint16_t lport)
+{
+  c_ip[0] = ip[0];
+  c_ip[1] = ip[1];
+  c_ip[2] = ip[2];
+  c_ip[3] = ip[3];
+  c_port  = port;
+  c_lport = lport;
+
+  return connectSocket(PROTO_TCP);
+}
+
+
+int RedFlyClient::connectUDP(uint8_t *ip, uint16_t port, uint16_t lport)
+{
+  c_ip[0] = ip[0];
+  c_ip[1] = ip[1];
+  c_ip[2] = ip[2];
+  c_ip[3] = ip[3];
+  c_port  = port;
+  c_lport = lport;
+
+  return connectSocket(PROTO_UDP);
+}
+
+
+int RedFlyClient::connect(char *host, uint16_t port)
+{
+  if(RedFly.getip(host, c_ip) == 0)
+  {
+    c_port  = port;
+    return connectSocket(PROTO_TCP);
+  }
+
+  return 0;
+}
+
+
+int RedFlyClient::connectUDP(char *host, uint16_t port)
+{
+  if(RedFly.getip(host, c_ip) == 0)
+  {
+    c_port  = port;
+    return connectSocket(PROTO_UDP);
+  }
+
+  return 0;
+}
+
+
+int RedFlyClient::connectSocket(uint8_t p)
+{
+  if(c_socket != INVALID_SOCKET)
+  {
+    return 0;
+  }
+
+  if(c_lport)
+  {
+    c_socket = RedFly.socketConnect(p, c_ip, c_port, c_lport);
+  }
+  else
+  {
+    c_socket = RedFly.socketConnect(p, c_ip, c_port);
+  }
+
+  if(c_socket == INVALID_SOCKET)
+  {
+    return 0;
+  }
+
+  proto = p;
+  error = 0;
+
+  return 1;
+}
+
+
+uint8_t RedFlyClient::connected(void)
+{
+  if(c_socket == INVALID_SOCKET)
+  {
+    return 0;
+  }
+
+  if(RedFly.socketClosed(c_socket)) //socket closed?
+  {
+    c_socket = INVALID_SOCKET;
+    return 0;
+  }
+
+  if(error >= MAX_ERRORS)
+  {
+    RedFly.socketClose(c_socket);
+    c_socket = INVALID_SOCKET;
+    return 0;
+  }
+
+  return 1;
+}
+
+
+void RedFlyClient::stop(void)
+{
+  if(c_socket == INVALID_SOCKET)
+  {
+    return;
+  }
+
+  flush(); //clear buffer
+
+  RedFly.socketClose(c_socket);
+  c_socket = INVALID_SOCKET;
+  error    = 0;
+
+  return;
+}
+
+
+uint8_t RedFlyClient::status(void)
+{
+  if(c_socket == INVALID_SOCKET)
+  {
+    return 1;
+  }
+
+  if(RedFly.socketStatus(c_socket)) //socket closed?
+  {
+    c_socket = INVALID_SOCKET;
+    return 1;
+  }
+
+  return 0;
+}
+
+
+uint8_t RedFlyClient::getsocket(void)
+{
+  return c_socket;
+}
+
+
+int RedFlyClient::available(void)
+{
+  uint8_t socket=c_socket;
+  uint16_t len=0;
+
+  if(socket != INVALID_SOCKET)
+  {
+    RedFly.socketRead(&socket, &len, 0, 0);
+  }
+
+  return (int)len;
+}
+
+
+int RedFlyClient::read(void)
+{
+  uint8_t b;
+  uint8_t socket=c_socket;
+  uint16_t len, rd;
+
+  if(socket == INVALID_SOCKET)
+  {
+    return -1;
+  }
+
+  rd = RedFly.socketRead(&socket, &len, &b, 1);
+
+  if(rd == 0)
+  {
+    return -1;
+  }
+  if(rd == 0xFFFF) //socket closed?
+  {
+    c_socket = INVALID_SOCKET;
+    return -1;
+  }
+ 
+  return b;
+}
+
+
+int RedFlyClient::read(uint8_t *s, size_t sz)
+{
+  int c, rd;
+
+  for(rd=0; sz;)
+  {
+    c = read();
+    if(c != -1)
+    {
+      *s++ = (uint8_t)c;
+      sz--;
+      rd++;
+    }
+    else
+    {
+      break;
+    }
+  }
+
+  return rd;
+}
+
+
+void RedFlyClient::flush(void)
+{
+  for(int len=available(); len!=0; len--)
+  {
+    read();
+  }
+
+  return;
+}
+
+
+size_t RedFlyClient::write(uint8_t b)
+{
+  if(c_socket != INVALID_SOCKET)
+  {
+    if(RedFly.socketSend(c_socket, (uint8_t*)&b, 1, c_ip, c_port))
+    {
+      if(++error >= MAX_ERRORS)
+      {
+        RedFly.socketClose(c_socket);
+        c_socket = INVALID_SOCKET;
+      }
+    }
+    else
+    {
+      error = 0;
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+
+size_t RedFlyClient::write(const char *s)
+{
+  if(c_socket != INVALID_SOCKET)
+  {
+    if(RedFly.socketSend(c_socket, (char*)s, c_ip, c_port))
+    {
+      if(++error >= MAX_ERRORS)
+      {
+        RedFly.socketClose(c_socket);
+        c_socket = INVALID_SOCKET;
+      }
+    }
+    else
+    {
+      error = 0;
+      return strlen(s);
+    }
+  }
+
+  return 0;
+}
+
+
+size_t RedFlyClient::write(const uint8_t *s, size_t size)
+{
+  if(c_socket != INVALID_SOCKET)
+  {
+    if(RedFly.socketSend(c_socket, (uint8_t*)s, size, c_ip, c_port))
+    {
+      if(++error >= MAX_ERRORS)
+      {
+        RedFly.socketClose(c_socket);
+        c_socket = INVALID_SOCKET;
+      }
+    }
+    else
+    {
+      error = 0;
+      return size;
+    }
+  }
+
+  return 0;
+}
+
+
+size_t RedFlyClient::print_P(PGM_P s)
+{
+  if(c_socket != INVALID_SOCKET)
+  {
+    if(RedFly.socketSendPGM(c_socket, s, c_ip, c_port))
+    {
+      if(++error >= MAX_ERRORS)
+      {
+        RedFly.socketClose(c_socket);
+        c_socket = INVALID_SOCKET;
+      }
+    }
+    else
+    {
+      error = 0;
+      return strlen_P(s);
+    }
+  }
+
+  return 0;
+}
+
+
+size_t RedFlyClient::println_P(PGM_P s)
+{
+  size_t len;
+
+  len = print_P(s);
+  if(len)
+  {
+    len += print_P(PSTR("\r\n"));
+  }
+
+  return len;
+}
+
+
+//the next function allows us to use the client returned by
+//RedFlyServer::available() as the condition in an if-statement.
+RedFlyClient::operator bool()
+{
+  return c_socket != INVALID_SOCKET;
+}

+ 63 - 0
lib/RedFly/RedFlyClient.h

@@ -0,0 +1,63 @@
+#ifndef REDFLYCLIENT_h
+#define REDFLYCLIENT_h
+
+
+#include <inttypes.h>
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+# include <avr/pgmspace.h>
+#endif
+#include "Print.h"
+#include "RedFly.h"
+#include "Server.h"
+
+
+class RedFlyClient : public Server
+{
+  public:
+    RedFlyClient(void);
+    RedFlyClient(uint8_t socket);
+    RedFlyClient(uint8_t *ip, uint16_t port);
+    RedFlyClient(uint8_t *ip, uint16_t port, uint16_t lport);
+    ~RedFlyClient(void);
+
+    virtual void begin(void); //same as connect()
+    virtual void beginUDP(void); //same as connect()
+    virtual int connect(void);
+    virtual int connectUDP(void);
+    virtual int connect(uint8_t *ip, uint16_t port);
+    virtual int connectUDP(uint8_t *ip, uint16_t port);
+    virtual int connect(uint8_t *ip, uint16_t port, uint16_t lport);
+    virtual int connectUDP(uint8_t *ip, uint16_t port, uint16_t lport);
+    virtual int connect(char *host, uint16_t port);
+    virtual int connectUDP(char *host, uint16_t port);
+    int connectSocket(uint8_t p);
+    virtual uint8_t connected(void);
+    virtual void stop(void);
+    uint8_t status(void);
+    uint8_t getsocket(void);
+
+    virtual int available(void);
+    virtual int read(void);
+    virtual int read(uint8_t *s, size_t sz);
+    //virtual int peek(void); //not available
+    virtual void flush(void);
+    virtual size_t write(uint8_t b);
+    virtual size_t write(const char *s);
+    virtual size_t write(const uint8_t *s, size_t sz);
+    virtual size_t print_P(PGM_P s);
+    virtual size_t println_P(PGM_P s);
+
+    virtual operator bool();
+
+    using Print::write;
+
+  private:
+    uint8_t c_socket;
+    uint8_t c_ip[4];
+    uint16_t c_port;
+    uint16_t c_lport;
+    uint8_t proto, error;
+};
+
+
+#endif //REDFLYCLIENT_h

+ 168 - 0
lib/RedFly/RedFlyCommands.h

@@ -0,0 +1,168 @@
+#ifndef REDFLYCOMMANDS_h
+#define REDFLYCOMMANDS_h
+
+
+#define CMD_OK          "OK"
+#define CMD_ERROR       "ERROR"
+
+
+//Command
+#define CMD_FWVERSION   "AT+RSI_FWVERSION?" //firmware version
+  //ret: OKMajor.Minor1.Minor2
+
+#define CMD_RESET       "AT+RSI_RESET" //soft reset
+  //ret: OK
+
+#define CMD_BAUDRATE    "AT+RSI_BAUDRATE=" //baud_rate
+  //ret: OK
+
+#define CMD_MAC         "AT+RSI_MAC?" //get MAC address of the module
+  //ret: OKabcdef
+
+#define CMD_RSSI        "AT+RSI_RSSI?" //get signal strength for current connection
+  //ret: OKa
+
+#define CMD_NWPARAMS    "AT+RSI_NWPARAMS?" //get module paramters
+  //        32    1         32   1    6        1                     4       4       4       1
+  //ret: OK<SSID><SEC_TYPE><PSK><Chn><MACaddr><DHCP_MODE/ERROR_CODE><IPaddr><SubNet><Gateway><NO_OF_OPEN_SOCKET>   
+  //       [<S_ID1><S_TYPE1><Sport1><Dport1><Dip1>][<S_ID2><S_TYPE2><Sport2><Dport2><Dip2>] (...up to <NO_OF_OPEN_SOCKET>)
+  //       <DNS_Server_Address> 
+
+#define CMD_BAND        "AT+RSI_BAND=" //set band
+#define BAND24          "0"            //set 2.4GHz
+#define BAND5           "1"            //set 5GHz
+
+#define CMD_INIT        "AT+RSI_INIT" //execut after BAND
+
+#define CMD_SCAN        "AT+RSI_SCAN=" //chn,SSID (SSID for hidden Access Points, chn=0 -> all channels)
+  //ret: OK<uSSID1uMode1uRSSIval1><uSSID2uMode2uRSSIval2>...
+#define CMD_NEXTSCAN    "AT+RSI_NEXTSCAN"
+  //ret: OK<uSSID1uMode1uRSSIval1><uSSID2uMode2uRSSIval2>...
+#define CMD_NUMSCAN     "AT+RSI_NUMSCAN=" //set number
+#define CMD_GETNUMSCAN  "AT+RSI_NUMSCAN?" //get number
+#define CMD_NWTYPE      "AT+RSI_NWTYPE?" //get network type (0=Ad-hoc, 1=Infrastructure)
+  //ret: OK<SSID1NwType1><SSID2NwType2>...
+#define CMD_BSSID       "AT+RSI_BSSID?" //get network MAC
+  //ret: OK<SSID1BSSID1><SSID2BSSID2>...
+#define MODE_OPEN       "0"
+#define MODE_WPA        "1"
+#define MODE_WPA2       "2"
+#define MODE_WEP        "3"
+  //chn: 0=all, 
+  //     2.4GHz 1...14,
+  //     5GHz   36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165
+  //ret: OK<uSSID1uMode1uRSSIval1><uSSID2uMode2uRSSIval2>...
+
+#define CMD_NETWORK     "AT+RSI_NETWORK=" //INFRASTRUCTURE or IBSS,type,chn
+  //IBSS type: 0 indicates IBSS Joiner and 1 indicates IBSS Creator
+  //for Joiner mode, chn has to be 0
+
+#define CMD_PSK         "AT+RSI_PSK=" //Pre Shared Key,  max length is 63 characters
+#define CMD_PSK_WEP     "AT+RSI_WEP_KEYS=" //3 WEP keys: key_index,key2,key3,key4
+
+#define CMD_AUTHMODE    "AT+RSI_AUTHMODE=" //auth mode
+#define AUTHMODE_WEPOK  "0"     //WEP Open Key
+#define AUTHMODE_WEPSK  "1"     //WEP Shared Key 
+#define AUTHMODE_WPA    "2"     //WPA
+#define AUTHMODE_WPA2   "3"     //WPA2
+#define AUTHMODE_OPEN   "4"     //No securtiy (open)
+
+#define CMD_JOIN        "AT+RSI_JOIN=" //SSID,TxRate(1 byte),TxPower(1 byte) 
+#define JOIN_LOWPW      ",0,0"   //auto data rate,       7dBm
+#define JOIN_MEDPW      ",0,1"   //auto data rate,      10dBm
+#define JOIN_HIGHPW     ",0,2"   //auto data rate, 16...17dBm
+#define JOIN_LOWPW1M    ",1,0"   //1 Mbps,               7dBm
+#define JOIN_MEDPW1M    ",1,1"   //1 Mbps,              10dBm
+#define JOIN_HIGHPW1M   ",1,2"   //1 Mbps,         16...17dBm
+#define JOIN_LOWPW2M    ",2,0"   //2 Mbps,               7dBm
+#define JOIN_MEDPW2M    ",2,1"   //2 Mbps,              10dBm
+#define JOIN_HIGHPW2M   ",2,2"   //2 Mbps,         16...17dBm
+#define JOIN_LOWPW11M   ",4,0"   //11 Mbps,              7dBm
+#define JOIN_MEDPW11M   ",4,1"   //11 Mbps,             10dBm
+#define JOIN_HIGHPW11M  ",4,2"   //11 Mbps,        16...17dBm
+#define JOIN_LOWPW12M   ",7,0"   //12 Mbps,              7dBm
+#define JOIN_MEDPW12M   ",7,1"   //12 Mbps,             10dBm
+#define JOIN_HIGHPW12M  ",7,2"   //12 Mbps,        16...17dBm
+#define JOIN_LOWPW24M   ",9,0"   //24 Mbps,              7dBm
+#define JOIN_MEDPW24M   ",9,1"   //24 Mbps,             10dBm
+#define JOIN_HIGHPW24M  ",9,2"   //24 Mbps,        16...17dBm
+#define JOIN_LOWPW54M   ",12,0"  //54 Mbps,              7dBm
+#define JOIN_MEDPW54M   ",12,1"  //54 Mbps,             10dBm
+#define JOIN_HIGHPW54M  ",12,2"  //54 Mbps,        16...17dBm
+  //DataRate (Mbps)=TxRate
+  // auto=0, 1=1, 2=2, 5.5=3, 11=4, 6=5, 9=6, 12=7, 18=8, 24=9, 36=10, 48=11, 54=12 
+  // MCS0=13, MCS1=14, MCS2=15, MCS3=16, MCS4=17, MCS5=18, MCS6=19, MCS7=20 
+  //802.11n:   6.5, 13, 19.5, 26, 39, 52, 58.5, 65 Mbps 
+  //802.11a/g: 6, 9, 12, 18, 24, 36, 48, 54 Mbps 
+  //802.11b:   1, 2, 5.5, 11 Mbps
+
+#define CMD_DISCONN     "AT+RSI_DISASSOC" //disassociate / disconnect
+
+#define CMD_PWMODE      "AT+RSI_PWMODE=" //power mode 0, 1 or 2
+
+#define CMD_SLEEPTIMER  "AT+RSI_SLEEPTIMER=" //milliseconds, max 10000
+
+
+//TCP/IP Commands
+/*
+#define ERROR_1          (-1) //255 Waiting for the connection from peer.
+#define ERROR_2          (-2) //254 Socket not available.
+#define ERROR_3          (-3) //253 Deauthentication from the Access Point.
+#define ERROR_4          (-4) //252 Illegal IP/Port parameters.
+#define ERROR_5          (-5) //251 TCP/IP configuration failure.
+#define ERROR_6          (-6) //250 Invalid socket.
+#define ERROR_7          (-7) //249 Association not done.
+#define ERROR_8          (-8) //248 Error in cmd.
+#define ERROR_9          (-9) //247 Error with byte stuffing for escape characters.
+#define ERROR_10        (-10) //246 IP Lease expired.
+#define ERROR_11        (-11) //245 TCP Connection closed.
+#define ERROR_12        (-12) //244 Pre-Shared Key not set for connection to a secure Access Point.
+#define ERROR_13        (-13) //243 No Access Points scanned 
+#define ERROR_14        (-14) //242 INIT cmd already issued. This error is sent when the INIT cmd is sent more than once.
+#define ERROR_15        (-15) //241 JOIN cmd already issued. This error is sent when the JOIN cmd is sent more than once.
+#define ERROR_16        (-16) //240 DHCP Failure.
+#define ERROR_17        (-17) //239 Baud Rate Not Supported.
+*/
+
+#define CMD_IPCONF      "AT+RSI_IPCONF=" //DHCP_MODE(0=manual, 1=DHCP),IP,SUBNET,GATEWAY
+  //ret: OKMACaddrIPaddrSUBNETGateway
+#define IPCONF_DHCP     "1,0,0"
+#define IPCONF_AUTOIP   "2,0,0"
+
+#define CMD_DNSSERVER   "AT+RSI_DNSSERVER=" //DNS server
+  //ret: OK
+  
+#define CMD_DNSGET      "AT+RSI_DNSGET=" // DNS Resolution
+  //ret: OKx...
+  //       x = number of IP addresses
+
+#define CMD_TCP         "AT+RSI_TCP=" //host,port,lport         //Open and Connect to a TCP Socket
+  //ret: OKsock_handle
+
+#define CMD_LTCP        "AT+RSI_LTCP=" //lport                  //Open a Listening TCP Socket
+  //ret: OKsock_handle
+
+#define CMD_UDP         "AT+RSI_UDP=" //host,port,lport         //Open a UDP Socket
+  //ret: OKsock_handle
+
+#define CMD_LUDP        "AT+RSI_LUDP=" //lport                  //Open a Listening UDP Socket
+  //ret: OKsock_handle
+
+#define CMD_MCAST       "AT+RSI_ MULTICAST=" //host,port,lport  //Open a Multicast Socket
+  //ret: OKsock_handle
+
+#define CMD_CTCP        "AT+RSI_CTCP=" //hn                     //Get a Listening socket's active conn. status
+  //ret: OKChnIP_AddressPort
+  //       Chn >=0: A handle to an active connected socket 
+  //       Chn =-1: No connection has been established
+
+#define CMD_CLS         "AT+RSI_CLS=" //hn                      //Close a Socket
+  //ret: OK
+
+#define CMD_SEND        "AT+RSI_SND=" //hn,sz,Dip,Dport,Data    //Send a byte stream to a Socket
+  //ret: OKsz (sz in 2bytes)
+
+#define CMD_READ        "AT+RSI_READ" //hn,sz,Sip,Sport,Data    //Receive a byte stream on a Socket
+
+
+#endif //REDFLYCOMMANDS_h

+ 223 - 0
lib/RedFly/RedFlyNBNS.cpp

@@ -0,0 +1,223 @@
+#include <inttypes.h>
+#if defined(__AVR__)
+# include <avr/pgmspace.h>
+#endif
+#if ARDUINO >= 100
+# include "Arduino.h"
+#else
+# include "WProgram.h"
+#endif
+#include "RedFly.h"
+#include "RedFlyNBNS.h"
+
+
+//NBNS Question
+#define NBNSQ_PACKETLEN      (38)
+#define NBNSQ_TYPE_NB        (0x0020)
+#define NBNSQ_CLASS_IN       (0x0001)
+typedef struct __attribute__((packed))
+{
+  uint8_t  len       :   8; // 8bit Len: 32
+  char     name[33];        //33byte Name + null
+  uint16_t type      :  16; //16bit Type
+  uint16_t clas      :  16; //16bit Class
+} NBNS_Question;
+
+//NBNS Answer
+#define NBNSA_PACKETLEN      (50)
+#define NBNSA_TYPE_NB        (0x0020)
+#define NBNSA_CLASS_IN       (0x0001)
+typedef struct __attribute__((packed))
+{
+  uint8_t  len       :   8; // 8bit Len: 32
+  char     name[33];        //33byte Name + null
+  uint16_t type      :  16; //16bit Type
+  uint16_t clas      :  16; //16bit Class
+  uint32_t ttl       :  32; //32bit Time to live
+  uint16_t rdlen     :  16; //16bit Data len
+  uint16_t flags     :  16; //16bit Flags    - rdata
+  uint8_t  addr[4];         //32bit IP Addr  - rdata
+} NBNS_Answer;
+
+//NBNS (NetBIOS Name Service)
+#define NBNS_PORT            (137)
+#define NBNS_PACKETLEN       (12)
+#define NBNS_OPMASK          (0x7800)
+#define NBNS_REPLYMASK       (0x000F)
+#define NBNS_FLAG_RESPONSE   (1<<15)
+#define NBNS_FLAG_QUERY      (0<<15)
+#define NBNS_FLAG_AUTHORITY  (1<<10)
+#define NBNS_OP_QUERY        (0<<11)
+typedef struct __attribute__((packed))
+{
+  uint16_t id        :  16; //16bit Transaction ID
+  uint16_t flags_op  :  16; //16bit Flags
+  uint16_t qdcount   :  16; //16bit Question Entries
+  uint16_t ancount   :  16; //16bit Answer RRs
+  uint16_t nscount   :  16; //16bit Authority RRs
+  uint16_t arcount   :  16; //16bit Additional RRs
+  union
+  {
+    NBNS_Question qd;
+    NBNS_Answer   an;
+  } data;
+} NBNS_Packet;
+
+
+//-------------------- Constructor/Destructor --------------------
+
+
+RedFlyNBNS::RedFlyNBNS(void) : RedFlyServer(NBNS_PORT)
+{
+  strcpy(devname, "REDFLY");
+
+  return;
+}
+
+
+RedFlyNBNS::RedFlyNBNS(char *name) : RedFlyServer(NBNS_PORT)
+{
+  strcpy(devname, name);
+
+  return;
+}
+
+
+RedFlyNBNS::~RedFlyNBNS(void)
+{
+  stop();
+
+  return;
+}
+
+
+//-------------------- Public --------------------
+
+
+void RedFlyNBNS::setName(char *name)
+{
+  strcpy(devname, name);
+
+  return;
+}
+
+
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+void RedFlyNBNS::setNamePGM(PGM_P name)
+{
+  strcpy_P(devname, name);
+
+  return;
+}
+#endif
+
+
+uint8_t RedFlyNBNS::service(void)
+{
+  uint16_t len;
+  uint8_t buf[NBNS_PACKETLEN+NBNSA_PACKETLEN];
+  NBNS_Packet *nbns;
+  char name[16+1];
+  uint8_t type;
+
+  if(!connected()) //listening port still open?
+  {
+    stop(); //stop and reset server
+    beginUDP(); //start server
+    return 1;
+  }
+
+  //data available?
+  len = available();
+  if(len >= (NBNS_PACKETLEN+NBNSQ_PACKETLEN))
+  {
+    //read data
+    read(buf, sizeof(buf));
+    flush(); //flush input buffer
+    //check data for NBNS header and question
+    nbns = (NBNS_Packet*) buf;
+    if((nbns->qdcount      == SWAP16(0x0001))         &&
+       (nbns->data.qd.len  == 32)                     &&
+       (nbns->data.qd.type == SWAP16(NBNSQ_TYPE_NB))  &&
+       (nbns->data.qd.clas == SWAP16(NBNSQ_CLASS_IN))) //NBNS question
+    {
+      type = decode(name, nbns->data.qd.name);
+      if((type == 0x00) && (strcasecmp(name, devname) == 0))//0x00 = Workstation
+      {
+        //create NBNS answer
+        nbns->id            = nbns->id;
+        nbns->flags_op      = SWAP16(NBNS_FLAG_RESPONSE|NBNS_FLAG_AUTHORITY);
+        nbns->qdcount       = SWAP16(0x0000);
+        nbns->ancount       = SWAP16(0x0001);
+        nbns->nscount       = SWAP16(0x0000);
+        nbns->arcount       = SWAP16(0x0000);
+        nbns->data.an.len   = 32;
+        nbns->data.an.type  = SWAP16(NBNSA_TYPE_NB);
+        nbns->data.an.clas  = SWAP16(NBNSA_CLASS_IN);
+        nbns->data.an.ttl   = SWAP32(3600); //time to live 3600 sec = 1 hour
+        nbns->data.an.rdlen = SWAP16(0x0006);
+        nbns->data.an.flags = SWAP16(0x0000);
+        RedFly.getlocalip(nbns->data.an.addr);
+        encode(nbns->data.an.name, devname, 0x00); //0x00 = Workstation
+        nbns->data.an.name[32] = 0;
+        //send answer
+        write(buf, NBNS_PACKETLEN+NBNSA_PACKETLEN);
+        return 0xFF;
+      }
+    }
+  }
+
+  return 0;
+}
+
+
+//-------------------- Private --------------------
+
+
+uint8_t RedFlyNBNS::decode(char *dst, char *src)
+{
+  uint8_t i, j;
+  char c;
+
+  for(i=0, j=0; i<15; i++)
+  {
+    c  = (src[j++]-'A')<<4;
+    c |= (src[j++]-'A')<<0;
+    if(c == ' ')
+    {
+      break;
+    }
+    dst[i] = toupper(c);
+  }
+  dst[i] = 0;
+
+  return (((src[30]-'A')<<4)|(src[31]-'A')); //0x00 = Workstation
+}
+
+
+void RedFlyNBNS::encode(char *dst, char *src, uint8_t type)
+{
+  uint8_t i, j;
+  char c;
+
+  //encode name
+  for(i=0, j=0; (i<15) && src[i]; i++)
+  {
+    c = toupper(src[i]);
+    dst[j++] = 'A'+((c>>4)&0x0f);
+    dst[j++] = 'A'+((c>>0)&0x0f);
+  }
+
+  //add spaces
+  for(; i<15; i++)
+  {
+    dst[j++] = 'A'+((' '>>4)&0x0f);
+    dst[j++] = 'A'+((' '>>0)&0x0f);
+  }
+
+  //set type (0x00 = Workstation)
+  dst[j++] = 'A'+((type>>4)&0x0f);
+  dst[j++] = 'A'+((type>>0)&0x0f);
+
+  return;
+}

+ 33 - 0
lib/RedFly/RedFlyNBNS.h

@@ -0,0 +1,33 @@
+#ifndef REDFLYNBNS_h
+#define REDFLYNBNS_h
+
+
+#include <inttypes.h>
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+# include <avr/pgmspace.h>
+#endif
+#include "RedFlyServer.h"
+
+
+class RedFlyNBNS : RedFlyServer
+{
+  public:
+    RedFlyNBNS(void);
+    RedFlyNBNS(char *name);
+    ~RedFlyNBNS(void);
+
+    void setName(char *name);
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+    void setNamePGM(PGM_P name);
+#endif
+    uint8_t service(void);
+
+  private:
+    char devname[16+1];
+
+    uint8_t decode(char *dst, char *src);
+    void encode(char *dst, char *src, uint8_t type);
+};
+
+
+#endif //REDFLYNBNS_h

+ 392 - 0
lib/RedFly/RedFlyServer.cpp

@@ -0,0 +1,392 @@
+#include <inttypes.h>
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+# include <avr/pgmspace.h>
+#endif
+#if ARDUINO >= 100
+# include "Arduino.h"
+#else
+# include "WProgram.h"
+#endif
+#include "RedFly.h"
+#include "RedFlyServer.h"
+
+
+#define MAX_ERRORS 10
+
+
+//-------------------- Constructor/Destructor --------------------
+
+
+RedFlyServer::RedFlyServer(void) 
+{
+  s_port   = 80;
+  s_socket = INVALID_SOCKET;
+
+  return;
+}
+
+
+RedFlyServer::RedFlyServer(uint16_t port)
+{
+  s_port   = port;
+  s_socket = INVALID_SOCKET;
+
+  return;
+}
+
+
+RedFlyServer::~RedFlyServer(void) 
+{
+  stop();
+
+  return;
+}
+
+
+//-------------------- Public --------------------
+
+
+void RedFlyServer::begin(void)
+{
+  connectSocket(PROTO_TCP);
+
+  return;
+}
+
+
+void RedFlyServer::beginUDP(void)
+{
+  connectSocket(PROTO_UDP);
+
+  return;
+}
+
+
+int RedFlyServer::connect(void)
+{
+  return connectSocket(PROTO_TCP);
+}
+
+
+int RedFlyServer::connectUDP(void)
+{
+  return connectSocket(PROTO_UDP);
+}
+
+
+int RedFlyServer::connect(uint16_t port)
+{
+  s_port = port;
+
+  return connectSocket(PROTO_TCP);
+}
+
+
+int RedFlyServer::connectUDP(uint16_t port)
+{
+  s_port = port;
+
+  return connectSocket(PROTO_UDP);
+}
+
+
+int RedFlyServer::connectSocket(uint8_t p)
+{
+  if(s_socket != INVALID_SOCKET)
+  {
+    return 0;
+  }
+
+  s_socket = RedFly.socketListen(p, s_port);
+
+  if(s_socket == INVALID_SOCKET)
+  {
+    return 0;
+  }
+
+  c_ip[0] = 0;
+  c_ip[1] = 0;
+  c_ip[2] = 0;
+  c_ip[3] = 0;
+  c_port  = 0;
+  proto   = p;
+  error   = 0;
+
+  return 1;
+}
+
+
+uint8_t RedFlyServer::connected(void)
+{
+  if(s_socket == INVALID_SOCKET)
+  {
+    return 0;
+  }
+
+  if(RedFly.socketClosed(s_socket)) //socket closed?
+  {
+    s_socket = INVALID_SOCKET;
+    return 0;
+  }
+
+  if(error >= MAX_ERRORS)
+  {
+    RedFly.socketClose(s_socket);
+    s_socket = INVALID_SOCKET;
+    return 0;
+  }
+
+  return 1;
+}
+
+
+void RedFlyServer::stop(void)
+{
+  if(s_socket == INVALID_SOCKET)
+  {
+    return;
+  }
+
+  flush(); //clear buffer
+
+  RedFly.socketClose(s_socket);
+  s_socket = INVALID_SOCKET;
+  error    = 0;
+
+  return;
+}
+
+
+uint8_t RedFlyServer::status(void)
+{
+  if(s_socket == INVALID_SOCKET)
+  {
+    return 1;
+  }
+
+  if(RedFly.socketStatus(s_socket)) //socket closed?
+  {
+    s_socket = INVALID_SOCKET;
+    return 1;
+  }
+
+  return 0;
+}
+
+
+uint8_t RedFlyServer::getsocket(void)
+{
+  return s_socket;
+}
+
+
+void RedFlyServer::getip(uint8_t *ip)
+{
+  ip[0] = c_ip[0];
+  ip[1] = c_ip[1];
+  ip[2] = c_ip[2];
+  ip[3] = c_ip[3];
+
+  return;
+}
+
+
+uint16_t RedFlyServer::getport(void)
+{
+  return c_port;
+}
+
+
+int RedFlyServer::available(void)
+{
+  uint8_t socket=s_socket;
+  uint16_t len=0;
+
+  if(socket != INVALID_SOCKET)
+  {
+    RedFly.socketRead(&socket, &len, 0, 0);
+  }
+
+  return (int)len;
+}
+
+
+int RedFlyServer::read(void)
+{
+  uint8_t b;
+  uint8_t socket=s_socket;
+  uint16_t len, rd;
+
+  if(socket == INVALID_SOCKET)
+  {
+    return -1;
+  }
+
+  if(RedFly.socketState(socket) == SOCKET_UDP)
+  {
+    rd = RedFly.socketRead(&socket, &len, c_ip, &c_port, &b, 1);
+  }
+  else
+  {
+    rd = RedFly.socketRead(&socket, &len, &b, 1);
+  }
+  if(rd == 0)
+  {
+    return -1;
+  }
+  if(rd == 0xFFFF) //socket closed?
+  {
+    s_socket = INVALID_SOCKET;
+    return -1;
+  }
+
+  return b;
+}
+
+
+int RedFlyServer::read(uint8_t *s, size_t sz)
+{
+  int c, rd;
+
+  for(rd=0; sz;)
+  {
+    c = read();
+    if(c != -1)
+    {
+      *s++ = (uint8_t)c;
+      sz--;
+      rd++;
+    }
+    else
+    {
+      break;
+    }
+  }
+
+  return rd;
+}
+
+
+void RedFlyServer::flush(void)
+{
+  for(int len=available(); len!=0; len--)
+  {
+    read();
+  }
+
+  return;
+}
+
+
+size_t RedFlyServer::write(uint8_t b) 
+{
+  if(s_socket != INVALID_SOCKET)
+  {
+    if(RedFly.socketSend(s_socket, (uint8_t*)&b, 1, c_ip, c_port))
+    {
+      if(++error >= MAX_ERRORS)
+      {
+        RedFly.socketClose(s_socket);
+        s_socket = INVALID_SOCKET;
+      }
+    }
+    else
+    {
+      error = 0;
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+
+size_t RedFlyServer::write(const char *s) 
+{
+  if(s_socket != INVALID_SOCKET)
+  {
+    if(RedFly.socketSend(s_socket, (char*)s, c_ip, c_port))
+    {
+      if(++error >= MAX_ERRORS)
+      {
+        RedFly.socketClose(s_socket);
+        s_socket = INVALID_SOCKET;
+      }
+    }
+    else
+    {
+      error = 0;
+      return strlen(s);
+    }
+  }
+
+  return 0;
+}
+
+
+size_t RedFlyServer::write(const uint8_t *s, size_t size) 
+{
+  if(s_socket != INVALID_SOCKET)
+  {
+    if(RedFly.socketSend(s_socket, (uint8_t*)s, size, c_ip, c_port))
+    {
+      if(++error >= MAX_ERRORS)
+      {
+        RedFly.socketClose(s_socket);
+        s_socket = INVALID_SOCKET;
+      }
+    }
+    else
+    {
+      error = 0;
+      return size;
+    }
+  }
+
+  return 0;
+}
+
+
+size_t RedFlyServer::print_P(PGM_P s)
+{
+  if(s_socket != INVALID_SOCKET)
+  {
+    if(RedFly.socketSendPGM(s_socket, s, c_ip, c_port))
+    {
+      if(++error >= MAX_ERRORS)
+      {
+        RedFly.socketClose(s_socket);
+        s_socket = INVALID_SOCKET;
+      }
+    }
+    else
+    {
+      error = 0;
+      return strlen_P(s);
+    }
+  }
+
+  return 0;
+}
+
+
+size_t RedFlyServer::println_P(PGM_P s)
+{
+  size_t len;
+
+  len = print_P(s);
+  if(len)
+  {
+    len += print_P(PSTR("\r\n"));
+  }
+
+  return len;
+}
+
+
+//the next function allows us to use the client returned by
+//RedFlyServer::available() as the condition in an if-statement.
+RedFlyServer::operator bool()
+{
+  return s_socket != INVALID_SOCKET;
+}

+ 59 - 0
lib/RedFly/RedFlyServer.h

@@ -0,0 +1,59 @@
+#ifndef REDFLYSERVER_h
+#define REDFLYSERVER_h
+
+
+#include <inttypes.h>
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+# include <avr/pgmspace.h>
+#endif
+#include "Print.h"
+#include "RedFly.h"
+#include "Server.h"
+
+
+class RedFlyServer : public Server
+{
+  public:
+    RedFlyServer(void);
+    RedFlyServer(uint16_t port);
+    ~RedFlyServer(void);
+
+    virtual void begin(void); //same as connect()
+    virtual void beginUDP(void); //same as connect()
+    virtual int connect(void);
+    virtual int connectUDP(void);
+    virtual int connect(uint16_t port);
+    virtual int connectUDP(uint16_t port);
+    int connectSocket(uint8_t p);
+    virtual uint8_t connected(void);
+    virtual void stop(void);
+    uint8_t status(void);
+    uint8_t getsocket(void);
+    void getip(uint8_t *ip);
+    uint16_t getport(void);
+
+    virtual int available(void);
+    virtual int read(void);
+    virtual int read(uint8_t *s, size_t sz);
+    //virtual int peek(void); //not available
+    virtual void flush(void);
+    virtual size_t write(uint8_t b);
+    virtual size_t write(const char *s);
+    virtual size_t write(const uint8_t *s, size_t sz);
+    virtual size_t print_P(PGM_P s);
+    virtual size_t println_P(PGM_P s);
+
+    virtual operator bool();
+
+    using Print::write;
+
+  private:
+    uint16_t s_port;
+    uint8_t s_socket;
+    uint8_t c_ip[4];
+    uint16_t c_port;
+    uint8_t proto, error;
+};
+
+
+#endif //REDFLYSERVER_h

+ 356 - 0
lib/RedFly/digitalWriteFast.h

@@ -0,0 +1,356 @@
+/*
+  Optimized digital functions for AVR microcontrollers
+  by Watterott electronic (www.watterott.com)
+  based on http://code.google.com/p/digitalwritefast
+ */
+
+#ifndef __digitalWriteFast_h_
+#define __digitalWriteFast_h_ 1
+
+// general macros/defines
+#ifndef BIT_READ
+# define BIT_READ(value, bit)            ((value) &   (1UL << (bit)))
+#endif
+#ifndef BIT_SET
+# define BIT_SET(value, bit)             ((value) |=  (1UL << (bit)))
+#endif
+#ifndef BIT_CLEAR
+# define BIT_CLEAR(value, bit)           ((value) &= ~(1UL << (bit)))
+#endif
+#ifndef BIT_WRITE
+# define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit))
+#endif
+
+#ifndef SWAP
+#define SWAP(x,y) do{ (x)=(x)^(y); (y)=(x)^(y); (x)=(x)^(y); }while(0)
+#endif
+
+#ifndef DEC
+# define DEC (10)
+#endif
+#ifndef HEX
+# define HEX (16)
+#endif
+#ifndef OCT
+# define OCT (8)
+#endif
+#ifndef BIN
+# define BIN (2)
+#endif
+
+
+// workarounds for ARM microcontrollers
+#if (!defined(__AVR__) || defined(ARDUINO_ARCH_SAM))
+#ifndef PROGMEM
+# define PROGMEM
+#endif
+#ifndef PGM_P
+# define PGM_P const char *
+#endif
+#ifndef PSTR
+# define PSTR(str) (str)
+#endif
+
+#ifndef memcpy_P
+# define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
+#endif
+#ifndef strcpy_P
+# define strcpy_P(dst, src)       strcpy((dst), (src))
+#endif
+#ifndef strcat_P
+# define strcat_P(dst, src)       strcat((dst), (src))
+#endif
+#ifndef strcmp_P
+# define strcmp_P(a, b)           strcmp((a), (b))
+#endif
+#ifndef strcasecmp_P
+# define strcasecmp_P(a, b)       strcasecmp((a), (b))
+#endif
+#ifndef strncmp_P
+# define strncmp_P(a, b, n)       strncmp((a), (b), (n))
+#endif
+#ifndef strncasecmp_P
+# define strncasecmp_P(a, b, n)   strncasecmp((a), (b), (n))
+#endif
+#ifndef strstr_P
+# define strstr_P(a, b)           strstr((a), (b))
+#endif
+#ifndef strlen_P
+# define strlen_P(a)              strlen((a))
+#endif
+#ifndef sprintf_P
+# define sprintf_P(s, f, ...)     sprintf((s), (f), __VA_ARGS__)
+#endif
+
+#ifndef pgm_read_byte
+# define pgm_read_byte(addr)      (*(const unsigned char *)(addr))
+#endif
+#ifndef pgm_read_word
+# define pgm_read_word(addr)      (*(const unsigned short *)(addr))
+#endif
+#ifndef pgm_read_dword
+# define pgm_read_dword(addr)     (*(const unsigned long *)(addr))
+#endif
+
+#endif
+
+
+// digital functions
+//#ifndef digitalPinToPortReg
+#define SPI_SW_SS_PIN   (10) //SS on Uno (for software SPI)
+#define SPI_SW_MOSI_PIN (11) //MOSI on Uno (for software SPI)
+#define SPI_SW_MISO_PIN (12) //MISO on Uno (for software SPI)
+#define SPI_SW_SCK_PIN  (13) //SCK on Uno (for software SPI)
+
+
+// --- Arduino Due ---
+#if (defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__))
+
+#define UART_RX_PIN     (0)
+#define UART_TX_PIN     (1)
+
+#define I2C_SDA_PIN     (20)
+#define I2C_SCL_PIN     (21)
+
+#define SPI_HW_SS_PIN   (78) //SS0:77, SS1:87, SS2:86, SS3:78
+#define SPI_HW_MOSI_PIN (75) //75
+#define SPI_HW_MISO_PIN (74) //74
+#define SPI_HW_SCK_PIN  (76) //76
+
+
+// --- Arduino Zero ---
+#elif (defined(ARDUINO_SAM_ZERO) || defined(__SAMD21G18A__))
+
+#define UART_RX_PIN     (0)
+#define UART_TX_PIN     (1)
+
+#define I2C_SDA_PIN     (16)
+#define I2C_SCL_PIN     (17)
+
+#define SPI_HW_SS_PIN   (14) //14
+#define SPI_HW_MOSI_PIN (21) //21
+#define SPI_HW_MISO_PIN (18) //18
+#define SPI_HW_SCK_PIN  (20) //20
+
+
+// --- Arduino Mega ---
+#elif (defined(ARDUINO_AVR_MEGA) || \
+       defined(ARDUINO_AVR_MEGA1280) || \
+       defined(ARDUINO_AVR_MEGA2560) || \
+       defined(__AVR_ATmega1280__) || \
+       defined(__AVR_ATmega1281__) || \
+       defined(__AVR_ATmega2560__) || \
+       defined(__AVR_ATmega2561__))
+
+#define UART_RX_PIN     (0) //PE0
+#define UART_TX_PIN     (1) //PE1
+
+#define I2C_SDA_PIN     (20)
+#define I2C_SCL_PIN     (21)
+
+#define SPI_HW_SS_PIN   (53) //PB0
+#define SPI_HW_MOSI_PIN (51) //PB2
+#define SPI_HW_MISO_PIN (50) //PB3
+#define SPI_HW_SCK_PIN  (52) //PB1
+
+#define __digitalPinToPortReg(P) \
+(((P) >= 22 && (P) <= 29) ? &PORTA : \
+((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \
+(((P) >= 30 && (P) <= 37) ? &PORTC : \
+((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \
+((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \
+(((P) >= 54 && (P) <= 61) ? &PORTF : \
+((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \
+((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \
+(((P) == 14 || (P) == 15) ? &PORTJ : \
+(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL))))))))))
+
+#define __digitalPinToDDRReg(P) \
+(((P) >= 22 && (P) <= 29) ? &DDRA : \
+((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \
+(((P) >= 30 && (P) <= 37) ? &DDRC : \
+((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \
+((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \
+(((P) >= 54 && (P) <= 61) ? &DDRF : \
+((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \
+((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \
+(((P) == 14 || (P) == 15) ? &DDRJ : \
+(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL))))))))))
+
+#define __digitalPinToPINReg(P) \
+(((P) >= 22 && (P) <= 29) ? &PINA : \
+((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \
+(((P) >= 30 && (P) <= 37) ? &PINC : \
+((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \
+((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \
+(((P) >= 54 && (P) <= 61) ? &PINF : \
+((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \
+((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \
+(((P) == 14 || (P) == 15) ? &PINJ : \
+(((P) >= 62 && (P) <= 69) ? &PINK : &PINL))))))))))
+
+#define __digitalPinToBit(P) \
+(((P) >=  7 && (P) <=  9) ? (P) - 3 : \
+(((P) >= 10 && (P) <= 13) ? (P) - 6 : \
+(((P) >= 22 && (P) <= 29) ? (P) - 22 : \
+(((P) >= 30 && (P) <= 37) ? 37 - (P) : \
+(((P) >= 39 && (P) <= 41) ? 41 - (P) : \
+(((P) >= 42 && (P) <= 49) ? 49 - (P) : \
+(((P) >= 50 && (P) <= 53) ? 53 - (P) : \
+(((P) >= 54 && (P) <= 61) ? (P) - 54 : \
+(((P) >= 62 && (P) <= 69) ? (P) - 62 : \
+(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \
+(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \
+(((P) == 19) ? 2 : \
+(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \
+(((P) == 2) ? 4 : \
+(((P) == 3 || (P) == 4) ? 5 : 7)))))))))))))))
+
+
+// --- Arduino 644 ---
+#elif (defined(__AVR_ATmega644__) || \
+       defined(__AVR_ATmega644P__))
+
+#define UART_RX_PIN     (8) //PD0
+#define UART_TX_PIN     (9) //PD1
+
+#define I2C_SDA_PIN     (17) //PC1
+#define I2C_SCL_PIN     (16) //PC0
+
+#define SPI_HW_SS_PIN   (4) //PB4
+#define SPI_HW_MOSI_PIN (5) //PB5
+#define SPI_HW_MISO_PIN (6) //PB6
+#define SPI_HW_SCK_PIN  (7) //PB7
+
+#define __digitalPinToPortReg(P) \
+(((P) >= 0 && (P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA)))
+#define __digitalPinToDDRReg(P) \
+(((P) >= 0 && (P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 8 && (P) <= 15) ? &DDRC : &DDRA)))
+#define __digitalPinToPINReg(P) \
+(((P) >= 0 && (P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 8 && (P) <= 15) ? &PINC : &PINA)))
+#define __digitalPinToBit(P) \
+(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24)))
+
+
+// --- Arduino Leonardo ---
+#elif (defined(ARDUINO_AVR_LEONARDO) || \
+       defined(__AVR_ATmega16U4__) || \
+       defined(__AVR_ATmega32U4__))
+
+#define UART_RX_PIN     (0) //PD2
+#define UART_TX_PIN     (1) //PD3
+
+#define I2C_SDA_PIN     (2) //PD1
+#define I2C_SCL_PIN     (3) //PD0
+
+#define SPI_HW_SS_PIN   (17) //PB0
+#define SPI_HW_MOSI_PIN (16) //PB2
+#define SPI_HW_MISO_PIN (14) //PB3
+#define SPI_HW_SCK_PIN  (15) //PB1
+
+#define __digitalPinToPortReg(P) \
+((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PORTD : (((P) == 5 || (P) == 13) ? &PORTC : (((P) >= 18 && (P) <= 23)) ? &PORTF : (((P) == 7) ? &PORTE : &PORTB)))
+#define __digitalPinToDDRReg(P) \
+((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &DDRD : (((P) == 5 || (P) == 13) ? &DDRC : (((P) >= 18 && (P) <= 23)) ? &DDRF : (((P) == 7) ? &DDRE : &DDRB)))
+#define __digitalPinToPINReg(P) \
+((((P) >= 0 && (P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PIND : (((P) == 5 || (P) == 13) ? &PINC : (((P) >= 18 && (P) <= 23)) ? &PINF : (((P) == 7) ? &PINE : &PINB)))
+#define __digitalPinToBit(P) \
+(((P) >= 8 && (P) <= 11) ? (P) - 4 : (((P) >= 18 && (P) <= 21) ? 25 - (P) : (((P) == 0) ? 2 : (((P) == 1) ? 3 : (((P) == 2) ? 1 : (((P) == 3) ? 0 : (((P) == 4) ? 4 : (((P) == 6) ? 7 : (((P) == 13) ? 7 : (((P) == 14) ? 3 : (((P) == 15) ? 1 : (((P) == 16) ? 2 : (((P) == 17) ? 0 : (((P) == 22) ? 1 : (((P) == 23) ? 0 : (((P) == 24) ? 4 : (((P) == 25) ? 7 : (((P) == 26) ? 4 : (((P) == 27) ? 5 : 6 )))))))))))))))))))
+
+
+// --- Arduino Uno ---
+#elif (defined(ARDUINO_AVR_UNO) || \
+       defined(ARDUINO_AVR_DUEMILANOVE) || \
+       defined(__AVR_ATmega328__) || \
+       defined(__AVR_ATmega328P__) || \
+       defined(__AVR_ATmega328PB__))
+
+#define UART_RX_PIN     (0) //PD0
+#define UART_TX_PIN     (1) //PD1
+
+#define I2C_SDA_PIN     (18) //A4
+#define I2C_SCL_PIN     (19) //A5
+
+#define SPI_HW_SS_PIN   (10) //PB0
+#define SPI_HW_MOSI_PIN (11) //PB2
+#define SPI_HW_MISO_PIN (12) //PB3
+#define SPI_HW_SCK_PIN  (13) //PB1
+
+#if defined(__AVR_ATmega328PB__)
+#define __digitalPinToPortReg(P) \
+(((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE)))
+#define __digitalPinToDDRReg(P) \
+(((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE)))
+#define __digitalPinToPINReg(P) \
+(((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE)))
+#define __digitalPinToBit(P) \
+(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (((P) >= 14 && (P) <= 19) ? (P) - 14 : (((P) >= 20 && (P) <= 21) ? (P) - 18 : (P) - 22))))
+#else
+#define __digitalPinToPortReg(P) \
+(((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC))
+#define __digitalPinToDDRReg(P) \
+(((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC))
+#define __digitalPinToPINReg(P) \
+(((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC))
+#define __digitalPinToBit(P) \
+(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))
+#endif
+
+
+// --- Other ---
+#else
+
+#define I2C_SDA_PIN     SDA
+#define I2C_SCL_PIN     SCL
+
+#define SPI_HW_SS_PIN   SS
+#define SPI_HW_MOSI_PIN MOSI
+#define SPI_HW_MISO_PIN MISO
+#define SPI_HW_SCK_PIN  SCK
+
+
+#endif
+//#endif  //#ifndef digitalPinToPortReg
+
+
+#ifndef digitalWriteFast
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+#define digitalWriteFast(P, V) \
+if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
+  BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \
+} else { \
+  digitalWrite((P), (V)); \
+}
+#else
+#define digitalWriteFast digitalWrite
+#endif
+#endif
+
+
+#ifndef pinModeFast
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+#define pinModeFast(P, V) \
+if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \
+  BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \
+} else { \
+  pinMode((P), (V)); \
+}
+#else
+#define pinModeFast pinMode
+#endif
+#endif
+
+
+#ifndef digitalReadFast
+#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR))
+#define digitalReadFast(P) ( (int) __digitalReadFast((P)) )
+#define __digitalReadFast(P ) \
+  (__builtin_constant_p(P) ) ? ( \
+  ( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \
+  digitalRead((P))
+#else
+#define digitalReadFast digitalRead
+#endif
+#endif
+
+#endif //__digitalWriteFast_h_

+ 182 - 0
lib/RedFly/examples/Adhoc/Adhoc.ino

@@ -0,0 +1,182 @@
+/*
+  Ad-hoc Test
+
+  This sketch connects two RedFly-Shields using an ad-hoc network
+  and synchronizes the state of a switch connected to pin A5 and GND.
+  One shield is the server and the other one is the client.
+  Use the Serial Monitor for configuration (9600 Baud).
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyClient.h>
+#include <RedFlyServer.h>
+
+
+uint8_t led_pin = 13; //pin 13 has a LED connected on most Arduino boards
+uint8_t sw_pin = A5; //connect switch to pin A5 and GND
+
+uint8_t working_mode = 0; //mode: 0=server, 1=client
+uint16_t comm_port = 1234; //communication port
+uint32_t last_time = 0;
+uint8_t last_state = 0;
+
+byte ip_server[] = { 192,168,0,50 }; //ip from server shield
+byte ip_client[] = { 192,168,0,51 }; //ip from client shield
+
+
+RedFlyClient client(ip_server, comm_port); //create client class
+RedFlyServer server(comm_port); //create server class
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+  //set pin config
+  pinMode(led_pin, OUTPUT);
+  digitalWrite(led_pin, LOW);
+  pinMode(sw_pin, INPUT);
+  digitalWrite(sw_pin, HIGH); //pull-up on
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  ret = RedFly.init(); //9600 baud, HIGH_POWER
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+    for(;;); //do nothing forevermore
+  }
+  else
+  {
+    RedFly.disable();
+    Serial.println("Press 0 for server or 1 for client");
+    while(Serial.available() == 0);
+    working_mode = Serial.read() - '0';
+    while(Serial.available() != 0){ Serial.read(); }
+    if(working_mode == 0) //server
+    {
+      Serial.println("Server...");
+    }
+    else
+    {
+      Serial.println("Client...");
+    }
+    RedFly.enable();
+
+    if(working_mode == 0) //server
+    {
+      do
+      {
+        delay(1000);
+        ret = RedFly.join("ADHOC", "1A2B3C4D5E", IBSS_CREATOR, 1); //create ad-hoc network
+      }
+      while(ret != 0);
+      ret = RedFly.begin(ip_server); //use static ip
+    }
+    else //client
+    {
+      do
+      {
+        delay(1000);
+        RedFly.scan(); //scan for wireless networks (must be run before join command)
+        ret = RedFly.join("ADHOC", "1A2B3C4D5E", IBSS_JOINER); //join ad-hoc network
+      }
+      while(ret != 0);
+      ret = RedFly.begin(ip_client); //use static ip
+    }
+
+    if(ret)
+    {
+      debugoutln("BEGIN ERR");
+      RedFly.disconnect();
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      debugoutln("started");
+    }
+  }
+}
+
+
+void loop()
+{
+  uint8_t c;
+  unsigned long ms = millis();
+
+  if(working_mode == 0) //server
+  {
+    if(!server.connected()) //server port open?
+    {
+      server.stop();
+      server.begin();
+    }
+    else if(server.available()) //new data available
+    {
+      c = (server.read()!=0) ? HIGH : LOW;
+      digitalWrite(led_pin, c);
+    }
+    else if((ms-last_time) > 100) //check switch every 100ms
+    {
+      last_time = ms; //save time
+      c = digitalRead(sw_pin); //read switch
+      if(c != last_state) //switch state changed?
+      {
+        last_state = c;
+        server.write(c); //send data over WLAN
+      }
+    }
+  }
+  else //client
+  {
+    if(!client.connected()) //client connected to server?
+    {
+      client.stop();
+      client.connect();
+    }
+    else if(client.available()) //new data available
+    {
+      c = (client.read()!=0) ? HIGH : LOW;
+      digitalWrite(led_pin, c);
+    }
+    else if((ms-last_time) > 100) //check switch every 100ms
+    {
+      last_time = ms; //save time
+      c = digitalRead(sw_pin); //read switch
+      if(c != last_state) //switch state changed?
+      {
+        last_state = c;
+        client.write(c); //send data over WLAN
+      }
+    }
+  }
+}

+ 147 - 0
lib/RedFly/examples/EchoTest/EchoTest.ino

@@ -0,0 +1,147 @@
+/*
+  Echo Test (Socket API)
+ 
+  This sketch acts as a echo server using a RedFly-Shield.
+  All received data will be resend to the client.
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+
+
+byte ip[]      = { 192,168,  0, 30 }; //ip from shield (server)
+byte netmask[] = { 255,255,255,  0 }; //netmask
+
+#define TCP_PORT  (80) //local TCP port on the shield
+#define UDP_PORT  (80) //local UDP port on the shield
+
+uint8_t hTCP=INVALID_SOCKET, hUDP=INVALID_SOCKET;  //socket handles
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, 0, 0, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+    }
+  }
+}
+
+
+void loop()
+{
+  uint8_t sock, buf[64], *ptr;
+  uint16_t buf_len, rd, len;
+  uint16_t port; //incomming UDP port
+  uint8_t ip[4]; //incomming UDP ip
+
+  //check if sockets are opened
+  if(RedFly.socketClosed(hTCP))
+  {
+    hTCP = RedFly.socketListen(PROTO_TCP, TCP_PORT); //open TCP socket
+  }
+  if(RedFly.socketClosed(hUDP))
+  {
+    hUDP = RedFly.socketListen(PROTO_UDP, UDP_PORT); //open UDP socket
+  }
+
+  //get data
+  sock    = 0xFF; //0xFF = return data from all open sockets
+  ptr     = buf;
+  buf_len = 0;
+  do
+  {
+    rd = RedFly.socketRead(&sock, &len, ip, &port, ptr, sizeof(buf)-buf_len);
+    if((rd != 0) && (rd != 0xFFFF)) //0xFFFF = connection closed
+    {
+      ptr     += rd;
+      buf_len += rd;
+    }
+  }while(len != 0);  //len contains the data size from rx buffer
+
+  //send data
+  if(buf_len && (sock != INVALID_SOCKET)) //data received for transmitting?
+  {
+    if(sock == hTCP)
+    {
+      RedFly.socketSend(hTCP, buf, buf_len); //send data to TCP socket
+    }
+    else if(sock == hUDP)
+    {
+      RedFly.socketSend(hUDP, buf, buf_len, ip, port); //send data to UDP socket
+    }
+  }
+}

+ 31 - 0
lib/RedFly/examples/FWupdate/FWupdate.ino

@@ -0,0 +1,31 @@
+/*
+  Firmware Update
+
+  Sketch that should be loaded on a Firmare Update.
+ */
+
+#define RX_PIN   (0)
+#define TX_PIN   (1)
+#define RST_PIN  (2)
+#define CS_PIN   (3)
+
+
+void setup()
+{
+  pinMode(RX_PIN, INPUT);
+
+  pinMode(TX_PIN, INPUT);
+
+  pinMode(RST_PIN, OUTPUT);
+  digitalWrite(RST_PIN, HIGH); //reset off
+
+  pinMode(CS_PIN, OUTPUT);
+  digitalWrite(CS_PIN, HIGH); //disable
+
+  while(1);
+}
+
+
+void loop()
+{
+}

+ 176 - 0
lib/RedFly/examples/Infrastructure/Infrastructure.ino

@@ -0,0 +1,176 @@
+/*
+  Infrastructure Test
+
+  This sketch connects two RedFly-Shields using an infrastructure network
+  and synchronizes the state of a switch connected to pin A5 and GND.
+  One shield is the server and the other one is the client.
+  Use the Serial Monitor for configuration (9600 Baud).
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyClient.h>
+#include <RedFlyServer.h>
+
+
+uint8_t led_pin = 13; //pin 13 has a LED connected on most Arduino boards
+uint8_t sw_pin = A5; //connect switch to pin A5 and GND
+
+uint8_t working_mode = 0; //mode: 0=server, 1=client
+uint16_t comm_port = 1234; //communication port
+uint32_t last_time = 0;
+uint8_t last_state = 0;
+
+byte ip_server[] = { 192,168,0,50 }; //ip from server shield
+byte ip_client[] = { 192,168,0,51 }; //ip from client shield
+
+
+RedFlyClient client(ip_server, comm_port); //create client class
+RedFlyServer server(comm_port); //create server class
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+  //set pin config
+  pinMode(led_pin, OUTPUT);
+  digitalWrite(led_pin, LOW);
+  pinMode(sw_pin, INPUT);
+  digitalWrite(sw_pin, HIGH); //pull-up on
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  ret = RedFly.init(); //9600 baud, HIGH_POWER
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+    for(;;); //do nothing forevermore
+  }
+  else
+  {
+    RedFly.disable();
+    Serial.println("Press 0 for server or 1 for client");
+    while(Serial.available() == 0);
+    working_mode = Serial.read() - '0';
+    while(Serial.available() != 0){ Serial.read(); }
+    if(working_mode == 0) //server
+    {
+      Serial.println("Server...");
+    }
+    else
+    {
+      Serial.println("Client...");
+    }
+    RedFly.enable();
+
+    do
+    {
+      delay(1000);
+      ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    }
+    while(ret != 0);
+
+    if(working_mode == 0) //server
+    {
+      ret = RedFly.begin(ip_server); //use static ip
+    }
+    else //client
+    {
+      ret = RedFly.begin(ip_client); //use static ip
+    }
+
+    if(ret)
+    {
+      debugoutln("BEGIN ERR");
+      RedFly.disconnect();
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      debugoutln("started");
+    }
+  }
+}
+
+
+void loop()
+{
+  uint8_t c;
+  unsigned long ms = millis();
+
+  if(working_mode == 0) //server
+  {
+    if(!server.connected()) //server port open?
+    {
+      server.stop();
+      server.begin();
+    }
+    else if(server.available()) //new data available
+    {
+      c = (server.read()!=0) ? HIGH : LOW;
+      digitalWrite(led_pin, c);
+    }
+    else if((ms-last_time) > 100) //check switch every 100ms
+    {
+      last_time = ms; //save time
+      c = digitalRead(sw_pin); //read switch
+      if(c != last_state) //switch state changed?
+      {
+        last_state = c;
+        server.write(c); //send data over WLAN
+      }
+    }
+  }
+  else //client
+  {
+    if(!client.connected()) //client connected to server?
+    {
+      client.stop();
+      client.connect();
+    }
+    else if(client.available()) //new data available
+    {
+      c = (client.read()!=0) ? HIGH : LOW;
+      digitalWrite(led_pin, c);
+    }
+    else if((ms-last_time) > 100) //check switch every 100ms
+    {
+      last_time = ms; //save time
+      c = digitalRead(sw_pin); //read switch
+      if(c != last_state) //switch state changed?
+      {
+        last_state = c;
+        client.write(c); //send data over WLAN
+      }
+    }
+  }
+}

+ 174 - 0
lib/RedFly/examples/NBNS/NBNS.ino

@@ -0,0 +1,174 @@
+/*
+  NBNS (NetBIOS Name Service) Test
+ 
+  This sketch shows the basic NetBIOS Name Service (NBNS) support in action.
+  For testing, open in your browser http://redfly/
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyServer.h>
+#include <RedFlyNBNS.h>
+
+
+byte ip[] = { 192,168,  0, 30 }; //ip from shield (client)
+
+//initialize the server library with the port 
+//you want to use (port 80 is default for HTTP)
+RedFlyServer server(80);
+
+//initialize the NBNS library with the device name (max. 16 characters)
+RedFlyNBNS NBNS("REDFLY");
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        //receive shield IP in case of DHCP/Auto-IP
+        RedFly.getlocalip(ip);
+
+        //start server
+        server.begin();
+
+        //set other device name
+        // NBNS.setName("REDFLY");
+        // NBNS.setNamePGM(PSTR("REDFLY"));
+      }
+    }
+  }
+}
+
+
+void loop()
+{
+  //NBNS service routine
+  NBNS.service();
+
+  //listen for incoming clients (HTTP server)
+  if(server.available())
+  {
+    //an http request ends with a blank line
+    boolean currentLineIsBlank = true;
+    while(server.available())
+    {
+      char c = server.read();
+      //if you've gotten to the end of the line (received a newline
+      //character) and the line is blank, the http request has ended,
+      //so you can send a reply
+      if(c == '\n' && currentLineIsBlank)
+      {
+        //clear input buffer
+        server.flush(); 
+
+        //send standard HTTP 200 header
+        server.print_P(PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));
+
+        //send some text
+        server.println_P(PSTR("Hello, World! <br><br>"));
+
+        //show IP address of RedFly
+        server.println_P(PSTR("My IP is: "));
+        server.print(ip[0], DEC); server.print(".");
+        server.print(ip[1], DEC); server.print(".");
+        server.print(ip[2], DEC); server.print(".");
+        server.print(ip[3], DEC);
+        break;
+      }
+      if(c == '\n')
+      {
+        //you're starting a new line
+        currentLineIsBlank = true;
+      } 
+      else if(c != '\r')
+      {
+        //you've gotten a character on the current line
+        currentLineIsBlank = false;
+      }
+    }
+
+    //close connection
+    server.stop();
+  }
+  else if(!server.connected()) //listening port still open?
+  {
+    server.stop(); //stop and reset server
+    server.begin(); //start server
+  }
+}

+ 132 - 0
lib/RedFly/examples/NTP/NTP.ino

@@ -0,0 +1,132 @@
+/*
+  NTP (Network Time Protocol) Test
+ 
+  This sketch connects to a NTP server and gets the current time.
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+
+
+byte ip[]        = { 192,168,  0, 30 }; //ip from shield (client)
+byte netmask[]   = { 255,255,255,  0 }; //netmask
+byte gateway[]   = { 192,168,  0,100 }; //ip from gateway/router
+byte dnsserver[] = { 192,168,  0,100 }; //ip from dns server
+byte server[]    = {   0,  0,  0,  0 }; //{ 188,138,107,156 }; //ip from pool.ntp.org (server)
+
+#define HOSTNAME "pool.ntp.org" //host
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        if(RedFly.getip(HOSTNAME, server) == 0) //get ip
+        {
+          uint32_t time;
+          time = RedFly.gettime(server); //get time
+          if(time != 0UL)
+          {
+            char tmp[64];
+            sprintf_P(tmp, PSTR("Time: %lu sec since 1970"), time);
+            debugoutln(tmp);
+          }
+          else
+          {
+            debugoutln("NTP ERR");
+            RedFly.disconnect();
+            for(;;); //do nothing forevermore
+          }
+        }
+        else
+        {
+          debugoutln("DNS ERR");
+          RedFly.disconnect();
+          for(;;); //do nothing forevermore
+        }
+      }
+    }
+  }
+}
+
+
+void loop()
+{
+
+}

+ 317 - 0
lib/RedFly/examples/Paint/Paint.ino

@@ -0,0 +1,317 @@
+/*
+  Paint
+ 
+  This sketch connects two RedFly-Shields with displays. 
+  One Arduino has to be WORKING_MODE=0 and the other WORKING_MODE=1.
+  Requires RedFly + mSD-shield with MI0283QT-Adapter.
+ */
+
+#include <Wire.h>
+#include <SPI.h>
+#include <digitalWriteFast.h>
+#include <GraphicsLib.h>
+#include <MI0283QT2.h>
+#include <MI0283QT9.h>
+#include <DisplaySPI.h>
+#include <DisplayI2C.h>
+#include <RedFly.h>
+#include <RedFlyClient.h>
+#include <RedFlyServer.h>
+
+
+//Declare only one display !
+// MI0283QT2 lcd;  //MI0283QT2 Adapter v1
+// MI0283QT9 lcd;  //MI0283QT9 Adapter v1
+// DisplaySPI lcd; //SPI (GLCD-Shield or MI0283QT Adapter v2)
+ DisplayI2C lcd; //I2C (GLCD-Shield or MI0283QT Adapter v2)
+
+#define WORKING_MODE 0 //0=server, 1=client
+
+byte ip_server[] = { 192,168,  0, 50 }; //ip from server shield
+byte ip_client[] = { 192,168,  0, 51 }; //ip from client shield
+
+uint16_t comm_port = 1000; //communication port
+
+#if WORKING_MODE == 0 //server
+RedFlyServer server(comm_port);
+#else
+RedFlyClient client(ip_server, comm_port);
+#endif
+
+uint16_t last_x=0, last_y=0, color=RGB(0,0,0);
+
+//display output functions
+#define infoClear()  lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(255,255,255))
+#define infoText(x)  lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(0,0,0)); lcd.drawTextPGM((lcd.getWidth()/2)-60, (lcd.getHeight()/2)-10, PSTR(x), RGB(255,255,255), RGB(0,0,0), 1)
+#define errorText(x) lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(0,0,0)); lcd.drawTextPGM((lcd.getWidth()/2)-60, (lcd.getHeight()/2)-10, PSTR(x), RGB(255,0,0), RGB(0,0,0), 1)
+
+
+uint8_t clearall(uint8_t send) //redraw complete screen
+{
+  if(send)
+  {
+    uint16_t buf[4]={0xBEEF,0x0000,0x0000,0x0000};
+#if WORKING_MODE == 0 //server
+    server.write((uint8_t*)buf, 8);
+#else
+    client.write((uint8_t*)buf, 8);
+#endif
+  }
+
+  lcd.fillRect(0, 0, 20, lcd.getHeight(), color);
+  lcd.fillRect(lcd.getWidth()-20, 0, 20, lcd.getHeight(), RGB(0,0,0));
+  lcd.fillRect(20, 0, lcd.getWidth()-40, lcd.getHeight(), RGB(255,255,255));
+}
+
+
+uint8_t start_wifi(void)
+{
+  uint8_t ret, i;
+
+  //init the WiFi module
+  infoText("WiFi...");
+  ret = RedFly.init(115200, HIGH_POWER); //baudrate, LOW_POWER MED_POWER HIGH_POWER
+  if(ret)
+  {
+    errorText("WiFi...Error"); //there are problems with the communication between the Arduino and the RedFly
+    return 1;
+  }
+
+  //join/create network
+  for(i=5; i!=0; i--) //try 5 times
+  {
+#if WORKING_MODE == 0 //server
+    infoText("Create network...");
+    ret = RedFly.join("PAINT", "1A2B3C4D5E", IBSS_CREATOR, 1); //create ad-hoc network
+#else
+    infoText("Scan...");
+    RedFly.scan(); //scan for wireless networks (must be run before join command)
+    infoText("Join...");
+    ret = RedFly.join("PAINT", "1A2B3C4D5E", IBSS_JOINER); //join ad-hoc network
+#endif
+    if(ret)
+    {
+      errorText("Join...Error");
+    }
+    else
+    {
+      break;
+    }
+  }
+  if(ret)
+  {
+    return 2;
+  }
+
+  //set ip config
+  infoText("IP...");
+#if WORKING_MODE == 0 //server
+  ret = RedFly.begin(ip_server);
+#else
+  ret = RedFly.begin(ip_client);
+#endif
+  if(ret)
+  {
+    errorText("IP...Error");
+    RedFly.disconnect();
+    return 3;
+  }
+
+#if WORKING_MODE == 0 //server
+  infoText("Server...");
+  server.begin();
+#else
+  infoText("Client...");
+  client.connect();
+#endif
+
+  clearall(1);
+
+  return 0;
+}
+
+
+void setup()
+{
+  //init display
+  lcd.begin();
+  //lcd.begin(SPI_CLOCK_DIV4, 8); //SPI Displays: spi-clk=Fcpu/4, rst-pin=8
+  //lcd.begin(0x20, 8); //I2C Displays: addr=0x20, rst-pin=8
+  lcd.touchStartCal(); //calibrate touchpanel
+
+  //show working mode
+#if WORKING_MODE == 0 //server
+  lcd.drawTextPGM((lcd.getWidth()/2)-50, (lcd.getHeight()/2)-10, PSTR("Server"), RGB(0,0,0), RGB(255,255,255), 2);
+  color = RGB(0,0,255);
+#else
+  lcd.drawTextPGM((lcd.getWidth()/2)-50, (lcd.getHeight()/2)-10, PSTR("Client"), RGB(0,0,0), RGB(255,255,255), 2);
+  color = RGB(255,0,0);
+#endif
+  delay(1000);
+  lcd.fillScreen(RGB(255,255,255));
+
+  //start WiFi
+  while(start_wifi() != 0){ delay(1000); }
+}
+
+
+void loop()
+{
+  uint16_t x=0, y=0;
+  uint16_t buf[4];
+  static uint8_t connection=0;
+
+#if WORKING_MODE == 0 //server
+  if(!server.connected())
+  {
+    if(server.connect() == 0) //open port for client (begin is the same as connect)
+    {
+      server.stop();
+      if(++connection >= 3)
+      {
+        while(start_wifi() != 0){ delay(1000); }
+      }
+    }
+    else
+    {
+      connection = 0;
+    }
+  }
+  else
+  {
+    while(server.available() >= 8) //data available?
+    {
+      //0xBEEF, x, y, color (all 16bit, total 8 bytes)
+      buf[0]  = (server.read()<<0); //1
+      buf[0] |= (server.read()<<8);
+      if(buf[0] == 0xBEEF)
+      {
+        buf[1]  = (server.read()<<0); //2
+        buf[1] |= (server.read()<<8);
+        buf[2]  = (server.read()<<0); //3
+        buf[2] |= (server.read()<<8);
+        buf[3]  = (server.read()<<0); //4
+        buf[3] |= (server.read()<<8);
+        if((buf[1] == 0) &&
+           (buf[2] == 0) &&
+           (buf[3] == 0))
+        {
+          clearall(0);
+        }
+        else
+        {
+          lcd.fillRect(buf[1], buf[2], 4, 4, buf[3]);
+        }
+      }
+    }
+  }
+#else
+  if(!client.connected())
+  {
+    if(client.connect() == 0) //connect to server
+    {
+      client.stop();
+      if(++connection >= 3)
+      {
+        while(start_wifi() != 0){ delay(1000); }
+      }
+    }
+    else
+    {
+      connection = 0;
+    }
+  }
+  else
+  {
+    while(client.available() >= 8) //data available?
+    {
+      //0xBEEF, x, y, color (all 16bit, total 8 bytes)
+      buf[0]  = (client.read()<<0); //1
+      buf[0] |= (client.read()<<8);
+      if(buf[0] == 0xBEEF)
+      {
+        buf[1]  = (client.read()<<0); //2
+        buf[1] |= (client.read()<<8);
+        buf[2]  = (client.read()<<0); //3
+        buf[2] |= (client.read()<<8);
+        buf[3]  = (client.read()<<0); //4
+        buf[3] |= (client.read()<<8);
+        if((buf[1] == 0) &&
+           (buf[2] == 0) &&
+           (buf[3] == 0))
+        {
+          clearall(0);
+        }
+        else
+        {
+          lcd.fillRect(buf[1], buf[2], 4, 4, buf[3]);
+        }
+      }
+    }
+  }
+#endif
+
+  //service routine for touch panel
+  lcd.touchRead();
+
+  //touch press?
+  if(lcd.touchZ() &&
+#if WORKING_MODE == 0 //server
+     server.connected() && !server.available()) //server
+#else
+     client.connected() && !client.available()) //client
+#endif
+  {
+    x = lcd.touchX();
+    y = lcd.touchY();
+
+    //change color
+    if(x < 20)
+    {
+      last_x = 0;
+      switch(color)
+      {
+        case RGB(0,0,0):   color = RGB(255,0,0); break;
+        case RGB(255,0,0): color = RGB(0,255,0); break;
+        case RGB(0,255,0): color = RGB(0,0,255); break;
+        case RGB(0,0,255): color = RGB(0,0,0);   break;
+      }
+      lcd.fillRect(0, 0, 20, lcd.getHeight(), color);
+      while(lcd.touchZ()){ lcd.touchRead(); }
+    }
+
+    //clear screen
+    else if(x > (lcd.getWidth()-20))
+    {
+      clearall(1);
+      while(lcd.touchZ()){ lcd.touchRead(); }
+    }
+
+    //draw line
+    else if((last_x == 0) ||
+            ((x >= (last_x-10)) && (x <= (last_x+10)) && (y >= (last_y-10)) && (y <= (last_y+10))))
+    {
+      if((x != last_x) || (y != last_y))
+      {
+        last_x = x;
+        last_y = y;
+        lcd.fillRect(x, y, 4, 4, color);
+
+        //0xBEEF, x, y, color (all 16bit, total 8 bytes)
+        buf[0] = 0xBEEF;
+        buf[1] = x;
+        buf[2] = y;
+        buf[3] = color;
+#if WORKING_MODE == 0 //server
+        server.write((uint8_t*)buf, 8);
+#else
+        client.write((uint8_t*)buf, 8);
+#endif
+      }
+    }
+  }
+  else
+  {
+    last_x = 0;
+  }
+}

+ 354 - 0
lib/RedFly/examples/TwitterRSSReader/TwitterRSSReader.ino

@@ -0,0 +1,354 @@
+/*
+  Twitter RSS Reader
+
+  This sketch reads RSS feeds from Twitter and shows them on a display.
+  Requires RedFly + mSD-shield with MI0283QT-Adapter.
+ */
+
+#include <Wire.h>
+#include <SPI.h>
+#include <digitalWriteFast.h>
+#include <GraphicsLib.h>
+#include <MI0283QT2.h>
+#include <MI0283QT9.h>
+#include <DisplaySPI.h>
+#include <DisplayI2C.h>
+#include <RedFly.h>
+#include <RedFlyClient.h>
+
+
+//Declare only one display !
+// MI0283QT2 lcd;  //MI0283QT2 Adapter v1
+// MI0283QT9 lcd;  //MI0283QT9 Adapter v1
+// DisplaySPI lcd; //SPI (GLCD-Shield or MI0283QT Adapter v2)
+ DisplayI2C lcd; //I2C (GLCD-Shield or MI0283QT Adapter v2)
+
+
+/*
+byte ip[]        = { 192,168,  0, 30 }; //ip from shield (client)
+byte netmask[]   = { 255,255,255,  0 }; //netmask
+byte gateway[]   = { 192,168,  0,100 }; //ip from gateway/router
+byte dnsserver[] = { 192,168,  0,100 }; //ip from dns server
+*/
+byte server[]    = {   0,  0,  0,  0 }; //ip from server
+
+RedFlyClient client(server, 80);
+
+//obsolete Twitter API
+// #define HOSTNAME "twitter.com"
+// #define FILENAME "statuses/user_timeline/redflyshield.rss?count=5"
+
+//alternative 1: http://www.rssitfor.me/getrss?name=USERNAME
+// #define HOSTNAME "rssitfor.me"
+// #define FILENAME "getrss?name=redflyshield?count=5"
+
+//alternatives 2: http://twfeed.com/feed/USERNAME or http://twfeed.com/atom/USERNAME
+ #define HOSTNAME "twfeed.com"
+ #define FILENAME "feed/redflyshield?count=5"
+
+
+//display output functions
+#define infoClear()  lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(255,255,255))
+#define infoText(x)  lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(0,0,0)); lcd.drawTextPGM((lcd.getWidth()/2)-60, (lcd.getHeight()/2)-10, PSTR(x), RGB(255,255,255), RGB(0,0,0), 1)
+#define errorText(x) lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(0,0,0)); lcd.drawTextPGM((lcd.getWidth()/2)-60, (lcd.getHeight()/2)-10, PSTR(x), RGB(255,0,0), RGB(0,0,0), 1)
+
+
+uint8_t start_wifi(void)
+{
+  uint8_t ret, i;
+
+  //init the WiFi module
+  infoText("WiFi...");
+  ret = RedFly.init(115200, HIGH_POWER); //baudrate, LOW_POWER MED_POWER HIGH_POWER
+  if(ret)
+  {
+    errorText("WiFi...Error"); //there are problems with the communication between the Arduino and the RedFly
+    return 1;
+  }
+
+  //join network
+  for(i=5; i!=0; i--) //try 5 times
+  {
+    //scan for wireless networks (must be run before join command)
+    infoText("Scan...");
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    infoText("Join...");
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      errorText("Join...Error");
+    }
+    else
+    {
+      break;
+    }
+  }
+  if(ret)
+  {
+    return 2;
+  }
+
+  //set ip config
+  // ret = RedFly.begin(); //DHCP
+  // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+  // ret = RedFly.begin(ip);
+  // ret = RedFly.begin(ip, dnsserver);
+  // ret = RedFly.begin(ip, dnsserver, gateway);
+  // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+  infoText("IP...");
+  ret = RedFly.begin();
+  if(ret)
+  {
+    errorText("IP...Error");
+    RedFly.disconnect();
+    return 3;
+  }
+
+  return 0;
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+  //init display
+  //init display
+  lcd.begin();
+  //lcd.begin(SPI_CLOCK_DIV4, 8); //SPI Displays: spi-clk=Fcpu/4, rst-pin=8
+  //lcd.begin(0x20, 8); //I2C Displays: addr=0x20, rst-pin=8
+  lcd.touchStartCal(); //calibrate touchpanel
+
+  //start WiFi
+  while(start_wifi() != 0){ delay(1000); }
+
+  //draw screen background
+  lcd.fillRect(0, 0, lcd.getWidth(), 20, RGB(0,0,0));
+  lcd.drawTextPGM((lcd.getWidth()/2)-20, 5, PSTR("newer"), RGB(255,255,255), RGB(0,0,0), 1);
+  lcd.fillRect(0, lcd.getHeight()-20, lcd.getWidth(), 20, RGB(0,0,0));
+  lcd.drawTextPGM((lcd.getWidth()/2)-20, lcd.getHeight()-15, PSTR("older"), RGB(255,255,255), RGB(0,0,0), 1);
+
+  //send request
+  while(request_data() != 0)
+  {
+    delay(1000);
+    start_wifi(); //restart wifi connection
+  }
+}
+
+
+char data[128];  //receive buffer
+unsigned int dlen=0; //receive buffer length
+uint8_t state=0, lastc1=0, lastc2=0, lastc3=0, rss_item=1, item=0;
+
+
+uint8_t request_data() //send request to server
+{
+  uint8_t i;
+  unsigned long ms, last_time;
+  char txt[8];
+
+  //draw item index
+  sprintf(txt, "%i", ((rss_item+1)/2));
+  lcd.drawText((lcd.getWidth()/2)-10, 50, txt, RGB(0,0,255), RGB(255,255,255), 2);
+
+  infoText("Get IP...");
+  if(RedFly.getip(HOSTNAME, server) != 0) //get ip
+  {
+    errorText("Get IP...Error");
+  }
+  else
+  {
+    for(i=0, last_time=0; client.connected() == 0;)
+    {
+      ms = millis();
+      if(((ms-last_time) > 3000)) //every 3s
+      {
+        last_time = ms; //save time
+        infoText("Connecting...");
+        if(client.connect(server, 80) == 0)
+        {
+          errorText("Connecting...Error");
+          if(++i > 5)
+          {
+            return 2;
+          }
+        }
+      }
+    }
+
+    for(i=0, last_time=0; client.available() == 0;)
+    {
+      ms = millis();
+      if(((ms-last_time) > 3000)) //every 3s
+      {
+        last_time = ms; //save time
+        infoText("Request...");
+        client.print_P(PSTR("GET /"FILENAME" HTTP/1.0\r\nHost: "HOSTNAME"\r\n\r\n")); //Connection: close\r\n
+        i++;
+      }
+      if((i > 5) || (client.connected() == 0))
+      {
+        errorText("Request...Error");
+        client.stop();
+        return 3;
+      }
+    }
+    infoText("Receive...");
+  }
+
+  return 0;
+}
+
+
+void read_data() //receive data from server
+{
+  int c;
+
+  switch(state)
+  {
+    case 0: //search http header end (data start)
+      for(;;)
+      {
+        c = client.read();
+        if(c == -1)
+        {
+          break;
+        }
+        else if((lastc1 == '\n') && (c == '\r'))
+        {
+          infoText("Header found...");
+          state++;
+          break;
+        }
+        lastc3 = lastc2;
+        lastc2 = lastc1;
+        lastc1 = c;
+      }
+      break;
+
+    case 1: //search item
+      for(;;)
+      {
+        c = client.read();
+        if(c == -1)
+        {
+          break;
+        }
+        else if((lastc3 == 'a') && (lastc2 == 'r') && (lastc1 == 'y') && (c == '>')) //new: <summary> old:<title> and <description>
+        {
+          if(++item == rss_item)
+          {
+            infoText("Tag found...");
+            state++;
+            break;
+          }
+        }
+        lastc3 = lastc2;
+        lastc2 = lastc1;
+        lastc1 = c;
+      }
+      break;
+
+    case 2: //copy
+      for(;;)
+      {
+        c = client.read();
+        if(c == -1)
+        {
+          state++;
+          break;
+        }
+        else if((c != '\n') && (c != '\r'))
+        {
+          if(dlen >= 128)
+          {
+            state++;
+            break;
+          }
+          else
+          {
+            data[dlen++] = c;
+            if((lastc1 == '<') && (c == '/')) //tag end "</"
+            {
+              dlen -= 2;
+              data[dlen] = 0;
+              state++;
+              break;
+            }
+          }
+        }
+        lastc3 = lastc2;
+        lastc2 = lastc1;
+        lastc1 = c;
+      }
+      break;
+
+    case 3: //stop receiving
+      client.stop();
+      break;
+  }
+}
+
+
+void loop()
+{
+  if(client.available()) //data availavle?
+  {
+    read_data();
+  }
+  else if(dlen && !client.connected()) //if the server's disconnected, stop the client
+  {
+    client.stop();
+    data[dlen] = 0;
+    lcd.fillRect(2, 25, lcd.getWidth()-2, lcd.getHeight()-50, RGB(255,255,255)); //clear text
+    lcd.setCursor(2, 25);
+    lcd.setTextColor(RGB(0,0,0), RGB(255,255,255));
+    lcd.setTextSize(2);
+    lcd.print(data);
+    dlen = 0;
+  }
+  else
+  {
+    lcd.touchRead(); //service routine for touch panel
+
+    //touch press?
+    if(lcd.touchZ()) 
+    {
+      if(lcd.touchY() < 50) //newer rss item
+      {
+        if(rss_item > 1) //1 is the first item
+          rss_item -= 2;
+      }
+      else if(lcd.touchY() > (lcd.getHeight()-50)) //older rss item
+      {
+        if(rss_item < 10)
+          rss_item +=2;
+      }
+      
+      //reset vars
+      state  = 0;
+      lastc1 = 0;
+      lastc2 = 0;
+      lastc3 = 0;
+      item   = 0;
+      dlen   = 0;
+
+      //send request
+      while(request_data() != 0)
+      {
+        delay(1000);
+        start_wifi(); //restart wifi connection
+      }
+    }
+  }
+}

+ 175 - 0
lib/RedFly/examples/TwitterTest/TwitterTest.ino

@@ -0,0 +1,175 @@
+/*
+  Twitter Test
+ 
+  This sketch connects to Twitter and posts a message on
+  http://twitter.com/RedFlyShield
+
+  Based on the Twitter Lib from NeoCat
+  http://www.arduino.cc/playground/Code/TwitterLibrary
+  http://arduino-tweet.appspot.com
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyClient.h>
+
+
+byte ip[]        = { 192,168,  0, 30 }; //ip from shield (client)
+byte netmask[]   = { 255,255,255,  0 }; //netmask
+byte gateway[]   = { 192,168,  0,100 }; //ip from gateway/router
+byte dnsserver[] = { 192,168,  0,100 }; //ip from dns server
+byte server[]    = {   0,  0,  0,  0 }; //{ 209, 85,149,141 }; //ip from arduino-tweet.appspot.com (server)
+
+#define HOSTNAME "arduino-tweet.appspot.com" //host
+#define TOKEN    "273978908-s6eBqQrr97iXcrXVw4abHcpZ0bof2v5mKdQANXEI" //token from twitter.com/RedFlyShield
+#define MESSAGE  "Hello, World. This is just a test."
+
+//initialize the client library with the ip and port of the server 
+//that you want to connect to (port 80 is default for HTTP)
+RedFlyClient client(server, 80);
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        if(RedFly.getip(HOSTNAME, server) == 0) //get ip
+        {
+          if(client.connect(server, 80))
+          {
+            //build message and send to Twitter app
+            char buf[8];
+            client.print_P(PSTR("POST http://"HOSTNAME"/update HTTP/1.0\r\nHost: "HOSTNAME"\r\nContent-Length: ")); //send HTTP header
+            sprintf(buf, "%i\r\n", strlen("token="TOKEN"&status="MESSAGE)); //calc content length
+            client.print(buf); //send content length
+            client.print_P(PSTR("Connection: close\r\n\r\n"));
+            client.print_P(PSTR("token="TOKEN"&status="MESSAGE)); //send token and data
+          }
+          else
+          {
+            debugoutln("CLIENT ERR");
+            RedFly.disconnect();
+            for(;;); //do nothing forevermore
+          }
+        }
+        else
+        {
+          debugoutln("DNS ERR");
+          RedFly.disconnect();
+          for(;;); //do nothing forevermore
+        }
+      }
+    }
+  }
+}
+
+
+char data[1024];  //receive buffer
+unsigned int len=0; //receive buffer length
+
+void loop()
+{
+  int c;
+
+  //if there are incoming bytes available 
+  //from the server then read them 
+  if(client.available())
+  {
+    do
+    {
+      c = client.read();
+      if((c != -1) && (len < (sizeof(data)-1)))
+      {
+        data[len++] = c;
+      }
+    }while(c != -1);
+  }
+
+  //if the server's disconnected, stop the client and print the received data
+  if(len && !client.connected())
+  {
+    client.stop();
+    RedFly.disconnect();
+
+    data[len] = 0;
+    debugout(data);
+    
+    len = 0;
+  }
+}

+ 177 - 0
lib/RedFly/examples/TwitterTest_Socket/TwitterTest_Socket.ino

@@ -0,0 +1,177 @@
+/*
+  Twitter Test (Socket API)
+ 
+  This sketch connects to Twitter and posts a message on
+  http://twitter.com/RedFlyShield
+
+  Based on the Twitter Lib from NeoCat
+  http://www.arduino.cc/playground/Code/TwitterLibrary
+  http://arduino-tweet.appspot.com
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+
+
+byte ip[]        = { 192,168,  0, 30 }; //ip from shield (client)
+byte netmask[]   = { 255,255,255,  0 }; //netmask
+byte gateway[]   = { 192,168,  0,100 }; //ip from gateway/router
+byte dnsserver[] = { 192,168,  0,100 }; //ip from dns server
+byte server[]    = {   0,  0,  0,  0 }; //{ 209, 85,149,141 }; //ip from arduino-tweet.appspot.com (server)
+
+#define HOSTNAME "arduino-tweet.appspot.com" //host
+#define TOKEN    "273978908-s6eBqQrr97iXcrXVw4abHcpZ0bof2v5mKdQANXEI" //token from twitter.com/RedFlyShield
+#define MESSAGE  "Hello, World. This is just a test."
+
+uint8_t http=INVALID_SOCKET; //socket handle
+uint16_t http_len=0; //receive len
+char http_buf[512];  //receive buffer
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        if(RedFly.getip(HOSTNAME, server) == 0) //get ip
+        {
+          http = RedFly.socketConnect(PROTO_TCP, server, 80); //start connection to server on port 80
+          if(http == 0xFF)
+          {
+            debugoutln("SOCKET ERR");
+            RedFly.disconnect();
+            for(;;); //do nothing forevermore
+          }
+          else
+          {
+            //build message and send to Twitter app
+            //note: to minimize the RAM usage everything is in Flash memory
+            char buf[8];
+            RedFly.socketSendPGM(http, PSTR("POST http://"HOSTNAME"/update HTTP/1.0\r\nHost: "HOSTNAME"\r\nContent-Length: ")); //send HTTP header
+            sprintf(buf, "%i\r\n\r\n", strlen("token="TOKEN"&status="MESSAGE)); //calc content length
+            RedFly.socketSend(http, buf); //send content length and HTTP header end
+            RedFly.socketSendPGM(http, PSTR("token="TOKEN"&status="MESSAGE)); //send token and data
+          }
+        }
+        else
+        {
+          debugoutln("DNS ERR");
+          RedFly.disconnect();
+          for(;;); //do nothing forevermore
+        }
+      }
+    }
+  }
+}
+
+
+void loop()
+{
+  uint8_t sock, buf[32];
+  uint16_t rd, len;
+
+  if(http == INVALID_SOCKET) //no socket open
+  {
+    return;
+  }
+
+  sock = 0xFF; //0xFF = return data from all open sockets
+  rd = RedFly.socketRead(&sock, &len, buf, sizeof(buf));
+  if(sock == http)
+  {
+    if((rd != 0) && (rd != 0xFFFF))
+    {
+      if((http_len+rd) > sizeof(http_buf))
+      {
+        rd = sizeof(http_buf)-http_len;
+      }
+      memcpy(&http_buf[http_len], buf, rd);
+      http_len += rd;
+    }
+
+    if((rd == 0xFFFF) || (len == 0)) //connection closed or all data received
+    {
+      //close connection
+      RedFly.socketClose(sock);
+
+      //show http buffer
+      http_buf[sizeof(http_buf)-1] = 0;
+      debugout(http_buf);
+    }
+  }
+}

+ 308 - 0
lib/RedFly/examples/TwitterWriter/TwitterWriter_Socket.ino

@@ -0,0 +1,308 @@
+/*
+  Twitter Writer (Socket API)
+ 
+  This sketch connects to Twitter and posts a message on
+  http://twitter.com/RedFlyShield
+
+  Based on the Twitter Lib from NeoCat
+  http://www.arduino.cc/playground/Code/TwitterLibrary
+  http://arduino-tweet.appspot.com
+
+  Requires RedFly (CS Pin4) + mSD-shield with MI0283QT-Adapter and the 
+  PS2Keyboard Library http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html
+ */
+
+#include <Wire.h>
+#include <SPI.h>
+#include <digitalWriteFast.h>
+#include <GraphicsLib.h>
+#include <MI0283QT2.h>
+#include <MI0283QT9.h>
+#include <DisplaySPI.h>
+#include <DisplayI2C.h>
+#include <PS2Keyboard.h>
+#include <RedFly.h>
+
+
+//Declare only one display !
+// MI0283QT2 lcd;  //MI0283QT2 Adapter v1
+// MI0283QT9 lcd;  //MI0283QT9 Adapter v1
+// DisplaySPI lcd; //SPI (GLCD-Shield or MI0283QT Adapter v2)
+ DisplayI2C lcd; //I2C (GLCD-Shield or MI0283QT Adapter v2)
+
+PS2Keyboard keyboard;
+/*
+byte ip[]        = { 192,168,  0, 30 }; //ip from shield (client)
+byte netmask[]   = { 255,255,255,  0 }; //netmask
+byte gateway[]   = { 192,168,  0,100 }; //ip from gateway/router
+byte dnsserver[] = { 192,168,  0,100 }; //ip from dns server
+*/
+byte server[]    = {   0,  0,  0,  0 }; //ip from server
+
+#define HOSTNAME "arduino-tweet.appspot.com" //host
+#define TOKEN    "273978908-s6eBqQrr97iXcrXVw4abHcpZ0bof2v5mKdQANXEI" //token from twitter.com/RedFlyShield
+
+char message[256]; //min. 141
+uint8_t m_pos=0;
+
+
+//display output functions
+#define infoClear()  lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(255,255,255))
+#define infoText(x)  lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(0,0,0)); lcd.drawTextPGM((lcd.getWidth()/2)-60, (lcd.getHeight()/2)-10, PSTR(x), RGB(255,255,255), RGB(0,0,0), 1)
+#define errorText(x) lcd.fillRect(0, (lcd.getHeight()/2)-15, lcd.getWidth(), 20, RGB(0,0,0)); lcd.drawTextPGM((lcd.getWidth()/2)-60, (lcd.getHeight()/2)-10, PSTR(x), RGB(255,0,0), RGB(0,0,0), 1)
+
+
+uint8_t clearall(void)
+{
+  lcd.fillScreen(RGB(255,255,255));
+  lcd.fillRect(0, 0, lcd.getWidth(), 20, RGB(0,0,0));
+  lcd.drawTextPGM(20, 3, PSTR("Write a message and press Enter..."), RGB(255,255,255), RGB(0,0,0), 1);
+}
+
+
+void setup()
+{
+  //init display
+  lcd.begin();
+  //lcd.begin(SPI_CLOCK_DIV4, 8); //SPI Displays: spi-clk=Fcpu/4, rst-pin=8
+  //lcd.begin(0x20, 8); //I2C Displays: addr=0x20, rst-pin=8
+  lcd.fillScreen(RGB(255,255,255));
+
+  //init RedFly
+  RedFly.init(115200, HIGH_POWER);
+
+  //init keyboard
+  keyboard.begin(5, 3, PS2Keymap_German); //Data, Clock/IRQ (Uno: 2 3 | Mega: 2 3 18 19 20 21)
+
+  //draw screen background
+  clearall();
+
+  //set print options
+  lcd.setCursor(2, 25);
+  lcd.setTextColor(RGB(0,0,0), RGB(255,255,255));
+  lcd.setTextSize(2);
+}
+
+
+uint8_t start_wifi(void)
+{
+  uint8_t ret, i;
+
+  //init the WiFi module
+  infoText("WiFi...");
+  ret = RedFly.init(115200, HIGH_POWER); //baud rate, LOW_POWER MED_POWER HIGH_POWER
+  if(ret)
+  {
+    errorText("WiFi...Error"); //there are problems with the communication between the Arduino and the RedFly
+    return 1;
+  }
+
+  //join network
+  for(i=5; i!=0; i--) //try 5 times
+  {
+    //scan for wireless networks (must be run before join command)
+    infoText("Scan...");
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    infoText("Join...");
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      errorText("Join...Error");
+    }
+    else
+    {
+      break;
+    }
+  }
+  if(ret)
+  {
+    return 2;
+  }
+
+  //set ip config
+  // ret = RedFly.begin(); //DHCP
+  // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+  // ret = RedFly.begin(ip);
+  // ret = RedFly.begin(ip, dnsserver);
+  // ret = RedFly.begin(ip, dnsserver, gateway);
+  // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+  infoText("IP...");
+  ret = RedFly.begin();
+  if(ret)
+  {
+    errorText("IP...Error");
+    RedFly.disconnect();
+    return 3;
+  }
+
+  infoClear();
+
+  return 0;
+}
+
+
+uint8_t send_msg(void)
+{
+  uint8_t http, sock, buf[32];
+  uint16_t rd, len, msg_len;
+
+  if(RedFly.getlocalip(buf) != 0) //RedFly connected?
+  {
+    return 1;
+  }
+
+  infoText("Get IP...");
+  if(RedFly.getip(HOSTNAME, server) == 0) //get ip
+  {
+    infoText("Connecting...");
+    http = RedFly.socketConnect(PROTO_TCP, server, 80); //start connection to server on port 80
+    if(http != INVALID_SOCKET)
+    {
+      infoText("Send message...");
+      //build message and send to Twitter app
+      RedFly.socketSendPGM(http, PSTR("POST http://"HOSTNAME"/update HTTP/1.0\r\nHost: "HOSTNAME"\r\nContent-Length: ")); //send HTTP header
+      sprintf((char*)buf, "%i\r\n\r\n", strlen("token="TOKEN"&status=")+strlen(message)); //calc content length
+      RedFly.socketSend(http, (char*)buf); //send content length and HTTP header end
+      RedFly.socketSendPGM(http, PSTR("token="TOKEN"&status=")); //send token
+      RedFly.socketSend(http, message); //send message
+      delay(100);
+
+      //get response
+      for(msg_len=0, message[0]=0;;)
+      {
+        sock = 0xFF; //0xFF = return data from all open sockets
+        rd = RedFly.socketRead(&sock, &len, buf, sizeof(buf));
+        if(sock == http)
+        {
+          if((rd != 0) && (rd != 0xFFFF))
+          {
+            if((msg_len+rd) > sizeof(message))
+            {
+              rd = sizeof(message)-msg_len;
+            }
+            memcpy(&message[msg_len], buf, rd);
+            msg_len += rd;
+          }
+          if((rd == 0xFFFF) || (len == 0)) //connection closed or all data received
+          {
+            break;
+          }
+        }
+        else if(RedFly.socketClosed(http))
+        {
+          break;
+        }
+      }
+      message[msg_len] = 0;
+
+      //print response
+      infoClear();
+      lcd.setCursor(2, 25);
+      lcd.setTextSize(1);
+      lcd.print(message);
+      lcd.setTextSize(2);
+      delay(5000);
+
+      RedFly.socketClose(http);
+      RedFly.socketReset();
+    }
+    else
+    {
+      errorText("Connecting...Error");
+      return 3;
+    }
+  }
+  else
+  {
+    errorText("Get IP...Error");
+    return 2;
+  }
+
+  infoClear();
+
+  return 0;
+}
+
+
+void loop()
+{
+  char c;
+  uint8_t i;
+
+  if(keyboard.available())
+  {
+    c = keyboard.read();
+    switch(c)
+    {
+      case PS2_ENTER:
+        if(m_pos != 0)
+        {
+          while(send_msg())
+          {
+            while(start_wifi() != 0){ delay(1000); } //restart wifi connection
+          }
+          message[0] = 0;
+          m_pos      = 0;
+          clearall();
+          lcd.setCursor(2, 25);
+          while(keyboard.read() != -1); //clear keyboard buffer
+        }
+        break;
+
+      case PS2_ESC:
+        if(m_pos != 0)
+        {
+          memset(message, 0, sizeof(message));
+          m_pos = 0;
+          clearall();
+          lcd.setCursor(2, 25);
+          while(keyboard.read() != -1); //clear keyboard buffer
+        }
+        break;
+
+      case PS2_DELETE:
+        if(m_pos > 0)
+        {
+          message[--m_pos] = 0;
+          lcd.fillRect(0, 20, lcd.getWidth(), lcd.getHeight()-20, RGB(255,255,255));
+          lcd.setCursor(2, 25);
+          lcd.print(message);
+          while(keyboard.read() != -1); //clear keyboard buffer
+        }
+        break;
+
+      default:
+        if((c >= '0') && (c <= '9') ||
+           (c >= 'A') && (c <= 'Z') ||
+           (c >= 'a') && (c <= 'z') ||
+           (c == ' ')               ||
+           (c == '@')               ||
+           (c == '#')               ||
+           (c == '-')               ||
+           (c == '+')               ||
+           (c == '*')               ||
+           (c == ',')               ||
+           (c == '.')               ||
+           (c == '!')               ||
+           (c == '?'))
+        {
+          if(m_pos < 140)
+          {
+            message[m_pos++] = c;
+            message[m_pos]   = 0;
+            lcd.print(c);
+          }
+        }
+        break;
+    }
+  }
+}

+ 139 - 0
lib/RedFly/examples/UDP/UDP.ino

@@ -0,0 +1,139 @@
+/*
+  UDP Test
+ 
+  Test sketch for UDP client/server API.
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyClient.h>
+#include <RedFlyServer.h>
+
+
+byte ip[]       = { 192,168,  0, 30 }; //ip from shield (client)
+byte serverip[] = { 192,168,  0, 20 };
+
+//initialize the libraries
+RedFlyClient client(serverip, 1000);
+RedFlyServer server(1000);
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        client.connectUDP();
+        client.println_P(PSTR("Hello, World!"));
+        //client.stop();
+
+        server.beginUDP();
+      }
+    }
+  }
+}
+
+
+void loop()
+{
+  uint8_t buf[128];
+  uint16_t i;
+
+  i = client.available();
+  if(i)
+  {
+    i = client.read(buf, i);
+    buf[i] = 0;
+    debugoutln("Client: ");
+    debugoutln((char*)buf);
+  }
+
+  i = server.available();
+  if(i)
+  {
+    i = server.read(buf, i);
+    buf[i] = 0;
+    debugoutln("Server: ");
+    debugoutln((char*)buf);
+  }
+  else if(!server.connected()) //listening port still open?
+  {
+    server.stop(); //stop and reset server
+    server.beginUDP(); //start server
+  }
+}

+ 119 - 0
lib/RedFly/examples/WLANScan/WLANScan.ino

@@ -0,0 +1,119 @@
+/*
+  WLAN Scanner
+ 
+  This sketch scans for WLANs using a RedFly-Shield. 
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR");
+    for(;;); //do nothing forevermore
+  }
+
+  //get firmware version
+  char ver[5+1];
+  if(RedFly.getversion(ver) == 0)
+  {
+    debugout("FW: ");
+    debugoutln(ver);
+  }
+
+  //get WiFi module MAC
+  uint8_t mac[6];
+  if(RedFly.getmac(mac) == 0)
+  {
+    char tmp[32];
+    sprintf_P(tmp, PSTR("MAC: %x:%x:%x:%x:%x:%x"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+    debugoutln(tmp);
+  }
+
+  debugoutln("-----------------");
+  debugoutln("Start scanning...");
+  debugoutln("-----------------");
+}
+
+
+void loop()
+{
+  uint8_t ret, mode, rssi, type, mac[6];
+  char buf[64];
+
+  //scan for wireless networks
+  buf[0] = 0;
+  ret = RedFly.scan(buf, &mode, &rssi);
+  while((ret == 0) && (rssi != 0))
+  {
+    //show mode (0=Open, 1=WPA, 2=WPA2, 3=WEP) and RSSI
+    debugout(buf);
+    sprintf_P(buf, PSTR(", mode %i, rssi -%i dBm"), mode, rssi);
+    debugoutln(buf);
+
+    //get and show type (0=Ad-hoc, 1=Infrastructure)
+    ret = RedFly.gettype(buf, &type);
+    if(ret == 0)
+    {
+      debugout(buf);
+      sprintf_P(buf, PSTR(", type %i"), type);
+      debugoutln(buf);
+    }
+
+    //get and show BSSID
+    ret = RedFly.getbssid(buf, mac);
+    if(ret == 0)
+    {
+      debugout(buf);
+      sprintf_P(buf, PSTR(", bssid %x:%x:%x:%x:%x:%x"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+      debugoutln(buf);
+    }
+
+    //next scan
+    buf[0] = 0;
+    ret = RedFly.nextscan(buf, &mode, &rssi);
+  }
+
+  //wait 3s
+  delay(3000); 
+}

+ 163 - 0
lib/RedFly/examples/WebClient/WebClient.ino

@@ -0,0 +1,163 @@
+/*
+  Web Client
+ 
+  This sketch connects to a website using a RedFly-Shield. 
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyClient.h>
+
+
+byte ip[]        = { 192,168,  0, 30 }; //ip from shield (client)
+byte netmask[]   = { 255,255,255,  0 }; //netmask
+byte gateway[]   = { 192,168,  0,100 }; //ip from gateway/router
+byte dnsserver[] = { 192,168,  0,100 }; //ip from dns server
+byte server[]    = {   0,  0,  0,  0 }; //{  85, 13,145,242 }; //ip from www.watterott.net (server)
+
+#define HOSTNAME "www.watterott.net"  //host
+
+//initialize the client library with the ip and port of the server 
+//that you want to connect to (port 80 is default for HTTP)
+RedFlyClient client(server, 80);
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        if(RedFly.getip(HOSTNAME, server) == 0) //get ip
+        {
+          if(client.connect(server, 80))
+          {
+            //make a HTTP request
+            client.print_P(PSTR("GET / HTTP/1.1\r\nHost: "HOSTNAME"\r\n\r\n"));
+          }
+          else
+          {
+            debugoutln("CLIENT ERR");
+            RedFly.disconnect();
+            for(;;); //do nothing forevermore
+          }
+        }
+        else
+        {
+          debugoutln("DNS ERR");
+          RedFly.disconnect();
+          for(;;); //do nothing forevermore
+        }
+      }
+    }
+  }
+}
+
+
+char data[1024];  //receive buffer
+unsigned int len=0; //receive buffer length
+
+void loop()
+{
+  int c;
+
+  //if there are incoming bytes available 
+  //from the server then read them 
+  if(client.available())
+  {
+    do
+    {
+      c = client.read();
+      if((c != -1) && (len < (sizeof(data)-1)))
+      {
+        data[len++] = c;
+      }
+    }while(c != -1);
+  }
+
+  //if the server's disconnected, stop the client and print the received data
+  if(len && !client.connected())
+  {
+    client.stop();
+    RedFly.disconnect();
+
+    data[len] = 0;
+    debugout(data);
+    
+    len = 0;
+  }
+}

+ 34 - 83
5x10_led_scrolltext.ino → lib/RedFly/examples/WebClient_Socket/WebClient_Socket.ino

@@ -1,15 +1,25 @@
+/*
+  Web Client (Socket API)
+ 
+  This sketch connects to a website using a RedFly-Shield. 
+ */
+
 #include <digitalWriteFast.h>
 #include <RedFly.h>
-#include <RedFlyServer.h>
 
 
-byte ip[]      = { 192,168,  0, 10 }; //ip from shield (server)
-byte netmask[] = { 255,255,255,  0 }; //netmask
-byte server[]  = { 192,168,  0,  2 }; //i.e. Raspberry Pi
+byte ip[]        = { 192,168,  0, 30 }; //ip from shield (client)
+byte netmask[]   = { 255,255,255,  0 }; //netmask
+byte gateway[]   = { 192,168,  0,100 }; //ip from gateway/router
+byte dnsserver[] = { 192,168,  0,100 }; //ip from dns server
+byte server[]    = {   0,  0,  0,  0 }; //{  85, 13,145,242 }; //ip from www.watterott.net (server)
+
+#define HOSTNAME "www.watterott.net"  //host
 
 uint8_t http=INVALID_SOCKET; //socket handle
 uint16_t http_len=0; //receive len
-char http_buf[1024];  //receive buffer
+char http_buf[512];  //receive buffer
+
 
 //debug output functions (9600 Baud, 8N2)
 //Leonardo boards use USB for communication, so we dont need to disable the RedFly
@@ -38,17 +48,13 @@ void debugoutln(char *s)
 
 void setup()
 {
-  for(int i=4; i<20; i++) pinMode(i, OUTPUT);
-  digitalWrite(15, 1);
-  digitalWrite(13, 1);
   uint8_t ret;
 
 #if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
   Serial.begin(9600); //init serial port and set baudrate
   while(!Serial); //wait for serial port to connect (needed for Leonardo only)
 #endif
-  digitalWrite(12, 1);
-  digitalWrite(11, 1);
+
   //init the WiFi module on the shield
   // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
   // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
@@ -60,7 +66,6 @@ void setup()
   }
   else
   {
-    digitalWrite(10, 1);
     //scan for wireless networks (must be run before join command)
     RedFly.scan();
 
@@ -72,8 +77,6 @@ void setup()
     // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
     // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
     // ret = join("wlan-ssid") //join infrastructure network
-    digitalWrite(9, 1);
-    digitalWrite(8, 1);
     ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
     if(ret)
     {
@@ -82,8 +85,6 @@ void setup()
     }
     else
     {
-      digitalWrite(7, 1);
-      digitalWrite(6, 1);
       //set ip config
       // ret = RedFly.begin(); //DHCP
       // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
@@ -91,7 +92,7 @@ void setup()
       // ret = RedFly.begin(ip, dnsserver);
       // ret = RedFly.begin(ip, dnsserver, gateway);
       // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
-      ret = RedFly.begin(ip, 0, 0, netmask);
+      ret = RedFly.begin(ip, dnsserver, gateway, netmask);
       if(ret)
       {
         debugoutln("BEGIN ERR");
@@ -100,9 +101,9 @@ void setup()
       }
       else
       {
-        digitalWrite(5, 1);
-        RedFly.getlocalip(ip); //receive shield IP in case of DHCP/Auto-IP
-        http = RedFly.socketConnect(PROTO_TCP, server, 80); //start connection to server on port 80
+        if(RedFly.getip(HOSTNAME, server) == 0) //get ip
+        {
+          http = RedFly.socketConnect(PROTO_TCP, server, 80); //start connection to server on port 80
           if(http == 0xFF)
           {
             debugoutln("SOCKET ERR");
@@ -112,17 +113,24 @@ void setup()
           else
           {
             //send HTTP request
-            RedFly.socketSendPGM(http, PSTR("GET /scroll.php HTTP/1.1\r\nHost: 192.168.0.2\r\n\r\n"));
+            RedFly.socketSendPGM(http, PSTR("GET / HTTP/1.1\r\nHost: "HOSTNAME"\r\n\r\n"));
           }
-        digitalWrite(4, 1);
+        }
+        else
+        {
+          debugoutln("DNS ERR");
+          RedFly.disconnect();
+          for(;;); //do nothing forevermore
+        }
       }
     }
   }
 }
 
+
 void loop()
 {
- uint8_t sock, buf[32];
+  uint8_t sock, buf[32];
   uint16_t rd, len;
 
   if(http == INVALID_SOCKET) //no socket open
@@ -136,79 +144,22 @@ void loop()
   {
     if((rd != 0) && (rd != 0xFFFF))
     {
-      /*if((http_len+rd-250) > sizeof(http_buf)) //overflow
+      if((http_len+rd) > sizeof(http_buf))
       {
         rd = sizeof(http_buf)-http_len;
-      }*/
-      if(http_len >= 250) //ignore header
-      {
-        memcpy(&http_buf[http_len-250], buf, rd);
       }
+      memcpy(&http_buf[http_len], buf, rd);
       http_len += rd;
     }
+
     if((rd == 0xFFFF) || (len == 0)) //connection closed or all data received
     {
       //close connection
       RedFly.socketClose(sock);
 
       //show http buffer
-      //http_buf[sizeof(http_buf)-1] = 0;
+      http_buf[sizeof(http_buf)-1] = 0;
       debugout(http_buf);
-      int start, width=sizeof(http_buf)-1, n=4;
-      for(int x=sizeof(http_buf)-1;x>0;x--)
-      {
-         if(http_buf[x] == 10)
-         {
-           width=start-x;
-           start=x;
-           
-           if (n>0)
-            n--;
-           else
-            break;
-         }
-      }   
-      if(0 && http_buf[start+1] < 32) {//http_buf[start[0]]!='0' && http_buf[start[0]]!='1'
-        digitalWrite(4, !digitalRead(4));
-        http = RedFly.socketConnect(PROTO_TCP, server, 80); //start connection to server on port 80
-        RedFly.socketSendPGM(http, PSTR("GET /led/scroll.php HTTP/1.1\r\nHost: 192.168.0.2\r\n\r\n"));
-      } else {
-        unsigned long ms=0;
-        unsigned long refresh=0;
-        int s=-9;
-        refresh=millis()+5*60*1000;
-        for(;;) {
-          if(millis()>ms) {
-            ms=millis()+100;
-            s++;
-            if (s>=width*7-7) {
-              s=-9;
-              if ( millis() > refresh) {
-                digitalWrite(15, 1);
-                digitalWrite(4, !digitalRead(4));
-                http_len=0;
-                http = RedFly.socketConnect(PROTO_TCP, server, 80); //start connection to server on port 80
-                RedFly.socketSendPGM(http, PSTR("GET /led/scroll.php HTTP/1.1\r\nHost: 192.168.0.2\r\n\r\n"));
-                break;
-              }
-            }
-          }
-          for(int a=15; a<20; a++){
-            digitalWrite(a, 1);
-            for(int b=0; b<10; b++){
-              if(s+b>=0 && s+b<width*7-7)
-                digitalWrite(13-b, ((http_buf[start+1+(s+b)/7+(19-a)*width] - 32) >> ((s+b)%7)) & 1);
-              else
-                digitalWrite(13-b, 0);
-            }
-            delay(1);
-            for(int b=4; b<14; b++){
-              digitalWrite(b, 0);
-            }
-            digitalWrite(a, 0);
-          }
-        }
-      }
     }
   }
 }

+ 181 - 0
lib/RedFly/examples/WebServer/WebServer.ino

@@ -0,0 +1,181 @@
+/*
+  Web Server
+  
+  This sketch acts as a server using a RedFly-Shield.
+  For testing, open in your browser http://192.168.0.30/
+  (Replace the IP with the one from your RedFly-Shield.)
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyServer.h>
+
+
+byte ip[]      = { 192,168,  0, 30 }; //ip from shield (server)
+byte netmask[] = { 255,255,255,  0 }; //netmask
+
+//initialize the server library with the port 
+//you want to use (port 80 is default for HTTP)
+RedFlyServer server(80);
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, 0, 0, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        RedFly.getlocalip(ip); //receive shield IP in case of DHCP/Auto-IP
+        server.begin();
+      }
+    }
+  }
+}
+
+
+void loop()
+{
+  uint8_t rssi;
+
+  //listen for incoming clients
+  if(server.available())
+  {
+    //a http request ends with a blank line
+    boolean currentLineIsBlank = true;
+    while(server.available())
+    {
+      char c = server.read();
+      //if you've gotten to the end of the line (received a newline
+      //character) and the line is blank, the http request has ended,
+      //so you can send a reply
+      if(c == '\n' && currentLineIsBlank)
+      {
+        //clear input buffer
+        server.flush(); 
+
+        //get RSSI before sending data
+        rssi = RedFly.getrssi();
+
+        //send standard HTTP 200 header
+        server.print_P(PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));
+
+        //send some text
+        server.println_P(PSTR("<h1>Hello, World!</h1><br>"));
+
+        //output the value of each analog input pin
+        for(int chn=0; chn < 6; chn++)
+        {
+          char tmp[32];
+          sprintf_P(tmp, PSTR("analog input %i is %i <br>"), chn, analogRead(chn));
+          server.println(tmp);
+        }
+
+        //show RSSI
+        server.print_P(PSTR("<br><i>RSSI: -"));
+        server.print(rssi, DEC); server.print(" dBm");
+        server.println_P(PSTR("</i><br>"));
+
+        //show IP address of RedFly
+        server.print_P(PSTR("<br><i>RedFly IP: "));
+        server.print(ip[0], DEC); server.print(".");
+        server.print(ip[1], DEC); server.print(".");
+        server.print(ip[2], DEC); server.print(".");
+        server.print(ip[3], DEC);
+        server.println_P(PSTR("</i><br>"));
+        break;
+      }
+      if(c == '\n')
+      {
+        //you're starting a new line
+        currentLineIsBlank = true;
+      } 
+      else if(c != '\r')
+      {
+        //you've gotten a character on the current line
+        currentLineIsBlank = false;
+      }
+    }
+
+    //close connection
+    server.stop();
+  }
+  else if(!server.connected()) //listening port still open?
+  {
+    server.stop(); //stop and reset server
+    server.begin(); //start server
+  }
+}

+ 390 - 0
lib/RedFly/examples/WebServer2/WebServer2.ino

@@ -0,0 +1,390 @@
+/*
+  Web Server with URL decoding/parameter support
+  
+  This sketch acts as a server using a RedFly-Shield. 
+  For testing, open in your browser http://192.168.0.30/
+  (Replace the IP with the one from your RedFly-Shield.)
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyServer.h>
+#include <RedFlyNBNS.h>
+
+
+#define FAVICONSIZE 318
+const uint8_t FAVICON[FAVICONSIZE] PROGMEM = {
+	0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00,
+	0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00,
+	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80,
+	0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
+	0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0x00, 0x80, 0x80,
+	0x80, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+	0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
+	0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x08, 0x66, 0x66, 0x80,
+	0x00, 0x00, 0x00, 0x08, 0x66, 0x66, 0x66, 0x66, 0x80, 0x00, 0x00, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x08, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x80, 0x06, 0x7F, 0xFF, 0x76, 0x67, 0xFF, 0xF7, 0x60, 0x87, 0xF6,
+	0x66, 0xF7, 0x7F, 0x66, 0x6F, 0x78, 0x6F, 0x66, 0x66, 0x6F, 0xF6, 0x6F,
+	0x66, 0xF6, 0x6F, 0x6F, 0xFF, 0x6F, 0xF6, 0xFF, 0xF6, 0xF6, 0x6F, 0x66,
+	0x66, 0x6F, 0xF6, 0x6F, 0x66, 0xF6, 0x67, 0xF6, 0x66, 0xF7, 0x7F, 0x66,
+	0x6F, 0x76, 0x86, 0x7F, 0xFF, 0x76, 0x67, 0xFF, 0xF7, 0x68, 0x06, 0x66,
+	0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x08, 0x66, 0x66, 0x66, 0x66, 0x66,
+	0x66, 0x80, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x08,
+	0x66, 0x66, 0x66, 0x66, 0x80, 0x00, 0x00, 0x00, 0x08, 0x66, 0x66, 0x80,
+	0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xC0, 0x03,
+	0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01,
+	0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x07,
+	0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00
+};
+
+
+byte ip[]      = { 192,168,  0, 30 }; //ip from shield (server)
+byte netmask[] = { 255,255,255,  0 }; //netmask
+
+//initialize the server library with the port 
+//you want to use (port 80 is default for HTTP)
+RedFlyServer server(80);
+//initialize the NBNS library with the device name (max. 16 characters)
+RedFlyNBNS NBNS("REDFLY");
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, 0, 0, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        server.begin();
+      }
+    }
+  }
+}
+
+
+char* strrmvspace(char *dst, const char *src) //remove space at start and end of a string
+{
+  uint16_t i;
+
+  if(*src == 0)
+  {
+    *dst = 0;
+  }
+  else
+  {
+    //at start
+    for(i=0; isspace(src[i]); i++);
+    strcpy(dst, &src[i]);
+    //at end
+    i=strlen(dst)-1;
+    for(i=strlen(dst)-1; isspace(dst[i]); i--)
+    {
+      dst[i] = 0;
+    }
+  }
+
+  return dst;
+}
+
+
+uint16_t htou(const char *src) //hex to uint
+{
+  uint16_t value=0;
+
+  while(*src)
+  {
+         if((*src >= '0') && (*src <= '9')) { value = (value*16) + (*src-'0'+ 0); }
+    else if((*src >= 'A') && (*src <= 'F')) { value = (value*16) + (*src-'A'+10); }
+    else if((*src >= 'a') && (*src <= 'f')) { value = (value*16) + (*src-'a'+10); }
+    else                                    { break; }
+    src++;
+  }
+
+  return value;
+}
+
+
+uint16_t url_decode(char *dst, const char *src, uint16_t len)
+{
+  uint16_t i;
+  char c, *ptr, buf[3]={0,0,0};
+
+  ptr = dst; //save dst
+
+  for(i=0; i<len;)
+  {
+    c = *src++; i++;
+    if((c == 0)    || 
+       (c == '&')  ||
+       (c == ' ')  ||
+       (c == '\n') ||
+       (c == '\r'))
+    {
+      break;
+    }
+    else if(c == '%')
+    {
+      buf[0] = *src++; i++;
+      buf[1] = *src++; i++;
+      *dst++ = (unsigned char)htou(buf);
+    }
+    else if(c == '+')
+    {
+      *dst++ = ' ';
+    }
+    else
+    {
+      *dst++ = c;
+    }
+  }
+  *dst = 0;
+
+  //remove space at start and end of string
+  strrmvspace(ptr, ptr);
+
+  return i;
+}
+
+
+void loop()
+{
+  char file[32], param[64], *ptr, *p1, *p2, *p3;
+  int c, i, len;
+
+  //NBNS service routine
+  NBNS.service();
+
+  //listen for data (HTTP server)
+  if(server.available() > 10)
+  {
+    //analyze HTTP header/request
+    file[0] = 0;
+    server.read((uint8_t*)file, 4);
+    if(strncmp_P(file, PSTR("GET "), 4) == 0) 
+    {
+      //get file
+      file[0] = 0;
+      ptr = file;
+      do
+      {
+        c = server.read();
+        if(isalnum(c) || (c == '/'))
+        {
+          *ptr++ = c;
+          *ptr   = 0;
+        }
+      }while((c != ' ') && (c != '?') && (c != -1));
+
+      //get parameter
+      param[0] = 0;
+      p1       = 0;
+      p2       = 0;
+      p3       = 0;
+      if(c == '?')
+      {
+        //read parameter
+        ptr = param;
+        len = 0;
+        do
+        {
+          c = server.read();
+          if((c != ' ') && (len < (sizeof(param)-1)))
+          {
+            *ptr++ = c;
+            *ptr   = 0;
+            len++;
+          }
+        }while((c != ' ') && (c != '\n') && (c != '\r') && (c != -1));
+
+        //decode parameter
+        ptr = param;
+        while(len != 0)
+        {
+               if(strncasecmp(ptr, "p1=", 3) == 0)
+          { ptr+=3; len-=3; p1=ptr; i=url_decode(ptr, ptr, len); ptr+=i; len-=i; }
+          else if(strncasecmp(ptr, "p2=", 3) == 0)
+          { ptr+=3; len-=3; p2=ptr; i=url_decode(ptr, ptr, len); ptr+=i; len-=i; }
+          else if(strncasecmp(ptr, "p3=", 3) == 0)
+          { ptr+=3; len-=3; p3=ptr; i=url_decode(ptr, ptr, len); ptr+=i; len-=i; }
+          else
+          {
+            ptr++; 
+            len--;
+          }
+        }
+      }
+
+      //clear input buffer
+      server.flush();
+
+      //send file
+      if(((file[0] == '/') && (file[1] == 0))          ||
+         (strncasecmp_P(file, PSTR("/index"), 6) == 0) ||
+         (strncasecmp_P(file, PSTR("/test"),  5) == 0) ||
+         (strncasecmp_P(file, PSTR("/abc"),   4) == 0)) //default file
+      {
+        //send standard HTTP 200 header
+        server.print_P(PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));
+
+        //send HTML
+        server.println_P(PSTR("<h2>RedFly Test</h2>\r\n" \
+                              "<a href=\"/index\">index</a> <a href=\"/test\">test</a> <a href=\"/abc\">abc</a> <a href=\"/favicon\">favicon</a><br><br>\r\n" \
+                              "<form method=\"get\">\r\n" \
+                              "P1: <input type=\"text\" name=\"p1\" maxlength=\"10\" value=\"\"><br>\r\n" \
+                              "P2: <input type=\"text\" name=\"p2\" maxlength=\"10\" value=\"\"><br>\r\n" \
+                              "P3: <input type=\"text\" name=\"p3\" maxlength=\"10\" value=\"\"><br>\r\n" \
+                              "<input type=\"submit\"></form>\r\n" \
+                              "<h3>Info</h3>"));
+
+        if(file[0])
+        {
+          server.print_P(PSTR("FILE: "));
+          server.print(file);
+          server.println_P(PSTR("<br>"));
+        }
+        if(p1)
+        {
+          server.print_P(PSTR("P1: "));
+          server.print(p1);
+          server.println_P(PSTR("<br>"));
+        }
+        if(p2)
+        {
+          server.print_P(PSTR("P2: "));
+          server.print(p2);
+          server.println_P(PSTR("<br>"));
+        }
+        if(p3)
+        {
+          server.print_P(PSTR("P3: "));
+          server.print(p3);
+          server.println_P(PSTR("<br>"));
+        }
+      }
+      else if(strncasecmp_P(file, PSTR("/favicon"), 8) == 0) //favicon
+      {
+        //send standard HTTP 200 header
+        server.print_P(PSTR("HTTP/1.1 200 OK\r\nContent-Type: image/x-icon\r\n\r\n"));
+        //send image data (from Flash)
+        PGM_P data;
+        data = (PGM_P)FAVICON;
+        for(len=FAVICONSIZE; len!=0;)
+        {
+          if(len >= 32)
+          {
+            memcpy_P(file, data, 32);
+            server.write((uint8_t*)file, 32);
+            data += 32;
+            len  -= 32;
+          }
+          else
+          {
+            memcpy_P(file, data, len);
+            server.write((uint8_t*)file, len);
+            data += len;
+            len   = 0;
+          }
+        }
+      }
+      else //file not found
+      {
+        //send HTTP 404 header
+        server.print_P(PSTR("HTTP/1.1 404 Not Found\r\n\r\nError 404 Not Found"));
+      }
+    }
+    else
+    {
+      //clear input buffer
+      server.flush();
+      //send HTTP 400 header
+      server.print_P(PSTR("HTTP/1.0 400 Bad request\r\n\r\nError 400 Bad request"));
+    }
+
+    //close connection
+    server.stop();
+  }
+  else if(!server.connected()) //listening port still open?
+  {
+    server.stop(); //stop and reset server
+    server.begin(); //start server
+  }
+}

+ 194 - 0
lib/RedFly/examples/WebServer_Socket/WebServer_Socket.ino

@@ -0,0 +1,194 @@
+/*
+  Web Server (Socket API)
+  
+  This sketch acts as a server using a RedFly-Shield.
+  For testing, open in your browser http://192.168.0.30/
+  (Replace the IP with the one from your RedFly-Shield.)
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+
+
+byte ip[]      = { 192,168,  0, 30 }; //ip from shield (server)
+byte netmask[] = { 255,255,255,  0 }; //netmask
+
+uint8_t http=INVALID_SOCKET; //socket handle
+uint16_t http_len=0; //receive len
+char http_buf[64];   //receive buffer
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, 0, 0, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        //RedFly.getlocalip(ip); //receive shield IP in case of DHCP/Auto-IP
+        http = RedFly.socketListen(PROTO_TCP, 80); //start listening on port 80
+        if(http == 0xFF)
+        {
+          debugoutln("SOCKET ERR");
+          RedFly.disconnect();
+          for(;;); //do nothing forevermore
+        }
+      }
+    }
+  }
+}
+
+
+void loop()
+{
+  uint8_t sock;
+  char buf[512], *ptr;
+  uint16_t buf_len, rd, len;
+
+  //check if socket is opened
+  if(RedFly.socketClosed(http)) //no socket open
+  {
+    http = RedFly.socketListen(PROTO_TCP, 80); //start listening on port 80
+  }
+
+  //get data
+  sock    = 0xFF; //0xFF = return data from all open sockets
+  ptr     = buf;
+  buf_len = 0;
+  do
+  {
+    rd = RedFly.socketRead(&sock, &len, (uint8_t*)ptr, sizeof(buf)-buf_len);
+    if((rd != 0) && (rd != 0xFFFF)) //0xFFFF = connection closed
+    {
+      ptr     += rd;
+      buf_len += rd;
+    }
+  }while((len != 0) && (buf_len < sizeof(buf)));
+
+  //progress the received data
+  if(buf_len && (sock == http) && (sock != INVALID_SOCKET))
+  {
+    if(strncmp_P(buf, PSTR("GET / HTTP"), 10) == 0) //main site
+    {
+      //send HTTP 200 header
+      RedFly.socketSendPGM(sock, PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n")); //Content-Length: xx\r\n
+      //send HTML data
+      RedFly.socketSendPGM(sock, PSTR("Hello, World! <br><br>"));
+
+      //output the value of each analog input pin
+      for(int chn=0; chn < 6; chn++)
+      {
+        sprintf((char*)buf, "analog input %i is %i <br>", chn, analogRead(chn));
+        RedFly.socketSend(sock, (char*)buf);
+      }
+
+      //show LED on/off link
+      RedFly.socketSendPGM(sock, PSTR("<br><br> <a href='/ledon'>LED on</a> - <a href='/ledoff'>LED off</a>"));
+    }
+    else if(strncmp_P(buf, PSTR("GET /ledon HTTP"), 15) == 0) //led on
+    {
+      //switch LED on
+      pinMode(13, OUTPUT);
+      digitalWrite(13, HIGH);
+
+      //send HTTP 200 header
+      RedFly.socketSendPGM(sock, PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));
+      //send HTML data
+      RedFly.socketSendPGM(sock, PSTR("Hello, World! <br><br>"));
+      RedFly.socketSendPGM(sock, PSTR("<a href='/ledoff'>LED off</a> <br><br>"));
+    }
+    else if(strncmp_P(buf, PSTR("GET /ledoff HTTP"), 16) == 0) //led off
+    {
+      //switch LED off
+      pinMode(13, OUTPUT);
+      digitalWrite(13, LOW);
+
+      //send HTTP 200 header
+      RedFly.socketSendPGM(sock, PSTR("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));
+      //send HTML data
+      RedFly.socketSendPGM(sock, PSTR("Hello, World! <br><br>"));
+      RedFly.socketSendPGM(sock, PSTR("<a href='/ledon'>LED on</a> <br><br>"));
+    }
+    else
+    {
+      //send HTTP 404 header
+      RedFly.socketSendPGM(sock, PSTR("HTTP/1.1 404 Not Found\r\n\r\n"));
+    }
+
+    //close connection
+    RedFly.socketClose(sock);
+  }
+}

+ 58 - 0
lib/RedFly/examples/WebServer_Socket/conn_test.htm

@@ -0,0 +1,58 @@
+<html>
+  <head>
+    <title>RedFly Connection Test</title>
+    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+    <script src="http://code.jquery.com/jquery-latest.js"></script>
+    <script type="text/javascript">
+      function requestCrossDomain(url, callback)
+      {
+        //build YQL query
+        var yql = 'http://query.yahooapis.com/v1/public/yql?q='+encodeURIComponent('select * from html where url="'+url+'"')+'&format=xml&callback=?';
+        //get YSQL string, and run callback function
+        $.getJSON
+        (
+          yql,
+          function(data)
+          {
+            if(data.results[0] && typeof callback === "function")
+            {  
+              data = data.results[0];
+              data = data.replace("/<noscript[^>]*>[\S\s]*?<\/noscript>/g", "");
+              data = data.replace("/<script[^>]*>[\S\s]*?<\/script>/g", "");
+              data = data.replace("/<script.*\/>/", "");
+              callback(data);
+            }
+            else
+            {
+              callback("ERROR");
+            }
+          }
+        );
+      }
+
+      function http_get()
+      {
+        var url = $("input#ip").val();
+        $("textarea#output").text("Start HTTP GET "+url);
+        requestCrossDomain
+        (
+          url,
+          function(data){ $("textarea#output").text(data); }
+        );
+      }
+    </script>
+  </head>
+
+  <body>
+    <h1>RedFly Connection Test</h1>
+    RedFly URL: <input type="text" name="ip" id="ip" size="40" value="http://192.168.0.30/">
+    <input type="button" name="get" id="get" value="HTTP GET" onClick="http_get()">
+    <br><br>
+    <textarea cols="75" rows="20" name="output" id="output"></textarea>
+    <br><br><br><br>
+    <i>
+    Using Yahoo YQL to bypass cross site protection.<br>
+    Route: HTML document -> Yahoo YQL -> Cross Domain -> Yahoo YQL -> HTML document
+    </i>
+  </body>
+</html>

+ 166 - 0
lib/RedFly/examples/XivelyClient/XivelyClient.ino

@@ -0,0 +1,166 @@
+/*
+  Xively Client (previously Cosm, Pachube)
+ 
+  This sketch connects to Xively (http://xively.com) using a RedFly-Shield.
+  https://xively.com/feeds/81548
+ */
+
+#include <digitalWriteFast.h>
+#include <RedFly.h>
+#include <RedFlyClient.h>
+
+
+byte ip[]        = { 192,168,  0, 30 }; //ip from shield (client)
+byte netmask[]   = { 255,255,255,  0 }; //netmask
+byte gateway[]   = { 192,168,  0,100 }; //ip from gateway/router
+byte dnsserver[] = { 192,168,  0,100 }; //ip from dns server
+byte server[]    = {   0,  0,  0,  0 }; //ip from api.xively.com (server)
+
+#define HOSTNAME  "api.xively.com"         //host
+#define APIKEY    "ZmR191JkoUttt0rQoCSqVKdKa5KSAKx5c1JDZGZ1OFFyYz0g" //your api key
+#define FEEDID    "81548"                  //your feed ID
+#define USERAGENT "My Arduino Project"     //user agent is the project name
+#define INTERVAL 10*1000UL                 //10s delay between updates
+
+unsigned long lastConnectionTime = 0; //last time you connected to the server, in milliseconds
+
+//initialize the client library with the ip and port of the server 
+//that you want to connect to (port 80 is default for HTTP)
+RedFlyClient client(server, 80);
+
+
+//debug output functions (9600 Baud, 8N2)
+//Leonardo boards use USB for communication, so we dont need to disable the RedFly
+void debugout(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.print(s);
+#else
+  RedFly.disable();
+  Serial.print(s);
+  RedFly.enable();
+#endif
+}
+
+void debugoutln(char *s)
+{
+#if defined(__AVR_ATmega32U4__)
+  Serial.println(s);
+#else
+  RedFly.disable();
+  Serial.println(s);
+  RedFly.enable();
+#endif
+}
+
+
+void setup()
+{
+  uint8_t ret;
+
+#if defined(__AVR_ATmega32U4__) //Leonardo boards use USB for communication
+  Serial.begin(9600); //init serial port and set baudrate
+  while(!Serial); //wait for serial port to connect (needed for Leonardo only)
+#endif
+
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init(pwr) //9600 baud, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+  // ret = RedFly.init() //9600 baud, HIGH_POWER
+  ret = RedFly.init();
+  if(ret)
+  {
+    debugoutln("INIT ERR"); //there are problems with the communication between the Arduino and the RedFly
+  }
+  else
+  {
+    //scan for wireless networks (must be run before join command)
+    RedFly.scan();
+
+    //join network
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER or IBSS_CREATOR, chn, authmode) //join infrastructure or ad-hoc network, or create ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw", IBSS_CREATOR, chn) //create ad-hoc network with password, channel 1-14
+    // ret = join("wlan-ssid", IBSS_CREATOR, chn) //create ad-hoc network, channel 1-14
+    // ret = join("wlan-ssid", "wlan-passw", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network with password
+    // ret = join("wlan-ssid", INFRASTRUCTURE or IBSS_JOINER) //join infrastructure or ad-hoc network
+    // ret = join("wlan-ssid", "wlan-passw") //join infrastructure network with password
+    // ret = join("wlan-ssid") //join infrastructure network
+    ret = RedFly.join("wlan-ssid", "wlan-passw", INFRASTRUCTURE);
+    if(ret)
+    {
+      debugoutln("JOIN ERR");
+      for(;;); //do nothing forevermore
+    }
+    else
+    {
+      //set ip config
+      // ret = RedFly.begin(); //DHCP
+      // ret = RedFly.begin(1 or 2); //1=DHCP or 2=Auto-IP
+      // ret = RedFly.begin(ip);
+      // ret = RedFly.begin(ip, dnsserver);
+      // ret = RedFly.begin(ip, dnsserver, gateway);
+      // ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      ret = RedFly.begin(ip, dnsserver, gateway, netmask);
+      if(ret)
+      {
+        debugoutln("BEGIN ERR");
+        RedFly.disconnect();
+        for(;;); //do nothing forevermore
+      }
+      else
+      {
+        if(RedFly.getip(HOSTNAME, server) == 0) //get ip
+        {
+          //everything okay
+          debugoutln("Start sending...");
+        }
+        else
+        {
+          debugoutln("DNS ERR");
+          RedFly.disconnect();
+          for(;;); //do nothing forevermore
+        }
+      }
+    }
+  }
+}
+
+
+void loop()
+{
+  unsigned long ms = millis();
+
+  if(!client.connected() && ((ms-lastConnectionTime) > INTERVAL))
+  {
+    lastConnectionTime = ms;
+
+    //read and pepare sensor data
+    char tmp[64];
+    int adc0 = analogRead(A0);
+    int adc1 = analogRead(A1);  
+    int adc2 = analogRead(A2);  
+    sprintf(tmp, "adc0,%i\r\nadc1,%i\r\nadc2,%i\r\n", adc0, adc1, adc2);
+
+    //connect to server
+    if(client.connect(server, 80)) 
+    {
+      //send HTTP header
+      client.print_P(PSTR("PUT /v2/feeds/"FEEDID".csv HTTP/1.1\r\n"));
+      client.print_P(PSTR("Host: "HOSTNAME"\r\n"));
+      client.print_P(PSTR("X-ApiKey: "APIKEY"\r\n"));
+      client.print_P(PSTR("User-Agent: "USERAGENT"\r\n"));
+      client.print_P(PSTR("Content-Type: text/csv\r\n"));
+      client.print_P(PSTR("Content-Length: "));
+      client.println(strlen(tmp));
+      client.print_P(PSTR("Connection: close\r\n\r\n"));
+      //here's the content of the PUT request
+      client.print(tmp);
+      //close connection
+      client.stop();
+    }
+    else
+    {
+      debugoutln("CONN ERR");
+    }
+  }
+}

+ 13 - 0
lib/RedFly/library.json

@@ -0,0 +1,13 @@
+{
+  "name": "RedFly",
+  "keywords": "wifi, wlan",
+  "description": "RedFly-Shield (WiFi/WLAN)",
+  "include": "RedFly",
+  "repository":
+  {
+    "type": "git",
+    "url": "https://github.com/watterott/Arduino-Libs.git"
+  },
+  "frameworks": "arduino",
+  "platforms": "atmelavr"
+}

+ 9 - 0
lib/RedFly/library.properties

@@ -0,0 +1,9 @@
+name=RedFly
+version=1.0.0
+author=Watterott
+maintainer=Watterott
+sentence=RedFly-Shield (WiFi/WLAN)
+paragraph=RedFly-Shield (WiFi/WLAN)
+category=Communication
+url=https://github.com/watterott/Arduino-Libs
+architectures=*

+ 20 - 0
platformio.ini

@@ -0,0 +1,20 @@
+; PlatformIO Project Configuration File
+;
+;   Build options: build flags, source filter
+;   Upload options: custom upload port, speed and extra flags
+;   Library options: dependencies, extra library storages
+;   Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[env:uno]
+platform = atmelavr
+board = uno
+framework = arduino
+#build_unflags = -Os
+build_flags = -O3
+
+#upload_port = /dev/ttyUSB1
+#monitor_port = /dev/ttyUSB1
+monitor_speed = 38400

+ 51 - 0
redfly-led.py

@@ -0,0 +1,51 @@
+#!/bin/python3
+
+import socket
+import sys
+import time
+import math
+
+# Create a TCP/IP socket
+sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+
+# Connect the socket to the port where the server is listening
+server_address = ('0.0.0.0', 2020)
+print('binding {} port {}'.format(*server_address))
+sock.bind(server_address)
+
+N_ROWS = 5
+N_COLS = 10
+
+oldTime = time.time()
+oldPing = time.time()
+
+def getBytes():
+  pixels = [0] * (N_ROWS * N_COLS)
+  for row in range(N_ROWS):
+    for col in range(N_COLS):
+      pixels[row*N_COLS + col] = int(math.sin(row + col + time.time()*15) * 8 + 8)
+
+  pixels[49] = int(pixels[49]/2)
+  return bytes([0x41] + pixels)
+
+client_address = None
+try:
+  while True:
+    if not client_address:
+      data, addr = sock.recvfrom(16)
+      print('received {} from {}'.format(data, addr))
+      client_address = addr
+    else:
+      sock.sendto(getBytes(), client_address)
+      if time.time() - oldPing > 30:
+        data, addr = sock.recvfrom(16)
+        print('received {} from {}'.format(data, addr))
+        client_address = addr
+        oldPing = time.time()
+
+    oldTime = time.time()
+    time.sleep(1/40)
+
+finally:
+    print('closing socket')
+    sock.close()

+ 96 - 0
serial-led.py

@@ -0,0 +1,96 @@
+#!/bin/python3
+
+import sys
+import time
+import math
+import serial
+
+N_ROWS = 5
+N_COLS = 10
+
+class SerialConnection:
+	def __init__(self):
+		self._ser = None
+		self.port = None
+		
+	def connect(self, port = None):
+		if port == None:
+			port = self.port
+
+		if port == None:
+			for port in ["/dev/ttyUSB{}".format(p) for p in range(4)]:
+				try:
+					self._ser = serial.Serial(port, 38400)
+					print("connected to " + port)
+					self.port = port
+					break
+				except serial.SerialException:
+					pass
+			
+		if port == None:
+			for port in ["COM{}".format(p) for p in range(3,20)]:
+				try:
+					self._ser = serial.Serial(port, 38400)
+					print("connected to " + port)
+					self.port = port
+					break
+				except serial.SerialException:
+					pass
+		else:
+			try:
+				self._ser = serial.Serial(port, 38400)
+				print("connected to " + port)
+				self.port = port
+			except serial.SerialException:
+				pass
+		if self._ser:
+			self._ser.write(b'A' + b'\15' * N_ROWS*N_COLS)
+		else:
+			print("connection to port {} failed".format(port))
+		
+	def send(self, pixels):
+		if not self._ser:
+			return
+		try:
+			self._ser.write(b'A')
+			self._ser.write(bytes(pixels))
+		except serial.SerialException:
+			self._ser = None
+		
+	def isConnected(self):
+		return self._ser != None
+
+
+oldTime = time.time()
+oldPing = time.time()
+
+def getBytes():
+  pixels = [0] * (N_ROWS * N_COLS)
+  for row in range(N_ROWS):
+    for col in range(N_COLS):
+      pixels[row*N_COLS + col] = int(math.sin(row + col + time.time()*15) * 8 + 8)
+
+  pixels[49] = int(pixels[49]/2)
+  return bytes([0x41] + pixels)
+
+client_address = None
+try:
+  while True:
+    if not client_address:
+      data, addr = sock.recvfrom(16)
+      print('received {} from {}'.format(data, addr))
+      client_address = addr
+    else:
+      sock.sendto(getBytes(), client_address)
+      if time.time() - oldPing > 30:
+        data, addr = sock.recvfrom(16)
+        print('received {} from {}'.format(data, addr))
+        client_address = addr
+        oldPing = time.time()
+
+    oldTime = time.time()
+    time.sleep(1/40)
+
+finally:
+    print('closing socket')
+    sock.close()

BIN
src/cie.ods


+ 11 - 0
src/config.cpp

@@ -0,0 +1,11 @@
+#include "config.hpp"
+
+config_t config;
+
+void config_init() {
+  EEPROM.get(0, config);
+}
+
+void config_save() {
+  EEPROM.put(0, config);
+}

+ 86 - 0
src/main.cpp

@@ -0,0 +1,86 @@
+#include <Arduino.h>
+#include <avr/wdt.h>
+
+#include <RedFly.h>
+
+#include "matrix.hpp"
+#include "config.hpp"
+#include "redFlyClient.hpp"
+#include "serialClient.hpp"
+
+void setup() {
+  pinMode(3, OUTPUT);
+  digitalWrite(3, HIGH);
+
+  Serial.begin(38400);
+  Serial.flush();
+  printf("boot\n");
+
+  delay(100);
+  
+  wdt_enable(WDTO_8S);
+
+  matrix_init();
+  config_init();
+
+  
+
+  if(RedFly.init(38400, HIGH_POWER)) {
+    debugout("INIT ERR\n"); //there are problems with the communication between the Arduino and the RedFly
+    matrix.bytes[0] ^= 0x0F;
+    delay(100);
+    asm volatile ("  jmp 0");
+  }
+
+  connect();
+}
+
+char mode = 0;
+unsigned long startS = 0, startW = 0;
+
+void loop() {
+  if(mode == 0) {
+    uint8_t rssi = RedFly.getrssi();
+    if(rssi == 0) {
+      if(connect()) {
+        matrix.bytes[49] ^= 0x0F;
+      }
+    } else {
+      mode = 'C';
+    }
+  }
+  if(mode == 'W' || mode == 'C') {
+    if(millis() - startW > 10000) {
+      ping();
+      startW = millis();
+    }
+
+    startS = millis();
+    while(millis()-startS < 1000) {
+      int8_t rc = readUDP();
+      if(rc == 0) {
+        mode = 'W';
+      } else if(rc == 2) {
+        mode = 0;
+      }
+    }
+  }
+
+  if(mode == 'S') {
+    readSerial();
+  }
+  if(mode == 0 || mode == 'C'){
+    RedFly.disable();
+    Serial.println("NO DATA");
+    startS = millis();
+    while(millis()-startS < 5000) {
+      int8_t rc = readSerial();
+      if(rc == 0) {
+        mode = 'S';
+        RedFly.disable();
+        return;
+      }
+    }
+    RedFly.enable();
+  }
+}

+ 80 - 0
src/matrix.cpp

@@ -0,0 +1,80 @@
+#include "matrix.hpp"
+
+// cie = POTENZ((v/15*100+16)/116;3) * 127
+//const uint8_t ciePWM[] = {0, 1, 2, 4, 6, 10, 14, 20, 27, 36, 46, 58, 72, 88, 106, 127}; // 7 bit
+const uint16_t cieCycles[] = {310, 557, 878, 1272, 1738, 2278, 2890, 3575, 4333, 5164, 6068, 7045, 8094, 9217, 10412}; //4ms
+
+uint8_t currentRow = 0;
+uint8_t currentVal = 0;
+matrix_t matrix = {
+ 15, 0, 0,10,15,15, 0,15,15, 2,
+ 15, 0, 0,15, 0, 0, 0,15, 0,15,
+ 15, 0, 0,15,15, 0, 0,15, 0,15,
+ 15, 0, 0,15, 0, 0, 0,15, 0,15,
+ 13,15, 1,10,15,15, 0,15,15, 2
+};
+uint16_t n = 0;
+
+void matrix_init() {
+
+  for(int i=4; i<20; i++) {
+    pinMode(i, OUTPUT);
+    digitalWrite(i, 0);
+  }
+
+  noInterrupts(); // disable all interrupts
+  // initialize Timer1
+  // for calculating the pixel PWM
+  TCCR1A = 0;
+  TCCR1B = 0;
+  TCNT1  = 0;
+
+  OCR1A = 800; // compare match register 16MHz/1/10kHz
+  TCCR1B |= (1 << WGM12); // CTC mode
+  TCCR1B |= (1 << CS10); // 1 prescaler
+  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
+  
+  interrupts(); // enable all interrupts
+}
+
+ISR(TIMER1_COMPA_vect) {
+  if(++currentRow >= N_ROWS) {
+    currentRow = 0;
+    
+    if(++currentVal >= 15) {
+      currentVal = 0;
+    }
+
+    OCR1A = cieCycles[currentVal];
+  }
+
+  const row_t& row = matrix.rows[currentRow];
+  const uint16_t pixels = 
+    (row.bytes[0] > currentVal ? 1 << (N_COLS - 1) : 0) |
+    (row.bytes[1] > currentVal ? 1 << (N_COLS - 2) : 0) |
+    (row.bytes[2] > currentVal ? 1 << (N_COLS - 3) : 0) |
+    (row.bytes[3] > currentVal ? 1 << (N_COLS - 4) : 0) |
+    (row.bytes[4] > currentVal ? 1 << (N_COLS - 5) : 0) |
+    (row.bytes[5] > currentVal ? 1 << (N_COLS - 6) : 0) |
+    (row.bytes[6] > currentVal ? 1 << (N_COLS - 7) : 0) |
+    (row.bytes[7] > currentVal ? 1 << (N_COLS - 8) : 0) |
+    (row.bytes[8] > currentVal ? 1 << (N_COLS - 9) : 0) |
+    (row.bytes[9] > currentVal ? 1 << (N_COLS - 10) : 0);
+
+  writeRow(currentRow, pixels);
+  n++;
+}
+
+
+
+void writeRow(const uint8_t& nRow, const uint16_t& values) {
+  //disable rows
+  PORTC = 0x00;
+  //set lower 4 values
+  PORTD &= 0x0F;
+  PORTD |= values << 4;
+  //set upper 6 values
+  PORTB = values >> 4;
+  //enable row
+  PORTC = 0b00100000 >> nRow;
+}

+ 123 - 0
src/redFlyClient.cpp

@@ -0,0 +1,123 @@
+#include "redFlyClient.hpp"
+
+RedFlyClient client;
+byte ip[4];
+
+void debugout(const char* fmt, ...) {
+  RedFly.disable();
+  char buffer[100];
+  va_list args;
+  va_start(args,fmt);
+  vsprintf(buffer, fmt, args);
+  Serial.write(buffer);
+  va_end(args);
+  RedFly.enable();
+}
+
+void debugMatrix(const matrix_t& matrix) {
+  RedFly.disable();
+  char buffer[10];
+  Serial.println();
+  for(uint8_t i=0; i<N_ROWS; i++) {
+    for(uint8_t k=0; k<N_COLS; k++) {
+      sprintf(buffer, "%2d ", matrix.rows[i].bytes[k]);
+      Serial.write(buffer);
+    }
+    Serial.println();
+  }
+  RedFly.enable();
+}
+
+
+int8_t extractIpAddress(char *sourceString, byte *ipAddress) {
+  byte len=0;
+  char cnt=0,cnt1=0,i,buf[5];
+
+  len=strlen(sourceString);
+  for(i=0;i<len;i++)
+  {
+    if(sourceString[i]!='.' && cnt < 4){
+      buf[cnt++] =sourceString[i];
+    }
+    if((sourceString[i]=='.' || i==len-1) && cnt1 < 4){
+      buf[cnt]='\0';
+      cnt=0;
+      ipAddress[cnt1++]=atoi(buf);
+    }
+  }
+  if(cnt1 != 4) {
+    return 1;
+  }
+  return 0;
+}
+
+int8_t connect() {
+  //init the WiFi module on the shield
+  // ret = RedFly.init(br, pwr) //br=9600|19200|38400|57600|115200|200000|230400, pwr=LOW_POWER|MED_POWER|HIGH_POWER
+
+  RedFly.scan();
+
+  wdt_reset();
+
+  if(RedFly.join(config.ssid, config.pass, INFRASTRUCTURE)) {
+    debugout("JOIN ERR\n");
+    return 2;
+  }
+
+  wdt_reset();
+
+  if(RedFly.begin()) {
+    debugout("BEGIN ERR\n");
+    RedFly.disconnect();
+    return 3;
+  }
+
+  wdt_reset();
+
+  RedFly.getlocalip(ip);
+  debugout("local ip: %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
+  if(extractIpAddress(config.host, ip) != 0) {
+    if(RedFly.getip(config.host, ip) != 0) {
+      debugout("DNS ERR\n");
+      return 4;
+    }
+  }
+  client.connectUDP(ip, config.port);
+
+  return 0;
+}
+
+void ping() {
+  if(client.connected()) {
+    client.write("hello");
+  }
+}
+
+int8_t readUDP() {
+  uint16_t len = client.available();
+  uint8_t buf[4];
+ 	
+  wdt_reset();
+
+  if(!client.connected()) {
+    debugout("udp disconnected\n");
+    client.stop(); //stop and reset server
+    client.connectUDP(ip, config.port);
+    return 2;
+  }
+  if(len < N_ROWS*N_COLS+1) {
+    return -1;
+  }
+
+  client.read(buf, 1);
+  if(buf[0] != 'A') {
+    debugout("A\n");
+    return 1;
+  }
+
+  len = client.read(matrix.bytes, N_ROWS*N_COLS);
+  //sprintf((char*)buf, "%d\n", len);
+  //client.write(buf, 3);
+
+  return 0;
+}

+ 51 - 0
src/serialClient.cpp

@@ -0,0 +1,51 @@
+#include "serialClient.hpp"
+
+int8_t readSerial() {
+  uint16_t len = Serial.available();
+  uint8_t buf[6];
+ 	
+  wdt_reset();
+
+  if(len < N_ROWS*N_COLS+1) {
+    return -1;
+  }
+  
+  Serial.readBytes(buf, 1);
+  if(buf[0] != 'A') {
+    if(buf[0] == 'C') {
+    Serial.readBytes(buf, 6);
+    if(memcmp(buf, "ONFIG:", 6) == 0) {
+      len = Serial.readBytesUntil(',', config.ssid, sizeof(config.ssid)-1);
+      config.ssid[len] = '\0';
+      len = Serial.readBytesUntil(',', config.pass, sizeof(config.pass)-1);
+      config.pass[len] = '\0';
+      len = Serial.readBytesUntil(',', config.host, sizeof(config.host)-1);
+      config.host[len] = '\0';
+      config.port = Serial.parseInt();
+      if(config.port > 0) {
+        wdt_reset();
+        config_save();
+        printf("Config saved.\n");
+        delay(100);
+        asm volatile ("  jmp 0");
+        return 0;
+      } else {
+        return 3;
+      }
+    } else {
+      return 2;
+    }
+
+    } else {
+      printf("A\n");
+      return 1;
+    }
+
+  }
+
+  len = Serial.readBytes(matrix.bytes, N_ROWS*N_COLS);
+  sprintf((char*)buf, "%d\n", len);
+  Serial.write(buf, 3);
+
+  return 0;
+}