Y SI / lib_Transmission

Dependents:   lib_Transmission_Serial_example 2022_TICE_Electrolyse lib_Transmission_TCP_example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lib_Transmission.cpp Source File

lib_Transmission.cpp

00001 #include "lib_Transmission.h"
00002 
00003 Transmission::Transmission(
00004     #if MBED_MAJOR_VERSION > 5
00005     UnbufferedSerial    *serial,
00006     #else
00007     Serial              *serial,
00008     #endif
00009     USBCDC              *usb,
00010     EthernetInterface   *eth,
00011     string              (*processing)(string),
00012     void                (*ethup)(void),
00013     bool                caseIgnore)
00014     :_serial(serial), _usb(usb), _eth(eth), _processing(processing), _ethup(ethup), _caseIgnore(caseIgnore)
00015 {
00016     if(_serial) _serial->attach(callback(this, &Transmission::serial_event));
00017     _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
00018     _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
00019 }
00020 
00021 Transmission::Transmission(
00022     #if MBED_MAJOR_VERSION > 5
00023     UnbufferedSerial    *serial,
00024     #else
00025     Serial              *serial,
00026     #endif
00027     USBCDC              *usb,
00028     string              (*processing)(string),
00029     bool                caseIgnore)
00030     :_serial(serial), _usb(usb), _processing(processing), _caseIgnore(caseIgnore)
00031 {
00032     if(_serial) _serial->attach(callback(this, &Transmission::serial_event));
00033     _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
00034     _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
00035 }
00036 
00037 Transmission::Transmission(
00038     #if MBED_MAJOR_VERSION > 5
00039     UnbufferedSerial    *serial,
00040     #else
00041     Serial              *serial,
00042     #endif
00043     EthernetInterface   *eth,
00044     string              (*processing)(string),
00045     void                (*ethup)(void),
00046     bool                caseIgnore)
00047     :_serial(serial), _eth(eth), _processing(processing), _ethup(ethup), _caseIgnore(caseIgnore)
00048 {
00049     if(_serial) _serial->attach(callback(this, &Transmission::serial_event));
00050     _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
00051     _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
00052 }
00053 
00054 Transmission::Transmission(
00055     #if MBED_MAJOR_VERSION > 5
00056     UnbufferedSerial    *serial,
00057     #else
00058     Serial              *serial,
00059     #endif
00060     string              (*processing)(string),
00061     bool                caseIgnore)
00062     :_serial(serial), _processing(processing), _caseIgnore(caseIgnore)
00063 {
00064     if(_serial) _serial->attach(callback(this, &Transmission::serial_event));
00065     _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
00066     _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
00067 }
00068 
00069 Transmission::Transmission(
00070     USBCDC              *usb,
00071     EthernetInterface   *eth,
00072     string              (*processing)(string),
00073     void                (*ethup)(void),
00074     bool                caseIgnore)
00075     :_usb(usb), _eth(eth), _processing(processing), _ethup(ethup), _caseIgnore(caseIgnore)
00076 {
00077     _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
00078     _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
00079 }
00080 
00081 Transmission::Transmission(
00082     EthernetInterface   *eth,
00083     string              (*processing)(string),
00084     void                (*ethup)(void),
00085     bool                caseIgnore)
00086     :_eth(eth), _processing(processing), _ethup(ethup), _caseIgnore(caseIgnore)
00087 {
00088     _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
00089     _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
00090 }
00091     
00092 Transmission::Transmission(
00093     USBCDC              *usb,
00094     string              (*processing)(string),
00095     bool                caseIgnore)
00096     :_usb(usb), _processing(processing), _caseIgnore(caseIgnore)
00097 {}
00098 
00099 string Transmission::ip(string ip)
00100 {
00101     if(!_eth) return "0.0.0.0:0";
00102     ostringstream address;
00103     SocketAddress socket;
00104     _eth->get_ip_address(&socket);
00105     address << (socket.get_ip_address()?socket.get_ip_address():"0.0.0.0") << ":" << message.PORT;
00106     if(ip == address.str())
00107     {
00108         _eth->get_netmask(&socket);
00109         address << " " << (socket.get_ip_address()?socket.get_ip_address():"0.0.0.0");
00110         _eth->get_gateway(&socket);
00111         address << " " << (socket.get_ip_address()?socket.get_ip_address():"0.0.0.0");
00112     }
00113     return address.str();
00114 }
00115 
00116 string Transmission::ip(const bool set, const char* ip, const uint16_t port, const char* mask, const char* gateway, const uint16_t timeout)
00117 {
00118     if(!_eth) return "00:00:00:00:00:00";
00119     if(message.SET && set)
00120     {
00121         if(message.PORT != port)
00122         {
00123             message.CONNECT = false;
00124             _serverTCP.sigio(NULL);
00125             eth_error("serverTCP_close", _serverTCP.close());
00126         }
00127         eth_error("Ethernet_disconnect", _eth->disconnect());
00128     }
00129     message.SET = set;
00130     message.IP = ip;
00131     message.PORT = port;
00132     message.MASK = mask;
00133     message.GATEWAY = gateway;
00134     message.TIMEOUT = timeout;
00135     message.DHCP = message.IP.empty();
00136     eth_connect();
00137     string MAC(_eth->get_mac_address()?_eth->get_mac_address():"00:00:00:00:00:00");
00138     for(char &c : MAC) if((c >= 'a') && (c <= 'z')) c += 'A'-'a';
00139     return MAC;
00140 }
00141 
00142 string Transmission::client(void)
00143 {
00144     if(message.status == BLUE_CLIENT)
00145     {
00146         SocketAddress peer;
00147         _clientTCP->getpeername(&peer);
00148         ostringstream ssend;
00149         ssend << peer.get_ip_address() << ":" << peer.get_port();
00150         return ssend.str();
00151     }
00152     return "0.0.0.0:0";
00153 }
00154 
00155 bool Transmission::eth_connect(void)
00156 {
00157     if(!_eth) return false;
00158     if(message.SET)
00159     {
00160         switch(_eth->get_connection_status())
00161         {
00162             case NSAPI_STATUS_DISCONNECTED:
00163                 eth_error("Ethernet_blocking", _eth->set_blocking(false));
00164                 eth_error("Ethernet_dhcp", _eth->set_dhcp(message.DHCP));
00165                 if(!message.DHCP) eth_error("Ethernet_static", _eth->set_network(SocketAddress(message.IP.c_str()), SocketAddress(message.MASK.c_str()), SocketAddress(message.GATEWAY.c_str())));
00166                 _eth->attach(callback(this, &Transmission::eth_event));
00167                 eth_error("Ethernet_connect", _eth->connect()); break;
00168             case NSAPI_STATUS_GLOBAL_UP: return message.CONNECT;break;
00169             default:                                            break;
00170         }
00171     }
00172     else if(_eth->get_connection_status() != NSAPI_STATUS_DISCONNECTED) eth_error("Ethernet_disconnect", _eth->disconnect());
00173     return false;
00174 }
00175 
00176 void Transmission::eth_event(nsapi_event_t status, intptr_t param)
00177 {
00178     eth_status("Ethernet_event", param);
00179     switch(param)
00180     {
00181         case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED;      break;
00182         case NSAPI_STATUS_CONNECTING:if(message.status == BLUE_CLIENT) eth_error("clientTCP_disconnect", _clientTCP->close());
00183                                         message.status = YELLOW_CONNECTING;     break;
00184         case NSAPI_STATUS_GLOBAL_UP:    message.status = GREEN_GLOBAL_UP;
00185                                         if(!message.CONNECT) serverTCP_connect();
00186                                         else                 serverTCP_event(); break;
00187         default:                                                                break;
00188     }
00189 }
00190 
00191 bool Transmission::serverTCP_connect(void)
00192 {
00193     if(!message.CONNECT)
00194         if(eth_error("serverTCP_open", _serverTCP.open(_eth)) == NSAPI_ERROR_OK)
00195             if(eth_error("serverTCP_bind", _serverTCP.bind(message.PORT)) == NSAPI_ERROR_OK)
00196                 if(eth_error("serverTCP_listen", _serverTCP.listen()) == NSAPI_ERROR_OK)
00197                 {
00198                     _serverTCP.set_blocking(false);
00199                     _serverTCP.sigio(callback(this, &Transmission::serverTCP_event));
00200                     message.CONNECT = true;
00201                     if(_ethup) _queue.call(_ethup);
00202                 }
00203     return message.CONNECT;
00204 }
00205 
00206 void Transmission::serverTCP_event(void)
00207 {
00208     _queue.call(this, &Transmission::serverTCP_accept);
00209 }
00210 
00211 void Transmission::serverTCP_accept(void)
00212 {
00213     if(message.status == GREEN_GLOBAL_UP)
00214     {
00215         nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
00216         message.status = MAGENTA_ACCEPT;
00217         _clientTCP = _serverTCP.accept(&ack);
00218         switch(ack)
00219         {
00220             case NSAPI_ERROR_OK:
00221                 _clientTCP->set_timeout(message.TIMEOUT);   // config client bloquante avec timeout sinon limite de transmission a 1072 octets
00222                 message.status = BLUE_CLIENT;
00223             break;
00224             case NSAPI_ERROR_NO_CONNECTION:
00225                 eth_state();
00226                 serverTCP_event();
00227             break;
00228             default:
00229                 eth_state();
00230                 if(ack < NSAPI_ERROR_WOULD_BLOCK) eth_error("serverTCP_accept", ack);
00231             break;
00232         }
00233     }
00234 }
00235 
00236 void Transmission::eth_state(void)
00237 {
00238     switch(_eth->get_connection_status())
00239     {
00240         case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED;  break;
00241         case NSAPI_STATUS_CONNECTING:   message.status = YELLOW_CONNECTING; break;
00242         case NSAPI_STATUS_GLOBAL_UP:    message.status = GREEN_GLOBAL_UP;   break;
00243         default:                                                            break;
00244     }
00245 }
00246 
00247 void Transmission::serial_event(void)
00248 {
00249     static char buffer[TRANSMISSION_BUFFER_SIZE] = {0};
00250     static uint16_t size = 0;
00251     char caractere;
00252     _serial->read(&caractere, 1);
00253     if(caractere == '\n')
00254     {
00255         buffer[size] = '\0';
00256         size = 0;
00257         if(_processing) _queue.call(this, &Transmission::preprocessing, buffer, SERIAL_DELIVERY);
00258     }
00259     else if((caractere > 31) && (caractere < 127))
00260     {
00261         if(size >= (TRANSMISSION_BUFFER_SIZE-1))
00262             for(int i = 0; i < size; i++) buffer[i] = (i < size-1)?buffer[i+1]:caractere;
00263         else buffer[size++] = caractere;
00264     }
00265 }
00266 
00267 Transmission::enum_trans_status Transmission::recv(void)
00268 {
00269     if(_usb)
00270     {
00271         if(_usb->ready())
00272         {
00273             uint8_t buffer[TRANSMISSION_BUFFER_SIZE] = {0};
00274             uint32_t ack = 0, size = 0;
00275             do{
00276                 ack = NSAPI_ERROR_OK;
00277                 _usb->receive_nb(&buffer[size], 1, &ack);   // un peu plus rapide sur les petits transferts
00278                 size += ack;
00279             }while((ack > NSAPI_ERROR_OK) && (size < TRANSMISSION_BUFFER_SIZE-1) && (buffer[size-ack] != '\n'));
00280             if(size && _processing) preprocessing((char *)buffer, USB_DELIVERY);
00281         } else _usb->connect();
00282     }
00283     if(eth_connect() && (message.status == BLUE_CLIENT))
00284     {
00285         char buffer[TRANSMISSION_BUFFER_SIZE] = {0};
00286         nsapi_error_t ack = 0, size = 0;
00287         do{
00288             ack = _clientTCP->recv(&buffer[size], TRANSMISSION_BUFFER_SIZE-size);
00289             if(ack > NSAPI_ERROR_OK) size += ack;
00290         }while((ack == 536) && (size < TRANSMISSION_BUFFER_SIZE));
00291         if(ack < NSAPI_ERROR_WOULD_BLOCK) eth_error("clientTCP_recv", ack);
00292         if((ack == NSAPI_ERROR_OK) || (ack == NSAPI_ERROR_NO_CONNECTION))
00293         {
00294             eth_error("clientTCP_disconnect", _clientTCP->close());
00295             eth_state();
00296             serverTCP_event();
00297         }
00298         if(size && _processing) preprocessing(buffer, TCP_DELIVERY);
00299     }
00300     else if(!_usb) for(int i = 0; ((i < 10) && (message.status != BLUE_CLIENT)); i++) ThisThread::sleep_for(10ms);
00301     return message.status;
00302 }
00303 
00304 void Transmission::preprocessing(char *buffer, const enum_trans_delivery delivery)
00305 {
00306     string cmd(buffer);
00307     for(char &c : cmd) if(_caseIgnore && (c >= 'a') && (c <= 'z')) c += 'A'-'a';
00308     if((cmd.find("HOST: ") != string::npos) || (cmd.find("Host: ") != string::npos))
00309         send(_processing(cmd), HTTP_DELIVERY);
00310     else if(!cmd.empty() && (cmd[0] != 22))
00311     {
00312         for(char &c : cmd) if(c == '\n') c = ';';
00313         istringstream srecv(cmd);
00314         string ssend;
00315         while(getline(srecv, cmd, ';'))
00316         {
00317             string process = _processing(cmd);
00318             if(!process.empty()) ssend += (ssend.size() > 0)?(' '+process):process;
00319         }
00320         send(ssend, delivery);
00321     }
00322 }
00323 
00324 nsapi_error_t Transmission::send(const string& buffer, const enum_trans_delivery& delivery)
00325 {
00326     nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
00327     string ssend(buffer+"\n");
00328     if(_usb && !buffer.empty() && ((delivery == USB_DELIVERY) || (delivery == ANY_DELIVERY)))
00329     {
00330         _usb->connect();
00331         if(_usb->ready()) _usb->send((uint8_t*)ssend.c_str(), ssend.size());
00332     }
00333     if(_serial  && !buffer.empty() && ((delivery == SERIAL_DELIVERY) || (delivery == ANY_DELIVERY)))
00334         ack = _serial->write(ssend.c_str(), ssend.length());
00335     if(_eth && ((delivery == TCP_DELIVERY) || (delivery == HTTP_DELIVERY) || (delivery == ANY_DELIVERY)))
00336     {
00337         if((message.status == BLUE_CLIENT) && !buffer.empty())
00338             eth_error("clientTCP_send", ack = _clientTCP->send(ssend.c_str(), ssend.size()));
00339         if(delivery == HTTP_DELIVERY)
00340         {
00341             eth_error("clientTCP_disconnect", _clientTCP->close());
00342             eth_state();
00343             serverTCP_event();
00344         }
00345     }
00346     return ack;
00347 }
00348 
00349 string Transmission::get(const string& ssend, const string& server, const int& port)
00350 {
00351     char buffer[256] = {0};
00352     if(!server.empty())
00353     {
00354         TCPSocket clientTCP;
00355         clientTCP.set_timeout(message.TIMEOUT);
00356         if(eth_error("clientTCP_open", clientTCP.open(_eth)) == NSAPI_ERROR_OK)
00357         {
00358             if(eth_error("clientTCP_connect", clientTCP.connect(SocketAddress(server.c_str(), port))) == NSAPI_ERROR_OK)
00359             {
00360                 eth_error("clientTCP_send", clientTCP.send(ssend.c_str(), ssend.size()));
00361                 eth_error("clientTCP_recv", clientTCP.recv(buffer, 256));
00362             }
00363         }
00364         eth_error("clientTCP_close", clientTCP.close());
00365     }
00366     return buffer;
00367 }
00368 
00369 bool Transmission::smtp(string mail, string from, string subject, string data, const char* server)
00370 {
00371     if((!_eth) || (!message.DHCP) || (_eth->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) || mail.empty()) return false;
00372     string code, smtpParams[][7] = {{ "", "HELO Mbed " + from + "\r\n", "MAIL FROM:<Mbed." + from + "@UNIVERSITE-PARIS-SACLAY.FR>\r\n", "RCPT TO:<" + mail + ">\r\n", "DATA\r\n",
00373                                       "From:\"Mbed " + from + "\" <Mbed." + from + "@UNIVERSITE-PARIS-SACLAY.FR>\r\nTo:<" + mail + ">\r\nSubject:" + subject + "\r\nMessage-Id:<" + mail.substr(0, mail.find("@")) + "." + to_string(time(NULL)) + mail.substr(mail.find("@")) + ">\r\n" + data + "\r\n.\r\n", "QUIT\r\n" },
00374                                     { "", "HELO Mbed\r\n", "MAIL FROM: <Mbed>\r\n","RCPT TO: <" + mail + ">\r\n", "QUIT\r\n" }};
00375     TCPSocket clientSMTP;
00376     clientSMTP.set_timeout(message.TIMEOUT);
00377     if(eth_error("clientSMTP_open", clientSMTP.open(_eth)) == NSAPI_ERROR_OK)
00378     {
00379         for(const string& ssend : smtpParams[from.empty()?1:0])
00380         {
00381             
00382             char buffer[64] = {0};
00383             if(code.empty()) { if(eth_error("clientSMTP_connect", clientSMTP.connect(SocketAddress(server, 25))) < NSAPI_ERROR_OK)  break; }
00384             else if(eth_error("clientSMTP_send", clientSMTP.send(ssend.c_str(), ssend.size())) < NSAPI_ERROR_OK)                    break;
00385             if(eth_error("clientSMTP_recv", clientSMTP.recv(buffer, 64)) < NSAPI_ERROR_OK)                                          break;
00386             buffer[3] = 0;
00387             code += buffer;
00388             if(ssend == "QUIT\r\n") break;
00389         }
00390         eth_error("clientSMTP_close", clientSMTP.close());
00391     }
00392     if(from.empty()) return code == "220250250250221";
00393     else if((code == "220250250250354250221") || (code == "220250250250354")) return true;
00394     else
00395     {
00396         #if MBED_MAJOR_VERSION > 5
00397         _queue.call_in(60s, this, &Transmission::smtp, mail, from, subject, data, server);
00398         #else
00399         _queue.call_in(60000, this, &Transmission::smtp, mail, from, subject, data, server);
00400         #endif
00401     }
00402     return false;
00403 }
00404 
00405 time_t Transmission::ntp(const char* server)
00406 {
00407     if(!_eth) return 0;
00408     if((!message.DHCP) || (_eth->get_connection_status() != NSAPI_STATUS_GLOBAL_UP)) return time(NULL);
00409     time_t timeStamp = 0;
00410     UDPSocket clientNTP;
00411     clientNTP.set_timeout(message.TIMEOUT);
00412     if(eth_error("clientNTP_open", clientNTP.open(_eth)) == NSAPI_ERROR_OK)
00413     {
00414         uint32_t buffer[12] = { 0b11011, 0 };  // VN = 3 & Mode = 3
00415         SocketAddress aSERVER(server, 123);
00416         string sSERVER(server);
00417         if(sSERVER != TRANSMISSION_NTP_SERVER) eth_error("eth_gethostbyname", _eth->gethostbyname(sSERVER.c_str(), &aSERVER));
00418         if(eth_error("clientNTP_send", clientNTP.sendto(aSERVER, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK)
00419         {
00420             if(eth_error("clientNTP_recv", clientNTP.recvfrom(NULL, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK)
00421             {
00422                 timeStamp = ((buffer[10] & 0xFF) << 24) | ((buffer[10] & 0xFF00) << 8) | ((buffer[10] & 0xFF0000UL) >> 8) | ((buffer[10] & 0xFF000000UL) >> 24);
00423                 timeStamp -= 2208985200U;   // 01/01/1970 Europe
00424                 struct tm * tmTimeStamp = localtime(&timeStamp);
00425                 if (((tmTimeStamp->tm_mon > 2) && (tmTimeStamp->tm_mon < 10)) || ((tmTimeStamp->tm_mon == 2) && ((tmTimeStamp->tm_mday - tmTimeStamp->tm_wday) > 24)) || ((tmTimeStamp->tm_mon == 9) && ((tmTimeStamp->tm_mday - tmTimeStamp->tm_wday) < 25)))
00426                     timeStamp += 3600;  // DST starts last Sunday of March; 2am (1am UTC), DST ends last Sunday of october; 3am (2am UTC)    
00427             }
00428         }
00429         eth_error("clientNTP_close", clientNTP.close());
00430     }
00431     return timeStamp;
00432 }
00433 
00434 intptr_t Transmission::eth_status(const string& source, const intptr_t& code)
00435 {
00436     #ifndef NDEBUG
00437     ostringstream message;
00438     message << "\n" << source << "[" << code << "] ";
00439     switch(code)
00440     {
00441         case NSAPI_STATUS_LOCAL_UP:             message << "NSAPI_STATUS_LOCAL_UP          < local IP address set >";       break;
00442         case NSAPI_STATUS_GLOBAL_UP:            message << "NSAPI_STATUS_GLOBAL_UP         < global IP address set >";      break;
00443         case NSAPI_STATUS_DISCONNECTED:         message << "NSAPI_STATUS_DISCONNECTED      < no connection to network >";   break;
00444         case NSAPI_STATUS_CONNECTING:           message << "NSAPI_STATUS_CONNECTING        < connecting to network >";      break;
00445         case NSAPI_STATUS_ERROR_UNSUPPORTED:    message << "NSAPI_STATUS_ERROR_UNSUPPORTED < unsupported functionality >";  break;
00446     }
00447     _serial->write(message.str().c_str(), message.str().size());
00448     #endif
00449     return code;
00450 }
00451 
00452 nsapi_error_t Transmission::eth_error(const string& source, const nsapi_error_t& code)
00453 {
00454     #ifndef NDEBUG
00455     ostringstream message;
00456     message << "\n" << source << "[" << code << "] ";
00457     switch(code)
00458     {
00459         case NSAPI_ERROR_OK:                    message << "NSAPI_ERROR_OK                 < no error >";                                           break;
00460         case NSAPI_ERROR_WOULD_BLOCK:           message << "NSAPI_ERROR_WOULD_BLOCK        < no data is not available but call is non-blocking >";  break;
00461         case NSAPI_ERROR_UNSUPPORTED:           message << "NSAPI_ERROR_UNSUPPORTED        < unsupported functionality >";                          break;
00462         case NSAPI_ERROR_PARAMETER:             message << "NSAPI_ERROR_PARAMETER          < invalid configuration >";                              break;
00463         case NSAPI_ERROR_NO_CONNECTION:         message << "NSAPI_ERROR_NO_CONNECTION      < not connected to a network >";                         break;
00464         case NSAPI_ERROR_NO_SOCKET:             message << "NSAPI_ERROR_NO_SOCKET          < socket not available for use >";                       break;
00465         case NSAPI_ERROR_NO_ADDRESS:            message << "NSAPI_ERROR_NO_ADDRESS         < IP address is not known >";                            break;
00466         case NSAPI_ERROR_NO_MEMORY:             message << "NSAPI_ERROR_NO_MEMORY          < memory resource not available >";                      break;
00467         case NSAPI_ERROR_NO_SSID:               message << "NSAPI_ERROR_NO_SSID            < ssid not found >";                                     break;
00468         case NSAPI_ERROR_DNS_FAILURE:           message << "NSAPI_ERROR_DNS_FAILURE        < DNS failed to complete successfully >";                break;
00469         case NSAPI_ERROR_DHCP_FAILURE:          message << "NSAPI_ERROR_DHCP_FAILURE       < DHCP failed to complete successfully >";               break;
00470         case NSAPI_ERROR_AUTH_FAILURE:          message << "NSAPI_ERROR_AUTH_FAILURE       < connection to access point failed >";                  break;
00471         case NSAPI_ERROR_DEVICE_ERROR:          message << "NSAPI_ERROR_DEVICE_ERROR       < failure interfacing with the network processor >";     break;
00472         case NSAPI_ERROR_IN_PROGRESS:           message << "NSAPI_ERROR_IN_PROGRESS        < operation (eg connect) in progress >";                 break;
00473         case NSAPI_ERROR_ALREADY:               message << "NSAPI_ERROR_ALREADY            < operation (eg connect) already in progress >";         break;
00474         case NSAPI_ERROR_IS_CONNECTED:          message << "NSAPI_ERROR_IS_CONNECTED       < socket is already connected >";                        break;
00475         case NSAPI_ERROR_CONNECTION_LOST:       message << "NSAPI_ERROR_CONNECTION_LOST    < connection lost >";                                    break;
00476         case NSAPI_ERROR_CONNECTION_TIMEOUT:    message << "NSAPI_ERROR_CONNECTION_TIMEOUT < connection timed out >";                               break;
00477         case NSAPI_ERROR_ADDRESS_IN_USE:        message << "NSAPI_ERROR_ADDRESS_IN_USE     < Address already in use >";                             break;
00478         case NSAPI_ERROR_TIMEOUT:               message << "NSAPI_ERROR_TIMEOUT            < operation timed out >";                                break;
00479         case NSAPI_ERROR_BUSY:                  message << "NSAPI_ERROR_BUSY               < device is busy and cannot accept new operation >";     break;
00480         default:                                message << "NSAPI_ERROR                    < unknow code >";                                        break;
00481     }
00482     if(code < NSAPI_ERROR_OK) _serial->write(message.str().c_str(), message.str().size());
00483     #endif
00484     return code;
00485 }