Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 _conn_stat(NSAPI_STATUS_DISCONNECTED), 00033 _conn_stat_cb(NULL) 00034 { 00035 _ism_debug = ism_interface_debug || debug; 00036 memset(_ids, 0, sizeof(_ids)); 00037 memset(_socket_obj, 0, sizeof(_socket_obj)); 00038 _ism.attach(this, &ISM43362Interface::update_conn_state_cb); 00039 memset(_cbs, 0, sizeof(_cbs)); 00040 memset(ap_ssid, 0, sizeof(ap_ssid)); 00041 memset(ap_pass, 0, sizeof(ap_pass)); 00042 ap_sec = ISM_SECURITY_UNKNOWN; 00043 00044 thread_read_socket.start(callback(this, &ISM43362Interface::socket_check_read)); 00045 00046 _mutex.lock(); 00047 00048 // Check all supported firmware versions 00049 _FwVersion = _ism.get_firmware_version(); 00050 00051 if (!_FwVersion) { 00052 error("ISM43362Interface: ERROR cannot read firmware version\r\n"); 00053 } 00054 00055 debug_if(_ism_debug, "ISM43362Interface: read_version = %lu\r\n", _FwVersion); 00056 /* FW Revision should be with format "CX.X.X.X" with X as a single digit */ 00057 if ( (_FwVersion < 1000) || (_FwVersion > 9999) ) { 00058 debug_if(_ism_debug, "ISM43362Interface: read_version issue\r\n"); 00059 } 00060 00061 #if TARGET_DISCO_L475VG_IOT01A 00062 if (_FwVersion < ParseNumber(LATEST_FW_VERSION_NUMBER, NULL)) { 00063 debug_if(_ism_debug, "ISM43362Interface: please update FW\r\n"); 00064 } 00065 #endif 00066 00067 _connect_status = NSAPI_ERROR_NO_CONNECTION; 00068 _mutex.unlock(); 00069 } 00070 00071 nsapi_error_t ISM43362Interface::connect(const char *ssid, const char *pass, nsapi_security_t security, 00072 uint8_t channel) 00073 { 00074 if (channel != 0) { 00075 return NSAPI_ERROR_UNSUPPORTED; 00076 } 00077 00078 nsapi_error_t credentials_status = set_credentials(ssid, pass, security); 00079 if (credentials_status) { 00080 return credentials_status; 00081 } 00082 00083 return connect(); 00084 } 00085 00086 nsapi_error_t ISM43362Interface::connect() 00087 { 00088 if (strlen(ap_ssid) == 0) { 00089 return NSAPI_ERROR_NO_SSID; 00090 } 00091 00092 _mutex.lock(); 00093 00094 if (!_ism.dhcp(true)) { 00095 _mutex.unlock(); 00096 return NSAPI_ERROR_DHCP_FAILURE; 00097 } 00098 00099 _connect_status = _ism.connect(ap_ssid, ap_pass, ap_sec); 00100 debug_if(_ism_debug, "ISM43362Interface: connect_status %d\n", _connect_status); 00101 00102 if (_connect_status != NSAPI_ERROR_OK) { 00103 _mutex.unlock(); 00104 return _connect_status; 00105 } 00106 00107 if (!_ism.getIPAddress()) { 00108 _connect_status = NSAPI_ERROR_DHCP_FAILURE; 00109 _mutex.unlock(); 00110 return NSAPI_ERROR_DHCP_FAILURE; 00111 } 00112 00113 _mutex.unlock(); 00114 00115 return NSAPI_ERROR_OK; 00116 } 00117 00118 nsapi_error_t ISM43362Interface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) 00119 { 00120 if (strlen(name) == 0) { 00121 return NSAPI_ERROR_NO_SOCKET; 00122 } 00123 00124 _mutex.lock(); 00125 if (address->set_ip_address(name)) { 00126 if (version != NSAPI_UNSPEC && address->get_ip_version() != version) { 00127 _mutex.unlock(); 00128 return NSAPI_ERROR_DNS_FAILURE; 00129 } 00130 00131 _mutex.unlock(); 00132 return NSAPI_ERROR_OK; 00133 } 00134 00135 char *ipbuff = new char[NSAPI_IP_SIZE]; 00136 int ret = 0; 00137 if (!_ism.dns_lookup(name, ipbuff)) { 00138 ret = NSAPI_ERROR_DNS_FAILURE; 00139 } else { 00140 address->set_ip_address(ipbuff); 00141 } 00142 _mutex.unlock(); 00143 00144 delete[] ipbuff; 00145 00146 return ret; 00147 } 00148 00149 int ISM43362Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) 00150 { 00151 if ((ssid == NULL) || (strlen(ssid) == 0) || (strlen(ssid) > 32)) { 00152 return NSAPI_ERROR_PARAMETER; 00153 } 00154 00155 if (security != NSAPI_SECURITY_NONE) { 00156 if ((pass == NULL) || (strcmp(pass, "") == 0)) { 00157 return NSAPI_ERROR_PARAMETER; 00158 } 00159 } 00160 00161 if (strlen(pass) > 63) { 00162 return NSAPI_ERROR_PARAMETER; 00163 } 00164 00165 _mutex.lock(); 00166 memset(ap_ssid, 0, sizeof(ap_ssid)); 00167 strncpy(ap_ssid, ssid, sizeof(ap_ssid)); 00168 00169 memset(ap_pass, 0, sizeof(ap_pass)); 00170 strncpy(ap_pass, pass, sizeof(ap_pass)); 00171 00172 switch (security) { 00173 case NSAPI_SECURITY_NONE: 00174 ap_sec = ISM_SECURITY_NONE; 00175 break; 00176 case NSAPI_SECURITY_WEP: 00177 ap_sec = ISM_SECURITY_WEP; 00178 break; 00179 case NSAPI_SECURITY_WPA: 00180 ap_sec = ISM_SECURITY_WPA; 00181 break; 00182 case NSAPI_SECURITY_WPA2: 00183 ap_sec = ISM_SECURITY_WPA2; 00184 break; 00185 case NSAPI_SECURITY_WPA_WPA2: 00186 ap_sec = ISM_SECURITY_WPA_WPA2; 00187 break; 00188 default: 00189 ap_sec = ISM_SECURITY_UNKNOWN; 00190 break; 00191 } 00192 _mutex.unlock(); 00193 00194 return NSAPI_ERROR_OK; 00195 } 00196 00197 int ISM43362Interface::set_channel(uint8_t channel) 00198 { 00199 return NSAPI_ERROR_UNSUPPORTED; 00200 } 00201 00202 nsapi_error_t ISM43362Interface::disconnect() 00203 { 00204 _mutex.lock(); 00205 00206 if (_connect_status != NSAPI_ERROR_OK) { 00207 _mutex.unlock(); 00208 return NSAPI_ERROR_NO_CONNECTION; 00209 } 00210 00211 if (!_ism.disconnect()) { 00212 _mutex.unlock(); 00213 return NSAPI_ERROR_DEVICE_ERROR; 00214 } 00215 00216 _connect_status = NSAPI_ERROR_NO_CONNECTION; 00217 _mutex.unlock(); 00218 return NSAPI_ERROR_OK; 00219 } 00220 00221 const char *ISM43362Interface::get_ip_address() 00222 { 00223 _mutex.lock(); 00224 const char *ret = _ism.getIPAddress(); 00225 _mutex.unlock(); 00226 return ret; 00227 } 00228 00229 const char *ISM43362Interface::get_mac_address() 00230 { 00231 _mutex.lock(); 00232 const char *ret = _ism.getMACAddress(); 00233 _mutex.unlock(); 00234 return ret; 00235 } 00236 00237 const char *ISM43362Interface::get_gateway() 00238 { 00239 _mutex.lock(); 00240 const char *ret = _ism.getGateway(); 00241 _mutex.unlock(); 00242 return ret; 00243 } 00244 00245 const char *ISM43362Interface::get_netmask() 00246 { 00247 _mutex.lock(); 00248 const char *ret = _ism.getNetmask(); 00249 _mutex.unlock(); 00250 return ret; 00251 } 00252 00253 int8_t ISM43362Interface::get_rssi() 00254 { 00255 _mutex.lock(); 00256 int8_t ret = _ism.getRSSI(); 00257 _mutex.unlock(); 00258 return ret; 00259 } 00260 00261 int ISM43362Interface::scan(WiFiAccessPoint *res, unsigned count) 00262 { 00263 _mutex.lock(); 00264 int ret = _ism.scan(res, count); 00265 _mutex.unlock(); 00266 return ret; 00267 } 00268 00269 struct ISM43362_socket { 00270 int id; 00271 nsapi_protocol_t proto; 00272 volatile bool connected; 00273 SocketAddress addr; 00274 char read_data[1400]; 00275 volatile uint32_t read_data_size; 00276 }; 00277 00278 int ISM43362Interface::socket_open(void **handle, nsapi_protocol_t proto) 00279 { 00280 // Look for an unused socket 00281 int id = -1; 00282 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00283 if (!_ids[i]) { 00284 id = i; 00285 _ids[i] = true; 00286 break; 00287 } 00288 } 00289 00290 if (id == -1) { 00291 return NSAPI_ERROR_NO_SOCKET; 00292 } 00293 _mutex.lock(); 00294 struct ISM43362_socket *socket = new struct ISM43362_socket; 00295 if (!socket) { 00296 _mutex.unlock(); 00297 return NSAPI_ERROR_NO_SOCKET; 00298 } 00299 socket->id = id; 00300 debug_if(_ism_debug, "ISM43362Interface: socket_open, id=%d\n", socket->id); 00301 memset(socket->read_data, 0, sizeof(socket->read_data)); 00302 socket->addr = 0; 00303 socket->read_data_size = 0; 00304 socket->proto = proto; 00305 socket->connected = false; 00306 *handle = socket; 00307 _mutex.unlock(); 00308 00309 return 0; 00310 } 00311 00312 int ISM43362Interface::socket_close(void *handle) 00313 { 00314 _mutex.lock(); 00315 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00316 debug_if(_ism_debug, "ISM43362Interface: socket_close, id=%d\n", socket->id); 00317 int err = 0; 00318 00319 if (!_ism.close(socket->id)) { 00320 err = NSAPI_ERROR_DEVICE_ERROR; 00321 } 00322 00323 socket->connected = false; 00324 _ids[socket->id] = false; 00325 _socket_obj[socket->id] = 0; 00326 _mutex.unlock(); 00327 delete socket; 00328 return err; 00329 } 00330 00331 int ISM43362Interface::socket_bind(void *handle, const SocketAddress &address) 00332 { 00333 return NSAPI_ERROR_UNSUPPORTED; 00334 } 00335 00336 int ISM43362Interface::socket_listen(void *handle, int backlog) 00337 { 00338 return NSAPI_ERROR_UNSUPPORTED; 00339 } 00340 00341 int ISM43362Interface::socket_connect(void *handle, const SocketAddress &addr) 00342 { 00343 _mutex.lock(); 00344 int ret = socket_connect_nolock(handle, addr); 00345 _mutex.unlock(); 00346 return ret; 00347 } 00348 00349 int ISM43362Interface::socket_connect_nolock(void *handle, const SocketAddress &addr) 00350 { 00351 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00352 const char *proto = (socket->proto == NSAPI_UDP) ? "1" : "0"; 00353 if (!_ism.open(proto, socket->id, addr.get_ip_address(), addr.get_port())) { 00354 return NSAPI_ERROR_DEVICE_ERROR; 00355 } 00356 _ids[socket->id] = true; 00357 _socket_obj[socket->id] = (uint32_t)socket; 00358 socket->connected = true; 00359 return 0; 00360 00361 } 00362 00363 00364 00365 void ISM43362Interface::socket_check_read() 00366 { 00367 while (1) { 00368 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00369 _mutex.lock(); 00370 if (_socket_obj[i] != 0) { 00371 struct ISM43362_socket *socket = (struct ISM43362_socket *)_socket_obj[i]; 00372 /* Check if there is something to read for this socket. But if it */ 00373 /* has already been read : don't read again */ 00374 if ((socket->connected) && (socket->read_data_size == 0) && _cbs[socket->id].callback) { 00375 /* if no callback is set, no need to read ?*/ 00376 int read_amount = _ism.check_recv_status(socket->id, socket->read_data); 00377 // debug_if(_ism_debug, "ISM43362Interface socket_check_read: i %d read_amount %d \r\n", i, read_amount); 00378 if (read_amount > 0) { 00379 socket->read_data_size = read_amount; 00380 } else if (read_amount < 0) { 00381 /* Mark donw connection has been lost or closed */ 00382 debug_if(_ism_debug, "ISM43362Interface socket_check_read: i %d closed\r\n", i); 00383 socket->connected = false; 00384 } 00385 if (read_amount != 0) { 00386 /* There is something to read in this socket*/ 00387 if (_cbs[socket->id].callback) { 00388 _cbs[socket->id].callback(_cbs[socket->id].data); 00389 } 00390 } 00391 } 00392 } 00393 _mutex.unlock(); 00394 } 00395 wait_ms(50); 00396 } 00397 } 00398 00399 int ISM43362Interface::socket_accept(void *server, void **socket, SocketAddress *addr) 00400 { 00401 return NSAPI_ERROR_UNSUPPORTED; 00402 } 00403 00404 int ISM43362Interface::socket_send(void *handle, const void *data, unsigned size) 00405 { 00406 _mutex.lock(); 00407 int ret = socket_send_nolock(handle, data, size); 00408 _mutex.unlock(); 00409 return ret; 00410 } 00411 00412 /* CAREFULL LOCK must be taken before callling this function */ 00413 int ISM43362Interface::socket_send_nolock(void *handle, const void *data, unsigned size) 00414 { 00415 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00416 00417 if (size > ES_WIFI_MAX_TX_PACKET_SIZE) { 00418 size = ES_WIFI_MAX_TX_PACKET_SIZE; 00419 } 00420 00421 if (!_ism.send(socket->id, data, size)) { 00422 debug_if(_ism_debug, "ISM43362Interface: socket_send ERROR\r\n"); 00423 return NSAPI_ERROR_DEVICE_ERROR; // or WOULD_BLOCK ? 00424 } 00425 00426 return size; 00427 } 00428 00429 int ISM43362Interface::socket_recv(void *handle, void *data, unsigned size) 00430 { 00431 _mutex.lock(); 00432 unsigned recv = 0; 00433 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00434 char *ptr = (char *)data; 00435 00436 // debug_if(_ism_debug, "ISM43362Interface socket_recv: req=%d read_data_size=%d connected %d\r\n", size, socket->read_data_size, socket->connected); 00437 00438 if (!socket->connected) { 00439 _mutex.unlock(); 00440 return 0; 00441 } 00442 00443 if (socket->read_data_size == 0) { 00444 /* if no callback is set, no need to read ?*/ 00445 int read_amount = _ism.check_recv_status(socket->id, socket->read_data); 00446 if (read_amount > 0) { 00447 socket->read_data_size = read_amount; 00448 } else if (read_amount < 0) { 00449 socket->connected = false; 00450 debug_if(_ism_debug, "ISM43362Interface socket_recv: socket closed\r\n"); 00451 _mutex.unlock(); 00452 return 0; 00453 } 00454 } 00455 00456 if (socket->read_data_size != 0) { 00457 // debug_if(_ism_debug, "ISM43362Interface socket_recv: read_data_size=%d\r\n", socket->read_data_size); 00458 uint32_t i = 0; 00459 while ((i < socket->read_data_size) && (i < size)) { 00460 *ptr++ = socket->read_data[i]; 00461 i++; 00462 } 00463 00464 recv += i; 00465 00466 if (i >= socket->read_data_size) { 00467 /* All the storeed data has been read, reset buffer */ 00468 memset(socket->read_data, 0, sizeof(socket->read_data)); 00469 socket->read_data_size = 0; 00470 // debug_if(_ism_debug, "ISM43362Interface: Socket_recv buffer reset\r\n"); 00471 } else { 00472 /* In case there is remaining data in buffer, update socket content 00473 * For now by shift copy of all data (not very efficient to be 00474 * revised */ 00475 while (i < socket->read_data_size) { 00476 socket->read_data[i - size] = socket->read_data[i]; 00477 i++; 00478 } 00479 00480 socket->read_data_size -= size; 00481 } 00482 } 00483 // else { 00484 // debug_if(_ism_debug, "ISM43362Interface socket_recv: Nothing in buffer\r\n"); 00485 // } 00486 00487 _mutex.unlock(); 00488 00489 if (recv > 0) { 00490 debug_if(_ism_debug, "ISM43362Interface socket_recv: recv=%d\r\n", recv); 00491 return recv; 00492 } else { 00493 debug_if(_ism_debug, "ISM43362Interface socket_recv: returns WOULD BLOCK\r\n"); 00494 return NSAPI_ERROR_WOULD_BLOCK; 00495 } 00496 } 00497 00498 int ISM43362Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) 00499 { 00500 _mutex.lock(); 00501 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00502 00503 if (socket->connected && socket->addr != addr) { 00504 if (!_ism.close(socket->id)) { 00505 debug_if(_ism_debug, "ISM43362Interface: socket_sendto ERROR\r\n"); 00506 _mutex.unlock(); 00507 return NSAPI_ERROR_DEVICE_ERROR; 00508 } 00509 socket->connected = false; 00510 _ids[socket->id] = false; 00511 _socket_obj[socket->id] = 0; 00512 } 00513 00514 if (!socket->connected) { 00515 int err = socket_connect_nolock(socket, addr); 00516 if (err < 0) { 00517 _mutex.unlock(); 00518 return err; 00519 } 00520 socket->addr = addr; 00521 } 00522 00523 int ret = socket_send_nolock(socket, data, size); 00524 00525 _mutex.unlock(); 00526 00527 return ret; 00528 } 00529 00530 int ISM43362Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) 00531 { 00532 int ret = socket_recv(handle, data, size); 00533 _mutex.lock(); 00534 if ((ret >= 0) && addr) { 00535 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00536 *addr = socket->addr; 00537 } 00538 _mutex.unlock(); 00539 return ret; 00540 } 00541 00542 void ISM43362Interface::socket_attach(void *handle, void (*cb)(void *), void *data) 00543 { 00544 _mutex.lock(); 00545 struct ISM43362_socket *socket = (struct ISM43362_socket *)handle; 00546 _cbs[socket->id].callback = cb; 00547 _cbs[socket->id].data = data; 00548 _mutex.unlock(); 00549 } 00550 00551 void ISM43362Interface::event() 00552 { 00553 for (int i = 0; i < ISM43362_SOCKET_COUNT; i++) { 00554 if (_cbs[i].callback) { 00555 _cbs[i].callback(_cbs[i].data); 00556 } 00557 } 00558 } 00559 00560 void ISM43362Interface::attach(Callback<void(nsapi_event_t, intptr_t)> status_cb) 00561 { 00562 debug_if(_ism_debug, "ISM43362Interface: attach\n"); 00563 _conn_stat_cb = status_cb; 00564 } 00565 00566 nsapi_connection_status_t ISM43362Interface::get_connection_status() const 00567 { 00568 debug_if(_ism_debug, "ISM43362Interface: get_connection_status %d\n", _conn_stat); 00569 return _conn_stat; 00570 } 00571 00572 00573 void ISM43362Interface::update_conn_state_cb() 00574 { 00575 nsapi_connection_status_t prev_stat = _conn_stat; 00576 _conn_stat = _ism.connection_status(); 00577 debug_if(_ism_debug, "ISM43362Interface: update_conn_state_cb %d -> %d\n", prev_stat, _conn_stat); 00578 00579 if (prev_stat == _conn_stat) { 00580 return; 00581 } 00582 00583 // Inform upper layers 00584 if (_conn_stat_cb) { 00585 _conn_stat_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _conn_stat); 00586 } 00587 } 00588 00589 00590 #if MBED_CONF_ISM43362_PROVIDE_DEFAULT 00591 00592 WiFiInterface *WiFiInterface::get_default_instance() { 00593 static ISM43362Interface ism; 00594 return &ism; 00595 } 00596 00597 #endif
Generated on Mon Aug 29 2022 19:53:39 by
