Qubit 2020 / presensfirmwareupdate

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     char* rf_payload_bytes;
00164 
00165     /*
00166      * Two step of configuration needed, since some parameters
00167      * can be applied only after restart, but due to unknown reason
00168      * some of them are not restored after restart.
00169     */
00170 
00171     /* clean in buffer to skip greetings. */
00172     readIx = writeIx;
00173 
00174     if (wifiEnterCmdMode() != OK) {
00175     return;
00176     }
00177     
00178     // Set the network type to infrastructure
00179     wifiSendString("ATAH 2\r");
00180     wait(WIFI_CMD_DELAY);
00181     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00182 
00183     // Set the infrastructure mode to soft access point
00184     wifiSendString("ATCE 1\r");
00185     wait(WIFI_CMD_DELAY);  
00186     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00187 
00188     // Set the ip protocol to TCP
00189     wifiSendString("ATIP 1\r");
00190     wait(WIFI_CMD_DELAY);
00191     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00192 
00193     // Set the ip addressing mode to Static
00194     wifiSendString("ATMA 1\r");
00195     wait(WIFI_CMD_DELAY);
00196     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);    
00197 
00198     // Set Serial Interface
00199     // Set Baud Rate to 9600
00200     wifiSendString("ATBD 3\r");
00201     wait(WIFI_CMD_DELAY);
00202     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00203 
00204     // Set API Enable to Transparent mode
00205     wifiSendString("ATAP 0\r");
00206     wait(WIFI_CMD_DELAY);
00207     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00208 
00209     // IO Functions
00210     wifiSendString("ATP2 6\r");
00211     wait(WIFI_CMD_DELAY);
00212     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00213     
00214     // Addressing
00215     // Broadcasting destination
00216     wifiSendString("ATDL FFFFFFFF\r");
00217     wait(WIFI_CMD_DELAY);
00218     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00219 
00220     //DNS 
00221     wifiSendString("ATNS 0\r");
00222     wait(WIFI_CMD_DELAY);
00223     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);    
00224     
00225     //Module IP Address 192.168.1.10 in hex
00226     wifiSendString("ATMY C0A8010A\r");
00227     wait(WIFI_CMD_DELAY);
00228     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00229     
00230     //Gateway Address
00231     wifiSendString("ATGW C0A80101\r");
00232     wait(WIFI_CMD_DELAY);
00233     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00234 
00235     // Local and source port number 2000 in hex
00236     wifiSendString("ATDE 7D0\r");
00237     wait(WIFI_CMD_DELAY);
00238     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00239 
00240     wifiSendString("ATC0 7D0\r");
00241     wait(WIFI_CMD_DELAY);
00242     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00243 
00244     //Mask
00245     wifiSendString("ATMK FFFFFF00\r");
00246     wait(WIFI_CMD_DELAY);
00247     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE); 
00248 
00249     INFO("Get mac");
00250     wifiSendString("ATSH\r");
00251     wait(WIFI_CMD_DELAY);
00252     message_temp = wifiGetStringMessage();
00253     new_var1 = (char*) malloc (strlen(message_temp)+1);
00254     
00255     charIt = message_temp;
00256     int charWriteIx = 0;
00257     //Removing <cr> in the string.
00258     for (; *charIt >= '0'; charIt++) {
00259         new_var1[charWriteIx++] = *charIt;
00260     }
00261     
00262     //new_var1 = (char*) malloc (strlen(message_temp)+1);
00263     //memcpy ( new_var1, message_temp, strlen(message_temp)+1 );
00264 
00265     wifiSendString("ATSL\r");
00266     wait(WIFI_CMD_DELAY);
00267     message_temp = wifiGetStringMessage();
00268     new_var2 = (char*) malloc (strlen(message_temp)+1);
00269     memcpy ( new_var2, message_temp, strlen(message_temp)+1 );
00270     INFO("Wifi's module MAC address:{%s%s}", new_var1, new_var2);  
00271     
00272  
00273     //message_temp[charWriteIx] = 0; 
00274     //INFO("Wifi's module MAC address:{%s}", message_temp);
00275     
00276     snprintf(instrumentId, 18, "CISME%s%s", new_var1, new_var2);
00277 
00278     
00279     wifiSendString("ATID CISME%s%s\r", new_var1, new_var2);
00280     //wifiSendString("ATID CISME\r");
00281     wait(WIFI_CMD_DELAY);
00282     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00283     
00284     // Set the ip addressing mode to DHCP
00285     //wifiSendString("ATMA 0\r");
00286     //wait(WIFI_CMD_DELAY);
00287     //wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE); 
00288     
00289     //get rf payload buffer size in hex
00290     wifiSendString("ATNP\r");
00291     wait(WIFI_CMD_DELAY);
00292     rf_payload_bytes = wifiGetStringMessage();
00293     INFO("Wifi's RF payload bytes:{%s}", rf_payload_bytes);
00294      
00295      
00296     wifiSendString("ATAC\r");
00297     wait(WIFI_CMD_DELAY);
00298     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00299         
00300     // Apply and Write the Parameters, Storing in config
00301     wifiSendString("ATWR\r");
00302     wait(WIFI_CMD_DELAY);
00303     wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
00304     
00305     wifiExitCmdMode();
00306 }
00307 
00308 static int wifiGetExpectedMessageSize()
00309 {
00310     int expectedMsgSize = 0;
00311     int byteIter;
00312     int sizeByteIx   = 0;
00313     int localReadIx  = readIx;
00314     int localWriteIx = writeIx;
00315 
00316     if (isCmdModeActive == true) {
00317         /*
00318          * In the CMD mode size of expected message is not defined, so
00319          * everything that received is expected.
00320         */
00321         return (localReadIx > localWriteIx) ?
00322                (WIFI_MESSAGE_BUF_LENGTH - localReadIx + localWriteIx) :
00323                (localWriteIx - localReadIx);
00324     }
00325     /* size can be more than one byte. */
00326     byteIter = localReadIx + 3;
00327     if (byteIter > WIFI_MESSAGE_BUF_LENGTH - 1) {
00328         byteIter -= WIFI_MESSAGE_BUF_LENGTH;
00329     }
00330 
00331     int payloadTagIx = (localReadIx + 2) > (WIFI_MESSAGE_BUF_LENGTH - 1) ?
00332                        (localReadIx + 2 - WIFI_MESSAGE_BUF_LENGTH) :
00333                        (localReadIx + 2);                       
00334     if (msgBuffer[localReadIx] != MSG_TAG_TYPE || msgBuffer[payloadTagIx] != MSG_TAG_PAYLOAD) {
00335         INFO("Message is broken, dropping all received messages.");
00336         readIx = writeIx;
00337         return 0;
00338     }
00339 
00340     /* Starting collection of message size. */
00341     do {
00342         expectedMsgSize |= (msgBuffer[byteIter] & (~0x80)) << (7 * sizeByteIx);
00343         sizeByteIx++;
00344 
00345         /* Check: is this the last byte of size?  the last byte has the highest bit 0. */
00346         if ((msgBuffer[byteIter] & 0x80) == 0) {
00347             break;
00348         }
00349 
00350         byteIter = (byteIter == WIFI_MESSAGE_BUF_LENGTH - 1) ? 0 : byteIter + 1;
00351     } while (byteIter != localWriteIx);
00352 
00353     if (byteIter == localWriteIx) {
00354         /* Receiving of message was finished in the middle of size field. */
00355         DEBUG1("Size of message is not fully received. current size of size field is %d current size field is %d", sizeByteIx, expectedMsgSize);
00356         return 0;
00357     }
00358 
00359     /* 4 is minimal size message header. (tag, msgId, tag, msgSize[0])*/
00360     return expectedMsgSize + 3 + sizeByteIx;
00361 }
00362 
00363 void wifiInit(void)
00364 {
00365     char* responce;
00366 
00367     /* Set settings for the Serial port for WIFI. */
00368     wifiComm.baud(WIFI_BAUD);
00369 
00370     wifiComm.format(WIFI_NO_BITS, WIFI_PARITY, WIFI_NO_STOP_BITS);
00371     reset_pin=1;
00372     reset();
00373     wait(WIFI_CMD_DELAY);
00374     INFO("Hardware reset done");
00375 
00376     wifiComm.attach(&wifiCallback, Serial::RxIrq);
00377 
00378     INFO("Reconfiguring WIFI module");
00379     wifiConfig();
00380 
00381     if ((debugGetCurrLvl() >= DEBUG_LEVEL_1) && wifiEnterCmdMode() == OK) {
00382 
00383         wifiSendString("ATMY\r");
00384         wait(1);
00385         responce = wifiGetStringMessage();
00386         INFO("Current IP settings:\n\r%s", responce);
00387 
00388         wifiSendString("ATGW\r");
00389         wait(1);
00390         responce = wifiGetStringMessage();
00391         INFO("Current wlan settings:\n\r%s", responce);
00392         
00393         wifiSendString("ATDL\r");
00394         wait(1);
00395         responce = wifiGetStringMessage();
00396         INFO("Current broadcast settings:\n\r%s", responce);
00397         
00398         wifiSendString("ATNS\r");
00399         wait(1);
00400         responce = wifiGetStringMessage();
00401         INFO("Current dns settings:\n\r%s", responce);
00402 
00403         wifiExitCmdMode();
00404         
00405     }
00406 
00407     INFO("Reconfiguration done");
00408 }
00409 
00410 size_t wifiGetMessage(uint8_t** msg)
00411 {
00412     static uint8_t receivedMessage[WIFI_MESSAGE_MAX_LENGTH + 1];
00413     int localReadIx  = readIx;
00414     int localWriteIx = writeIx;
00415     int targetPlace  = 0;
00416     int sizeOfReceived;
00417     int expectedMsgSize = 0;
00418 
00419     if (readIx == writeIx) {
00420         DEBUG1("No message received");
00421         return 0;
00422     }
00423 
00424     sizeOfReceived = (localReadIx > localWriteIx)? WIFI_MESSAGE_BUF_LENGTH - localReadIx + localWriteIx : localWriteIx - localReadIx;
00425 
00426     if (sizeOfReceived < 4 && isCmdModeActive == false) {
00427         // size of message is not received
00428         DEBUG1("Size of message is not received. sizeOfReceived=%d", sizeOfReceived);
00429         return 0;
00430     }
00431 
00432     expectedMsgSize = wifiGetExpectedMessageSize();
00433 
00434     if (expectedMsgSize == 0 || expectedMsgSize > sizeOfReceived) {
00435         DEBUG1("Message is not fully received. sizeOfReceived=%d expectedSize=%d", sizeOfReceived, expectedMsgSize);
00436         return 0;
00437     }
00438 
00439     readIx = localReadIx + expectedMsgSize;
00440     memset(receivedMessage, 0, WIFI_MESSAGE_MAX_LENGTH + 1);
00441 
00442     if (readIx > WIFI_MESSAGE_BUF_LENGTH - 1) {
00443         readIx     -= WIFI_MESSAGE_BUF_LENGTH;
00444         targetPlace = WIFI_MESSAGE_BUF_LENGTH - localReadIx;
00445         memcpy(receivedMessage, msgBuffer + localReadIx, targetPlace);
00446         localReadIx = 0;
00447     }
00448 
00449     memcpy(receivedMessage + targetPlace, msgBuffer + localReadIx, expectedMsgSize - targetPlace);
00450     *msg = receivedMessage;
00451     return expectedMsgSize;
00452 }
00453 
00454 void wifiSendMessage(const uint8_t* msg, size_t len)
00455 {
00456     for (size_t symbIx = 0; symbIx < len; symbIx++) {
00457         wifiComm.putc(msg[symbIx]);
00458     }
00459 }
00460 
00461 bool wifiTcpConnectionActive(void)
00462 {
00463     return (tcpStatus.read() != 1);
00464 }
00465 
00466 #endif // USE_WIFI