Qubit 2020 / presensfirmwareupdate

Dependencies:   mbed

Revision:
0:1121a7ef2e36
Child:
1:eac9f7a0488f
diff -r 000000000000 -r 1121a7ef2e36 2021fork3/wifi.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2021fork3/wifi.cpp	Tue Mar 09 20:50:11 2021 +0000
@@ -0,0 +1,457 @@
+#include <stdarg.h>
+
+#include "cisme.h"
+#include "wifi.h"
+#include "debug.h"
+
+#ifdef USE_WIFI
+
+/* Wifi comm settings. */
+#define WIFI_BAUD                             9600
+/* The number of bits in a word (5-8; default = 8) */
+#define WIFI_NO_BITS                             8
+/* parity - The parity used (Serial::None, Serial::Odd, Serial::Even, Serial::Forced1, Serial::Forced0; default = Serial::None) */
+#define WIFI_PARITY                   Serial::None
+/* stop - The number of stop bits (1 or 2; default = 1) */
+#define WIFI_NO_STOP_BITS                        1
+
+/* Wifi module settings. */
+#define WIFI_IP_LOCAL_ADDRESS       "192.168.1.10"
+#define WIFI_IP_LOCAL_PORT                    2000
+#define WIFI_IP_DHCP                             4 /* Enable DHCP in the soft AP mode. */
+#define WIFI_IP_NET                "255.255.255.0"
+
+#define WIFI_IP_PROTOCOL                         2 // TCP server
+
+#define WIFI_OPT_DEVICE_ID                 "CISME"
+#define WIFI_WLAN_SSID                     "CISME"
+#define WIFI_WLAN_PASSWORD                 "CISME"
+
+#define WIFI_WLAN_JOIN                           7
+
+#define WIFI_CMD_MODE_DELAY                    1
+#define WIFI_CMD_DELAY                         0.5
+
+#define WIFI_ENTER_CMD_MODE_RESPONCE         "OK"
+#define WIFI_EXIT_CMD_MODE_RESPONCE         "OK"
+#define WIFI_NORMAL_CMD_RESPONSE             "OK"
+
+#define WIFI_MESSAGE_BUF_LENGTH 1024
+
+#define OK      0
+#define NOK     1
+
+#define MSG_TAG_TYPE     0x08
+#define MSG_TAG_PAYLOAD  0x12
+
+static Serial wifiComm(p13, p14);
+static DigitalOut reset_pin(p19);
+static DigitalIn tcpStatus(p17);
+static uint8_t msgBuffer[WIFI_MESSAGE_BUF_LENGTH];
+
+static int writeIx;
+static int readIx;
+static bool isCmdModeActive = false;
+
+static void reset(void)
+{
+    wait(0.5);
+    reset_pin = 0;
+    /* clean in buffer. */
+    readIx = writeIx;
+    wait(0.5);
+    reset_pin = 1;
+    wait(0.5);
+ }
+
+static void wifiCallback(void)
+{
+    msgBuffer[writeIx] = wifiComm.getc();
+
+    writeIx = (writeIx == WIFI_MESSAGE_BUF_LENGTH - 1) ? 0 : writeIx + 1;
+
+    if (writeIx == readIx) {
+        ERROR("Wi-Fi message buffer overflow");
+        readIx = (readIx == WIFI_MESSAGE_BUF_LENGTH - 1)? 0 : readIx + 1;
+    }
+}
+
+static char* wifiGetStringMessage(void)
+{
+    char* msg;
+
+    size_t msgLen = wifiGetMessage((uint8_t**)&msg);
+    if (msgLen == 0) {
+        return "";
+    }
+
+    msg[msgLen] = 0;
+    DEBUG1("Received message={%s}", msg);
+
+    return msg;
+}
+
+static void wifiSendString(const char* format, ...)
+{
+    static char messageToSend[WIFI_MESSAGE_MAX_LENGTH];
+    va_list params;
+
+    va_start(params, format);
+
+    vsnprintf(messageToSend, WIFI_MESSAGE_MAX_LENGTH, format, params);
+
+    va_end(params);
+
+    wifiSendMessage((uint8_t*)messageToSend, strlen(messageToSend));
+}
+
+static bool wifiCheckResponse(const char* expectedRsp)
+{
+    char* response = wifiGetStringMessage();
+
+    if (strstr(response, expectedRsp) == NULL) {
+        ERROR("Unexpected response. Expected:{%s} Received:{%s}", expectedRsp, response);
+        return false;
+    }
+
+    return true;
+}
+
+static int wifiEnterCmdMode(void)
+{
+    isCmdModeActive = true;
+    wifiSendString("+++");
+    wait(WIFI_CMD_MODE_DELAY);
+    wait(WIFI_CMD_MODE_DELAY);
+    wifiSendString("+++");
+    /*
+     * According to user guied fo the device there is 500ms delay during which it's better to not sent anything
+     * before entering to CMD mode. Otherwise the string will be treated as data and sent to client
+     * through the socket.
+    */
+    wait(WIFI_CMD_MODE_DELAY);
+    wait(WIFI_CMD_MODE_DELAY);
+    if (!wifiCheckResponse(WIFI_ENTER_CMD_MODE_RESPONCE)) {
+        ERROR("Failed to enter CMD mode");
+        isCmdModeActive = false;
+        return NOK;
+    }
+
+    return OK;
+}
+
+static int wifiExitCmdMode(void)
+{
+    wifiSendString("atcn\r");
+    wait(WIFI_CMD_MODE_DELAY);
+
+    if (!wifiCheckResponse(WIFI_EXIT_CMD_MODE_RESPONCE)) {
+        ERROR("Something was wrong on exit from CMD mode");
+        return NOK;
+    }
+
+    isCmdModeActive = false;
+    return OK;
+}
+
+static void wifiConfig(void)
+{
+    char* message_temp;
+    char* charIt;
+    char* new_var1;
+    char* new_var2;
+
+    /*
+     * Two step of configuration needed, since some parameters
+     * can be applied only after restart, but due to unknown reason
+     * some of them are not restored after restart.
+    */
+
+    /* clean in buffer to skip greetings. */
+    readIx = writeIx;
+
+    if (wifiEnterCmdMode() != OK) {
+    return;
+    }
+    
+    // Set the network type to infrastructure
+    wifiSendString("ATAH 2\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    // Set the infrastructure mode to soft access point
+    wifiSendString("ATCE 1\r");
+    wait(WIFI_CMD_DELAY);  
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    // Set the ip protocol to TCP
+    wifiSendString("ATIP 1\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    // Set the ip addressing mode to Static
+    wifiSendString("ATMA 1\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);    
+
+    // Set Serial Interface
+    // Set Baud Rate to 9600
+    wifiSendString("ATBD 3\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    // Set API Enable to Transparent mode
+    wifiSendString("ATAP 0\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    // IO Functions
+    wifiSendString("ATP2 6\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+    
+    // Addressing
+    // Broadcasting destination
+    wifiSendString("ATDL FFFFFFFF\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    //DNS 
+    wifiSendString("ATNS 0\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);    
+    
+    //Module IP Address 192.168.1.10 in hex
+    wifiSendString("ATMY C0A8010A\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+    
+    //Gateway Address
+    wifiSendString("ATGW C0A80101\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    // Local and source port number 2000 in hex
+    wifiSendString("ATDE 7D0\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    wifiSendString("ATC0 7D0\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+
+    //Mask
+    wifiSendString("ATMK FFFFFF00\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE); 
+
+    INFO("Get mac");
+    wifiSendString("ATSH\r");
+    wait(WIFI_CMD_DELAY);
+    message_temp = wifiGetStringMessage();
+    new_var1 = (char*) malloc (strlen(message_temp)+1);
+    
+    charIt = message_temp;
+    int charWriteIx = 0;
+    //Removing <cr> in the string.
+    for (; *charIt >= '0'; charIt++) {
+        new_var1[charWriteIx++] = *charIt;
+    }
+    
+    //new_var1 = (char*) malloc (strlen(message_temp)+1);
+    //memcpy ( new_var1, message_temp, strlen(message_temp)+1 );
+
+    wifiSendString("ATSL\r");
+    wait(WIFI_CMD_DELAY);
+    message_temp = wifiGetStringMessage();
+    new_var2 = (char*) malloc (strlen(message_temp)+1);
+    memcpy ( new_var2, message_temp, strlen(message_temp)+1 );
+    INFO("Wifi's module MAC address:{%s%s}", new_var1, new_var2);  
+     
+
+    //message_temp[charWriteIx] = 0; 
+    //INFO("Wifi's module MAC address:{%s}", message_temp);
+    
+    snprintf(instrumentId, 18, "CISME%s%s", new_var1, new_var2);
+
+    
+    wifiSendString("ATID CISME%s%s\r", new_var1, new_var2);
+    //wifiSendString("ATID CISME\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+    
+    // Set the ip addressing mode to DHCP
+    //wifiSendString("ATMA 0\r");
+    //wait(WIFI_CMD_DELAY);
+    //wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);  
+
+    wifiSendString("ATAC\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+        
+    // Apply and Write the Parameters, Storing in config
+    wifiSendString("ATWR\r");
+    wait(WIFI_CMD_DELAY);
+    wifiCheckResponse(WIFI_NORMAL_CMD_RESPONSE);
+    
+    wifiExitCmdMode();
+}
+
+static int wifiGetExpectedMessageSize()
+{
+    int expectedMsgSize = 0;
+    int byteIter;
+    int sizeByteIx   = 0;
+    int localReadIx  = readIx;
+    int localWriteIx = writeIx;
+
+    if (isCmdModeActive == true) {
+        /*
+         * In the CMD mode size of expected message is not defined, so
+         * everything that received is expected.
+        */
+        return (localReadIx > localWriteIx) ?
+               (WIFI_MESSAGE_BUF_LENGTH - localReadIx + localWriteIx) :
+               (localWriteIx - localReadIx);
+    }
+    /* size can be more than one byte. */
+    byteIter = localReadIx + 3;
+    if (byteIter > WIFI_MESSAGE_BUF_LENGTH - 1) {
+        byteIter -= WIFI_MESSAGE_BUF_LENGTH;
+    }
+
+    int payloadTagIx = (localReadIx + 2) > (WIFI_MESSAGE_BUF_LENGTH - 1) ?
+                       (localReadIx + 2 - WIFI_MESSAGE_BUF_LENGTH) :
+                       (localReadIx + 2);                       
+    if (msgBuffer[localReadIx] != MSG_TAG_TYPE || msgBuffer[payloadTagIx] != MSG_TAG_PAYLOAD) {
+        INFO("Message is broken, dropping all received messages.");
+        readIx = writeIx;
+        return 0;
+    }
+
+    /* Starting collection of message size. */
+    do {
+        expectedMsgSize |= (msgBuffer[byteIter] & (~0x80)) << (7 * sizeByteIx);
+        sizeByteIx++;
+
+        /* Check: is this the last byte of size?  the last byte has the highest bit 0. */
+        if ((msgBuffer[byteIter] & 0x80) == 0) {
+            break;
+        }
+
+        byteIter = (byteIter == WIFI_MESSAGE_BUF_LENGTH - 1) ? 0 : byteIter + 1;
+    } while (byteIter != localWriteIx);
+
+    if (byteIter == localWriteIx) {
+        /* Receiving of message was finished in the middle of size field. */
+        DEBUG1("Size of message is not fully received. current size of size field is %d current size field is %d", sizeByteIx, expectedMsgSize);
+        return 0;
+    }
+
+    /* 4 is minimal size message header. (tag, msgId, tag, msgSize[0])*/
+    return expectedMsgSize + 3 + sizeByteIx;
+}
+
+void wifiInit(void)
+{
+    char* responce;
+
+    /* Set settings for the Serial port for WIFI. */
+    wifiComm.baud(WIFI_BAUD);
+
+    wifiComm.format(WIFI_NO_BITS, WIFI_PARITY, WIFI_NO_STOP_BITS);
+    reset_pin=1;
+    reset();
+    wait(WIFI_CMD_DELAY);
+    INFO("Hardware reset done");
+
+    wifiComm.attach(&wifiCallback, Serial::RxIrq);
+
+    INFO("Reconfiguring WIFI module");
+    wifiConfig();
+
+    if ((debugGetCurrLvl() >= DEBUG_LEVEL_1) && wifiEnterCmdMode() == OK) {
+
+        wifiSendString("ATMY\r");
+        wait(1);
+        responce = wifiGetStringMessage();
+        INFO("Current IP settings:\n\r%s", responce);
+
+        wifiSendString("ATGW\r");
+        wait(1);
+        responce = wifiGetStringMessage();
+        INFO("Current wlan settings:\n\r%s", responce);
+        
+        wifiSendString("ATDL\r");
+        wait(1);
+        responce = wifiGetStringMessage();
+        INFO("Current broadcast settings:\n\r%s", responce);
+        
+        wifiSendString("ATNS\r");
+        wait(1);
+        responce = wifiGetStringMessage();
+        INFO("Current dns settings:\n\r%s", responce);
+
+        wifiExitCmdMode();
+    }
+
+    INFO("Reconfiguration done");
+}
+
+size_t wifiGetMessage(uint8_t** msg)
+{
+    static uint8_t receivedMessage[WIFI_MESSAGE_MAX_LENGTH + 1];
+    int localReadIx  = readIx;
+    int localWriteIx = writeIx;
+    int targetPlace  = 0;
+    int sizeOfReceived;
+    int expectedMsgSize = 0;
+
+    if (readIx == writeIx) {
+        DEBUG1("No message received");
+        return 0;
+    }
+
+    sizeOfReceived = (localReadIx > localWriteIx)? WIFI_MESSAGE_BUF_LENGTH - localReadIx + localWriteIx : localWriteIx - localReadIx;
+
+    if (sizeOfReceived < 4 && isCmdModeActive == false) {
+        // size of message is not received
+        DEBUG1("Size of message is not received. sizeOfReceived=%d", sizeOfReceived);
+        return 0;
+    }
+
+    expectedMsgSize = wifiGetExpectedMessageSize();
+
+    if (expectedMsgSize == 0 || expectedMsgSize > sizeOfReceived) {
+        DEBUG1("Message is not fully received. sizeOfReceived=%d expectedSize=%d", sizeOfReceived, expectedMsgSize);
+        return 0;
+    }
+
+    readIx = localReadIx + expectedMsgSize;
+    memset(receivedMessage, 0, WIFI_MESSAGE_MAX_LENGTH + 1);
+
+    if (readIx > WIFI_MESSAGE_BUF_LENGTH - 1) {
+        readIx     -= WIFI_MESSAGE_BUF_LENGTH;
+        targetPlace = WIFI_MESSAGE_BUF_LENGTH - localReadIx;
+        memcpy(receivedMessage, msgBuffer + localReadIx, targetPlace);
+        localReadIx = 0;
+    }
+
+    memcpy(receivedMessage + targetPlace, msgBuffer + localReadIx, expectedMsgSize - targetPlace);
+    *msg = receivedMessage;
+    return expectedMsgSize;
+}
+
+void wifiSendMessage(const uint8_t* msg, size_t len)
+{
+    for (size_t symbIx = 0; symbIx < len; symbIx++) {
+        wifiComm.putc(msg[symbIx]);
+    }
+}
+
+bool wifiTcpConnectionActive(void)
+{
+    return (tcpStatus.read() != 1);
+}
+
+#endif // USE_WIFI
\ No newline at end of file