Mindstorms 3rd Party ROBOTC Drivers RobotC
[Home] [Download] [Submit a bug/suggestion] [ROBOTC Forums] [Blog] [Support this project]

benedettelli-nxt2wifi.h

Go to the documentation of this file.
00001 /*!@addtogroup other
00002  * @{
00003  * @defgroup NXT2WIFI NXT2WIFI Wifi Sensor
00004  * Dani's WiFi Sensor
00005  * @{
00006  */
00007 
00008 /*
00009  * $Id: benedettelli-nxt2wifi.h 133 2013-03-10 15:15:38Z xander $
00010  */
00011 
00012 #ifndef __N2W_H__
00013 #define __N2W_H__
00014 /** \file benedettelli-nxt2wifi.h
00015  * \brief Dani's WiFi Sensor
00016  *
00017  * benedettelli-nxt2wifi.h provides an API for Dani's WiFi Sensor.\n
00018  *
00019  * Changelog:
00020  * - 0.1: Initial release
00021  *
00022  * Credits:
00023  * - Big thanks to Dani for providing me with the hardware necessary to write and test this.
00024  *
00025  * License: You may use this code as you wish, provided you give credit where its due.
00026  *
00027  * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 3.59 AND HIGHER. 
00028 
00029  * \author Xander Soldaat (xander_at_botbench.com)
00030  * \date 12 June 2012
00031  * \version 0.1
00032  * \example benedettelli-nxt2wifi-test1.c
00033  * \example benedettelli-nxt2wifi-test2.c
00034  * \example benedettelli-nxt2wifi-test3.c
00035  * \example benedettelli-nxt2wifi-test4.c
00036  */
00037 
00038 #pragma systemFile
00039 
00040 #ifndef __COMMON_H__
00041 #include "common.h"
00042 #endif
00043 
00044 #ifndef __RS485_H__
00045 #include "common-rs485.h"
00046 #endif
00047 
00048 #define WS_WEBLABEL                 1   /*!< Web page widget: label */
00049 #define WS_WEBBUTTON                2   /*!< Web page widget: button */
00050 #define WS_WEBCHECKBOX              3   /*!< Web page widget: checkbox */
00051 #define WS_WEBSLIDER                4   /*!< Web page widget: slider */
00052 #define WS_WEBBARGRAPH              5   /*!< Web page widget: bargraph */
00053 
00054 #define WF_SEC_OPEN                                           0   /*!< Open Security (none) */
00055 #define WF_SEC_WEP_40                                 1   /*!< 40 bit WEP  */
00056 #define WF_SEC_WEP_104                                2   /*!< 104 bit WEP */
00057 #define WF_SEC_WPA_KEY                                3   /*!< WPA using key */
00058 #define WF_SEC_WPA_PASSPHRASE       4   /*!< WPA using passphrase */
00059 #define WF_SEC_WPA2_KEY                               5   /*!< WPA2 using key */
00060 #define WF_SEC_WPA2_PASSPHRASE      6   /*!< WPA2 using passphrase */
00061 #define WF_SEC_WPA_AUTO_KEY                 7   /*!< Automatically determine WPA type and use key */
00062 #define WF_SEC_WPA_AUTO_PASSPHRASE  8   /*!< Automatically determine WPA type and use passphrase */
00063 
00064 #define AD_HOC 1
00065 #define INFRASTRUCTURE 0
00066 
00067 #define N2WchillOut()  wait1Msec(50)                   /*!< Wait 50ms between messages, this allows transmission to be done */
00068 #define N2WsetIPAddress(X)    _N2WsetPar("IPAD", X) /*!< Macro for setting the IP address */
00069 #define N2WsetMask(X)         _N2WsetPar("MASK", X) /*!< Macro for setting the netmask */
00070 #define N2WsetGateway(X)      _N2WsetPar("GWAY", X) /*!< Macro for setting the gateway IP address */
00071 #define N2WsetDNS1(X)         _N2WsetPar("DNS1", X) /*!< Macro for setting the first DNS server IP address */
00072 #define N2WsetDNS2(X)         _N2WsetPar("DNS2", X) /*!< Macro for setting the second DNS server IP address */
00073 #define N2WsetSSID(X)         _N2WsetPar("SSID", X) /*!< Macro for setting the SSID to connect to */
00074 #define N2WsetNetbiosName(X)  _N2WsetPar("NAME", X) /*!< Macro for setting the Netbios Name */
00075 
00076 
00077 
00078 string N2WscratchString;   /*!< string for tmp formatting, scratch data */
00079 
00080 intrinsic int StringFind(const char *sSrce, const char *pzFindString)    asm(opcdStringOps, strOpFind, variableRefCharPtr(sSrce), functionReturn, variableRefCharPtr(pzFindString));
00081 
00082 
00083 /**
00084  * Parse the buffer and return the number in the NXT2WIFI response
00085  * @param buf the buffer to pull the number from
00086  * @return the number or -1 if no number found.
00087  */
00088 int N2WgetNumericResponse(tMassiveArray &buf)
00089 {
00090   long retval = 0;
00091   int pos = 0;
00092   for (pos = 0; pos < sizeof(tMassiveArray); pos++)
00093   {
00094     memset(N2WscratchString, 0, 20);
00095     memcpy(N2WscratchString, buf, 19);
00096     pos = StringFind(N2WscratchString, "=");
00097     memset(N2WscratchString, 0, 20);
00098     memcpy(N2WscratchString, &buf[pos+1], sizeof(tMassiveArray) - (pos + 1));
00099     retval = atoi(N2WscratchString);
00100     return retval;
00101   }
00102   return 0;
00103 }
00104 
00105 
00106 /**
00107  * Parse the buffer and return the string in the NXT2WIFI response
00108  * @param buf the buffer to pull the string from
00109  * @param response the string to hold the response from the sensor
00110  */
00111 void N2WgetStringResponse(const tMassiveArray &buf, string &response)
00112 {
00113   int pos = 0;
00114 
00115   memset(N2WscratchString, 0, 20);
00116   memcpy(N2WscratchString, buf, 19);
00117   pos = StringFind(N2WscratchString, "=");
00118   memset(N2WscratchString, 0, 20);
00119   memcpy(response, &buf[pos+1], 19);
00120 
00121 }
00122 
00123 
00124 /**
00125  * Enable debugging
00126  * @param en whether or not to enable debugging
00127  * @return true if no error occured, false if it did
00128  */
00129 bool N2WsetDebug(bool en)
00130 {
00131   N2WscratchString = (en) ? "$DBG1\n" : "$DBG0\n";
00132   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00133   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00134     return false;
00135   wait1Msec(10);
00136   RS485clearRead();
00137   return true;
00138 }
00139 
00140 
00141 /**
00142  * Connect to the currently configured WiFi network
00143  * @param custom use the default or custom profile
00144  * @return true if no error occured, false if it did
00145  */
00146 bool N2WConnect(bool custom)
00147 {
00148   N2WscratchString = (custom) ? "$WFC1\n" : "$WFC0\n";
00149   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00150   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00151     return false;
00152   wait1Msec(10);
00153   RS485clearRead();
00154   return true;
00155 }
00156 
00157 
00158 /**
00159  * Disconnect from the current WiFi network
00160  * @return true if no error occured, false if it did
00161  */
00162 bool N2WDisconnect() {
00163   N2WscratchString = "$WFX\n";
00164   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00165   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00166     return false;
00167   wait1Msec(10);
00168   RS485clearRead();
00169   return true;
00170 }
00171 
00172 
00173 /**
00174  * Stop reconnecting when disconnected
00175  * @return true if no error occured, false if it did
00176  */
00177 bool N2WStopConnecting()
00178 {
00179   if (!RS485sendString("$WFQ\n"))
00180     return false;
00181   //N2WscratchString = "$WFQ\n";
00182   //memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00183   //if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00184   //  return false;
00185   wait1Msec(10);
00186   RS485clearRead();
00187   return true;
00188 }
00189 
00190 
00191 /**
00192  * Delete the currently configured custom profile
00193  * @return true if no error occured, false if it did
00194  */
00195 bool N2WDelete()
00196 {
00197   if(!RS485sendString("$WFKD\n"))
00198     return false;
00199   wait1Msec(10);
00200   RS485clearRead();
00201   return true;
00202 }
00203 
00204 
00205 /**
00206  * Save the currently configured custom profile
00207  * @return true if no error occured, false if it did
00208  */
00209 bool N2WSave() {
00210   RS485sendString("$WFKS\n");
00211   wait1Msec(10);
00212   RS485clearRead();
00213   return true;
00214 }
00215 
00216 
00217 /**
00218  * Load the currently configured custom profile
00219  * @return true if no error occured, false if it did
00220  */
00221 bool N2WLoad() {
00222   if (!RS485sendString("$WFKL\n"))
00223     return false;
00224   wait1Msec(10);
00225   RS485clearRead();
00226   return true;
00227 }
00228 
00229 
00230 /**
00231  * Reset the NXT2WIFI sensor.
00232  */
00233 void N2WReset()
00234 {
00235   RS485sendString("$RST\n");
00236 }
00237 
00238 
00239 /**
00240  * Confgure the security settings for the custom profile\n
00241  * Note: this is an internal function and shouldn't be used directly
00242  * @param mode the security mode to use
00243  * @param pKeypass the keypass to use
00244  * @param keylen the length of the key
00245  * @param keyind used for WEP, usually set to 0
00246  * @return true if no error occured, false if it did
00247  */
00248 bool N2WSecurity(int mode, const ubyte *pKeypass, int keylen, int keyind) {
00249   int index = 0;
00250   writeDebugStreamLine("keylen: %d", keylen);
00251   index = RS485appendToBuff((tBigByteArray)RS485txbuffer, index, "$WFS?");
00252   sprintf(N2WscratchString, "%d:", mode);
00253   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00254   index = RS485appendToBuff(RS485txbuffer, index, pKeypass, keylen);
00255   sprintf(N2WscratchString, ":%d\n", keyind);
00256   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00257   return RS485write(RS485txbuffer, index);
00258 }
00259 
00260 
00261 /**
00262  * Set the WPA2 key
00263  * @param key the WPA2 key to use
00264  * @param len the length of the WPA2 key
00265  * @return true if no error occured, false if it did
00266  */
00267 bool N2WSecurityWPA2Key(tBigByteArray &key, int len) {
00268         return N2WSecurity(WF_SEC_WPA2_KEY, &key[0], len, 0);
00269 }
00270 
00271 
00272 /**
00273  * Set the WPA2 passphrase
00274  * @param passphrase the WPA2 passphrase to use
00275  * @return true if no error occured, false if it did
00276  */
00277 bool N2WSecurityWPA2Passphrase(const string passphrase) {
00278   tByteArray tmpArray;
00279         memcpy(tmpArray, passphrase, strlen(passphrase));
00280         return N2WSecurity(WF_SEC_WPA2_PASSPHRASE, &tmpArray[0], strlen(passphrase), 0);
00281 }
00282 
00283 
00284 /**
00285  * Set the WPA key
00286  * @param key the WPA key to use
00287  * @param len the length of the WPA key
00288  * @return true if no error occured, false if it did
00289  */
00290 bool N2WSecurityWPAKey(tBigByteArray &key, int len) {
00291         return N2WSecurity(WF_SEC_WPA_KEY, &key[0], len, 0);
00292 }
00293 
00294 
00295 /**
00296  * Set the WPA passphrase
00297  * @param passphrase the WPA passphrase to use
00298  * @return true if no error occured, false if it did
00299  */
00300 bool N2WSecurityWPAPassphrase(const string &passphrase) {
00301   tByteArray tmpArray;
00302         memcpy(tmpArray, passphrase, strlen(passphrase));
00303         return N2WSecurity(WF_SEC_WPA_PASSPHRASE, &tmpArray[0], strlen(passphrase), 0);
00304 }
00305 
00306 
00307 /**
00308  * Set the WEP passphrase.  Please don't use this, it's very insecure.
00309  * @param passphrase the WEP passphrase to use
00310  * @return true if no error occured, false if it did
00311  */
00312 bool N2WSecurityWEP104(const string &passphrase) {
00313   tByteArray tmpArray;
00314   writeDebugStreamLine("wep104: %d:", strlen(passphrase));
00315   writeDebugStreamLine("phrase: %s", passphrase);
00316         return N2WSecurity(WF_SEC_WEP_104, passphrase, strlen(passphrase), 1);
00317 }
00318 
00319 
00320 /**
00321  * Use no security at all.  Just as effective as WEP but less annoying.
00322  * @return true if no error occured, false if it did
00323  */
00324 bool N2WSecurityOpen() {
00325   tByteArray tmpArray;
00326         return N2WSecurity(WF_SEC_OPEN, &tmpArray[0] , 0, 0);
00327 }
00328 
00329 
00330 /**
00331  * Use ad-hoc network or infrastructure
00332  * @param adhoc if true, use adhoc, otherwise use infrastructure mode
00333  * @return true if no error occured, false if it did
00334  */
00335 bool N2WsetAdHoc(bool adhoc) {
00336   if (adhoc)
00337     RS485sendString("$WFE?TYPE=1\n");
00338   else
00339     RS485sendString("$WFE?TYPE=0\n");
00340   RS485clearRead();
00341   return true;
00342 }
00343 
00344 
00345 /**
00346  * Set a specific parameter.\n
00347  * Note: this is an internal function and should not be used directly.
00348  * @param type the parameter type
00349  * @param param the value to pass to the parameter
00350  * @return true if no error occured, false if it did
00351  */
00352 bool _N2WsetPar(const string type, const string param) {
00353   int index = 0;
00354         N2WscratchString = "$WFE?";
00355         index = RS485appendToBuff((tBigByteArray)RS485txbuffer, index, N2WscratchString);
00356         index = RS485appendToBuff((tBigByteArray)RS485txbuffer, index, type);
00357         index = RS485appendToBuff((tBigByteArray)RS485txbuffer, index, "=");
00358         index = RS485appendToBuff((tBigByteArray)RS485txbuffer, index, param);
00359         index = RS485appendToBuff((tBigByteArray)RS485txbuffer, index, "\n");
00360   return RS485write(RS485txbuffer, index);
00361 }
00362 
00363 
00364 /**
00365  * Configure to use DHCP.
00366  * @param yes if set to true, use DHCP
00367  * @return true if no error occured, false if it did
00368  */
00369 bool N2WsetDHCP(bool yes) {
00370   N2WscratchString = (yes) ? "$WFE?DHCP=1\n" : "$WFE?DHCP=0\n";
00371 
00372   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00373   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00374     return false;
00375   wait1Msec(10);
00376   RS485clearRead();
00377   return true;
00378 }
00379 
00380 
00381 /**
00382  * Set the default profileto connect to after initial startup
00383  * @param profile The profile to connect to, 0 = none, 1 = custom profile, 2 = default
00384  * @return true if no error occured, false if it did
00385  */
00386 bool N2WsetDefaultProfile(ubyte profile)
00387 {
00388   ubyte len;
00389   sprintf(N2WscratchString, "$COS%d\n", profile);
00390   writeDebugStreamLine(N2WscratchString);
00391   memset(RS485txbuffer, 0, sizeof(RS485txbuffer));
00392   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00393   RS485write(RS485txbuffer, strlen(N2WscratchString));
00394   wait1Msec(10);
00395         RS485read(RS485rxbuffer, len, 100);
00396         return (N2WgetNumericResponse(RS485rxbuffer) == 1);
00397 }
00398 
00399 
00400 /**
00401  * Check if a the custom profile exists.
00402  * @return true if the profile exists, false if it does not or an error occured.
00403  */
00404 bool N2WCustomExist()
00405 {
00406 
00407   ubyte len;
00408   RS485sendString("$WFKE\n");
00409   wait1Msec(100);
00410         RS485read(RS485rxbuffer, len, 100);
00411         return (N2WgetNumericResponse(RS485rxbuffer) == 1);
00412 }
00413 
00414 
00415 /**
00416  * Enter or exit hibernation mode
00417  * @param hibernate enter hibernation mode if true, exit if false
00418  * @return true if no error occured, false if it did
00419  */
00420 bool N2WsetHibernate(bool hibernate)
00421 {
00422   N2WscratchString = (hibernate) ? "$WFH\n" : "WFO\n";
00423   if (!RS485sendString(N2WscratchString))
00424     return false;
00425   wait1Msec(10);
00426   RS485clearRead();
00427   return true;
00428 }
00429 
00430 
00431 
00432 /**
00433  * Enable or disable power saving
00434  * @param powersave enable powersaving if true, disable if false
00435  * @return true if no error occured, false if it did
00436  */
00437 bool N2WsetPowerSave(bool powersave)
00438 {
00439   N2WscratchString = (powersave) ? "$WFP1\n" : "WFP0\n";
00440   if (!RS485sendString(N2WscratchString))
00441     return false;
00442   wait1Msec(10);
00443   RS485clearRead();
00444   return true;
00445 }
00446 
00447 
00448 /**
00449  * Get the current connection status.
00450  * @return true if no error occured, false if it did
00451  */
00452 int N2WStatus() {
00453   ubyte len;
00454   RS485sendString("$WFGS\n");
00455   N2WchillOut();
00456         RS485read(RS485rxbuffer, len, 100);
00457         return N2WgetNumericResponse(RS485rxbuffer);
00458 }
00459 
00460 
00461 /**
00462  * Are we connected to the WiFi network?
00463  * @return true if connected, false if not connected an error occured
00464  */
00465 bool N2WConnected() {
00466         return (N2WStatus() == 2);
00467 }
00468 
00469 
00470 /**
00471  * Get the current IP address.  If the address could not be determined
00472  * 0.0.0.0 is returned.
00473  * @param IP the string to put the address into
00474  * @return true if no error occured, false if it did
00475  */
00476 bool N2WgetIP(string &IP) {
00477   ubyte len;
00478   N2WscratchString = "$WFIP\n";
00479   memset(RS485txbuffer, 0, sizeof(RS485txbuffer));
00480   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00481   RS485write(RS485txbuffer, strlen(N2WscratchString));
00482         wait1Msec(100);
00483         RS485read(RS485rxbuffer, len, 100);
00484 
00485         if (len < 1)
00486         {
00487           IP = "0.0.0.0";
00488           return false;
00489         }
00490         else
00491         {
00492           N2WgetStringResponse(RS485rxbuffer, IP);
00493           return true;
00494         }
00495 }
00496 
00497 
00498 /**
00499  * Get the NXT2WIFI's MAC address.
00500  * @param mac string to hold MAC address
00501  */
00502 void N2WgetMAC(string &mac)
00503 {
00504   ubyte len;
00505   sprintf(N2WscratchString, "$MAC\n");
00506   memset(RS485txbuffer, 0, sizeof(RS485txbuffer));
00507   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00508   RS485write(RS485txbuffer, strlen(N2WscratchString));
00509         N2WchillOut();
00510         RS485read(RS485rxbuffer, len, 100);
00511 
00512         if (len < 1)
00513         {
00514           mac = "00-00-00-00-00-00";
00515         }
00516         else
00517   {
00518     N2WgetStringResponse(RS485rxbuffer, mac);
00519   }
00520 }
00521 
00522 
00523 /**
00524  * Open a UDP datastream to a remote host on a port
00525  * @param id the connection ID to use, can be 1 to 4
00526  * @param ip the IP address of the remote host
00527  * @param port the port of the service on the remote host
00528  * @return true if no error occured, false if it did
00529  */
00530 bool N2WUDPOpenClient(int id, string ip, int port) {
00531   int index = 0;
00532   int respOK = 0;
00533   ubyte len;
00534   sprintf(N2WscratchString, "$UDPOC%d?", id);
00535   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00536   index = RS485appendToBuff(RS485txbuffer, index, ip);
00537   sprintf(N2WscratchString, ",%d\n", port);
00538   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00539   RS485write(RS485txbuffer, index);
00540         N2WchillOut();
00541         RS485read(RS485rxbuffer, len, 100);
00542         respOK = N2WgetNumericResponse(RS485rxbuffer);
00543         return (respOK == 1) ? true : false;
00544 }
00545 
00546 
00547 /**
00548  * Open a listening UDP socket on the specified port
00549  * @param id the connection ID to use, can be 1 to 4
00550  * @param port the port on which to start listening
00551  * @return true if no error occured, false if it did
00552  */
00553 bool N2WUDPOpenServer(int id, int port) {
00554   int index = 0;
00555   int respOK = 0;
00556   ubyte len;
00557   sprintf(N2WscratchString, "$UDPOS%d?%d\n", id, port);
00558   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00559   RS485write(RS485txbuffer, index);
00560         N2WchillOut();
00561         RS485read(RS485rxbuffer, len, 100);
00562         respOK = N2WgetNumericResponse(RS485rxbuffer);
00563         return (respOK == 1) ? true : false;
00564 }
00565 
00566 
00567 /**
00568  * Check if there are bytes available for reading on the specified connection.
00569  * @param id the connection ID to use, can be 1 to 4
00570  * @return the number of bytes available for reading
00571  */
00572 int N2WUDPAvail(int id) {
00573   int index = 0;
00574   ubyte len;
00575   sprintf(N2WscratchString, "$UDPL%d\n", id);
00576   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00577   RS485write(RS485txbuffer, index);
00578         N2WchillOut();
00579         RS485read(RS485rxbuffer, len, 100);
00580   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00581     return false;
00582   wait1Msec(10);
00583   RS485clearRead();
00584   return true;
00585 }
00586 
00587 
00588 /**
00589  * Read the specified number of bytes from the connection ID.
00590  * Bytes are read into the RS485rxbuffer variable.
00591  * @param id the connection ID to use, can be 1 to 4
00592  * @param datalen the number of bytes to read
00593  * @return true if no error occured, false if it did
00594  */
00595 int N2WUDPRead(int id, int datalen) {
00596   int index = 0;
00597   memset(N2WscratchString, 0, 20);
00598   ubyte offset;
00599 
00600   sprintf(N2WscratchString, "$UDPR%d?%d\n", id, datalen);
00601   offset = (datalen > 9) ? 8 : 7;
00602   datalen += offset;
00603   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00604   RS485write(RS485txbuffer, index);
00605         N2WchillOut();
00606         //wait1Msec(100);
00607         RS485readLargeResponse(RS485rxbuffer, datalen, 100);
00608 
00609 
00610         // This part seperates the data from the pre-amble
00611         for (int i = 0; i < sizeof(RS485rxbuffer); i++)
00612         {
00613           if (RS485rxbuffer[i] != ',')
00614           {
00615             continue;
00616           }
00617           else
00618           {
00619             N2WscratchString = "";
00620             memmove(&RS485rxbuffer[0], &RS485rxbuffer[offset+1], datalen);
00621             return atoi(N2WscratchString);
00622           }
00623         }
00624         return 0;
00625 }
00626 
00627 
00628 /**
00629  * Write the specified number of bytes to the connection ID.
00630  * @param id the connection ID to use, can be 1 to 4
00631  * @param data the tHugeByteArray containing the data to be transmitted
00632  * @param datalen the number of bytes to read
00633  * @return true if no error occured, false if it did
00634  */
00635 bool N2WUDPWrite(int id, tHugeByteArray &data, int datalen) {
00636   // writeDebugStreamLine("N2WUDPWrite");
00637   int index = 0;
00638   int respOK;
00639   memset(N2WscratchString, 0, 20);
00640 
00641   sprintf(N2WscratchString, "$UDPW%d?%d,", id, datalen);
00642   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00643   index = RS485appendToBuff((tBigByteArray)RS485txbuffer, index, &data[0], datalen);
00644   N2WscratchString = "\n";
00645   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00646   RS485write(RS485txbuffer, index);
00647   N2WchillOut();
00648         respOK = N2WgetNumericResponse(RS485rxbuffer);
00649         return (respOK == 1) ? true : false;
00650 }
00651 
00652 
00653 /**
00654  * Close the specified connection.  Use 0 to close all connections
00655  * @param id the connection ID to use, can be 1 to 4 or 0 for all
00656  * @return true if no error occured, false if it did
00657  */
00658 bool N2WUDPClose(int id) {
00659         StringFormat(N2WscratchString, "$UDPX%d\n", id);
00660   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00661   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00662     return false;
00663   RS485clearRead();
00664   return true;
00665 }
00666 
00667 
00668 /**
00669  * Flush the buffers of the specified connection
00670  * @param id the connection ID to use, can be 1 to 4 or 0 for all
00671  * @return true if no error occured, false if it did
00672  */
00673 bool N2WUDPFlush(int id) {
00674         StringFormat(N2WscratchString, "$UDPF%d\n", id);
00675   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00676   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00677     return false;
00678   wait1Msec(10);
00679   RS485clearRead();
00680   return true;
00681 }
00682 
00683 
00684 /**
00685  * Open a TCP connection to a remote host on a port
00686  * @param id the connection ID to use, can be 1 to 4
00687  * @param host the IP address of name of the remote host
00688  * @param port the port of the service on the remote host
00689  * @return true if no error occured, false if it did
00690  */
00691 bool N2WTCPOpenClient(int id, string host, int port) {
00692   int index = 0;
00693   int respOK = 0;
00694   ubyte len;
00695   sprintf(N2WscratchString, "$TCPOC%d?", id);
00696   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00697   index = RS485appendToBuff(RS485txbuffer, index, host);
00698   sprintf(N2WscratchString, ",%d\n", port);
00699   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00700   RS485write(RS485txbuffer, index);
00701         N2WchillOut();
00702         RS485read(RS485rxbuffer, len, 100);
00703         respOK = N2WgetNumericResponse(RS485rxbuffer);
00704         return (respOK == 1) ? true : false;
00705 }
00706 
00707 
00708 /**
00709  * Open a TCP connection to a remote host on a port
00710  * @param id the connection ID to use, can be 1 to 4
00711  * @param host the IP address of name of the remote host
00712  * @param port the port of the service on the remote host
00713  * @return true if no error occured, false if it did
00714  */
00715 bool N2WTCPOpenClient(int id, char *host, int port) {
00716   writeDebugStreamLine("TCPOC pointer version");
00717   int index = 0;
00718   int respOK = 0;
00719   ubyte len;
00720   writeDebugStreamLine("host: %s", host);
00721   sprintf(N2WscratchString, "$TCPOC%d?", id);
00722   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00723   index = RS485appendToBuff(RS485txbuffer, index, host);
00724   sprintf(N2WscratchString, ",%d\n", port);
00725   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00726   RS485write(RS485txbuffer, index);
00727         N2WchillOut();
00728         RS485read(RS485rxbuffer, len, 100);
00729         respOK = N2WgetNumericResponse(RS485rxbuffer);
00730         return (respOK == 1) ? true : false;
00731 }
00732 
00733 
00734 /**
00735  * Open a listening UDP socket on the specified port
00736  * @param id the connection ID to use, can be 1 to 4
00737  * @param port the port on which to start listening
00738  * @return true if no error occured, false if it did
00739  */
00740 bool N2WTCPOpenServer(int id, int port) {
00741   int index = 0;
00742   int respOK = 0;
00743   ubyte len;
00744   sprintf(N2WscratchString, "$TCPOS%d?%d\n", id, port);
00745   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00746   RS485write(RS485txbuffer, index);
00747         wait1Msec(500);
00748         RS485read(RS485rxbuffer, len, 100);
00749         respOK = N2WgetNumericResponse(RS485rxbuffer);
00750         return (respOK == 1) ? true : false;
00751 }
00752 
00753 
00754 /**
00755  * Closes a connection to a remote client
00756  * @param id the connection ID to use, can be 1 to 4
00757  * @return true if no error occured, false if it did
00758  */
00759 bool N2WTCPDetachClient(int id) {
00760   int index = 0;
00761   int respOK = 0;
00762   ubyte len;
00763   sprintf(N2WscratchString, "$TCPD%d\n", id);
00764   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00765   RS485write(RS485txbuffer, index);
00766         N2WchillOut();
00767         RS485read(RS485rxbuffer, len, 100);
00768         respOK = N2WgetNumericResponse(RS485rxbuffer);
00769         return (respOK == 1) ? true : false;
00770 }
00771 
00772 
00773 /**
00774  * Close the specified connection
00775  * @param id the connection ID to use, can be 1 to 4 or 0 for all
00776  * @return true if no error occured, false if it did
00777  */
00778 bool N2WTCPClose(int id) {
00779         StringFormat(N2WscratchString, "$TCPX%d\n", id);
00780   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00781   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00782     return false;
00783   RS485clearRead();
00784   return true;
00785 }
00786 
00787 
00788 /**
00789  * Flush the buffers of the specified connection
00790  * @param id the connection ID to use, can be 1 to 4 or 0 for all
00791  * @return true if no error occured, false if it did
00792  */
00793 bool N2WTCPFlush(int id) {
00794         StringFormat(N2WscratchString, "$TCPF%d\n", id);
00795   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00796   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00797     return false;
00798   wait1Msec(10);
00799   RS485clearRead();
00800   return true;
00801 }
00802 
00803 
00804 /**
00805  * Check if there are bytes available for reading on the specified connection.
00806  * @param id the connection ID to use, can be 1 to 4
00807  * @return the number of bytes available for reading
00808  */
00809 int N2WTCPAvail(int id) {
00810   int index = 0;
00811   ubyte len;
00812   sprintf(N2WscratchString, "$TCPL%d\n", id);
00813   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00814   RS485write(RS485txbuffer, index);
00815         N2WchillOut();
00816         RS485read(RS485rxbuffer, len, 100);
00817         return N2WgetNumericResponse(RS485rxbuffer);
00818 }
00819 
00820 
00821 /**
00822  * Read the specified number of bytes from the connection ID.
00823  * Bytes are read into the RS485rxbuffer variable.
00824  * @param id the connection ID to use, can be 1 to 4
00825  * @param datalen the number of bytes to read
00826  * @return true if no error occured, false if it did
00827  */
00828 int N2WTCPRead(int id, int datalen) {
00829   int index = 0;
00830   memset(N2WscratchString, 0, 20);
00831   ubyte offset;
00832 
00833   sprintf(N2WscratchString, "$TCPR%d?%d\n", id, datalen);
00834   offset = (datalen > 9) ? 8 : 7;
00835   datalen += offset;
00836   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00837   RS485write(RS485txbuffer, index);
00838         N2WchillOut();
00839         RS485readLargeResponse(RS485rxbuffer, datalen, 100);
00840 
00841 
00842         for (int i = 0; i < sizeof(RS485rxbuffer); i++)
00843         {
00844           if (RS485rxbuffer[i] != ',')
00845           {
00846             continue;
00847           }
00848           else
00849           {
00850             N2WscratchString = "";
00851             memmove(&RS485rxbuffer[0], &RS485rxbuffer[offset+1], datalen);
00852             return atoi(N2WscratchString);
00853           }
00854         }
00855         return 0;
00856 }
00857 
00858 
00859 /**
00860  * Write the specified number of bytes to the connection ID.
00861  * @param id the connection ID to use, can be 1 to 4
00862  * @param data the tHugeByteArray containing the data to be transmitted
00863  * @param datalen the number of bytes to read
00864  * @return true if no error occured, false if it did
00865  */
00866 int N2WTCPWrite(int id, tHugeByteArray &data, int datalen)
00867 {
00868   writeDebugStream("N2WTCPWrite: ");
00869   writeDebugStreamLine("datalen: %d", datalen);
00870   int index = 0;
00871   int respOK;
00872   memset(N2WscratchString, 0, 20);
00873 
00874   sprintf(N2WscratchString, "$TCPW%d?%d,", id, datalen);
00875   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00876   index = RS485appendToBuff(RS485txbuffer, index, &data[0], datalen);
00877   N2WscratchString = "\n";
00878   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
00879   RS485write(RS485txbuffer, index);
00880   N2WchillOut();
00881         respOK = N2WgetNumericResponse(RS485rxbuffer);
00882         return (respOK == 1) ? true : false;
00883 }
00884 
00885 
00886 /**
00887  * Get the remote client's IP address
00888  * @param id the connection ID to use, can be 1 to 4
00889  * @param ip string to hold IP address
00890  * @return true if no error occured, false if it did
00891  */
00892 void N2WTCPClientIP(int id, string &ip)
00893 {
00894   ubyte len;
00895   sprintf(N2WscratchString, "$TCPSI%d\n", id);
00896   memset(RS485txbuffer, 0, sizeof(RS485txbuffer));
00897   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00898   RS485write(RS485txbuffer, strlen(N2WscratchString));
00899         N2WchillOut();
00900         RS485read(RS485rxbuffer, len, 100);
00901 
00902         if (len < 1)
00903         {
00904           ip = "0.0.0.0";
00905         }
00906         else
00907   {
00908     N2WgetStringResponse(RS485rxbuffer, ip);
00909   }
00910 }
00911 
00912 
00913 /**
00914  * Get the remote client's MAC address.  Only useful for local network client.
00915  * @param id the connection ID to use, can be 1 to 4
00916  * @param mac string to hold MAC address
00917  */
00918 void N2WTCPClientMAC(int id, string &mac)
00919 {
00920   ubyte len;
00921   sprintf(N2WscratchString, "$TCPSM%d\n", id);
00922   memset(RS485txbuffer, 0, sizeof(RS485txbuffer));
00923   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00924   RS485write(RS485txbuffer, strlen(N2WscratchString));
00925         N2WchillOut();
00926         RS485read(RS485rxbuffer, len, 100);
00927 
00928         if (len < 1)
00929         {
00930           mac = "00-00-00-00-00-00";
00931         }
00932         else
00933   {
00934     N2WgetStringResponse(RS485rxbuffer, mac);
00935   }
00936 }
00937 
00938 
00939 /**
00940  * Enable the built-in webserver.  This cannot be used together with
00941  * normal TCP/UDP operations.
00942  * @param enable enables the web server if set to true, disables it if false
00943  * @return true if no error occured, false if it did
00944  */
00945 bool N2WenableWS(bool enable) {
00946   N2WscratchString = (enable) ? "$SRV=1\n" : "$SRV=0\n";
00947   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
00948   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
00949     return false;
00950   wait1Msec(10);
00951   RS485clearRead();
00952   return true;
00953 }
00954 
00955 /**
00956  * Read data from the web server.  This cannot be used together with
00957  * normal TCP/UDP operations. \n
00958  * Type can be one of the following:
00959  * - WS_WEBLABEL
00960  * - WS_WEBBUTTON
00961  * - WS_WEBCHECKBOX
00962  * - WS_WEBSLIDER
00963  * @param type the type of widget
00964  * @param ID ID of the element that was pressed or submitted
00965  * @param state additional data from the UI element
00966  * @param value the value of the UI element
00967  * @return true if no error occured, false if it did
00968  */
00969 bool N2WreadWS(ubyte &type, ubyte &ID, ubyte &state, ubyte &value)
00970 {
00971   ubyte avail = nxtGetAvailHSBytes();
00972   if (avail >= 5)
00973   {
00974     nxtReadRawHS(&RS485rxbuffer[0], avail);
00975     writeDebugStream("N2WreadWS[%d]: ", avail);
00976 
00977     for (int i = 0; i < avail - 2; i++)
00978     {
00979       if ((RS485rxbuffer[i] == 0x00) && (RS485rxbuffer[i+1] == 0x80) && (RS485rxbuffer[i+2] == 0x14))
00980       {
00981         type = RS485rxbuffer[i+3];
00982         ID = RS485rxbuffer[i+4];
00983         state = RS485rxbuffer[i+5];
00984         value = RS485rxbuffer[i+6];
00985         return true;
00986       }
00987     }
00988   }
00989   return false;
00990 }
00991 
00992 
00993 /**
00994  * Write data to the webserver. \n
00995  * Type can be one of the following:
00996  * - WS_WEBLABEL
00997  * - WS_WEBBUTTON
00998  * - WS_WEBCHECKBOX
00999  * - WS_WEBSLIDER
01000  * - WS_WEBBARGRAPH
01001  * @param type the type of webpage element
01002  * @param id the field number in the web page
01003  * @param wsmessage data to be transmitted
01004  * @param wsmsglen length of the data
01005  * @return true if no error occured, false if it did
01006  */
01007 bool N2WwriteWS(ubyte type, ubyte id, tHugeByteArray &wsmessage, ubyte wsmsglen)
01008 {
01009         writeDebugStream("N2WwriteWS: ");
01010         writeDebugStreamLine("datalen: %d, id: %d", wsmsglen, id);
01011         for (ubyte i = 0; i < wsmsglen; i++)
01012         {
01013           writeDebugStream("0x%2X ", wsmessage[i]);
01014         }
01015         writeDebugStreamLine(" ");
01016         int index = 0;
01017         int respOK;
01018         memset(N2WscratchString, 0, 20);
01019 
01020         string web;
01021         switch (type)
01022         {
01023                 case 1: web = "$WEBLBL%d?%d,"; break;
01024                 case 2: web = "$WEBBTN%d?%d,"; break;
01025                 case 3: web = "$WEBCHK%d?%d,"; break;
01026                 case 4: web = "$WEBSLD%d?%d,"; break;
01027                 case 5: web = "$WEBBAR%d?%d,"; break;
01028                 default: break;
01029         }
01030 
01031         sprintf(N2WscratchString, web, id, wsmsglen);
01032   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
01033   index = RS485appendToBuff(RS485txbuffer, index, &wsmessage[0], wsmsglen);
01034   N2WscratchString = "\n";
01035 
01036   index = RS485appendToBuff(RS485txbuffer, index, N2WscratchString);
01037   RS485write(RS485txbuffer, index);
01038   N2WchillOut();
01039         respOK = N2WgetNumericResponse(RS485rxbuffer);
01040         return (respOK == 1) ? true : false;
01041 }
01042 
01043 
01044 
01045 
01046 
01047 /**
01048  * Clears all webpage fields.  This cannot be used together with
01049  * normal TCP/UDP operations.
01050  * @return true if no error occured, false if it did
01051  */
01052 bool N2WclearFields() {
01053   N2WscratchString = "$RXD\n";
01054   memcpy(RS485txbuffer, N2WscratchString, strlen(N2WscratchString));
01055   if (!RS485write(RS485txbuffer, strlen(N2WscratchString)))
01056     return false;
01057   wait1Msec(10);
01058   RS485clearRead();
01059   return true;
01060 }
01061 
01062 
01063 #endif // __N2W_H__
01064 
01065 /*
01066  * $Id: benedettelli-nxt2wifi.h 133 2013-03-10 15:15:38Z xander $
01067  */
01068 /* @} */
01069 /* @} */