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:
14:9e3accc681c4
Parent:
13:1e13e40b03c9
Child:
15:b2da6ab01a21
--- a/lib_Transmission.cpp	Tue Dec 15 10:29:38 2020 +0000
+++ b/lib_Transmission.cpp	Fri Feb 12 15:29:54 2021 +0000
@@ -1,26 +1,21 @@
 #include "lib_Transmission.h"
 
-#if MBED_MAJOR_VERSION > 5
-Transmission::Transmission(UnbufferedSerial *serial, EthernetInterface *eth, void(*init)(void), void(*processing)(string, Transmission::enum_trans_to))
+Transmission::Transmission(
+    #if MBED_MAJOR_VERSION > 5
+    UnbufferedSerial *serial,
+    #else
+    Serial *serial,
+    #endif
+    EthernetInterface *eth,
+    void(*init)(void),
+    void(*processing)(string, Transmission::enum_trans_to))
+    :_serial(serial), _eth(eth), _init(init), _processing(processing)
 {
-    _queueThread.start(callback(&_queue, &EventQueue::dispatch_forever));
-    _serial = serial;
-    _eth = eth;
-    _init = init;
-    _processing = processing;
+    if(_serial != NULL) _serial->attach(callback(this, &Transmission::serial_event));
+    _queue = mbed_event_queue();
 }
-#else
-Transmission::Transmission(Serial *serial, EthernetInterface *eth, void(*init)(void), void(*processing)(string, Transmission::enum_trans_to))
-{
-    _queueThread.start(callback(&_queue, &EventQueue::dispatch_forever));
-    _serial = serial;
-    _eth = eth;
-    _init = init;
-    _processing = processing;
-}
-#endif
 
-string Transmission::set(bool SET, const char* IP, uint16_t PORT)
+string Transmission::ip(const bool& SET, const char* IP, const uint16_t& PORT, const uint16_t& TIMEOUT)
 {
     if(_eth == NULL) return "00:00:00:00:00:00";
     if(message.SET && SET)
@@ -36,12 +31,13 @@
     message.SET = SET;
     message.IP = IP;
     message.PORT = PORT;
+    message.TIMEOUT = TIMEOUT;
     message.DHCP = message.IP.empty();
     eth_connect();
-    return _eth->get_mac_address();
+    return _eth->get_mac_address()?_eth->get_mac_address():"00:00:00:00:00:00";
 }
 
-string Transmission::get(void)
+string Transmission::ip(void)
 {
     if(_eth == NULL) return "0.0.0.0";
     SocketAddress ip;
@@ -59,24 +55,14 @@
         switch(_eth->get_connection_status())
         {
             case NSAPI_STATUS_DISCONNECTED:
-                if(message.status == RED_DISCONNECTED)
-                {
-                    eth_error("Ethernet_blocking", _eth->set_blocking(false));
-                    eth_error("Ethernet_dhcp", _eth->set_dhcp(message.DHCP));
-                    if(!message.DHCP) eth_error("Ethernet_static", _eth->set_network(SocketAddress(message.IP.c_str()), SocketAddress("255.255.255.0"), SocketAddress("192.168.1.1")));
-                    eth_error("Ethernet_connect", _eth->connect());
-                }
+                eth_error("Ethernet_blocking", _eth->set_blocking(false));
+                eth_error("Ethernet_dhcp", _eth->set_dhcp(message.DHCP));
+                if(!message.DHCP) eth_error("Ethernet_static", _eth->set_network(SocketAddress(message.IP.c_str()), SocketAddress("255.255.255.0"), SocketAddress("192.168.1.1")));
+                _eth->attach(callback(this, &Transmission::eth_event));
+                eth_error("Ethernet_connect", _eth->connect());
             break;
-            case NSAPI_STATUS_CONNECTING:
-                if(message.status == RED_DISCONNECTED)
-                {
-                    eth_status("Ethernet_connect", NSAPI_STATUS_CONNECTING);
-                    message.status = YELLOW_CONNECTING;
-                    _eth->attach(callback(this, &Transmission::eth_event));
-                }
-            break;
-            case NSAPI_STATUS_GLOBAL_UP:    return message.CONNECT; break;
-            default:                                                break;
+            case NSAPI_STATUS_GLOBAL_UP: return message.CONNECT;break;
+            default:                                            break;
         }
     }
     else if(_eth->get_connection_status() != NSAPI_STATUS_DISCONNECTED) eth_error("Ethernet_disconnect", _eth->disconnect());
@@ -109,14 +95,14 @@
                     _serverTCP.set_blocking(false);
                     _serverTCP.sigio(callback(this, &Transmission::serverTCP_event));
                     message.CONNECT = true;
-                    if(_init != NULL) _queue.call(_init);
+                    if(_init != NULL) _queue->call(_init);
                 }
     return message.CONNECT;
 }
 
 void Transmission::serverTCP_event(void)
 {
-    _queue.call(this, &Transmission::serverTCP_accept);
+    _queue->call(this, &Transmission::serverTCP_accept);
 }
 
 void Transmission::serverTCP_accept(void)
@@ -129,7 +115,7 @@
         switch(ack)
         {
             case NSAPI_ERROR_OK:
-                _clientTCP->set_timeout(REQUEST_TIMEOUT);
+                _clientTCP->set_timeout(message.TIMEOUT);   // config client bloquante avec timeout sinon limite de transmission a 1072 octets
                 message.status = BLUE_CLIENT;
             break;
             case NSAPI_ERROR_NO_CONNECTION:
@@ -155,36 +141,37 @@
     }
 }
 
+void Transmission::serial_event(void)
+{
+    static char buffer[TRANSMISSION_DEFAULT_BUFFER_SIZE] = {0};
+    static uint16_t size = 0;
+    char caractere;
+    #if MBED_MAJOR_VERSION > 5
+    _serial->read(&caractere, 1);
+    #else
+    caractere = _serial->getc();
+    #endif
+    if((caractere == '\n') || (caractere == '\r'))
+    {
+        buffer[size] = '\0';
+        size = 0;
+        if(_processing != NULL) _queue->call(_processing, buffer, SERIAL);
+    }
+    else if((caractere > 31) && (caractere < 127) && (size < (TRANSMISSION_DEFAULT_BUFFER_SIZE-2))) buffer[size++] = caractere;
+}
+
 Transmission::enum_trans_status Transmission::recv(void)
 {
-    if(eth_connect())
+    if(eth_connect() && (message.status == BLUE_CLIENT))
     {
-        char buffer[1072] = {0};
+        char buffer[TRANSMISSION_DEFAULT_BUFFER_SIZE] = {0};
         nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK, size = 0;
-        if(message.status == BLUE_CLIENT) while((ack = _clientTCP->recv(&buffer[size], 1072-size)) > NSAPI_ERROR_OK) size += ack;
+        while((ack = _clientTCP->recv(&buffer[size], TRANSMISSION_DEFAULT_BUFFER_SIZE-size)) > NSAPI_ERROR_OK) size += ack;
         if(ack < NSAPI_ERROR_WOULD_BLOCK) eth_error("clientTCP_recv", ack);
         if(!size) message.BREAK = ((ack == NSAPI_ERROR_OK) || (ack == NSAPI_ERROR_NO_CONNECTION));
         for(int i = 0; i < size; i++) if(buffer[i] == '\n') buffer[i] = ';';
         if(_processing != NULL) _processing(buffer, TCP);
     }
-    if(_serial != NULL)
-    {
-        if(_serial->readable())
-        {
-            char caractere;
-            #if MBED_MAJOR_VERSION > 5
-            _serial->read(&caractere, 1);
-            #else
-            caractere = _serial->getc();
-            #endif
-            if((caractere == '\n') || (caractere == '\r'))
-            {
-                if(_processing != NULL) _processing(message.serial, SERIAL);
-                message.serial.clear();
-            }
-            else if((caractere > 31) && (caractere < 127)) message.serial += caractere;
-        }
-    }
     return message.status;
 }
 
@@ -217,22 +204,22 @@
     return ack;
 }
 
-bool Transmission::smtp(const char* MAIL, const char* FROM, const char* SUBJECT, const char* DATA)
+bool Transmission::smtp(const char* MAIL, const char* FROM, const char* SUBJECT, const char* DATA, const char* SERVER)
 {
     if(_eth == NULL) return false;
     if((!message.DHCP) || (_eth->get_connection_status() != NSAPI_STATUS_GLOBAL_UP)) return false;
     TCPSocket clientSMTP;
-    clientSMTP.set_timeout(REQUEST_TIMEOUT*20);
-    const string sMAIL(MAIL), sFROM(FROM), sSUBJECT(SUBJECT), sDATA(DATA), sTO(sMAIL.substr(0, sMAIL.find("@")));
-    const string smtpParams[][7] = {{ "", "HELO Mbed " + sFROM + "\r\n", "MAIL FROM: <Mbed." + sFROM + "@UNIVERSITE-PARIS-SACLAY.FR>\r\n", "RCPT TO: <" + sMAIL + ">\r\n", "DATA\r\n", "From: \"Mbed " + sFROM + "\" <Mbed." + sFROM + "@UNIVERSITE-PARIS-SACLAY.FR>\r\nTo: \"" + sTO + "\" <" + sMAIL + ">\r\nSubject:" + sSUBJECT + "\r\n" + sDATA + "\r\n.\r\n", "QUIT\r\n" },
+    clientSMTP.set_timeout(2000);
+    string sMAIL(MAIL), sFROM(FROM), sSUBJECT(SUBJECT), sDATA(DATA), sTO(sMAIL.substr(0, sMAIL.find("@")));
+    string smtpParams[][7] = {{ "", "HELO Mbed " + sFROM + "\r\n", "MAIL FROM: <Mbed." + sFROM + "@UNIVERSITE-PARIS-SACLAY.FR>\r\n", "RCPT TO: <" + sMAIL + ">\r\n", "DATA\r\n", "From: \"Mbed " + sFROM + "\" <Mbed." + sFROM + "@UNIVERSITE-PARIS-SACLAY.FR>\r\nTo: \"" + sTO + "\" <" + sMAIL + ">\r\nSubject:" + sSUBJECT + "\r\n" + sDATA + "\r\n\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])
+        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; }
+            if(code.empty()) { if(eth_error("clientSMTP_connect", clientSMTP.connect(SocketAddress(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;
@@ -243,27 +230,27 @@
     }
     if(sFROM.empty()) return code == "220250250250221";
     #if MBED_MAJOR_VERSION > 5
-    else if(code != "220250250250354250221") _queue.call_in(60s, this, &Transmission::smtp, MAIL, FROM, SUBJECT, DATA);
+    else if(code != "220250250250354250221") _queue->call_in(60s, this, &Transmission::smtp, MAIL, FROM, SUBJECT, DATA, SERVER);
     #else
-    else if(code != "220250250250354250221") _queue.call_in(60000, this, &Transmission::smtp, MAIL, FROM, SUBJECT, DATA);
+    else if(code != "220250250250354250221") _queue->call_in(60000, this, &Transmission::smtp, MAIL, FROM, SUBJECT, DATA, SERVER);
     #endif
     return code == "220250250250354250221";
 }
 
-time_t Transmission::ntp(const char* ADDRESS)
+time_t Transmission::ntp(const char* SERVER)
 {
     if(_eth == NULL) return 0;
     if((!message.DHCP) || (_eth->get_connection_status() != NSAPI_STATUS_GLOBAL_UP)) return 0;
     time_t timeStamp = 0;
     UDPSocket clientNTP;
-    clientNTP.set_timeout(REQUEST_TIMEOUT*20);
+    clientNTP.set_timeout(2000);
     if(eth_error("clientNTP_open", clientNTP.open(_eth)) == NSAPI_ERROR_OK)
     {
-        string sADDRESS(ADDRESS);
         uint32_t buffer[12] = { 0b11011, 0 };  // VN = 3 & Mode = 3
-        SocketAddress address(NTP_SERVER, 123);
-        if(!sADDRESS.empty()) eth_error("eth_gethostbyname", _eth->gethostbyname(sADDRESS.c_str(), &address));
-        if(eth_error("clientNTP_send", clientNTP.sendto(address, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK)
+        SocketAddress server(SERVER, 123);
+        string sSERVER(SERVER);
+        if(sSERVER != TRANSMISSION_DEFAULT_NTP_SERVER) eth_error("eth_gethostbyname", _eth->gethostbyname(sSERVER.c_str(), &server));
+        if(eth_error("clientNTP_send", clientNTP.sendto(server, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK)
         {
             if(eth_error("clientNTP_recv", clientNTP.recvfrom(NULL, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK)
             {
@@ -281,7 +268,8 @@
 
 intptr_t Transmission::eth_status(const string& source, const intptr_t& code)
 {
-    stringstream message;
+    #ifndef NDEBUG
+    ostringstream message;
     message << "\n" << source << "[" << code;
     switch(code)
     {
@@ -291,7 +279,6 @@
         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;
     }
-    #ifndef NDEBUG
     _serial->write(message.str().c_str(), message.str().size());
     #endif
     return code;
@@ -299,7 +286,8 @@
 
 nsapi_error_t Transmission::eth_error(const string& source, const nsapi_error_t& code)
 {
-    stringstream message;
+    #ifndef NDEBUG
+    ostringstream message;
     message << "\n" << source << "[" << code;
     switch(code)
     {
@@ -326,7 +314,6 @@
         case NSAPI_ERROR_BUSY:                  message << "] NSAPI_ERROR_BUSY               < device is busy and cannot accept new operation >";   break;
         default:                                message << "] NSAPI_ERROR                    < unknow code >";                                      break;
     }
-    #ifndef NDEBUG
     if(code < NSAPI_ERROR_OK) _serial->write(message.str().c_str(), message.str().size());
     #endif
     return code;