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

Committer:
YSI
Date:
Wed Jan 05 12:48:55 2022 +0000
Revision:
29:0d321d298d37
Parent:
28:24f7e0ddf6f5
serial_event out of memory debug.; smtp error retry for ever.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
YSI 0:2fc6fc3b5e15 1 #include "lib_Transmission.h"
YSI 18:15778c8a97a1 2
YSI 18:15778c8a97a1 3 Transmission::Transmission(
YSI 18:15778c8a97a1 4 #if MBED_MAJOR_VERSION > 5
YSI 18:15778c8a97a1 5 UnbufferedSerial *serial,
YSI 18:15778c8a97a1 6 #else
YSI 18:15778c8a97a1 7 Serial *serial,
YSI 18:15778c8a97a1 8 #endif
YSI 18:15778c8a97a1 9 USBCDC *usb,
YSI 18:15778c8a97a1 10 EthernetInterface *eth,
YSI 18:15778c8a97a1 11 string (*processing)(string),
YSI 18:15778c8a97a1 12 void (*ethup)(void),
YSI 18:15778c8a97a1 13 bool caseIgnore)
YSI 18:15778c8a97a1 14 :_serial(serial), _usb(usb), _eth(eth), _processing(processing), _ethup(ethup), _caseIgnore(caseIgnore)
YSI 18:15778c8a97a1 15 {
YSI 18:15778c8a97a1 16 if(_serial) _serial->attach(callback(this, &Transmission::serial_event));
YSI 25:01db56f04262 17 _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
YSI 22:e99892e6fd8d 18 _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
YSI 18:15778c8a97a1 19 }
YSI 18:15778c8a97a1 20
YSI 18:15778c8a97a1 21 Transmission::Transmission(
YSI 18:15778c8a97a1 22 #if MBED_MAJOR_VERSION > 5
YSI 18:15778c8a97a1 23 UnbufferedSerial *serial,
YSI 18:15778c8a97a1 24 #else
YSI 18:15778c8a97a1 25 Serial *serial,
YSI 18:15778c8a97a1 26 #endif
YSI 18:15778c8a97a1 27 USBCDC *usb,
YSI 18:15778c8a97a1 28 string (*processing)(string),
YSI 18:15778c8a97a1 29 bool caseIgnore)
YSI 18:15778c8a97a1 30 :_serial(serial), _usb(usb), _processing(processing), _caseIgnore(caseIgnore)
YSI 18:15778c8a97a1 31 {
YSI 18:15778c8a97a1 32 if(_serial) _serial->attach(callback(this, &Transmission::serial_event));
YSI 25:01db56f04262 33 _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
YSI 22:e99892e6fd8d 34 _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
YSI 18:15778c8a97a1 35 }
YSI 0:2fc6fc3b5e15 36
YSI 14:9e3accc681c4 37 Transmission::Transmission(
YSI 14:9e3accc681c4 38 #if MBED_MAJOR_VERSION > 5
YSI 15:b2da6ab01a21 39 UnbufferedSerial *serial,
YSI 14:9e3accc681c4 40 #else
YSI 15:b2da6ab01a21 41 Serial *serial,
YSI 14:9e3accc681c4 42 #endif
YSI 15:b2da6ab01a21 43 EthernetInterface *eth,
YSI 15:b2da6ab01a21 44 string (*processing)(string),
YSI 18:15778c8a97a1 45 void (*ethup)(void),
YSI 15:b2da6ab01a21 46 bool caseIgnore)
YSI 18:15778c8a97a1 47 :_serial(serial), _eth(eth), _processing(processing), _ethup(ethup), _caseIgnore(caseIgnore)
YSI 0:2fc6fc3b5e15 48 {
YSI 16:3ef69ffede76 49 if(_serial) _serial->attach(callback(this, &Transmission::serial_event));
YSI 25:01db56f04262 50 _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
YSI 22:e99892e6fd8d 51 _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
YSI 18:15778c8a97a1 52 }
YSI 18:15778c8a97a1 53
YSI 18:15778c8a97a1 54 Transmission::Transmission(
YSI 15:b2da6ab01a21 55 #if MBED_MAJOR_VERSION > 5
YSI 15:b2da6ab01a21 56 UnbufferedSerial *serial,
YSI 15:b2da6ab01a21 57 #else
YSI 15:b2da6ab01a21 58 Serial *serial,
YSI 15:b2da6ab01a21 59 #endif
YSI 15:b2da6ab01a21 60 string (*processing)(string),
YSI 15:b2da6ab01a21 61 bool caseIgnore)
YSI 15:b2da6ab01a21 62 :_serial(serial), _processing(processing), _caseIgnore(caseIgnore)
YSI 15:b2da6ab01a21 63 {
YSI 16:3ef69ffede76 64 if(_serial) _serial->attach(callback(this, &Transmission::serial_event));
YSI 25:01db56f04262 65 _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
YSI 22:e99892e6fd8d 66 _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
YSI 21:59c0adcdfe9b 67 }
YSI 21:59c0adcdfe9b 68
YSI 21:59c0adcdfe9b 69 Transmission::Transmission(
YSI 21:59c0adcdfe9b 70 USBCDC *usb,
YSI 21:59c0adcdfe9b 71 EthernetInterface *eth,
YSI 21:59c0adcdfe9b 72 string (*processing)(string),
YSI 21:59c0adcdfe9b 73 void (*ethup)(void),
YSI 21:59c0adcdfe9b 74 bool caseIgnore)
YSI 21:59c0adcdfe9b 75 :_usb(usb), _eth(eth), _processing(processing), _ethup(ethup), _caseIgnore(caseIgnore)
YSI 21:59c0adcdfe9b 76 {
YSI 25:01db56f04262 77 _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
YSI 22:e99892e6fd8d 78 _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
YSI 15:b2da6ab01a21 79 }
YSI 15:b2da6ab01a21 80
YSI 15:b2da6ab01a21 81 Transmission::Transmission(
YSI 15:b2da6ab01a21 82 EthernetInterface *eth,
YSI 15:b2da6ab01a21 83 string (*processing)(string),
YSI 18:15778c8a97a1 84 void (*ethup)(void),
YSI 15:b2da6ab01a21 85 bool caseIgnore)
YSI 18:15778c8a97a1 86 :_eth(eth), _processing(processing), _ethup(ethup), _caseIgnore(caseIgnore)
YSI 15:b2da6ab01a21 87 {
YSI 25:01db56f04262 88 _evenThread = new Thread(osPriorityNormal, TRANSMISSION_THREAD_SIZE);
YSI 22:e99892e6fd8d 89 _evenThread->start(callback(&_queue, &EventQueue::dispatch_forever));
YSI 15:b2da6ab01a21 90 }
YSI 15:b2da6ab01a21 91
YSI 15:b2da6ab01a21 92 Transmission::Transmission(
YSI 15:b2da6ab01a21 93 USBCDC *usb,
YSI 15:b2da6ab01a21 94 string (*processing)(string),
YSI 15:b2da6ab01a21 95 bool caseIgnore)
YSI 18:15778c8a97a1 96 :_usb(usb), _processing(processing), _caseIgnore(caseIgnore)
YSI 18:15778c8a97a1 97 {}
YSI 15:b2da6ab01a21 98
YSI 22:e99892e6fd8d 99 string Transmission::ip(string ip)
YSI 21:59c0adcdfe9b 100 {
YSI 25:01db56f04262 101 if(!_eth) return "0.0.0.0:0";
YSI 21:59c0adcdfe9b 102 ostringstream address;
YSI 21:59c0adcdfe9b 103 SocketAddress socket;
YSI 21:59c0adcdfe9b 104 _eth->get_ip_address(&socket);
YSI 21:59c0adcdfe9b 105 address << (socket.get_ip_address()?socket.get_ip_address():"0.0.0.0") << ":" << message.PORT;
YSI 22:e99892e6fd8d 106 if(ip == address.str())
YSI 21:59c0adcdfe9b 107 {
YSI 21:59c0adcdfe9b 108 _eth->get_netmask(&socket);
YSI 21:59c0adcdfe9b 109 address << " " << (socket.get_ip_address()?socket.get_ip_address():"0.0.0.0");
YSI 21:59c0adcdfe9b 110 _eth->get_gateway(&socket);
YSI 21:59c0adcdfe9b 111 address << " " << (socket.get_ip_address()?socket.get_ip_address():"0.0.0.0");
YSI 21:59c0adcdfe9b 112 }
YSI 21:59c0adcdfe9b 113 return address.str();
YSI 21:59c0adcdfe9b 114 }
YSI 21:59c0adcdfe9b 115
YSI 22:e99892e6fd8d 116 string Transmission::ip(const bool set, const char* ip, const uint16_t port, const char* mask, const char* gateway, const uint16_t timeout)
YSI 3:7e15bf0a71f4 117 {
YSI 16:3ef69ffede76 118 if(!_eth) return "00:00:00:00:00:00";
YSI 22:e99892e6fd8d 119 if(message.SET && set)
YSI 3:7e15bf0a71f4 120 {
YSI 22:e99892e6fd8d 121 if(message.PORT != port)
YSI 3:7e15bf0a71f4 122 {
YSI 3:7e15bf0a71f4 123 message.CONNECT = false;
YSI 3:7e15bf0a71f4 124 _serverTCP.sigio(NULL);
YSI 3:7e15bf0a71f4 125 eth_error("serverTCP_close", _serverTCP.close());
YSI 3:7e15bf0a71f4 126 }
YSI 3:7e15bf0a71f4 127 eth_error("Ethernet_disconnect", _eth->disconnect());
YSI 3:7e15bf0a71f4 128 }
YSI 22:e99892e6fd8d 129 message.SET = set;
YSI 22:e99892e6fd8d 130 message.IP = ip;
YSI 22:e99892e6fd8d 131 message.PORT = port;
YSI 22:e99892e6fd8d 132 message.MASK = mask;
YSI 22:e99892e6fd8d 133 message.GATEWAY = gateway;
YSI 22:e99892e6fd8d 134 message.TIMEOUT = timeout;
YSI 3:7e15bf0a71f4 135 message.DHCP = message.IP.empty();
YSI 10:25e049353db5 136 eth_connect();
YSI 27:87c2a2a23d06 137 string MAC(_eth->get_mac_address()?_eth->get_mac_address():"00:00:00:00:00:00");
YSI 27:87c2a2a23d06 138 for(char &c : MAC) if((c >= 'a') && (c <= 'z')) c += 'A'-'a';
YSI 27:87c2a2a23d06 139 return MAC;
YSI 3:7e15bf0a71f4 140 }
YSI 3:7e15bf0a71f4 141
YSI 25:01db56f04262 142 string Transmission::client(void)
YSI 25:01db56f04262 143 {
YSI 25:01db56f04262 144 if(message.status == BLUE_CLIENT)
YSI 25:01db56f04262 145 {
YSI 25:01db56f04262 146 SocketAddress peer;
YSI 25:01db56f04262 147 _clientTCP->getpeername(&peer);
YSI 25:01db56f04262 148 ostringstream ssend;
YSI 25:01db56f04262 149 ssend << peer.get_ip_address() << ":" << peer.get_port();
YSI 25:01db56f04262 150 return ssend.str();
YSI 25:01db56f04262 151 }
YSI 25:01db56f04262 152 return "0.0.0.0:0";
YSI 25:01db56f04262 153 }
YSI 25:01db56f04262 154
YSI 0:2fc6fc3b5e15 155 bool Transmission::eth_connect(void)
YSI 0:2fc6fc3b5e15 156 {
YSI 16:3ef69ffede76 157 if(!_eth) return false;
YSI 10:25e049353db5 158 if(message.SET)
YSI 0:2fc6fc3b5e15 159 {
YSI 0:2fc6fc3b5e15 160 switch(_eth->get_connection_status())
YSI 0:2fc6fc3b5e15 161 {
YSI 0:2fc6fc3b5e15 162 case NSAPI_STATUS_DISCONNECTED:
YSI 14:9e3accc681c4 163 eth_error("Ethernet_blocking", _eth->set_blocking(false));
YSI 14:9e3accc681c4 164 eth_error("Ethernet_dhcp", _eth->set_dhcp(message.DHCP));
YSI 21:59c0adcdfe9b 165 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())));
YSI 14:9e3accc681c4 166 _eth->attach(callback(this, &Transmission::eth_event));
YSI 15:b2da6ab01a21 167 eth_error("Ethernet_connect", _eth->connect()); break;
YSI 14:9e3accc681c4 168 case NSAPI_STATUS_GLOBAL_UP: return message.CONNECT;break;
YSI 14:9e3accc681c4 169 default: break;
YSI 0:2fc6fc3b5e15 170 }
YSI 0:2fc6fc3b5e15 171 }
YSI 0:2fc6fc3b5e15 172 else if(_eth->get_connection_status() != NSAPI_STATUS_DISCONNECTED) eth_error("Ethernet_disconnect", _eth->disconnect());
YSI 0:2fc6fc3b5e15 173 return false;
YSI 0:2fc6fc3b5e15 174 }
YSI 0:2fc6fc3b5e15 175
YSI 0:2fc6fc3b5e15 176 void Transmission::eth_event(nsapi_event_t status, intptr_t param)
YSI 0:2fc6fc3b5e15 177 {
YSI 0:2fc6fc3b5e15 178 eth_status("Ethernet_event", param);
YSI 0:2fc6fc3b5e15 179 switch(param)
YSI 0:2fc6fc3b5e15 180 {
YSI 15:b2da6ab01a21 181 case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED; break;
YSI 4:9a4ab4f406ab 182 case NSAPI_STATUS_CONNECTING:if(message.status == BLUE_CLIENT) eth_error("clientTCP_disconnect", _clientTCP->close());
YSI 15:b2da6ab01a21 183 message.status = YELLOW_CONNECTING; break;
YSI 3:7e15bf0a71f4 184 case NSAPI_STATUS_GLOBAL_UP: message.status = GREEN_GLOBAL_UP;
YSI 15:b2da6ab01a21 185 if(!message.CONNECT) serverTCP_connect();
YSI 15:b2da6ab01a21 186 else serverTCP_event(); break;
YSI 15:b2da6ab01a21 187 default: break;
YSI 1:27f6baabb15e 188 }
YSI 1:27f6baabb15e 189 }
YSI 1:27f6baabb15e 190
YSI 1:27f6baabb15e 191 bool Transmission::serverTCP_connect(void)
YSI 1:27f6baabb15e 192 {
YSI 3:7e15bf0a71f4 193 if(!message.CONNECT)
YSI 3:7e15bf0a71f4 194 if(eth_error("serverTCP_open", _serverTCP.open(_eth)) == NSAPI_ERROR_OK)
YSI 3:7e15bf0a71f4 195 if(eth_error("serverTCP_bind", _serverTCP.bind(message.PORT)) == NSAPI_ERROR_OK)
YSI 3:7e15bf0a71f4 196 if(eth_error("serverTCP_listen", _serverTCP.listen()) == NSAPI_ERROR_OK)
YSI 1:27f6baabb15e 197 {
YSI 3:7e15bf0a71f4 198 _serverTCP.set_blocking(false);
YSI 3:7e15bf0a71f4 199 _serverTCP.sigio(callback(this, &Transmission::serverTCP_event));
YSI 3:7e15bf0a71f4 200 message.CONNECT = true;
YSI 21:59c0adcdfe9b 201 if(_ethup) _queue.call(_ethup);
YSI 1:27f6baabb15e 202 }
YSI 3:7e15bf0a71f4 203 return message.CONNECT;
YSI 1:27f6baabb15e 204 }
YSI 1:27f6baabb15e 205
YSI 1:27f6baabb15e 206 void Transmission::serverTCP_event(void)
YSI 1:27f6baabb15e 207 {
YSI 21:59c0adcdfe9b 208 _queue.call(this, &Transmission::serverTCP_accept);
YSI 1:27f6baabb15e 209 }
YSI 1:27f6baabb15e 210
YSI 1:27f6baabb15e 211 void Transmission::serverTCP_accept(void)
YSI 1:27f6baabb15e 212 {
YSI 1:27f6baabb15e 213 if(message.status == GREEN_GLOBAL_UP)
YSI 1:27f6baabb15e 214 {
YSI 1:27f6baabb15e 215 nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
YSI 1:27f6baabb15e 216 message.status = MAGENTA_ACCEPT;
YSI 3:7e15bf0a71f4 217 _clientTCP = _serverTCP.accept(&ack);
YSI 1:27f6baabb15e 218 switch(ack)
YSI 1:27f6baabb15e 219 {
YSI 1:27f6baabb15e 220 case NSAPI_ERROR_OK:
YSI 14:9e3accc681c4 221 _clientTCP->set_timeout(message.TIMEOUT); // config client bloquante avec timeout sinon limite de transmission a 1072 octets
YSI 1:27f6baabb15e 222 message.status = BLUE_CLIENT;
YSI 1:27f6baabb15e 223 break;
YSI 1:27f6baabb15e 224 case NSAPI_ERROR_NO_CONNECTION:
YSI 4:9a4ab4f406ab 225 eth_state();
YSI 3:7e15bf0a71f4 226 serverTCP_event();
YSI 1:27f6baabb15e 227 break;
YSI 1:27f6baabb15e 228 default:
YSI 4:9a4ab4f406ab 229 eth_state();
YSI 4:9a4ab4f406ab 230 if(ack < NSAPI_ERROR_WOULD_BLOCK) eth_error("serverTCP_accept", ack);
YSI 1:27f6baabb15e 231 break;
YSI 1:27f6baabb15e 232 }
YSI 1:27f6baabb15e 233 }
YSI 1:27f6baabb15e 234 }
YSI 1:27f6baabb15e 235
YSI 4:9a4ab4f406ab 236 void Transmission::eth_state(void)
YSI 4:9a4ab4f406ab 237 {
YSI 4:9a4ab4f406ab 238 switch(_eth->get_connection_status())
YSI 4:9a4ab4f406ab 239 {
YSI 4:9a4ab4f406ab 240 case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED; break;
YSI 4:9a4ab4f406ab 241 case NSAPI_STATUS_CONNECTING: message.status = YELLOW_CONNECTING; break;
YSI 4:9a4ab4f406ab 242 case NSAPI_STATUS_GLOBAL_UP: message.status = GREEN_GLOBAL_UP; break;
YSI 15:b2da6ab01a21 243 default: break;
YSI 4:9a4ab4f406ab 244 }
YSI 4:9a4ab4f406ab 245 }
YSI 4:9a4ab4f406ab 246
YSI 14:9e3accc681c4 247 void Transmission::serial_event(void)
YSI 14:9e3accc681c4 248 {
YSI 29:0d321d298d37 249 static char buffer[TRANSMISSION_BUFFER_SIZE] = {0};
YSI 14:9e3accc681c4 250 static uint16_t size = 0;
YSI 29:0d321d298d37 251 char caractere;
YSI 14:9e3accc681c4 252 _serial->read(&caractere, 1);
YSI 29:0d321d298d37 253 if(caractere == '\n')
YSI 14:9e3accc681c4 254 {
YSI 14:9e3accc681c4 255 buffer[size] = '\0';
YSI 14:9e3accc681c4 256 size = 0;
YSI 21:59c0adcdfe9b 257 if(_processing) _queue.call(this, &Transmission::preprocessing, buffer, SERIAL_DELIVERY);
YSI 14:9e3accc681c4 258 }
YSI 29:0d321d298d37 259 else if((caractere > 31) && (caractere < 127))
YSI 29:0d321d298d37 260 {
YSI 29:0d321d298d37 261 if(size >= (TRANSMISSION_BUFFER_SIZE-1))
YSI 29:0d321d298d37 262 for(int i = 0; i < size; i++) buffer[i] = (i < size-1)?buffer[i+1]:caractere;
YSI 29:0d321d298d37 263 else buffer[size++] = caractere;
YSI 29:0d321d298d37 264 }
YSI 14:9e3accc681c4 265 }
YSI 14:9e3accc681c4 266
YSI 11:de94dcd67561 267 Transmission::enum_trans_status Transmission::recv(void)
YSI 1:27f6baabb15e 268 {
YSI 16:3ef69ffede76 269 if(_usb)
YSI 15:b2da6ab01a21 270 {
YSI 15:b2da6ab01a21 271 if(_usb->ready())
YSI 15:b2da6ab01a21 272 {
YSI 25:01db56f04262 273 uint8_t buffer[TRANSMISSION_BUFFER_SIZE] = {0};
YSI 18:15778c8a97a1 274 uint32_t ack = 0, size = 0;
YSI 18:15778c8a97a1 275 do{
YSI 20:2672d4aea6b7 276 ack = NSAPI_ERROR_OK;
YSI 18:15778c8a97a1 277 _usb->receive_nb(&buffer[size], 1, &ack); // un peu plus rapide sur les petits transferts
YSI 18:15778c8a97a1 278 size += ack;
YSI 25:01db56f04262 279 }while((ack > NSAPI_ERROR_OK) && (size < TRANSMISSION_BUFFER_SIZE-1) && (buffer[size-ack] != '\n'));
YSI 19:6c5777719ece 280 if(size && _processing) preprocessing((char *)buffer, USB_DELIVERY);
YSI 19:6c5777719ece 281 } else _usb->connect();
YSI 15:b2da6ab01a21 282 }
YSI 14:9e3accc681c4 283 if(eth_connect() && (message.status == BLUE_CLIENT))
YSI 1:27f6baabb15e 284 {
YSI 25:01db56f04262 285 char buffer[TRANSMISSION_BUFFER_SIZE] = {0};
YSI 20:2672d4aea6b7 286 nsapi_error_t ack = 0, size = 0;
YSI 20:2672d4aea6b7 287 do{
YSI 25:01db56f04262 288 ack = _clientTCP->recv(&buffer[size], TRANSMISSION_BUFFER_SIZE-size);
YSI 20:2672d4aea6b7 289 if(ack > NSAPI_ERROR_OK) size += ack;
YSI 25:01db56f04262 290 }while((ack == 536) && (size < TRANSMISSION_BUFFER_SIZE));
YSI 10:25e049353db5 291 if(ack < NSAPI_ERROR_WOULD_BLOCK) eth_error("clientTCP_recv", ack);
YSI 20:2672d4aea6b7 292 if((ack == NSAPI_ERROR_OK) || (ack == NSAPI_ERROR_NO_CONNECTION))
YSI 18:15778c8a97a1 293 {
YSI 18:15778c8a97a1 294 eth_error("clientTCP_disconnect", _clientTCP->close());
YSI 18:15778c8a97a1 295 eth_state();
YSI 18:15778c8a97a1 296 serverTCP_event();
YSI 18:15778c8a97a1 297 }
YSI 19:6c5777719ece 298 if(size && _processing) preprocessing(buffer, TCP_DELIVERY);
YSI 20:2672d4aea6b7 299 }
YSI 20:2672d4aea6b7 300 else if(!_usb) for(int i = 0; ((i < 10) && (message.status != BLUE_CLIENT)); i++) ThisThread::sleep_for(10ms);
YSI 1:27f6baabb15e 301 return message.status;
YSI 1:27f6baabb15e 302 }
YSI 1:27f6baabb15e 303
YSI 16:3ef69ffede76 304 void Transmission::preprocessing(char *buffer, const enum_trans_delivery delivery)
YSI 16:3ef69ffede76 305 {
YSI 16:3ef69ffede76 306 string cmd(buffer);
YSI 17:9b7100c31466 307 for(char &c : cmd) if(_caseIgnore && (c >= 'a') && (c <= 'z')) c += 'A'-'a';
YSI 16:3ef69ffede76 308 if((cmd.find("HOST: ") != string::npos) || (cmd.find("Host: ") != string::npos))
YSI 21:59c0adcdfe9b 309 send(_processing(cmd), HTTP_DELIVERY);
YSI 18:15778c8a97a1 310 else if(!cmd.empty() && (cmd[0] != 22))
YSI 16:3ef69ffede76 311 {
YSI 17:9b7100c31466 312 for(char &c : cmd) if(c == '\n') c = ';';
YSI 17:9b7100c31466 313 istringstream srecv(cmd);
YSI 16:3ef69ffede76 314 string ssend;
YSI 16:3ef69ffede76 315 while(getline(srecv, cmd, ';'))
YSI 16:3ef69ffede76 316 {
YSI 17:9b7100c31466 317 string process = _processing(cmd);
YSI 17:9b7100c31466 318 if(!process.empty()) ssend += (ssend.size() > 0)?(' '+process):process;
YSI 16:3ef69ffede76 319 }
YSI 16:3ef69ffede76 320 send(ssend, delivery);
YSI 16:3ef69ffede76 321 }
YSI 16:3ef69ffede76 322 }
YSI 16:3ef69ffede76 323
YSI 22:e99892e6fd8d 324 nsapi_error_t Transmission::send(const string& buffer, const enum_trans_delivery& delivery)
YSI 1:27f6baabb15e 325 {
YSI 1:27f6baabb15e 326 nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
YSI 22:e99892e6fd8d 327 string ssend(buffer+"\n");
YSI 22:e99892e6fd8d 328 if(_usb && !buffer.empty() && ((delivery == USB_DELIVERY) || (delivery == ANY_DELIVERY)))
YSI 18:15778c8a97a1 329 {
YSI 18:15778c8a97a1 330 _usb->connect();
YSI 18:15778c8a97a1 331 if(_usb->ready()) _usb->send((uint8_t*)ssend.c_str(), ssend.size());
YSI 18:15778c8a97a1 332 }
YSI 22:e99892e6fd8d 333 if(_serial && !buffer.empty() && ((delivery == SERIAL_DELIVERY) || (delivery == ANY_DELIVERY)))
YSI 11:de94dcd67561 334 ack = _serial->write(ssend.c_str(), ssend.length());
YSI 19:6c5777719ece 335 if(_eth && ((delivery == TCP_DELIVERY) || (delivery == HTTP_DELIVERY) || (delivery == ANY_DELIVERY)))
YSI 1:27f6baabb15e 336 {
YSI 22:e99892e6fd8d 337 if((message.status == BLUE_CLIENT) && !buffer.empty())
YSI 4:9a4ab4f406ab 338 eth_error("clientTCP_send", ack = _clientTCP->send(ssend.c_str(), ssend.size()));
YSI 19:6c5777719ece 339 if(delivery == HTTP_DELIVERY)
YSI 4:9a4ab4f406ab 340 {
YSI 4:9a4ab4f406ab 341 eth_error("clientTCP_disconnect", _clientTCP->close());
YSI 4:9a4ab4f406ab 342 eth_state();
YSI 4:9a4ab4f406ab 343 serverTCP_event();
YSI 4:9a4ab4f406ab 344 }
YSI 1:27f6baabb15e 345 }
YSI 1:27f6baabb15e 346 return ack;
YSI 1:27f6baabb15e 347 }
YSI 1:27f6baabb15e 348
YSI 22:e99892e6fd8d 349 string Transmission::get(const string& ssend, const string& server, const int& port)
YSI 22:e99892e6fd8d 350 {
YSI 22:e99892e6fd8d 351 char buffer[256] = {0};
YSI 22:e99892e6fd8d 352 if(!server.empty())
YSI 22:e99892e6fd8d 353 {
YSI 22:e99892e6fd8d 354 TCPSocket clientTCP;
YSI 27:87c2a2a23d06 355 clientTCP.set_timeout(message.TIMEOUT);
YSI 22:e99892e6fd8d 356 if(eth_error("clientTCP_open", clientTCP.open(_eth)) == NSAPI_ERROR_OK)
YSI 22:e99892e6fd8d 357 {
YSI 22:e99892e6fd8d 358 if(eth_error("clientTCP_connect", clientTCP.connect(SocketAddress(server.c_str(), port))) == NSAPI_ERROR_OK)
YSI 22:e99892e6fd8d 359 {
YSI 22:e99892e6fd8d 360 eth_error("clientTCP_send", clientTCP.send(ssend.c_str(), ssend.size()));
YSI 22:e99892e6fd8d 361 eth_error("clientTCP_recv", clientTCP.recv(buffer, 256));
YSI 22:e99892e6fd8d 362 }
YSI 22:e99892e6fd8d 363 }
YSI 22:e99892e6fd8d 364 eth_error("clientTCP_close", clientTCP.close());
YSI 22:e99892e6fd8d 365 }
YSI 22:e99892e6fd8d 366 return buffer;
YSI 22:e99892e6fd8d 367 }
YSI 22:e99892e6fd8d 368
YSI 28:24f7e0ddf6f5 369 bool Transmission::smtp(string mail, string from, string subject, string data, const char* server)
YSI 1:27f6baabb15e 370 {
YSI 28:24f7e0ddf6f5 371 if((!_eth) || (!message.DHCP) || (_eth->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) || mail.empty()) return false;
YSI 28:24f7e0ddf6f5 372 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",
YSI 28:24f7e0ddf6f5 373 "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" },
YSI 28:24f7e0ddf6f5 374 { "", "HELO Mbed\r\n", "MAIL FROM: <Mbed>\r\n","RCPT TO: <" + mail + ">\r\n", "QUIT\r\n" }};
YSI 1:27f6baabb15e 375 TCPSocket clientSMTP;
YSI 27:87c2a2a23d06 376 clientSMTP.set_timeout(message.TIMEOUT);
YSI 1:27f6baabb15e 377 if(eth_error("clientSMTP_open", clientSMTP.open(_eth)) == NSAPI_ERROR_OK)
YSI 1:27f6baabb15e 378 {
YSI 28:24f7e0ddf6f5 379 for(const string& ssend : smtpParams[from.empty()?1:0])
YSI 1:27f6baabb15e 380 {
YSI 28:24f7e0ddf6f5 381
YSI 26:fe26375f733e 382 char buffer[64] = {0};
YSI 28:24f7e0ddf6f5 383 if(code.empty()) { if(eth_error("clientSMTP_connect", clientSMTP.connect(SocketAddress(server, 25))) < NSAPI_ERROR_OK) break; }
YSI 28:24f7e0ddf6f5 384 else if(eth_error("clientSMTP_send", clientSMTP.send(ssend.c_str(), ssend.size())) < NSAPI_ERROR_OK) break;
YSI 28:24f7e0ddf6f5 385 if(eth_error("clientSMTP_recv", clientSMTP.recv(buffer, 64)) < NSAPI_ERROR_OK) break;
YSI 1:27f6baabb15e 386 buffer[3] = 0;
YSI 1:27f6baabb15e 387 code += buffer;
YSI 1:27f6baabb15e 388 if(ssend == "QUIT\r\n") break;
YSI 1:27f6baabb15e 389 }
YSI 1:27f6baabb15e 390 eth_error("clientSMTP_close", clientSMTP.close());
YSI 1:27f6baabb15e 391 }
YSI 28:24f7e0ddf6f5 392 if(from.empty()) return code == "220250250250221";
YSI 29:0d321d298d37 393 else if((code == "220250250250354250221") || (code == "220250250250354")) return true;
YSI 29:0d321d298d37 394 else
YSI 28:24f7e0ddf6f5 395 {
YSI 28:24f7e0ddf6f5 396 #if MBED_MAJOR_VERSION > 5
YSI 28:24f7e0ddf6f5 397 _queue.call_in(60s, this, &Transmission::smtp, mail, from, subject, data, server);
YSI 28:24f7e0ddf6f5 398 #else
YSI 28:24f7e0ddf6f5 399 _queue.call_in(60000, this, &Transmission::smtp, mail, from, subject, data, server);
YSI 28:24f7e0ddf6f5 400 #endif
YSI 28:24f7e0ddf6f5 401 }
YSI 29:0d321d298d37 402 return false;
YSI 0:2fc6fc3b5e15 403 }
YSI 0:2fc6fc3b5e15 404
YSI 22:e99892e6fd8d 405 time_t Transmission::ntp(const char* server)
YSI 6:d6a07fd1548a 406 {
YSI 16:3ef69ffede76 407 if(!_eth) return 0;
YSI 26:fe26375f733e 408 if((!message.DHCP) || (_eth->get_connection_status() != NSAPI_STATUS_GLOBAL_UP)) return time(NULL);
YSI 6:d6a07fd1548a 409 time_t timeStamp = 0;
YSI 6:d6a07fd1548a 410 UDPSocket clientNTP;
YSI 27:87c2a2a23d06 411 clientNTP.set_timeout(message.TIMEOUT);
YSI 6:d6a07fd1548a 412 if(eth_error("clientNTP_open", clientNTP.open(_eth)) == NSAPI_ERROR_OK)
YSI 6:d6a07fd1548a 413 {
YSI 6:d6a07fd1548a 414 uint32_t buffer[12] = { 0b11011, 0 }; // VN = 3 & Mode = 3
YSI 22:e99892e6fd8d 415 SocketAddress aSERVER(server, 123);
YSI 22:e99892e6fd8d 416 string sSERVER(server);
YSI 25:01db56f04262 417 if(sSERVER != TRANSMISSION_NTP_SERVER) eth_error("eth_gethostbyname", _eth->gethostbyname(sSERVER.c_str(), &aSERVER));
YSI 22:e99892e6fd8d 418 if(eth_error("clientNTP_send", clientNTP.sendto(aSERVER, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK)
YSI 6:d6a07fd1548a 419 {
YSI 6:d6a07fd1548a 420 if(eth_error("clientNTP_recv", clientNTP.recvfrom(NULL, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK)
YSI 6:d6a07fd1548a 421 {
YSI 6:d6a07fd1548a 422 timeStamp = ((buffer[10] & 0xFF) << 24) | ((buffer[10] & 0xFF00) << 8) | ((buffer[10] & 0xFF0000UL) >> 8) | ((buffer[10] & 0xFF000000UL) >> 24);
YSI 6:d6a07fd1548a 423 timeStamp -= 2208985200U; // 01/01/1970 Europe
YSI 6:d6a07fd1548a 424 struct tm * tmTimeStamp = localtime(&timeStamp);
YSI 10:25e049353db5 425 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)))
YSI 7:98b12722e9e2 426 timeStamp += 3600; // DST starts last Sunday of March; 2am (1am UTC), DST ends last Sunday of october; 3am (2am UTC)
YSI 6:d6a07fd1548a 427 }
YSI 6:d6a07fd1548a 428 }
YSI 6:d6a07fd1548a 429 eth_error("clientNTP_close", clientNTP.close());
YSI 6:d6a07fd1548a 430 }
YSI 6:d6a07fd1548a 431 return timeStamp;
YSI 6:d6a07fd1548a 432 }
YSI 6:d6a07fd1548a 433
YSI 0:2fc6fc3b5e15 434 intptr_t Transmission::eth_status(const string& source, const intptr_t& code)
YSI 0:2fc6fc3b5e15 435 {
YSI 14:9e3accc681c4 436 #ifndef NDEBUG
YSI 14:9e3accc681c4 437 ostringstream message;
YSI 25:01db56f04262 438 message << "\n" << source << "[" << code << "] ";
YSI 0:2fc6fc3b5e15 439 switch(code)
YSI 0:2fc6fc3b5e15 440 {
YSI 25:01db56f04262 441 case NSAPI_STATUS_LOCAL_UP: message << "NSAPI_STATUS_LOCAL_UP < local IP address set >"; break;
YSI 25:01db56f04262 442 case NSAPI_STATUS_GLOBAL_UP: message << "NSAPI_STATUS_GLOBAL_UP < global IP address set >"; break;
YSI 25:01db56f04262 443 case NSAPI_STATUS_DISCONNECTED: message << "NSAPI_STATUS_DISCONNECTED < no connection to network >"; break;
YSI 25:01db56f04262 444 case NSAPI_STATUS_CONNECTING: message << "NSAPI_STATUS_CONNECTING < connecting to network >"; break;
YSI 25:01db56f04262 445 case NSAPI_STATUS_ERROR_UNSUPPORTED: message << "NSAPI_STATUS_ERROR_UNSUPPORTED < unsupported functionality >"; break;
YSI 0:2fc6fc3b5e15 446 }
YSI 1:27f6baabb15e 447 _serial->write(message.str().c_str(), message.str().size());
YSI 1:27f6baabb15e 448 #endif
YSI 0:2fc6fc3b5e15 449 return code;
YSI 0:2fc6fc3b5e15 450 }
YSI 0:2fc6fc3b5e15 451
YSI 0:2fc6fc3b5e15 452 nsapi_error_t Transmission::eth_error(const string& source, const nsapi_error_t& code)
YSI 0:2fc6fc3b5e15 453 {
YSI 14:9e3accc681c4 454 #ifndef NDEBUG
YSI 14:9e3accc681c4 455 ostringstream message;
YSI 25:01db56f04262 456 message << "\n" << source << "[" << code << "] ";
YSI 0:2fc6fc3b5e15 457 switch(code)
YSI 0:2fc6fc3b5e15 458 {
YSI 25:01db56f04262 459 case NSAPI_ERROR_OK: message << "NSAPI_ERROR_OK < no error >"; break;
YSI 25:01db56f04262 460 case NSAPI_ERROR_WOULD_BLOCK: message << "NSAPI_ERROR_WOULD_BLOCK < no data is not available but call is non-blocking >"; break;
YSI 25:01db56f04262 461 case NSAPI_ERROR_UNSUPPORTED: message << "NSAPI_ERROR_UNSUPPORTED < unsupported functionality >"; break;
YSI 25:01db56f04262 462 case NSAPI_ERROR_PARAMETER: message << "NSAPI_ERROR_PARAMETER < invalid configuration >"; break;
YSI 25:01db56f04262 463 case NSAPI_ERROR_NO_CONNECTION: message << "NSAPI_ERROR_NO_CONNECTION < not connected to a network >"; break;
YSI 25:01db56f04262 464 case NSAPI_ERROR_NO_SOCKET: message << "NSAPI_ERROR_NO_SOCKET < socket not available for use >"; break;
YSI 25:01db56f04262 465 case NSAPI_ERROR_NO_ADDRESS: message << "NSAPI_ERROR_NO_ADDRESS < IP address is not known >"; break;
YSI 25:01db56f04262 466 case NSAPI_ERROR_NO_MEMORY: message << "NSAPI_ERROR_NO_MEMORY < memory resource not available >"; break;
YSI 25:01db56f04262 467 case NSAPI_ERROR_NO_SSID: message << "NSAPI_ERROR_NO_SSID < ssid not found >"; break;
YSI 25:01db56f04262 468 case NSAPI_ERROR_DNS_FAILURE: message << "NSAPI_ERROR_DNS_FAILURE < DNS failed to complete successfully >"; break;
YSI 25:01db56f04262 469 case NSAPI_ERROR_DHCP_FAILURE: message << "NSAPI_ERROR_DHCP_FAILURE < DHCP failed to complete successfully >"; break;
YSI 25:01db56f04262 470 case NSAPI_ERROR_AUTH_FAILURE: message << "NSAPI_ERROR_AUTH_FAILURE < connection to access point failed >"; break;
YSI 25:01db56f04262 471 case NSAPI_ERROR_DEVICE_ERROR: message << "NSAPI_ERROR_DEVICE_ERROR < failure interfacing with the network processor >"; break;
YSI 25:01db56f04262 472 case NSAPI_ERROR_IN_PROGRESS: message << "NSAPI_ERROR_IN_PROGRESS < operation (eg connect) in progress >"; break;
YSI 25:01db56f04262 473 case NSAPI_ERROR_ALREADY: message << "NSAPI_ERROR_ALREADY < operation (eg connect) already in progress >"; break;
YSI 25:01db56f04262 474 case NSAPI_ERROR_IS_CONNECTED: message << "NSAPI_ERROR_IS_CONNECTED < socket is already connected >"; break;
YSI 25:01db56f04262 475 case NSAPI_ERROR_CONNECTION_LOST: message << "NSAPI_ERROR_CONNECTION_LOST < connection lost >"; break;
YSI 25:01db56f04262 476 case NSAPI_ERROR_CONNECTION_TIMEOUT: message << "NSAPI_ERROR_CONNECTION_TIMEOUT < connection timed out >"; break;
YSI 25:01db56f04262 477 case NSAPI_ERROR_ADDRESS_IN_USE: message << "NSAPI_ERROR_ADDRESS_IN_USE < Address already in use >"; break;
YSI 25:01db56f04262 478 case NSAPI_ERROR_TIMEOUT: message << "NSAPI_ERROR_TIMEOUT < operation timed out >"; break;
YSI 25:01db56f04262 479 case NSAPI_ERROR_BUSY: message << "NSAPI_ERROR_BUSY < device is busy and cannot accept new operation >"; break;
YSI 25:01db56f04262 480 default: message << "NSAPI_ERROR < unknow code >"; break;
YSI 0:2fc6fc3b5e15 481 }
YSI 1:27f6baabb15e 482 if(code < NSAPI_ERROR_OK) _serial->write(message.str().c_str(), message.str().size());
YSI 1:27f6baabb15e 483 #endif
YSI 0:2fc6fc3b5e15 484 return code;
YSI 0:2fc6fc3b5e15 485 }