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@15:b2da6ab01a21, 2021-03-03 (annotated)
- Committer:
- YSI
- Date:
- Wed Mar 03 13:02:28 2021 +0000
- Revision:
- 15:b2da6ab01a21
- Parent:
- 14:9e3accc681c4
- Child:
- 16:3ef69ffede76
add usbcdc and simplification of library use
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
YSI | 0:2fc6fc3b5e15 | 1 | #include "lib_Transmission.h" |
YSI | 0:2fc6fc3b5e15 | 2 | |
YSI | 14:9e3accc681c4 | 3 | Transmission::Transmission( |
YSI | 14:9e3accc681c4 | 4 | #if MBED_MAJOR_VERSION > 5 |
YSI | 15:b2da6ab01a21 | 5 | UnbufferedSerial *serial, |
YSI | 14:9e3accc681c4 | 6 | #else |
YSI | 15:b2da6ab01a21 | 7 | Serial *serial, |
YSI | 14:9e3accc681c4 | 8 | #endif |
YSI | 15:b2da6ab01a21 | 9 | EthernetInterface *eth, |
YSI | 15:b2da6ab01a21 | 10 | USBCDC *usb, |
YSI | 15:b2da6ab01a21 | 11 | string (*processing)(string), |
YSI | 15:b2da6ab01a21 | 12 | void (*startuped)(void), |
YSI | 15:b2da6ab01a21 | 13 | bool caseIgnore) |
YSI | 15:b2da6ab01a21 | 14 | :_serial(serial), _eth(eth), _usb(usb), _processing(processing), _startuped(startuped), _caseIgnore(caseIgnore) |
YSI | 0:2fc6fc3b5e15 | 15 | { |
YSI | 14:9e3accc681c4 | 16 | if(_serial != NULL) _serial->attach(callback(this, &Transmission::serial_event)); |
YSI | 14:9e3accc681c4 | 17 | _queue = mbed_event_queue(); |
YSI | 0:2fc6fc3b5e15 | 18 | } |
YSI | 0:2fc6fc3b5e15 | 19 | |
YSI | 15:b2da6ab01a21 | 20 | Transmission::Transmission( |
YSI | 15:b2da6ab01a21 | 21 | #if MBED_MAJOR_VERSION > 5 |
YSI | 15:b2da6ab01a21 | 22 | UnbufferedSerial *serial, |
YSI | 15:b2da6ab01a21 | 23 | #else |
YSI | 15:b2da6ab01a21 | 24 | Serial *serial, |
YSI | 15:b2da6ab01a21 | 25 | #endif |
YSI | 15:b2da6ab01a21 | 26 | string (*processing)(string), |
YSI | 15:b2da6ab01a21 | 27 | bool caseIgnore) |
YSI | 15:b2da6ab01a21 | 28 | :_serial(serial), _processing(processing), _caseIgnore(caseIgnore) |
YSI | 15:b2da6ab01a21 | 29 | { |
YSI | 15:b2da6ab01a21 | 30 | if(_serial != NULL) _serial->attach(callback(this, &Transmission::serial_event)); |
YSI | 15:b2da6ab01a21 | 31 | _queue = mbed_event_queue(); |
YSI | 15:b2da6ab01a21 | 32 | } |
YSI | 15:b2da6ab01a21 | 33 | |
YSI | 15:b2da6ab01a21 | 34 | Transmission::Transmission( |
YSI | 15:b2da6ab01a21 | 35 | EthernetInterface *eth, |
YSI | 15:b2da6ab01a21 | 36 | string (*processing)(string), |
YSI | 15:b2da6ab01a21 | 37 | void (*startuped)(void), |
YSI | 15:b2da6ab01a21 | 38 | bool caseIgnore) |
YSI | 15:b2da6ab01a21 | 39 | :_eth(eth), _processing(processing), _startuped(startuped), _caseIgnore(caseIgnore) |
YSI | 15:b2da6ab01a21 | 40 | { |
YSI | 15:b2da6ab01a21 | 41 | _queue = mbed_event_queue(); |
YSI | 15:b2da6ab01a21 | 42 | } |
YSI | 15:b2da6ab01a21 | 43 | |
YSI | 15:b2da6ab01a21 | 44 | Transmission::Transmission( |
YSI | 15:b2da6ab01a21 | 45 | USBCDC *usb, |
YSI | 15:b2da6ab01a21 | 46 | string (*processing)(string), |
YSI | 15:b2da6ab01a21 | 47 | bool caseIgnore) |
YSI | 15:b2da6ab01a21 | 48 | :_usb(usb), _processing(processing), _caseIgnore(caseIgnore){} |
YSI | 15:b2da6ab01a21 | 49 | |
YSI | 14:9e3accc681c4 | 50 | string Transmission::ip(const bool& SET, const char* IP, const uint16_t& PORT, const uint16_t& TIMEOUT) |
YSI | 3:7e15bf0a71f4 | 51 | { |
YSI | 11:de94dcd67561 | 52 | if(_eth == NULL) return "00:00:00:00:00:00"; |
YSI | 10:25e049353db5 | 53 | if(message.SET && SET) |
YSI | 3:7e15bf0a71f4 | 54 | { |
YSI | 3:7e15bf0a71f4 | 55 | if(message.PORT != PORT) |
YSI | 3:7e15bf0a71f4 | 56 | { |
YSI | 3:7e15bf0a71f4 | 57 | message.CONNECT = false; |
YSI | 3:7e15bf0a71f4 | 58 | _serverTCP.sigio(NULL); |
YSI | 3:7e15bf0a71f4 | 59 | eth_error("serverTCP_close", _serverTCP.close()); |
YSI | 3:7e15bf0a71f4 | 60 | } |
YSI | 3:7e15bf0a71f4 | 61 | eth_error("Ethernet_disconnect", _eth->disconnect()); |
YSI | 3:7e15bf0a71f4 | 62 | } |
YSI | 10:25e049353db5 | 63 | message.SET = SET; |
YSI | 3:7e15bf0a71f4 | 64 | message.IP = IP; |
YSI | 3:7e15bf0a71f4 | 65 | message.PORT = PORT; |
YSI | 14:9e3accc681c4 | 66 | message.TIMEOUT = TIMEOUT; |
YSI | 3:7e15bf0a71f4 | 67 | message.DHCP = message.IP.empty(); |
YSI | 10:25e049353db5 | 68 | eth_connect(); |
YSI | 14:9e3accc681c4 | 69 | return _eth->get_mac_address()?_eth->get_mac_address():"00:00:00:00:00:00"; |
YSI | 3:7e15bf0a71f4 | 70 | } |
YSI | 3:7e15bf0a71f4 | 71 | |
YSI | 14:9e3accc681c4 | 72 | string Transmission::ip(void) |
YSI | 3:7e15bf0a71f4 | 73 | { |
YSI | 11:de94dcd67561 | 74 | if(_eth == NULL) return "0.0.0.0"; |
YSI | 3:7e15bf0a71f4 | 75 | SocketAddress ip; |
YSI | 3:7e15bf0a71f4 | 76 | _eth->get_ip_address(&ip); |
YSI | 3:7e15bf0a71f4 | 77 | string address(ip.get_ip_address()?ip.get_ip_address():"0.0.0.0"); |
YSI | 3:7e15bf0a71f4 | 78 | address += ":" + to_string(message.PORT); |
YSI | 3:7e15bf0a71f4 | 79 | return address; |
YSI | 3:7e15bf0a71f4 | 80 | } |
YSI | 3:7e15bf0a71f4 | 81 | |
YSI | 0:2fc6fc3b5e15 | 82 | bool Transmission::eth_connect(void) |
YSI | 0:2fc6fc3b5e15 | 83 | { |
YSI | 11:de94dcd67561 | 84 | if(_eth == NULL) return false; |
YSI | 10:25e049353db5 | 85 | if(message.SET) |
YSI | 0:2fc6fc3b5e15 | 86 | { |
YSI | 0:2fc6fc3b5e15 | 87 | switch(_eth->get_connection_status()) |
YSI | 0:2fc6fc3b5e15 | 88 | { |
YSI | 0:2fc6fc3b5e15 | 89 | case NSAPI_STATUS_DISCONNECTED: |
YSI | 14:9e3accc681c4 | 90 | eth_error("Ethernet_blocking", _eth->set_blocking(false)); |
YSI | 14:9e3accc681c4 | 91 | eth_error("Ethernet_dhcp", _eth->set_dhcp(message.DHCP)); |
YSI | 14:9e3accc681c4 | 92 | 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"))); |
YSI | 14:9e3accc681c4 | 93 | _eth->attach(callback(this, &Transmission::eth_event)); |
YSI | 15:b2da6ab01a21 | 94 | eth_error("Ethernet_connect", _eth->connect()); break; |
YSI | 14:9e3accc681c4 | 95 | case NSAPI_STATUS_GLOBAL_UP: return message.CONNECT;break; |
YSI | 14:9e3accc681c4 | 96 | default: break; |
YSI | 0:2fc6fc3b5e15 | 97 | } |
YSI | 0:2fc6fc3b5e15 | 98 | } |
YSI | 0:2fc6fc3b5e15 | 99 | else if(_eth->get_connection_status() != NSAPI_STATUS_DISCONNECTED) eth_error("Ethernet_disconnect", _eth->disconnect()); |
YSI | 0:2fc6fc3b5e15 | 100 | return false; |
YSI | 0:2fc6fc3b5e15 | 101 | } |
YSI | 0:2fc6fc3b5e15 | 102 | |
YSI | 0:2fc6fc3b5e15 | 103 | void Transmission::eth_event(nsapi_event_t status, intptr_t param) |
YSI | 0:2fc6fc3b5e15 | 104 | { |
YSI | 0:2fc6fc3b5e15 | 105 | eth_status("Ethernet_event", param); |
YSI | 0:2fc6fc3b5e15 | 106 | switch(param) |
YSI | 0:2fc6fc3b5e15 | 107 | { |
YSI | 15:b2da6ab01a21 | 108 | case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED; break; |
YSI | 4:9a4ab4f406ab | 109 | case NSAPI_STATUS_CONNECTING:if(message.status == BLUE_CLIENT) eth_error("clientTCP_disconnect", _clientTCP->close()); |
YSI | 15:b2da6ab01a21 | 110 | message.status = YELLOW_CONNECTING; break; |
YSI | 3:7e15bf0a71f4 | 111 | case NSAPI_STATUS_GLOBAL_UP: message.status = GREEN_GLOBAL_UP; |
YSI | 15:b2da6ab01a21 | 112 | if(!message.CONNECT) serverTCP_connect(); |
YSI | 15:b2da6ab01a21 | 113 | else serverTCP_event(); break; |
YSI | 15:b2da6ab01a21 | 114 | default: break; |
YSI | 1:27f6baabb15e | 115 | } |
YSI | 1:27f6baabb15e | 116 | } |
YSI | 1:27f6baabb15e | 117 | |
YSI | 1:27f6baabb15e | 118 | bool Transmission::serverTCP_connect(void) |
YSI | 1:27f6baabb15e | 119 | { |
YSI | 3:7e15bf0a71f4 | 120 | if(!message.CONNECT) |
YSI | 3:7e15bf0a71f4 | 121 | if(eth_error("serverTCP_open", _serverTCP.open(_eth)) == NSAPI_ERROR_OK) |
YSI | 3:7e15bf0a71f4 | 122 | if(eth_error("serverTCP_bind", _serverTCP.bind(message.PORT)) == NSAPI_ERROR_OK) |
YSI | 3:7e15bf0a71f4 | 123 | if(eth_error("serverTCP_listen", _serverTCP.listen()) == NSAPI_ERROR_OK) |
YSI | 1:27f6baabb15e | 124 | { |
YSI | 3:7e15bf0a71f4 | 125 | _serverTCP.set_blocking(false); |
YSI | 3:7e15bf0a71f4 | 126 | _serverTCP.sigio(callback(this, &Transmission::serverTCP_event)); |
YSI | 3:7e15bf0a71f4 | 127 | message.CONNECT = true; |
YSI | 15:b2da6ab01a21 | 128 | if(_startuped != NULL) _queue->call(_startuped); |
YSI | 1:27f6baabb15e | 129 | } |
YSI | 3:7e15bf0a71f4 | 130 | return message.CONNECT; |
YSI | 1:27f6baabb15e | 131 | } |
YSI | 1:27f6baabb15e | 132 | |
YSI | 1:27f6baabb15e | 133 | void Transmission::serverTCP_event(void) |
YSI | 1:27f6baabb15e | 134 | { |
YSI | 14:9e3accc681c4 | 135 | _queue->call(this, &Transmission::serverTCP_accept); |
YSI | 1:27f6baabb15e | 136 | } |
YSI | 1:27f6baabb15e | 137 | |
YSI | 1:27f6baabb15e | 138 | void Transmission::serverTCP_accept(void) |
YSI | 1:27f6baabb15e | 139 | { |
YSI | 1:27f6baabb15e | 140 | if(message.status == GREEN_GLOBAL_UP) |
YSI | 1:27f6baabb15e | 141 | { |
YSI | 1:27f6baabb15e | 142 | nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK; |
YSI | 1:27f6baabb15e | 143 | message.status = MAGENTA_ACCEPT; |
YSI | 3:7e15bf0a71f4 | 144 | _clientTCP = _serverTCP.accept(&ack); |
YSI | 1:27f6baabb15e | 145 | switch(ack) |
YSI | 1:27f6baabb15e | 146 | { |
YSI | 1:27f6baabb15e | 147 | case NSAPI_ERROR_OK: |
YSI | 14:9e3accc681c4 | 148 | _clientTCP->set_timeout(message.TIMEOUT); // config client bloquante avec timeout sinon limite de transmission a 1072 octets |
YSI | 1:27f6baabb15e | 149 | message.status = BLUE_CLIENT; |
YSI | 1:27f6baabb15e | 150 | break; |
YSI | 1:27f6baabb15e | 151 | case NSAPI_ERROR_NO_CONNECTION: |
YSI | 4:9a4ab4f406ab | 152 | eth_state(); |
YSI | 3:7e15bf0a71f4 | 153 | serverTCP_event(); |
YSI | 1:27f6baabb15e | 154 | break; |
YSI | 1:27f6baabb15e | 155 | default: |
YSI | 4:9a4ab4f406ab | 156 | eth_state(); |
YSI | 4:9a4ab4f406ab | 157 | if(ack < NSAPI_ERROR_WOULD_BLOCK) eth_error("serverTCP_accept", ack); |
YSI | 1:27f6baabb15e | 158 | break; |
YSI | 1:27f6baabb15e | 159 | } |
YSI | 1:27f6baabb15e | 160 | } |
YSI | 1:27f6baabb15e | 161 | } |
YSI | 1:27f6baabb15e | 162 | |
YSI | 4:9a4ab4f406ab | 163 | void Transmission::eth_state(void) |
YSI | 4:9a4ab4f406ab | 164 | { |
YSI | 4:9a4ab4f406ab | 165 | switch(_eth->get_connection_status()) |
YSI | 4:9a4ab4f406ab | 166 | { |
YSI | 4:9a4ab4f406ab | 167 | case NSAPI_STATUS_DISCONNECTED: message.status = RED_DISCONNECTED; break; |
YSI | 4:9a4ab4f406ab | 168 | case NSAPI_STATUS_CONNECTING: message.status = YELLOW_CONNECTING; break; |
YSI | 4:9a4ab4f406ab | 169 | case NSAPI_STATUS_GLOBAL_UP: message.status = GREEN_GLOBAL_UP; break; |
YSI | 15:b2da6ab01a21 | 170 | default: break; |
YSI | 4:9a4ab4f406ab | 171 | } |
YSI | 4:9a4ab4f406ab | 172 | } |
YSI | 4:9a4ab4f406ab | 173 | |
YSI | 15:b2da6ab01a21 | 174 | void Transmission::delivery(const enum_trans_delivery& delivery) |
YSI | 15:b2da6ab01a21 | 175 | { |
YSI | 15:b2da6ab01a21 | 176 | _delivery = delivery; |
YSI | 15:b2da6ab01a21 | 177 | } |
YSI | 15:b2da6ab01a21 | 178 | |
YSI | 15:b2da6ab01a21 | 179 | void Transmission::preprocessing(char *buffer, const enum_trans_delivery delivery) |
YSI | 15:b2da6ab01a21 | 180 | { |
YSI | 15:b2da6ab01a21 | 181 | _delivery = delivery; |
YSI | 15:b2da6ab01a21 | 182 | string ssend, cmd(buffer); |
YSI | 15:b2da6ab01a21 | 183 | if(_caseIgnore) for(unsigned int i = 0; i < cmd.size(); i++) if ((cmd[i] >= 'a') && (cmd[i] <= 'z')) cmd[i] += 'A' - 'a'; |
YSI | 15:b2da6ab01a21 | 184 | istringstream srecv(cmd); |
YSI | 15:b2da6ab01a21 | 185 | while(getline(srecv, cmd, ';')) |
YSI | 15:b2da6ab01a21 | 186 | { |
YSI | 15:b2da6ab01a21 | 187 | if(ssend.size() > 0) ssend += ' '; |
YSI | 15:b2da6ab01a21 | 188 | ssend += _processing(cmd); |
YSI | 15:b2da6ab01a21 | 189 | } |
YSI | 15:b2da6ab01a21 | 190 | send(ssend, _delivery); |
YSI | 15:b2da6ab01a21 | 191 | } |
YSI | 15:b2da6ab01a21 | 192 | |
YSI | 14:9e3accc681c4 | 193 | void Transmission::serial_event(void) |
YSI | 14:9e3accc681c4 | 194 | { |
YSI | 14:9e3accc681c4 | 195 | static char buffer[TRANSMISSION_DEFAULT_BUFFER_SIZE] = {0}; |
YSI | 14:9e3accc681c4 | 196 | static uint16_t size = 0; |
YSI | 14:9e3accc681c4 | 197 | char caractere; |
YSI | 14:9e3accc681c4 | 198 | _serial->read(&caractere, 1); |
YSI | 14:9e3accc681c4 | 199 | if((caractere == '\n') || (caractere == '\r')) |
YSI | 14:9e3accc681c4 | 200 | { |
YSI | 14:9e3accc681c4 | 201 | buffer[size] = '\0'; |
YSI | 14:9e3accc681c4 | 202 | size = 0; |
YSI | 15:b2da6ab01a21 | 203 | if(_processing != NULL) _queue->call(this, &Transmission::preprocessing, buffer, SERIAL); |
YSI | 14:9e3accc681c4 | 204 | } |
YSI | 14:9e3accc681c4 | 205 | else if((caractere > 31) && (caractere < 127) && (size < (TRANSMISSION_DEFAULT_BUFFER_SIZE-2))) buffer[size++] = caractere; |
YSI | 14:9e3accc681c4 | 206 | } |
YSI | 14:9e3accc681c4 | 207 | |
YSI | 11:de94dcd67561 | 208 | Transmission::enum_trans_status Transmission::recv(void) |
YSI | 1:27f6baabb15e | 209 | { |
YSI | 15:b2da6ab01a21 | 210 | if(_usb != NULL) |
YSI | 15:b2da6ab01a21 | 211 | { |
YSI | 15:b2da6ab01a21 | 212 | _usb->connect(); |
YSI | 15:b2da6ab01a21 | 213 | if(_usb->ready()) |
YSI | 15:b2da6ab01a21 | 214 | { |
YSI | 15:b2da6ab01a21 | 215 | uint32_t size = 0; |
YSI | 15:b2da6ab01a21 | 216 | uint8_t buffer[TRANSMISSION_DEFAULT_BUFFER_SIZE] = {0}; |
YSI | 15:b2da6ab01a21 | 217 | _usb->receive_nb(buffer, TRANSMISSION_DEFAULT_BUFFER_SIZE, &size); |
YSI | 15:b2da6ab01a21 | 218 | if(size) |
YSI | 15:b2da6ab01a21 | 219 | { |
YSI | 15:b2da6ab01a21 | 220 | for(int i = 0; i < size; i++) if(buffer[i] == '\n') buffer[i] = ';'; |
YSI | 15:b2da6ab01a21 | 221 | if(_processing != NULL) preprocessing((char *)buffer, USB); |
YSI | 15:b2da6ab01a21 | 222 | } |
YSI | 15:b2da6ab01a21 | 223 | } |
YSI | 15:b2da6ab01a21 | 224 | } |
YSI | 14:9e3accc681c4 | 225 | if(eth_connect() && (message.status == BLUE_CLIENT)) |
YSI | 1:27f6baabb15e | 226 | { |
YSI | 14:9e3accc681c4 | 227 | char buffer[TRANSMISSION_DEFAULT_BUFFER_SIZE] = {0}; |
YSI | 10:25e049353db5 | 228 | nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK, size = 0; |
YSI | 14:9e3accc681c4 | 229 | while((ack = _clientTCP->recv(&buffer[size], TRANSMISSION_DEFAULT_BUFFER_SIZE-size)) > NSAPI_ERROR_OK) size += ack; |
YSI | 10:25e049353db5 | 230 | if(ack < NSAPI_ERROR_WOULD_BLOCK) eth_error("clientTCP_recv", ack); |
YSI | 10:25e049353db5 | 231 | if(!size) message.BREAK = ((ack == NSAPI_ERROR_OK) || (ack == NSAPI_ERROR_NO_CONNECTION)); |
YSI | 10:25e049353db5 | 232 | for(int i = 0; i < size; i++) if(buffer[i] == '\n') buffer[i] = ';'; |
YSI | 15:b2da6ab01a21 | 233 | if(_processing != NULL) preprocessing(buffer, TCP); |
YSI | 0:2fc6fc3b5e15 | 234 | } |
YSI | 1:27f6baabb15e | 235 | return message.status; |
YSI | 1:27f6baabb15e | 236 | } |
YSI | 1:27f6baabb15e | 237 | |
YSI | 15:b2da6ab01a21 | 238 | nsapi_error_t Transmission::send(const string& buff, const enum_trans_delivery& delivery) |
YSI | 1:27f6baabb15e | 239 | { |
YSI | 1:27f6baabb15e | 240 | nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK; |
YSI | 1:27f6baabb15e | 241 | string ssend(buff+"\n"); |
YSI | 15:b2da6ab01a21 | 242 | if((_usb != NULL) && !buff.empty() && ((delivery == USB) || (delivery == ANY))) |
YSI | 15:b2da6ab01a21 | 243 | _usb->send((uint8_t*)ssend.c_str(), ssend.size()); |
YSI | 15:b2da6ab01a21 | 244 | if((_serial != NULL) && !buff.empty() && ((delivery == SERIAL) || (delivery == ANY))) |
YSI | 11:de94dcd67561 | 245 | ack = _serial->write(ssend.c_str(), ssend.length()); |
YSI | 15:b2da6ab01a21 | 246 | if((_eth != NULL) && ((delivery == TCP) || (delivery == HTTP) || (delivery == ANY))) |
YSI | 1:27f6baabb15e | 247 | { |
YSI | 15:b2da6ab01a21 | 248 | if(!message.BREAK && (message.status == BLUE_CLIENT) && !buff.empty()) |
YSI | 4:9a4ab4f406ab | 249 | eth_error("clientTCP_send", ack = _clientTCP->send(ssend.c_str(), ssend.size())); |
YSI | 15:b2da6ab01a21 | 250 | if(message.BREAK || (delivery == HTTP)) |
YSI | 4:9a4ab4f406ab | 251 | { |
YSI | 10:25e049353db5 | 252 | message.BREAK = false; |
YSI | 4:9a4ab4f406ab | 253 | eth_error("clientTCP_disconnect", _clientTCP->close()); |
YSI | 4:9a4ab4f406ab | 254 | eth_state(); |
YSI | 4:9a4ab4f406ab | 255 | serverTCP_event(); |
YSI | 4:9a4ab4f406ab | 256 | } |
YSI | 1:27f6baabb15e | 257 | } |
YSI | 1:27f6baabb15e | 258 | return ack; |
YSI | 1:27f6baabb15e | 259 | } |
YSI | 1:27f6baabb15e | 260 | |
YSI | 14:9e3accc681c4 | 261 | bool Transmission::smtp(const char* MAIL, const char* FROM, const char* SUBJECT, const char* DATA, const char* SERVER) |
YSI | 1:27f6baabb15e | 262 | { |
YSI | 11:de94dcd67561 | 263 | if(_eth == NULL) return false; |
YSI | 10:25e049353db5 | 264 | if((!message.DHCP) || (_eth->get_connection_status() != NSAPI_STATUS_GLOBAL_UP)) return false; |
YSI | 1:27f6baabb15e | 265 | TCPSocket clientSMTP; |
YSI | 14:9e3accc681c4 | 266 | clientSMTP.set_timeout(2000); |
YSI | 14:9e3accc681c4 | 267 | string sMAIL(MAIL), sFROM(FROM), sSUBJECT(SUBJECT), sDATA(DATA), sTO(sMAIL.substr(0, sMAIL.find("@"))); |
YSI | 15:b2da6ab01a21 | 268 | 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 | 269 | { "", "HELO Mbed\r\n", "MAIL FROM: <Mbed>\r\n","RCPT TO: <" + sMAIL + ">\r\n", "QUIT\r\n" }}; |
YSI | 1:27f6baabb15e | 270 | string code; |
YSI | 1:27f6baabb15e | 271 | if(eth_error("clientSMTP_open", clientSMTP.open(_eth)) == NSAPI_ERROR_OK) |
YSI | 1:27f6baabb15e | 272 | { |
YSI | 14:9e3accc681c4 | 273 | for(const string& ssend : smtpParams[(sFROM.empty())?1:0]) |
YSI | 1:27f6baabb15e | 274 | { |
YSI | 1:27f6baabb15e | 275 | char buffer[256] = {0}; |
YSI | 14:9e3accc681c4 | 276 | if(code.empty()) { if(eth_error("clientSMTP_connect", clientSMTP.connect(SocketAddress(SERVER, 25))) < NSAPI_ERROR_OK) break; } |
YSI | 1:27f6baabb15e | 277 | else if(eth_error("clientSMTP_send", clientSMTP.send(ssend.c_str(), ssend.size())) < NSAPI_ERROR_OK) break; |
YSI | 1:27f6baabb15e | 278 | if(eth_error("clientSMTP_recv", clientSMTP.recv(buffer, 256)) < NSAPI_ERROR_OK) break; |
YSI | 1:27f6baabb15e | 279 | buffer[3] = 0; |
YSI | 1:27f6baabb15e | 280 | code += buffer; |
YSI | 1:27f6baabb15e | 281 | if(ssend == "QUIT\r\n") break; |
YSI | 1:27f6baabb15e | 282 | } |
YSI | 1:27f6baabb15e | 283 | eth_error("clientSMTP_close", clientSMTP.close()); |
YSI | 1:27f6baabb15e | 284 | } |
YSI | 1:27f6baabb15e | 285 | if(sFROM.empty()) return code == "220250250250221"; |
YSI | 12:e22ff63d237c | 286 | #if MBED_MAJOR_VERSION > 5 |
YSI | 14:9e3accc681c4 | 287 | else if(code != "220250250250354250221") _queue->call_in(60s, this, &Transmission::smtp, MAIL, FROM, SUBJECT, DATA, SERVER); |
YSI | 12:e22ff63d237c | 288 | #else |
YSI | 14:9e3accc681c4 | 289 | else if(code != "220250250250354250221") _queue->call_in(60000, this, &Transmission::smtp, MAIL, FROM, SUBJECT, DATA, SERVER); |
YSI | 12:e22ff63d237c | 290 | #endif |
YSI | 1:27f6baabb15e | 291 | return code == "220250250250354250221"; |
YSI | 0:2fc6fc3b5e15 | 292 | } |
YSI | 0:2fc6fc3b5e15 | 293 | |
YSI | 14:9e3accc681c4 | 294 | time_t Transmission::ntp(const char* SERVER) |
YSI | 6:d6a07fd1548a | 295 | { |
YSI | 11:de94dcd67561 | 296 | if(_eth == NULL) return 0; |
YSI | 10:25e049353db5 | 297 | if((!message.DHCP) || (_eth->get_connection_status() != NSAPI_STATUS_GLOBAL_UP)) return 0; |
YSI | 6:d6a07fd1548a | 298 | time_t timeStamp = 0; |
YSI | 6:d6a07fd1548a | 299 | UDPSocket clientNTP; |
YSI | 14:9e3accc681c4 | 300 | clientNTP.set_timeout(2000); |
YSI | 6:d6a07fd1548a | 301 | if(eth_error("clientNTP_open", clientNTP.open(_eth)) == NSAPI_ERROR_OK) |
YSI | 6:d6a07fd1548a | 302 | { |
YSI | 6:d6a07fd1548a | 303 | uint32_t buffer[12] = { 0b11011, 0 }; // VN = 3 & Mode = 3 |
YSI | 14:9e3accc681c4 | 304 | SocketAddress server(SERVER, 123); |
YSI | 14:9e3accc681c4 | 305 | string sSERVER(SERVER); |
YSI | 14:9e3accc681c4 | 306 | if(sSERVER != TRANSMISSION_DEFAULT_NTP_SERVER) eth_error("eth_gethostbyname", _eth->gethostbyname(sSERVER.c_str(), &server)); |
YSI | 14:9e3accc681c4 | 307 | if(eth_error("clientNTP_send", clientNTP.sendto(server, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK) |
YSI | 6:d6a07fd1548a | 308 | { |
YSI | 6:d6a07fd1548a | 309 | if(eth_error("clientNTP_recv", clientNTP.recvfrom(NULL, (void*)buffer, sizeof(buffer))) > NSAPI_ERROR_OK) |
YSI | 6:d6a07fd1548a | 310 | { |
YSI | 6:d6a07fd1548a | 311 | timeStamp = ((buffer[10] & 0xFF) << 24) | ((buffer[10] & 0xFF00) << 8) | ((buffer[10] & 0xFF0000UL) >> 8) | ((buffer[10] & 0xFF000000UL) >> 24); |
YSI | 6:d6a07fd1548a | 312 | timeStamp -= 2208985200U; // 01/01/1970 Europe |
YSI | 6:d6a07fd1548a | 313 | struct tm * tmTimeStamp = localtime(&timeStamp); |
YSI | 10:25e049353db5 | 314 | 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 | 315 | timeStamp += 3600; // DST starts last Sunday of March; 2am (1am UTC), DST ends last Sunday of october; 3am (2am UTC) |
YSI | 6:d6a07fd1548a | 316 | } |
YSI | 6:d6a07fd1548a | 317 | } |
YSI | 6:d6a07fd1548a | 318 | eth_error("clientNTP_close", clientNTP.close()); |
YSI | 6:d6a07fd1548a | 319 | } |
YSI | 6:d6a07fd1548a | 320 | return timeStamp; |
YSI | 6:d6a07fd1548a | 321 | } |
YSI | 6:d6a07fd1548a | 322 | |
YSI | 0:2fc6fc3b5e15 | 323 | intptr_t Transmission::eth_status(const string& source, const intptr_t& code) |
YSI | 0:2fc6fc3b5e15 | 324 | { |
YSI | 14:9e3accc681c4 | 325 | #ifndef NDEBUG |
YSI | 14:9e3accc681c4 | 326 | ostringstream message; |
YSI | 0:2fc6fc3b5e15 | 327 | message << "\n" << source << "[" << code; |
YSI | 0:2fc6fc3b5e15 | 328 | switch(code) |
YSI | 0:2fc6fc3b5e15 | 329 | { |
YSI | 0:2fc6fc3b5e15 | 330 | case NSAPI_STATUS_LOCAL_UP: message << "] NSAPI_STATUS_LOCAL_UP < local IP address set >"; break; |
YSI | 0:2fc6fc3b5e15 | 331 | case NSAPI_STATUS_GLOBAL_UP: message << "] NSAPI_STATUS_GLOBAL_UP < global IP address set >"; break; |
YSI | 0:2fc6fc3b5e15 | 332 | case NSAPI_STATUS_DISCONNECTED: message << "] NSAPI_STATUS_DISCONNECTED < no connection to network >"; break; |
YSI | 0:2fc6fc3b5e15 | 333 | case NSAPI_STATUS_CONNECTING: message << "] NSAPI_STATUS_CONNECTING < connecting to network >"; break; |
YSI | 0:2fc6fc3b5e15 | 334 | case NSAPI_STATUS_ERROR_UNSUPPORTED: message << "] NSAPI_STATUS_ERROR_UNSUPPORTED < unsupported functionality >";break; |
YSI | 0:2fc6fc3b5e15 | 335 | } |
YSI | 1:27f6baabb15e | 336 | _serial->write(message.str().c_str(), message.str().size()); |
YSI | 1:27f6baabb15e | 337 | #endif |
YSI | 0:2fc6fc3b5e15 | 338 | return code; |
YSI | 0:2fc6fc3b5e15 | 339 | } |
YSI | 0:2fc6fc3b5e15 | 340 | |
YSI | 0:2fc6fc3b5e15 | 341 | nsapi_error_t Transmission::eth_error(const string& source, const nsapi_error_t& code) |
YSI | 0:2fc6fc3b5e15 | 342 | { |
YSI | 14:9e3accc681c4 | 343 | #ifndef NDEBUG |
YSI | 14:9e3accc681c4 | 344 | ostringstream message; |
YSI | 0:2fc6fc3b5e15 | 345 | message << "\n" << source << "[" << code; |
YSI | 0:2fc6fc3b5e15 | 346 | switch(code) |
YSI | 0:2fc6fc3b5e15 | 347 | { |
YSI | 0:2fc6fc3b5e15 | 348 | case NSAPI_ERROR_OK: message << "] NSAPI_ERROR_OK < no error >"; break; |
YSI | 0:2fc6fc3b5e15 | 349 | case NSAPI_ERROR_WOULD_BLOCK: message << "] NSAPI_ERROR_WOULD_BLOCK < no data is not available but call is non-blocking >";break; |
YSI | 0:2fc6fc3b5e15 | 350 | case NSAPI_ERROR_UNSUPPORTED: message << "] NSAPI_ERROR_UNSUPPORTED < unsupported functionality >"; break; |
YSI | 0:2fc6fc3b5e15 | 351 | case NSAPI_ERROR_PARAMETER: message << "] NSAPI_ERROR_PARAMETER < invalid configuration >"; break; |
YSI | 0:2fc6fc3b5e15 | 352 | case NSAPI_ERROR_NO_CONNECTION: message << "] NSAPI_ERROR_NO_CONNECTION < not connected to a network >"; break; |
YSI | 0:2fc6fc3b5e15 | 353 | case NSAPI_ERROR_NO_SOCKET: message << "] NSAPI_ERROR_NO_SOCKET < socket not available for use >"; break; |
YSI | 0:2fc6fc3b5e15 | 354 | case NSAPI_ERROR_NO_ADDRESS: message << "] NSAPI_ERROR_NO_ADDRESS < IP address is not known >"; break; |
YSI | 0:2fc6fc3b5e15 | 355 | case NSAPI_ERROR_NO_MEMORY: message << "] NSAPI_ERROR_NO_MEMORY < memory resource not available >"; break; |
YSI | 0:2fc6fc3b5e15 | 356 | case NSAPI_ERROR_NO_SSID: message << "] NSAPI_ERROR_NO_SSID < ssid not found >"; break; |
YSI | 0:2fc6fc3b5e15 | 357 | case NSAPI_ERROR_DNS_FAILURE: message << "] NSAPI_ERROR_DNS_FAILURE < DNS failed to complete successfully >"; break; |
YSI | 0:2fc6fc3b5e15 | 358 | case NSAPI_ERROR_DHCP_FAILURE: message << "] NSAPI_ERROR_DHCP_FAILURE < DHCP failed to complete successfully >"; break; |
YSI | 0:2fc6fc3b5e15 | 359 | case NSAPI_ERROR_AUTH_FAILURE: message << "] NSAPI_ERROR_AUTH_FAILURE < connection to access point failed >"; break; |
YSI | 0:2fc6fc3b5e15 | 360 | case NSAPI_ERROR_DEVICE_ERROR: message << "] NSAPI_ERROR_DEVICE_ERROR < failure interfacing with the network processor >"; break; |
YSI | 0:2fc6fc3b5e15 | 361 | case NSAPI_ERROR_IN_PROGRESS: message << "] NSAPI_ERROR_IN_PROGRESS < operation (eg connect) in progress >"; break; |
YSI | 0:2fc6fc3b5e15 | 362 | case NSAPI_ERROR_ALREADY: message << "] NSAPI_ERROR_ALREADY < operation (eg connect) already in progress >"; break; |
YSI | 0:2fc6fc3b5e15 | 363 | case NSAPI_ERROR_IS_CONNECTED: message << "] NSAPI_ERROR_IS_CONNECTED < socket is already connected >"; break; |
YSI | 0:2fc6fc3b5e15 | 364 | case NSAPI_ERROR_CONNECTION_LOST: message << "] NSAPI_ERROR_CONNECTION_LOST < connection lost >"; break; |
YSI | 0:2fc6fc3b5e15 | 365 | case NSAPI_ERROR_CONNECTION_TIMEOUT: message << "] NSAPI_ERROR_CONNECTION_TIMEOUT < connection timed out >"; break; |
YSI | 0:2fc6fc3b5e15 | 366 | case NSAPI_ERROR_ADDRESS_IN_USE: message << "] NSAPI_ERROR_ADDRESS_IN_USE < Address already in use >"; break; |
YSI | 0:2fc6fc3b5e15 | 367 | case NSAPI_ERROR_TIMEOUT: message << "] NSAPI_ERROR_TIMEOUT < operation timed out >"; break; |
YSI | 0:2fc6fc3b5e15 | 368 | case NSAPI_ERROR_BUSY: message << "] NSAPI_ERROR_BUSY < device is busy and cannot accept new operation >"; break; |
YSI | 0:2fc6fc3b5e15 | 369 | default: message << "] NSAPI_ERROR < unknow code >"; break; |
YSI | 0:2fc6fc3b5e15 | 370 | } |
YSI | 1:27f6baabb15e | 371 | if(code < NSAPI_ERROR_OK) _serial->write(message.str().c_str(), message.str().size()); |
YSI | 1:27f6baabb15e | 372 | #endif |
YSI | 0:2fc6fc3b5e15 | 373 | return code; |
YSI | 0:2fc6fc3b5e15 | 374 | } |