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