Simplify using of UnbufferedSerial(Serial), USBCDC, TCP, SMTP, NTP Fork : https://github.com/YSI-LPS/lib_Transmission

Dependents:   lib_Transmission_Serial_example 2022_TICE_Electrolyse lib_Transmission_TCP_example

Revision:
1:27f6baabb15e
Parent:
0:2fc6fc3b5e15
Child:
2:ec88f3f8b619
--- a/lib_Transmission.cpp	Wed Jun 24 14:30:34 2020 +0000
+++ b/lib_Transmission.cpp	Tue Jun 30 09:11:02 2020 +0000
@@ -1,12 +1,12 @@
 #include "lib_Transmission.h"
 
-Transmission::Transmission(UnbufferedSerial *serial, EthernetInterface *eth, EventQueue *queue, void(*com_init)(void), void(*com_processing)(string, const enumCOM&))
+Transmission::Transmission(UnbufferedSerial *serial, EthernetInterface *eth, EventQueue *queue, void(*_init)(void), void(*_processing)(string, const enumTRANSMISSION&))
 {
     _serial = serial;
     _eth = eth;
     _queue = queue;
-    fn_com_init = com_init;
-    fn_com_processing = com_processing;
+    fn_init = _init;
+    fn_processing = _processing;
 }
 
 bool Transmission::eth_connect(void)
@@ -16,20 +16,19 @@
         switch(_eth->get_connection_status())
         {
             case NSAPI_STATUS_DISCONNECTED:
-                if(statusCOLOR == RED_DISCONNECTED)
+                if(message.status == RED_DISCONNECTED)
                 {
                     eth_error("Ethernet_blocking", _eth->set_blocking(false));
                     eth_error("Ethernet_dhcp", _eth->set_dhcp(TCP_SET_DHCP));
                     if(!TCP_SET_DHCP) eth_error("Ethernet_static", _eth->set_network(SocketAddress(TCP_IP), SocketAddress(TCP_NETMASK), SocketAddress(TCP_GATEWAY)));
-                    //{ SocketAddress ip(TCP_IP); SocketAddress mask(TCP_NETMASK); SocketAddress gateway(TCP_GATEWAY); eth_error("Ethernet_static", eth_error("Ethernet_static", _eth->set_network(ip, mask, gateway))); }
                     eth_error("Ethernet_connect", _eth->connect());
                 }
             break;
             case NSAPI_STATUS_CONNECTING:
-                if(statusCOLOR == RED_DISCONNECTED)
+                if(message.status == RED_DISCONNECTED)
                 {
                     eth_status("Ethernet_connect", NSAPI_STATUS_CONNECTING);
-                    statusCOLOR = YELLOW_CONNECTING;
+                    message.status = YELLOW_CONNECTING;
                     _eth->attach(callback(this, &Transmission::eth_event));
                 }
             break;
@@ -46,11 +45,174 @@
     eth_status("Ethernet_event", param);
     switch(param)
     {
-        case NSAPI_STATUS_CONNECTING:   statusCOLOR = YELLOW_CONNECTING;  break;
-        case NSAPI_STATUS_DISCONNECTED: statusCOLOR = RED_DISCONNECTED;   break;
-        case NSAPI_STATUS_GLOBAL_UP:    statusCOLOR = GREEN_GLOBAL_UP;    break;
-        default:                                                                break;
+        case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED;  break;
+        case NSAPI_STATUS_CONNECTING:
+        if(message.status == BLUE_CLIENT) eth_error("clientTCP_disconnect", clientTCP->close());
+                                        message.status = YELLOW_CONNECTING; break;
+        case NSAPI_STATUS_GLOBAL_UP:    _queue->call(this, &Transmission::serverTCP_accept);
+                                        message.status = GREEN_GLOBAL_UP;   break;
+        default:                                                            break;
+    }
+}
+
+bool Transmission::serverTCP_connect(void)
+{
+    static bool serverTCP_connect = false;
+    if(!serverTCP_connect)
+        if (eth_error("serverTCP_open", serverTCP.open(_eth)) == NSAPI_ERROR_OK)
+            if (eth_error("serverTCP_bind", serverTCP.bind(TCP_PORT)) == NSAPI_ERROR_OK)
+                if (eth_error("serverTCP_listen", serverTCP.listen()) == NSAPI_ERROR_OK)
+                {
+                    serverTCP.set_blocking(false);
+                    serverTCP.sigio(callback(this, &Transmission::serverTCP_event));
+                    serverTCP_connect = true;
+                    fn_init();
+                }
+    return serverTCP_connect;
+}
+
+void Transmission::serverTCP_event(void)
+{
+    _queue->call(this, &Transmission::serverTCP_accept);
+}
+
+void Transmission::serverTCP_accept(void)
+{
+    if(message.status == GREEN_GLOBAL_UP)
+    {
+        nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
+        message.status = MAGENTA_ACCEPT;
+        clientTCP = serverTCP.accept(&ack);
+        switch(ack)
+        {
+            case NSAPI_ERROR_OK:
+                clientTCP->set_timeout(TCP_CLIENT_TIMEOUT);
+                message.status = BLUE_CLIENT;
+            break;
+            case NSAPI_ERROR_PARAMETER:
+            case NSAPI_ERROR_WOULD_BLOCK:
+                message.status = GREEN_GLOBAL_UP;
+            break;
+            case NSAPI_ERROR_NO_CONNECTION:
+                message.status = GREEN_GLOBAL_UP;
+                _queue->call(this, &Transmission::serverTCP_accept);
+            break;
+            default:
+                message.status = GREEN_GLOBAL_UP;
+                eth_error("serverTCP_accept", ack);
+            break;
+        }
+    }
+}
+
+enumSTATUS Transmission::recv(void)
+{
+    if(eth_connect())
+    {
+        char buffer[1024] = {0};
+        nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
+        if(message.status == BLUE_CLIENT)
+            if((ack = clientTCP->recv(buffer, 1024)) < NSAPI_ERROR_WOULD_BLOCK)
+                eth_error("clientTCP_recv", ack);
+        switch(ack)
+        {
+            case NSAPI_ERROR_NO_CONNECTION:
+            case NSAPI_ERROR_OK:
+            message.BREAK = true;   break;
+            default:                break;
+        }
+        for(int i = 0; i < ack; i++) if(buffer[i] == '\n') buffer[i] = ';';
+        fn_processing(message.buffer[TCP] = buffer, TCP);
+        message.buffer[TCP].clear();
     }
+    if(_serial->readable())
+    {
+        char caractere;
+        _serial->read(&caractere, 1);
+        switch(caractere)
+        {
+            case '\n':
+                fn_processing(message.buffer[SERIAL], SERIAL);
+                message.buffer[SERIAL].clear();
+            break;
+            default:
+                if((caractere > 31) && (caractere < 127)) message.buffer[SERIAL] += caractere;
+            break;
+        }
+    }
+    return message.status;
+}
+
+nsapi_error_t Transmission::send(const string& buff, const enumTRANSMISSION& type)
+{
+    nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
+    string ssend(buff+"\n");
+    switch(type)
+    {
+        case TCP:
+            if(message.BREAK)
+            {
+                message.BREAK = false;
+                eth_error("clientTCP_disconnect", clientTCP->close());
+                switch(_eth->get_connection_status())
+                {
+                    case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED;  break;
+                    case NSAPI_STATUS_CONNECTING:   message.status = YELLOW_CONNECTING; break;
+                    case NSAPI_STATUS_GLOBAL_UP:    message.status = GREEN_GLOBAL_UP;   break;
+                    default:                                                            break;
+                }
+                _queue->call(this, &Transmission::serverTCP_accept);
+            }
+            else if(!buff.empty())
+            {
+                eth_error("clientTCP_send", ack = clientTCP->send(ssend.c_str(), ssend.size()));
+                if(message.HTTP)
+                {
+                    message.HTTP = false;
+                    eth_error("clientTCP_disconnect", clientTCP->close());
+                    switch(_eth->get_connection_status())
+                    {
+                        case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED;   break;
+                        case NSAPI_STATUS_CONNECTING:   message.status = YELLOW_CONNECTING;  break;
+                        case NSAPI_STATUS_GLOBAL_UP:    message.status = GREEN_GLOBAL_UP;    break;
+                        default:                                                          break;
+                    }
+                    _queue->call(this, &Transmission::serverTCP_accept);
+                }
+            }
+        break;
+        case SERIAL:
+            if(!buff.empty()) ack = _serial->write(ssend.c_str(), ssend.length());
+        break;
+    }
+    return ack;
+}
+
+bool Transmission::smtp(const char* MAIL, const char* FROM, const char* SUBJECT, const char* DATA)
+{
+    TCPSocket clientSMTP;
+    clientSMTP.set_timeout(5000);
+    const string sMAIL(MAIL), sFROM(FROM), sSUBJECT(SUBJECT), sDATA(DATA);
+    const string smtpParams[][7] = {{ "", "HELO Mbed " + sFROM + "\r\n", "MAIL FROM: <Mbed." + sFROM + "@U-PSUD.FR>\r\n", "RCPT TO: <" + sMAIL + ">\r\n", "DATA\r\n", "From: \"Mbed " + sFROM + "\" <Mbed." + sFROM + "@U-PSUD.FR>\r\nTo: \"DESTINATAIRE\" <" + sMAIL + ">\r\nSubject:" + sSUBJECT + "\r\n" + sDATA + "\r\n.\r\n", "QUIT\r\n" },
+                                    { "", "HELO Mbed\r\n", "MAIL FROM: <Mbed>\r\n","RCPT TO: <" + sMAIL + ">\r\n", "QUIT\r\n" }};
+    string code;
+    if(eth_error("clientSMTP_open", clientSMTP.open(_eth)) == NSAPI_ERROR_OK)
+    {
+        for(const string ssend : smtpParams[(sFROM.empty())?1:0])
+        {
+            char buffer[256] = {0};
+            if(code.empty()) { if(eth_error("clientSMTP_connect", clientSMTP.connect(SocketAddress(SMTP_SERVER, 25))) < NSAPI_ERROR_OK) break; }
+            else if(eth_error("clientSMTP_send", clientSMTP.send(ssend.c_str(), ssend.size())) < NSAPI_ERROR_OK)                        break;
+            if(eth_error("clientSMTP_recv", clientSMTP.recv(buffer, 256)) < NSAPI_ERROR_OK)                                             break;
+            buffer[3] = 0;
+            code += buffer;
+            if(ssend == "QUIT\r\n") break;
+        }
+        eth_error("clientSMTP_close", clientSMTP.close());
+    }
+    if(sFROM.empty()) return code == "220250250250221";
+    else if(code != "220250250250354250221") _queue->call_in(60s, this, &Transmission::smtp, MAIL, FROM, SUBJECT, DATA);
+    return code == "220250250250354250221";
 }
 
 intptr_t Transmission::eth_status(const string& source, const intptr_t& code)
@@ -65,7 +227,9 @@
         case NSAPI_STATUS_CONNECTING:           message << "] NSAPI_STATUS_CONNECTING        < connecting to network >";    break;
         case NSAPI_STATUS_ERROR_UNSUPPORTED:    message << "] NSAPI_STATUS_ERROR_UNSUPPORTED < unsupported functionality >";break;
     }
-    _serial->write(message.str().c_str(), message.str().size());//debug("%s", message.str().c_str());
+    #ifndef NDEBUG
+    _serial->write(message.str().c_str(), message.str().size());
+    #endif
     return code;
 }
 
@@ -98,190 +262,8 @@
         case NSAPI_ERROR_BUSY:                  message << "] NSAPI_ERROR_BUSY               < device is busy and cannot accept new operation >";   break;
         default:                                message << "] NSAPI_ERROR                    < unknow code >";                                      break;
     }
-    if(code < NSAPI_ERROR_OK) _serial->write(message.str().c_str(), message.str().size());//debug("%s", message.str().c_str());
+    #ifndef NDEBUG
+    if(code < NSAPI_ERROR_OK) _serial->write(message.str().c_str(), message.str().size());
+    #endif
     return code;
-}
-
-bool Transmission::serverTCP_connect(void)
-{
-    static bool serverTCP_connect = false;
-    if(!serverTCP_connect)
-        if (eth_error("serverTCP_open", serverTCP.open(_eth)) == NSAPI_ERROR_OK)
-            if (eth_error("serverTCP_bind", serverTCP.bind(TCP_PORT)) == NSAPI_ERROR_OK)
-                if (eth_error("serverTCP_listen", serverTCP.listen()) == NSAPI_ERROR_OK)
-                {
-                    serverTCP.set_blocking(false);
-                    serverTCP.sigio(callback(this, &Transmission::serverTCP_event));
-                    serverTCP_connect = true;
-                    fn_com_init();
-                }
-    return serverTCP_connect;
-}
-
-void Transmission::serverTCP_event(void)
-{
-    _queue->call(this, &Transmission::serverTCP_accept);
-}
-
-void Transmission::serverTCP_accept(void)
-{
-    if(statusCOLOR == GREEN_GLOBAL_UP)
-    {
-        nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
-        statusCOLOR = MAGENTA_ACCEPT;
-        clientTCP = serverTCP.accept(&ack);
-        switch(ack)
-        {
-            case NSAPI_ERROR_OK:
-                clientTCP->set_timeout(TCP_CLIENT_TIMEOUT);
-                statusCOLOR = BLUE_CLIENT;
-            break;
-            case NSAPI_ERROR_WOULD_BLOCK:
-                statusCOLOR = GREEN_GLOBAL_UP;
-            break;
-            case NSAPI_ERROR_NO_CONNECTION:
-                statusCOLOR = GREEN_GLOBAL_UP;
-                _queue->call(this, &Transmission::serverTCP_accept);
-            break;
-            default:
-                statusCOLOR = GREEN_GLOBAL_UP;
-                eth_error("serverTCP_accept", ack);
-            break;
-        }
-    }
-}
-
-nsapi_error_t Transmission::send(const string& buff, const enumCOM& type)
-{
-    nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
-    string ssend(buff+"\n");
-    switch(type)
-    {
-        case TCP:
-            if(message.BREAK)
-            {
-                message.BREAK = false;
-                eth_error("clientTCP_disconnect", clientTCP->close());
-                switch(_eth->get_connection_status())
-                {
-                    case NSAPI_STATUS_DISCONNECTED: statusCOLOR = RED_DISCONNECTED;   break;
-                    case NSAPI_STATUS_CONNECTING:   statusCOLOR = YELLOW_CONNECTING;  break;
-                    case NSAPI_STATUS_GLOBAL_UP:    statusCOLOR = GREEN_GLOBAL_UP;    break;
-                    default:                                                                break;
-                }
-                _queue->call(this, &Transmission::serverTCP_accept);
-            }
-            else if(!buff.empty())
-            {
-                ack = clientTCP->send(ssend.c_str(), ssend.size());
-                if(message.HTTP)
-                {
-                    message.HTTP = false;
-                    eth_error("clientTCP_disconnect", clientTCP->close());
-                    switch(_eth->get_connection_status())
-                    {
-                        case NSAPI_STATUS_DISCONNECTED: statusCOLOR = RED_DISCONNECTED;   break;
-                        case NSAPI_STATUS_CONNECTING:   statusCOLOR = YELLOW_CONNECTING;  break;
-                        case NSAPI_STATUS_GLOBAL_UP:    statusCOLOR = GREEN_GLOBAL_UP;    break;
-                        default:                                                                break;
-                    }
-                    _queue->call(this, &Transmission::serverTCP_accept);
-                }
-            }
-        break;
-        case SERIAL:
-            if(!buff.empty()) ack = _serial->write(ssend.c_str(), ssend.length());
-        break;
-    }
-    return ack;
-}
-
-enumCOLOR Transmission::recv(void)
-{
-    if(eth_connect())
-    {
-        char buffer[1024] = {0};
-        nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
-        if(statusCOLOR == BLUE_CLIENT)
-            if((ack = clientTCP->recv(buffer, 1024)) < NSAPI_ERROR_WOULD_BLOCK)
-                eth_error("clientTCP_recv", ack);
-        switch(ack)
-        {
-            case NSAPI_ERROR_NO_CONNECTION:
-            case NSAPI_ERROR_OK:
-            message.BREAK = true;   break;
-            default:            break;
-        }
-        for(int i = 0; i < ack; i++) if(buffer[i] == '\n') buffer[i] = ';';
-        fn_com_processing(message.buffer[TCP] = buffer, TCP);
-        message.buffer[TCP].clear();
-    }
-    if(_serial->readable())
-    {
-        char caractere;
-        _serial->read(&caractere, 1);
-        switch(caractere)
-        {
-            case '\n':
-                fn_com_processing(message.buffer[SERIAL], SERIAL);
-                message.buffer[SERIAL].clear();
-            break;
-            default:
-                if((caractere > 31) && (caractere < 127)) message.buffer[SERIAL] += caractere;
-            break;
-        }
-    }
-    return statusCOLOR;
-}
-
-bool Transmission::sendSMTP(const char* MAIL, const char* FROM, const char* SUBJECT, const char* DATA)
-{
-    TCPSocket clientSMTP;
-    clientSMTP.set_timeout(5000);
-    string code;
-    if(eth_error("clientSMTP_open", clientSMTP.open(_eth)) == NSAPI_ERROR_OK)
-    {
-        const string sMAIL(MAIL), sFROM(FROM), sSUBJECT(SUBJECT), sDATA(DATA), 
-        smtpSend[] = { "", "HELO Mbed " + sFROM + "\r\n", "MAIL FROM: <Mbed." + sFROM + "@U-PSUD.FR>\r\n", "RCPT TO: <" + sMAIL + ">\r\n", "DATA\r\n",
-        "From: \"Mbed " + sFROM + "\" <Mbed." + sFROM + "@U-PSUD.FR>\r\nTo: \"DESTINATAIRE\" <" + sMAIL + ">\r\nSubject:" + sSUBJECT + "\r\n" + sDATA + "\r\n.\r\n", "QUIT\r\n" };
-        for(const string ssend : smtpSend)
-        {
-            char buffer[256] = {0};
-            if(code.empty()) { if(eth_error("clientSMTP_connect", clientSMTP.connect(SocketAddress(SMTP_SERVER, 25))) < NSAPI_ERROR_OK)  break; }
-            else if(eth_error("clientSMTP_send", clientSMTP.send(ssend.c_str(), ssend.size())) < NSAPI_ERROR_OK)                                    break;
-            if(eth_error("clientSMTP_recv", clientSMTP.recv(buffer, 256)) < NSAPI_ERROR_OK)                                                         break;
-            buffer[3] = 0;
-            code += buffer;
-        }
-        eth_error("clientSMTP_close", clientSMTP.close());
-    }
-    if(code != "220250250250354250221")
-    {
-        _queue->call_in(60s, this, &Transmission::sendSMTP, MAIL, FROM, SUBJECT, DATA);
-        return false;
-    }
-    return true;
-}
-
-bool Transmission::checkSMTP(const char* MAIL)
-{
-    TCPSocket clientSMTP;
-    clientSMTP.set_timeout(5000);
-    string code(MAIL);
-    if(eth_error("clientSMTP_open", clientSMTP.open(_eth)) == NSAPI_ERROR_OK)
-    {
-        const string smtpSend[] = { "", "HELO Mbed\r\n", "MAIL FROM: <Mbed>\r\n","RCPT TO: <" + code + ">\r\n", "QUIT\r\n" };
-        code.clear();
-        for(const string ssend : smtpSend)
-        {
-            char buffer[256] = {0};
-            if(code.empty()) { if(eth_error("clientSMTP_connect", clientSMTP.connect(SocketAddress(SMTP_SERVER, 25))) < NSAPI_ERROR_OK) break; }
-            else if(eth_error("clientSMTP_send", clientSMTP.send(ssend.c_str(), ssend.size())) < NSAPI_ERROR_OK)                        break;
-            if(eth_error("clientSMTP_recv", clientSMTP.recv(buffer, 256)) < NSAPI_ERROR_OK)                                             break;
-            buffer[3] = 0;
-            code += buffer;
-        }
-        eth_error("clientSMTP_close", clientSMTP.close());
-    }
-    return code == "220250250250221";
 }
\ No newline at end of file