for testing

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wifi.cpp Source File

wifi.cpp

00001 #include <stdarg.h>
00002 
00003 #include "cisme.h"
00004 #include "wifi.h"
00005 #include "debug.h"
00006 
00007 #ifdef USE_WIFI
00008 
00009 /* Wifi comm settings. */
00010 #define WIFI_BAUD                             9600
00011 /* The number of bits in a word (5-8; default = 8) */
00012 #define WIFI_NO_BITS                             8
00013 /* parity - The parity used (Serial::None, Serial::Odd, Serial::Even, Serial::Forced1, Serial::Forced0; default = Serial::None) */
00014 #define WIFI_PARITY                   Serial::None
00015 /* stop - The number of stop bits (1 or 2; default = 1) */
00016 #define WIFI_NO_STOP_BITS                        1
00017 
00018 /* Wifi module settings. */
00019 #define WIFI_IP_LOCAL_ADDRESS       "192.168.1.10"
00020 #define WIFI_IP_LOCAL_PORT                    2000
00021 #define WIFI_IP_DHCP                             4 /* Enable DHCP in the soft AP mode. */
00022 #define WIFI_IP_NET                "255.255.255.0"
00023 
00024 #define WIFI_IP_PROTOCOL                         2 // TCP server
00025 
00026 #define WIFI_OPT_DEVICE_ID                 "CISME"
00027 #define WIFI_WLAN_SSID                     "CISME"
00028 #define WIFI_WLAN_PASSWORD                 "CISME"
00029 
00030 #define WIFI_WLAN_JOIN                           7
00031 
00032 #define WIFI_CMD_MODE_DELAY                    1
00033 #define WIFI_CMD_DELAY                         0.5
00034 
00035 #define WIFI_ENTER_CMD_MODE_RESPONCE         "OK"
00036 #define WIFI_EXIT_CMD_MODE_RESPONCE         "OK"
00037 #define WIFI_NORMAL_CMD_RESPONSE             "OK"
00038 
00039 #define WIFI_MESSAGE_BUF_LENGTH 1024
00040 
00041 #define OK      0
00042 #define NOK     1
00043 
00044 #define MSG_TAG_TYPE     0x08
00045 #define MSG_TAG_PAYLOAD  0x12
00046 
00047 static Serial wifiComm(p13, p14);
00048 static DigitalOut reset_pin(p19);
00049 static DigitalIn tcpStatus(p17);
00050 static uint8_t msgBuffer[WIFI_MESSAGE_BUF_LENGTH];
00051 
00052 static int writeIx;
00053 static int readIx;
00054 static bool isCmdModeActive = false;
00055 
00056 static void reset(void)
00057 {
00058     wait(0.5);
00059     reset_pin = 0;
00060     /* clean in buffer. */
00061     readIx = writeIx;
00062     wait(0.5);
00063     reset_pin = 1;
00064     wait(0.5);
00065  }
00066 
00067 static void wifiCallback(void)
00068 {
00069     msgBuffer[writeIx] = wifiComm.getc();
00070 
00071     writeIx = (writeIx == WIFI_MESSAGE_BUF_LENGTH - 1) ? 0 : writeIx + 1;
00072 
00073     if (writeIx == readIx) {
00074         ERROR("Wi-Fi message buffer overflow");
00075         readIx = (readIx == WIFI_MESSAGE_BUF_LENGTH - 1)? 0 : readIx + 1;
00076     }
00077 }
00078 
00079 static char* wifiGetStringMessage(void)
00080 {
00081     char* msg;
00082 
00083     size_t msgLen = wifiGetMessage((uint8_t**)&msg);
00084     if (msgLen == 0) {
00085         return "";
00086     }
00087 
00088     msg[msgLen] = 0;
00089     DEBUG1("Received message={%s}", msg);
00090 
00091     return msg;
00092 }
00093 
00094 static void wifiSendString(const char* format, ...)
00095 {
00096     static char messageToSend[WIFI_MESSAGE_MAX_LENGTH];
00097     va_list params;
00098 
00099     va_start(params, format);
00100 
00101     vsnprintf(messageToSend, WIFI_MESSAGE_MAX_LENGTH, format, params);
00102 
00103     va_end(params);
00104 
00105     wifiSendMessage((uint8_t*)messageToSend, strlen(messageToSend));
00106 }
00107 
00108 static bool wifiCheckResponse(const char* expectedRsp)
00109 {
00110     char* response = wifiGetStringMessage();
00111 
00112     if (strstr(response, expectedRsp) == NULL) {
00113         ERROR("Unexpected response. Expected:{%s} Received:{%s}", expectedRsp, response);
00114         return false;
00115     }
00116 
00117     return true;
00118 }
00119 
00120 static int wifiEnterCmdMode(void)
00121 {
00122     isCmdModeActive = true;
00123     wifiSendString("+++");
00124     wait(WIFI_CMD_MODE_DELAY);
00125     wait(WIFI_CMD_MODE_DELAY);
00126     wifiSendString("+++");
00127     /*
00128      * According to user guied fo the device there is 500ms delay during which it's better to not sent anything
00129      * before entering to CMD mode. Otherwise the string will be treated as data and sent to client
00130      * through the socket.
00131     */
00132     wait(WIFI_CMD_MODE_DELAY);
00133     wait(WIFI_CMD_MODE_DELAY);
00134     if (!wifiCheckResponse(WIFI_ENTER_CMD_MODE_RESPONCE)) {
00135         ERROR("Failed to enter CMD mode");
00136         isCmdModeActive = false;
00137         return NOK;
00138     }
00139 
00140     return OK;
00141 }
00142 
00143 static int wifiExitCmdMode(void)
00144 {
00145     wifiSendString("atcn\r");
00146     wait(WIFI_CMD_MODE_DELAY);
00147 
00148     if (!wifiCheckResponse(WIFI_EXIT_CMD_MODE_RESPONCE)) {
00149         ERROR("Something was wrong on exit from CMD mode");
00150         return NOK;
00151     }
00152 
00153     isCmdModeActive = false;
00154     return OK;
00155 }
00156 
00157 static void wifiConfig(void)
00158 {
00159     char* message_temp;
00160     char* charIt;
00161     char* new_var1;
00162     char* new_var2;
00163 
00164     /*
00165      * Two step of configuration needed, since some parameters
00166      * can be applied only after restart, but due to unknown reason
00167      * some of them are not restored after restart.
00168     */
00169 
00170     /* clean in buffer to skip greetings. */
00171     readIx = writeIx;
00172 
00173     if (wifiEnterCmdMode() != OK) {
00174     return;
00175     }
00176     
00177     // Set the network type to infrastructure
00178     wifiSendString("ATAH 2\r");
00179     wait(WIFI_CMD_DELAY);
00180     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00181 
00182     // Set the infrastructure mode to soft access point
00183     wifiSendString("ATCE 1\r");
00184     wait(WIFI_CMD_DELAY);  
00185     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00186 
00187     // Set the ip protocol to TCP
00188     wifiSendString("ATIP 1\r");
00189     wait(WIFI_CMD_DELAY);
00190     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00191 
00192     // Set the ip addressing mode to Static
00193     wifiSendString("ATMA 1\r");
00194     wait(WIFI_CMD_DELAY);
00195     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);    
00196 
00197     // Set Serial Interface
00198     // Set Baud Rate to 9600
00199     wifiSendString("ATBD 3\r");
00200     wait(WIFI_CMD_DELAY);
00201     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00202 
00203     // Set API Enable to Transparent mode
00204     wifiSendString("ATAP 0\r");
00205     wait(WIFI_CMD_DELAY);
00206     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00207 
00208     // IO Functions
00209     wifiSendString("ATP2 6\r");
00210     wait(WIFI_CMD_DELAY);
00211     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00212     
00213     // Addressing
00214     // Broadcasting destination
00215     wifiSendString("ATDL FFFFFFFF\r");
00216     wait(WIFI_CMD_DELAY);
00217     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00218 
00219     //DNS 
00220     wifiSendString("ATNS 0\r");
00221     wait(WIFI_CMD_DELAY);
00222     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);    
00223     
00224     //Module IP Address 192.168.1.10 in hex
00225     wifiSendString("ATMY C0A8010A\r");
00226     wait(WIFI_CMD_DELAY);
00227     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00228     
00229     //Gateway Address
00230     wifiSendString("ATGW C0A80101\r");
00231     wait(WIFI_CMD_DELAY);
00232     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00233 
00234     // Local and source port number 2000 in hex
00235     wifiSendString("ATDE 7D0\r");
00236     wait(WIFI_CMD_DELAY);
00237     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00238 
00239     wifiSendString("ATC0 7D0\r");
00240     wait(WIFI_CMD_DELAY);
00241     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00242 
00243     //Mask
00244     wifiSendString("ATMK FFFFFF00\r");
00245     wait(WIFI_CMD_DELAY);
00246     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE); 
00247 
00248     INFO("Get mac");
00249     wifiSendString("ATSH\r");
00250     wait(WIFI_CMD_DELAY);
00251     message_temp = wifiGetStringMessage();
00252     new_var1 = (char*) malloc (strlen(message_temp)+1);
00253     
00254     charIt = message_temp;
00255     int charWriteIx = 0;
00256     //Removing <cr> in the string.
00257     for (; *charIt >= '0'; charIt++) {
00258         new_var1[charWriteIx++] = *charIt;
00259     }
00260     
00261     //new_var1 = (char*) malloc (strlen(message_temp)+1);
00262     //memcpy ( new_var1, message_temp, strlen(message_temp)+1 );
00263 
00264     wifiSendString("ATSL\r");
00265     wait(WIFI_CMD_DELAY);
00266     message_temp = wifiGetStringMessage();
00267     new_var2 = (char*) malloc (strlen(message_temp)+1);
00268     memcpy ( new_var2, message_temp, strlen(message_temp)+1 );
00269     INFO("Wifi's module MAC address:{%s%s}", new_var1, new_var2);  
00270      
00271 
00272     //message_temp[charWriteIx] = 0; 
00273     //INFO("Wifi's module MAC address:{%s}", message_temp);
00274     
00275     snprintf(instrumentId, 18, "CISME%s%s", new_var1, new_var2);
00276 
00277     
00278     wifiSendString("ATID CISME%s%s\r", new_var1, new_var2);
00279     //wifiSendString("ATID CISME\r");
00280     wait(WIFI_CMD_DELAY);
00281     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00282     
00283     // Set the ip addressing mode to DHCP
00284     wifiSendString("ATMA 0\r");
00285     wait(WIFI_CMD_DELAY);
00286     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);  
00287 
00288     wifiSendString("ATAC\r");
00289     wait(WIFI_CMD_DELAY);
00290     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00291         
00292     // Apply and Write the Parameters, Storing in config
00293     wifiSendString("ATWR\r");
00294     wait(WIFI_CMD_DELAY);
00295     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00296     
00297     wifiExitCmdMode();
00298 }
00299 
00300 static int wifiGetExpectedMessageSize()
00301 {
00302     int expectedMsgSize = 0;
00303     int byteIter;
00304     int sizeByteIx   = 0;
00305     int localReadIx  = readIx;
00306     int localWriteIx = writeIx;
00307 
00308     if (isCmdModeActive == true) {
00309         /*
00310          * In the CMD mode size of expected message is not defined, so
00311          * everything that received is expected.
00312         */
00313         return (localReadIx > localWriteIx) ?
00314                (WIFI_MESSAGE_BUF_LENGTH - localReadIx + localWriteIx) :
00315                (localWriteIx - localReadIx);
00316     }
00317     /* size can be more than one byte. */
00318     byteIter = localReadIx + 3;
00319     if (byteIter > WIFI_MESSAGE_BUF_LENGTH - 1) {
00320         byteIter -= WIFI_MESSAGE_BUF_LENGTH;
00321     }
00322 
00323     int payloadTagIx = (localReadIx + 2) > (WIFI_MESSAGE_BUF_LENGTH - 1) ?
00324                        (localReadIx + 2 - WIFI_MESSAGE_BUF_LENGTH) :
00325                        (localReadIx + 2);                       
00326     if (msgBuffer[localReadIx] != MSG_TAG_TYPE || msgBuffer[payloadTagIx] != MSG_TAG_PAYLOAD) {
00327         INFO("Message is broken, dropping all received messages.");
00328         readIx = writeIx;
00329         return 0;
00330     }
00331 
00332     /* Starting collection of message size. */
00333     do {
00334         expectedMsgSize |= (msgBuffer[byteIter] & (~0x80)) << (7 * sizeByteIx);
00335         sizeByteIx++;
00336 
00337         /* Check: is this the last byte of size?  the last byte has the highest bit 0. */
00338         if ((msgBuffer[byteIter] & 0x80) == 0) {
00339             break;
00340         }
00341 
00342         byteIter = (byteIter == WIFI_MESSAGE_BUF_LENGTH - 1) ? 0 : byteIter + 1;
00343     } while (byteIter != localWriteIx);
00344 
00345     if (byteIter == localWriteIx) {
00346         /* Receiving of message was finished in the middle of size field. */
00347         DEBUG1("Size of message is not fully received. current size of size field is %d current size field is %d", sizeByteIx, expectedMsgSize);
00348         return 0;
00349     }
00350 
00351     /* 4 is minimal size message header. (tag, msgId, tag, msgSize[0])*/
00352     return expectedMsgSize + 3 + sizeByteIx;
00353 }
00354 
00355 void wifiInit(void)
00356 {
00357     char* responce;
00358 
00359     /* Set settings for the Serial port for WIFI. */
00360     wifiComm.baud(WIFI_BAUD);
00361 
00362     wifiComm.format(WIFI_NO_BITS, WIFI_PARITY, WIFI_NO_STOP_BITS);
00363     reset_pin=1;
00364     reset();
00365     wait(WIFI_CMD_DELAY);
00366     INFO("Hardware reset done");
00367 
00368     wifiComm.attach(&wifiCallback, Serial::RxIrq);
00369 
00370     INFO("Reconfiguring WIFI module");
00371     wifiConfig();
00372 
00373     if ((debugGetCurrLvl() >= DEBUG_LEVEL_1) && wifiEnterCmdMode() == OK) {
00374 
00375         wifiSendString("ATMY\r");
00376         wait(1);
00377         responce = wifiGetStringMessage();
00378         INFO("Current IP settings:\n\r%s", responce);
00379 
00380         wifiSendString("ATGW\r");
00381         wait(1);
00382         responce = wifiGetStringMessage();
00383         INFO("Current wlan settings:\n\r%s", responce);
00384         
00385         wifiSendString("ATDL\r");
00386         wait(1);
00387         responce = wifiGetStringMessage();
00388         INFO("Current broadcast settings:\n\r%s", responce);
00389         
00390         wifiSendString("ATNS\r");
00391         wait(1);
00392         responce = wifiGetStringMessage();
00393         INFO("Current dns settings:\n\r%s", responce);
00394 
00395         wifiExitCmdMode();
00396     }
00397 
00398     INFO("Reconfiguration done");
00399 }
00400 
00401 size_t wifiGetMessage(uint8_t** msg)
00402 {
00403     static uint8_t receivedMessage[WIFI_MESSAGE_MAX_LENGTH + 1];
00404     int localReadIx  = readIx;
00405     int localWriteIx = writeIx;
00406     int targetPlace  = 0;
00407     int sizeOfReceived;
00408     int expectedMsgSize = 0;
00409 
00410     if (readIx == writeIx) {
00411         DEBUG1("No message received");
00412         return 0;
00413     }
00414 
00415     sizeOfReceived = (localReadIx > localWriteIx)? WIFI_MESSAGE_BUF_LENGTH - localReadIx + localWriteIx : localWriteIx - localReadIx;
00416 
00417     if (sizeOfReceived < 4 && isCmdModeActive == false) {
00418         // size of message is not received
00419         DEBUG1("Size of message is not received. sizeOfReceived=%d", sizeOfReceived);
00420         return 0;
00421     }
00422 
00423     expectedMsgSize = wifiGetExpectedMessageSize();
00424 
00425     if (expectedMsgSize == 0 || expectedMsgSize > sizeOfReceived) {
00426         DEBUG1("Message is not fully received. sizeOfReceived=%d expectedSize=%d", sizeOfReceived, expectedMsgSize);
00427         return 0;
00428     }
00429 
00430     readIx = localReadIx + expectedMsgSize;
00431     memset(receivedMessage, 0, WIFI_MESSAGE_MAX_LENGTH + 1);
00432 
00433     if (readIx > WIFI_MESSAGE_BUF_LENGTH - 1) {
00434         readIx     -= WIFI_MESSAGE_BUF_LENGTH;
00435         targetPlace = WIFI_MESSAGE_BUF_LENGTH - localReadIx;
00436         memcpy(receivedMessage, msgBuffer + localReadIx, targetPlace);
00437         localReadIx = 0;
00438     }
00439 
00440     memcpy(receivedMessage + targetPlace, msgBuffer + localReadIx, expectedMsgSize - targetPlace);
00441     *msg = receivedMessage;
00442     return expectedMsgSize;
00443 }
00444 
00445 void wifiSendMessage(const uint8_t* msg, size_t len)
00446 {
00447     for (size_t symbIx = 0; symbIx < len; symbIx++) {
00448         wifiComm.putc(msg[symbIx]);
00449     }
00450 }
00451 
00452 bool wifiTcpConnectionActive(void)
00453 {
00454     return (tcpStatus.read() != 1);
00455 }
00456 
00457 #endif // USE_WIFI