Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
ISM43362Interface.cpp
00001 /* ISM43362 implementation of NetworkInterfaceAPI 00002 * Copyright (c) STMicroelectronics 2018 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include <string.h> 00018 #include "ISM43362Interface.h" 00019 #include "mbed_debug.h" 00020 00021 // Product ID,FW Revision,API Revision,Stack Revision,RTOS Revision,CPU Clock,Product Name 00022 #define LATEST_FW_VERSION_NUMBER "C3.5.2.5" // ISM43362-M3G-L44-SPI,C3.5.2.5.STM,v3.5.2,v1.4.0.rc1,v8.2.1,120000000,Inventek eS-WiFi 00023 00024 // activate / de-activate debug 00025 #define ism_interface_debug 0 00026 00027 #define MIN(a,b) (((a)<(b))?(a):(b)) 00028 00029 // ISM43362Interface implementation 00030 ISM43362Interface::ISM43362Interface(bool debug) 00031 : _ism(MBED_CONF_ISM43362_WIFI_MOSI, MBED_CONF_ISM43362_WIFI_MISO, MBED_CONF_ISM43362_WIFI_SCLK, MBED_CONF_ISM43362_WIFI_NSS, MBED_CONF_ISM43362_WIFI_RESET, MBED_CONF_ISM43362_WIFI_DATAREADY, MBED_CONF_ISM43362_WIFI_WAKEUP, debug) 00032 { 00033 _ism_debug = ism_interface_debug || debug; 00034 memset(_ids, 0, sizeof(_ids)); 00035 memset(_socket_obj, 0, sizeof(_socket_obj)); 00036 memset(_cbs, 0, sizeof(_cbs)); 00037 memset(ap_ssid, 0, sizeof(ap_ssid)); 00038 memset(ap_pass, 0, sizeof(ap_pass)); 00039 ap_sec = ISM_SECURITY_UNKNOWN; 00040 00041 thread_read_socket.start(callback(this, &ISM43362Interface::socket_check_read)); 00042 00043 _mutex.lock(); 00044 00045 // Check all supported firmware versions 00046 _FwVersion = _ism.get_firmware_version(); 00047 00048 if (!_FwVersion) { 00049 error("ISM43362Interface: ERROR cannot read firmware version\r\n"); 00050 } 00051 00052 debug_if(_ism_debug, "ISM43362Interface: read_version = %lu\r\n", _FwVersion); 00053 /* FW Revision should be with format "CX.X.X.X" with X as a single digit */ 00054 if ( (_FwVersion < 1000) || (_FwVersion > 9999) ) { 00055 debug_if(_ism_debug, "ISM43362Interface: read_version issue\r\n"); 00056 } 00057 00058 #if TARGET_DISCO_L475VG_IOT01A 00059 if (_FwVersion < ParseNumber(LATEST_FW_VERSION_NUMBER, NULL)) { 00060 debug_if(_ism_debug, "ISM43362Interface: please update FW\r\n"); 00061 } 00062 #endif 00063 00064 _mutex.unlock(); 00065 } 00066 00067 int ISM43362Interface::connect(const char *ssid, const char *pass, nsapi_security_t security, 00068 uint8_t channel) 00069 { 00070 if (channel != 0) { 00071 return NSAPI_ERROR_UNSUPPORTED; 00072 } 00073 00074 nsapi_error_t credentials_status = set_credentials(ssid, pass, security); 00075 if (credentials_status) { 00076 return credentials_status; 00077 } 00078 00079 return connect(); 00080 } 00081 00082 int ISM43362Interface::connect() 00083 { 00084 if (strlen(ap_ssid) == 0) { 00085 return NSAPI_ERROR_NO_SSID; 00086 } 00087 00088 _mutex.lock(); 00089 00090 if (!_ism.dhcp(true)) { 00091 _mutex.unlock(); 00092 return NSAPI_ERROR_DHCP_FAILURE; 00093 } 00094 00095 int connect_status = _ism.connect(ap_ssid, ap_pass, ap_sec); 00096 debug_if(_ism_debug, "ISM43362Interface: connect_status %d\n", connect_status); 00097 00098 if (connect_status != NSAPI_ERROR_OK) { 00099 _mutex.unlock(); 00100 return connect_status; 00101 } 00102 00103 if (!_ism.getIPAddress()) { 00104 _mutex.unlock(); 00105 return NSAPI_ERROR_DHCP_FAILURE; 00106 } 00107 00108 _mutex.unlock(); 00109 00110 return NSAPI_ERROR_OK; 00111 } 00112 00113 nsapi_error_t ISM43362Interface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) 00114 { 00115 if (strlen(name) == 0) { 00116 return NSAPI_ERROR_NO_SOCKET; 00117 } 00118 00119 _mutex.lock(); 00120 if (address->set_ip_address(name)) { 00121 if (version != NSAPI_UNSPEC && address->get_ip_version() != version) { 00122 _mutex.unlock(); 00123 return NSAPI_ERROR_DNS_FAILURE; 00124 } 00125 00126 _mutex.unlock(); 00127 return NSAPI_ERROR_OK; 00128 } 00129 00130 char *ipbuff = new char[NSAPI_IP_SIZE]; 00131 int ret = 0; 00132 if (!_ism.dns_lookup(name, ipbuff)) { 00133 ret = NSAPI_ERROR_DEVICE_ERROR; 00134 } else { 00135 address->set_ip_address(ipbuff); 00136 } 00137 _mutex.unlock(); 00138 00139 delete[] ipbuff; 00140 00141 return ret; 00142 } 00143 00144 int ISM43362Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) 00145 { 00146 if ((strlen(ssid) == 0) || (strlen(ssid) > 32)) { 00147 return NSAPI_ERROR_PARAMETER; 00148 } 00149 00150 if ((security != NSAPI_SECURITY_NONE) && (strcmp(pass, "") == 0)) { 00151 return NSAPI_ERROR_PARAMETER; 00152 } 00153 00154 if (strlen(pass) > 63) { 00155 return NSAPI_ERROR_PARAMETER; 00156 } 00157 00158 _mutex.lock(); 00159 memset(ap_ssid, 0, sizeof(ap_ssid)); 00160 strncpy(ap_ssid, ssid, sizeof(ap_ssid)); 00161 00162 memset(ap_pass, 0, sizeof(ap_pass)); 00163 strncpy(ap_pass, pass, sizeof(ap_pass)); 00164 00165 switch (security) { 00166 case NSAPI_SECURITY_NONE: 00167 ap_sec = ISM_SECURITY_NONE; 00168 break; 00169 case NSAPI_SECURITY_WEP: 00170 ap_sec = ISM_SECURITY_WEP; 00171 break; 00172 case NSAPI_SECURITY_WPA: 00173 ap_sec = ISM_SECURITY_WPA; 00174 break; 00175 case NSAPI_SECURITY_WPA2: 00176 ap_sec = ISM_SECURITY_WPA2; 00177 break; 00178 case NSAPI_SECURITY_WPA_WPA2: 00179 ap_sec = ISM_SECURITY_WPA_WPA2; 00180 break; 00181 default: 00182 ap_sec = ISM_SECURITY_UNKNOWN; 00183 break; 00184 } 00185 _mutex.unlock(); 00186 00187 return NSAPI_ERROR_OK; 00188 } 00189 00190 int ISM43362Interface::set_channel(uint8_t channel) 00191 { 00192 return NSAPI_ERROR_UNSUPPORTED; 00193 } 00194 00195 int ISM43362Interface::disconnect() 00196 { 00197 _mutex.lock(); 00198 00199 if (!_ism.disconnect()) { 00200 _mutex.unlock(); 00201 return NSAPI_ERROR_DEVICE_ERROR; 00202 } 00203 00204 _mutex.unlock(); 00205 00206 return NSAPI_ERROR_OK; 00207 } 00208 00209 const char *ISM43362Interface::get_ip_address() 00210 { 00211 _mutex.lock(); 00212 const char *ret = _ism.getIPAddress(); 00213 _mutex.unlock(); 00214 return ret; 00215 } 00216 00217 const char *ISM43362Interface::get_mac_address() 00218 { 00219 _mutex.lock(); 00220 const char *ret = _ism.getMACAddress(); 00221 _mutex.unlock(); 00222 return ret; 00223 } 00224 00225 const char *ISM43362Interface::get_gateway() 00226 { 00227 _mutex.lock(); 00228 const char *ret = _ism.getGateway(); 00229 _mutex.unlock(); 00230 return ret; 00231 } 00232 00233 const char *ISM43362Interface::get_netmask() 00234 { 00235 _mutex.lock(); 00236 const char *ret = _ism.getNetmask(); 00237 _mutex.unlock(); 00238 return ret; 00239 } 00240 00241 int8_t ISM43362Interface::get_rssi() 00242 { 00243 _mutex.lock(); 00244 int8_t ret = _ism.getRSSI(); 00245 _mutex.unlock(); 00246 return ret; 00247 } 00248 00249 int ISM43362Interface::scan(WiFiAccessPoint *res, unsigned count) 00250 { 00251 _mutex.lock(); 00252 int ret = _ism.scan(res, count); 00253 _mutex.unlock(); 00254 return ret; 00255 } 00256 00257 struct ISM43362_socket { 00258 int id; 00259 nsapi_protocol_t proto; 00260 volatile bool connected; 00261 SocketAddress addr; 00262 char read_data[1400]; 00263 volatile uint32_t read_data_size; 00264 }; 00265 00266 int ISM43362Interface::socket_open(void **handle, nsapi_protocol_t proto) 00267 { 00268 // Look for an unused socket 00269 int id = -1; 00270 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00271 if (!_ids[i]) { 00272 id = i; 00273 _ids[i] = true; 00274 break; 00275 } 00276 } 00277 00278 if (id == -1) { 00279 return NSAPI_ERROR_NO_SOCKET; 00280 } 00281 _mutex.lock(); 00282 struct ISM43362_socket *socket = new struct ISM43362_socket; 00283 if (!socket) { 00284 _mutex.unlock(); 00285 return NSAPI_ERROR_NO_SOCKET; 00286 } 00287 socket->id = id; 00288 debug_if(_ism_debug, "ISM43362Interface: socket_open, id=%d\n", socket->id); 00289 memset(socket->read_data, 0, sizeof(socket->read_data)); 00290 socket->addr = 0; 00291 socket->read_data_size = 0; 00292 socket->proto = proto; 00293 socket->connected = false; 00294 *handle = socket; 00295 _mutex.unlock(); 00296 00297 return 0; 00298 } 00299 00300 int ISM43362Interface::socket_close(void *handle) 00301 { 00302 _mutex.lock(); 00303 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00304 debug_if(_ism_debug, "ISM43362Interface: socket_close, id=%d\n", socket->id); 00305 int err = 0; 00306 00307 if (!_ism.close(socket->id)) { 00308 err = NSAPI_ERROR_DEVICE_ERROR; 00309 } 00310 00311 socket->connected = false; 00312 _ids[socket->id] = false; 00313 _socket_obj[socket->id] = 0; 00314 _mutex.unlock(); 00315 delete socket; 00316 return err; 00317 } 00318 00319 int ISM43362Interface::socket_bind(void *handle, const SocketAddress &address) 00320 { 00321 return NSAPI_ERROR_UNSUPPORTED; 00322 } 00323 00324 int ISM43362Interface::socket_listen(void *handle, int backlog) 00325 { 00326 return NSAPI_ERROR_UNSUPPORTED; 00327 } 00328 00329 int ISM43362Interface::socket_connect(void *handle, const SocketAddress &addr) 00330 { 00331 _mutex.lock(); 00332 int ret = socket_connect_nolock(handle, addr); 00333 _mutex.unlock(); 00334 return ret; 00335 } 00336 00337 int ISM43362Interface::socket_connect_nolock(void *handle, const SocketAddress &addr) 00338 { 00339 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00340 const char *proto = (socket->proto == NSAPI_UDP) ? "1" : "0"; 00341 if (!_ism.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) { 00342 return NSAPI_ERROR_DEVICE_ERROR; 00343 } 00344 _ids[socket->id] = true; 00345 _socket_obj[socket->id] = (uint32_t)socket; 00346 socket->connected = true; 00347 return 0; 00348 00349 } 00350 00351 00352 00353 void ISM43362Interface::socket_check_read() 00354 { 00355 while (1) { 00356 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00357 _mutex.lock(); 00358 if (_socket_obj[i] != 0) { 00359 struct ISM43362_socket *socket = (struct ISM43362_socket *)_socket_obj[i]; 00360 /* Check if there is something to read for this socket. But if it */ 00361 /* has already been read : don't read again */ 00362 if ((socket->connected) && (socket->read_data_size == 0) && _cbs[socket->id].callback) { 00363 /* if no callback is set, no need to read ?*/ 00364 int read_amount = _ism.check_recv_status(socket->id, socket->read_data); 00365 // debug_if(_ism_debug, "ISM43362Interface socket_check_read: i %d read_amount %d \r\n", i, read_amount); 00366 if (read_amount > 0) { 00367 socket->read_data_size = read_amount; 00368 } else if (read_amount < 0) { 00369 /* Mark donw connection has been lost or closed */ 00370 debug_if(_ism_debug, "ISM43362Interface socket_check_read: i %d closed\r\n", i, read_amount); 00371 socket->connected = false; 00372 } 00373 if (read_amount != 0) { 00374 /* There is something to read in this socket*/ 00375 if (_cbs[socket->id].callback) { 00376 _cbs[socket->id].callback(_cbs[socket->id].data); 00377 } 00378 } 00379 } 00380 } 00381 _mutex.unlock(); 00382 } 00383 wait_ms(50); 00384 } 00385 } 00386 00387 int ISM43362Interface::socket_accept(void *server, void **socket, SocketAddress *addr) 00388 { 00389 return NSAPI_ERROR_UNSUPPORTED; 00390 } 00391 00392 int ISM43362Interface::socket_send(void *handle, const void *data, unsigned size) 00393 { 00394 _mutex.lock(); 00395 int ret = socket_send_nolock(handle, data, size); 00396 _mutex.unlock(); 00397 return ret; 00398 } 00399 00400 /* CAREFULL LOCK must be taken before callling this function */ 00401 int ISM43362Interface::socket_send_nolock(void *handle, const void *data, unsigned size) 00402 { 00403 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00404 00405 if (size > ES_WIFI_MAX_TX_PACKET_SIZE) { 00406 size = ES_WIFI_MAX_TX_PACKET_SIZE; 00407 } 00408 00409 if (!_ism.send(socket->id, data, size)) { 00410 debug_if(_ism_debug, "ISM43362Interface: socket_send ERROR\r\n"); 00411 return NSAPI_ERROR_DEVICE_ERROR; // or WOULD_BLOCK ? 00412 } 00413 00414 return size; 00415 } 00416 00417 int ISM43362Interface::socket_recv(void *handle, void *data, unsigned size) 00418 { 00419 _mutex.lock(); 00420 unsigned recv = 0; 00421 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00422 char *ptr = (char *)data; 00423 00424 // debug_if(_ism_debug, "ISM43362Interface socket_recv: req=%d read_data_size=%d connected %d\r\n", size, socket->read_data_size, socket->connected); 00425 00426 if (!socket->connected) { 00427 _mutex.unlock(); 00428 return NSAPI_ERROR_CONNECTION_LOST; 00429 } 00430 00431 if (socket->read_data_size == 0) { 00432 /* if no callback is set, no need to read ?*/ 00433 int read_amount = _ism.check_recv_status(socket->id, socket->read_data); 00434 if (read_amount > 0) { 00435 socket->read_data_size = read_amount; 00436 } else if (read_amount < 0) { 00437 socket->connected = false; 00438 debug_if(_ism_debug, "ISM43362Interface socket_recv: socket closed\r\n"); 00439 _mutex.unlock(); 00440 return NSAPI_ERROR_CONNECTION_LOST; 00441 } 00442 } 00443 00444 if (socket->read_data_size != 0) { 00445 // debug_if(_ism_debug, "ISM43362Interface socket_recv: read_data_size=%d\r\n", socket->read_data_size); 00446 uint32_t i = 0; 00447 while ((i < socket->read_data_size) && (i < size)) { 00448 *ptr++ = socket->read_data[i]; 00449 i++; 00450 } 00451 00452 recv += i; 00453 00454 if (i >= socket->read_data_size) { 00455 /* All the storeed data has been read, reset buffer */ 00456 memset(socket->read_data, 0, sizeof(socket->read_data)); 00457 socket->read_data_size = 0; 00458 // debug_if(_ism_debug, "ISM43362Interface: Socket_recv buffer reset\r\n"); 00459 } else { 00460 /* In case there is remaining data in buffer, update socket content 00461 * For now by shift copy of all data (not very efficient to be 00462 * revised */ 00463 while (i < socket->read_data_size) { 00464 socket->read_data[i - size] = socket->read_data[i]; 00465 i++; 00466 } 00467 00468 socket->read_data_size -= size; 00469 } 00470 } 00471 // else { 00472 // debug_if(_ism_debug, "ISM43362Interface socket_recv: Nothing in buffer\r\n"); 00473 // } 00474 00475 _mutex.unlock(); 00476 00477 if (recv > 0) { 00478 debug_if(_ism_debug, "ISM43362Interface socket_recv: recv=%d\r\n", recv); 00479 return recv; 00480 } else { 00481 debug_if(_ism_debug, "ISM43362Interface socket_recv: returns WOULD BLOCK\r\n"); 00482 return NSAPI_ERROR_WOULD_BLOCK; 00483 } 00484 } 00485 00486 int ISM43362Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00487 { 00488 _mutex.lock(); 00489 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00490 00491 if (socket->connected && socket->addr != addr) { 00492 if (!_ism.close(socket->id)) { 00493 debug_if(_ism_debug, "ISM43362Interface: socket_sendto ERROR\r\n"); 00494 _mutex.unlock(); 00495 return NSAPI_ERROR_DEVICE_ERROR; 00496 } 00497 socket->connected = false; 00498 _ids[socket->id] = false; 00499 _socket_obj[socket->id] = 0; 00500 } 00501 00502 if (!socket->connected) { 00503 int err = socket_connect_nolock(socket, addr); 00504 if (err < 0) { 00505 _mutex.unlock(); 00506 return err; 00507 } 00508 socket->addr = addr; 00509 } 00510 00511 int ret = socket_send_nolock(socket, data, size); 00512 00513 _mutex.unlock(); 00514 00515 return ret; 00516 } 00517 00518 int ISM43362Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00519 { 00520 int ret = socket_recv(handle, data, size); 00521 _mutex.lock(); 00522 if ((ret >= 0) && addr) { 00523 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00524 *addr = socket->addr; 00525 } 00526 _mutex.unlock(); 00527 return ret; 00528 } 00529 00530 void ISM43362Interface::socket_attach(void *handle, void (*cb)(void *), void *data) 00531 { 00532 _mutex.lock(); 00533 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00534 _cbs[socket->id].callback = cb; 00535 _cbs[socket->id].data = data; 00536 _mutex.unlock(); 00537 } 00538 00539 void ISM43362Interface::event() 00540 { 00541 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00542 if (_cbs[i].callback) { 00543 _cbs[i].callback(_cbs[i].data); 00544 } 00545 } 00546 } 00547 00548 #if MBED_CONF_ISM43362_PROVIDE_DEFAULT 00549 00550 WiFiInterface *WiFiInterface::get_default_instance() { 00551 static ISM43362Interface ism; 00552 return &ism; 00553 } 00554 00555 #endif
Generated on Tue Jul 12 2022 19:12:12 by 1.7.2