Murata Type YD Wi-Fi driver
Dependents: easy-connect-type-yd
TypeYDInterface.cpp
- Committer:
- MACRUM
- Date:
- 2017-07-12
- Revision:
- 0:35a2186cf186
File content as of revision 0:35a2186cf186:
/* Murata Type-YD implementation of NetworkInterfaceAPI * Copyright (c) 2017 Murat Manufacturing CO., LTD. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <string.h> #include "TypeYDInterface.h" #include "SNICInterface/Socket/SNIC_Socket.h" #include "SNICInterface/Socket/Endpoint.h" #include "SNICInterface/Socket/SNIC_UDPSocket.h" #include "SNICInterface/Socket/TCPSocketConnection.h" #include "SNICInterface/Socket/TCPSocketServer.h" #include "mbed.h" #include "mbed-trace/mbed_trace.h" #define TRACE_GROUP "SNIC" //#define USE_DYNAMIC_CAST // socket structure struct managed_socket { nsapi_protocol_t proto; bool connected; SnicSocket *snic_socket; void (*callback)(void *); void *data; }; // TypeYDInterface implementation TypeYDInterface::TypeYDInterface(PinName tx, PinName rx, PinName cts, PinName rts, PinName reset, PinName alarm, int baud) : _snic(tx, rx, cts, rts, reset, alarm, baud) { } int TypeYDInterface::init() { int ret = _snic.init(); if (ret == 0) { tagWIFI_STATUS_T status; _snic.getWifiStatus(&status); memcpy(mac_address, status.mac_address, sizeof(mac_address)); sprintf(str_macaddr, "%02x:%02x:%02x:%02x:%02x:%02x", mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]); ret = _snic.wifi_softap_off(); if (ret != 0) { tr_error("wifi off error"); } } return ret; } int TypeYDInterface::getFWVersion(unsigned char *version, int length) { int ret = _snic.getFWVersion(version, &length); return ret; } int TypeYDInterface::connect() { int ret; if( _snic.disconnect() != 0 ) { return NSAPI_ERROR_DEVICE_ERROR; } int ssid_length = strlen(ap_ssid); int pass_length = strlen(ap_pass); if (_snic.connect(ap_ssid, ssid_length, ap_esec, ap_pass, pass_length) != 0) { ret = NSAPI_ERROR_NO_CONNECTION; } else if (_snic.setIPConfig(true) != 0) { ret = NSAPI_ERROR_DHCP_FAILURE; } else { ret = NSAPI_ERROR_OK; } return ret; } int TypeYDInterface::connect(const char *ssid, const char *pass, nsapi_security_t security, uint8_t channel) { int ret; if (channel != 0) { return NSAPI_ERROR_UNSUPPORTED; } set_credentials(ssid, pass, security); int ssid_length = strlen(ap_ssid); int pass_length = strlen(ap_pass); #if 0 int repeat = 0; bool bFound = false; do { tr_info("scan...%d\n", repeat); WiFiAccessPoint res[10]; ret = scan(res,10); if (ret < 0) { tr_info("scan fail %d\n",ret); } else { tr_info("scan result = %d\n", ret); for (int i = 0; i < ret; i++) { tr_info("ssid :%s\n", res[i].get_ssid()); tr_info("channel :%d\n", res[i].get_channel()); if (strcmp(ap_ssid, res[i].get_ssid()) == 0) { bFound = true; tr_info("-------- BSS ---------\n"); tr_info("ssid :%s\n", res[i].get_ssid()); tr_info("channel :%d\n", res[i].get_channel()); tr_info("rssi :%d\n", res[i].get_rssi()); tr_info("security :%d\n", res[i].get_security()); const uint8_t *bssid = res[i].get_bssid(); tr_info("bssid :%02x-%02x-%02x-%02x-%02x-%02x\n", bssid[0],bssid[1],bssid[2], bssid[3],bssid[4],bssid[5]); break; } } } }while((bFound == false) && (repeat++ < 10)); #endif do { wait(0.5); if( _snic.disconnect() != 0 ) { return NSAPI_ERROR_DEVICE_ERROR; } wait(0.5); /* ret = _snic.getWifiStatus(&status); if (ret == 0) { printf("status:%02x\n", status.status); printf("mac :%02x-%02x-%02x-%02x-%02x-%02x\n", status.mac_address[0],status.mac_address[1],status.mac_address[2], status.mac_address[3],status.mac_address[4],status.mac_address[5]); }*/ tr_info("TryConnect\r\n"); if (_snic.connect(ap_ssid, ssid_length, ap_esec, ap_pass, pass_length) != 0) { ret = NSAPI_ERROR_NO_CONNECTION; } else if (_snic.setIPConfig(true) != 0) { ret = NSAPI_ERROR_DHCP_FAILURE; } else { ret = NSAPI_ERROR_OK; } } while (ret != NSAPI_ERROR_OK); return ret; } int TypeYDInterface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security) { ap_esec = e_SEC_WPA2_MIXED; switch(security) { case NSAPI_SECURITY_NONE: /*!< open access point */ ap_esec = e_SEC_OPEN; break; case NSAPI_SECURITY_WEP: /*!< phrase conforms to WEP */ ap_esec = e_SEC_WEP; break; case NSAPI_SECURITY_WPA: /*!< phrase conforms to WPA */ ap_esec = e_SEC_WPA_TKIP; break; case NSAPI_SECURITY_WPA2: /*!< phrase conforms to WPA2 */ ap_esec = e_SEC_WPA2_MIXED; break; case NSAPI_SECURITY_WPA_WPA2: /*!< phrase conforms to WPA/WPA2 */ ap_esec = e_SEC_WPA2_MIXED; break; default: break; } strncpy(ap_ssid, ssid, sizeof(ap_ssid)); ap_ssid[sizeof(ap_ssid)-1] = 0; strncpy(ap_pass, pass, sizeof(ap_pass)); ap_pass[sizeof(ap_pass)-1] = 0; return 0; } int TypeYDInterface::set_channel(uint8_t channel) { return NSAPI_ERROR_UNSUPPORTED; } int TypeYDInterface::disconnect() { if (!_snic.disconnect()) { return NSAPI_ERROR_DEVICE_ERROR; } return NSAPI_ERROR_OK; } const char *TypeYDInterface::get_ip_address() { return _snic.getIPAddress(); } const char *TypeYDInterface::get_mac_address() { return (const char*)str_macaddr; } const char *TypeYDInterface::get_gateway() { return _snic.getGatewayAddress(); } const char *TypeYDInterface::get_netmask() { return _snic.getSubnetAddress(); } int8_t TypeYDInterface::get_rssi() { signed char rssi; _snic.getRssi(&rssi); return (int8_t)rssi; } static volatile int _scan_wait = 0; static WiFiAccessPoint *_scan_results = 0; static int _scan_count; static int _scan_limit; static void scan_results_callback(tagSCAN_RESULT_T *scan_result) { nsapi_wifi_ap_t ap; if (_scan_count < _scan_limit) { memcpy(ap.ssid, scan_result->ssid, 33); memcpy(ap.bssid, scan_result->bssid, 6); switch(scan_result->security) { case e_SEC_OPEN: ap.security = NSAPI_SECURITY_NONE; break; case e_SEC_WEP: ap.security = NSAPI_SECURITY_WEP; break; case e_SEC_WPA_TKIP: ap.security = NSAPI_SECURITY_WPA; break; case e_SEC_WPA2_AES: ap.security = NSAPI_SECURITY_WPA2; break; case e_SEC_WPA2_MIXED: ap.security = NSAPI_SECURITY_WPA_WPA2; break; case e_SEC_WPA_AES: ap.security = NSAPI_SECURITY_WPA; break; default: ap.security = NSAPI_SECURITY_UNKNOWN; break; } ap.rssi = scan_result->rssi; ap.channel = scan_result->channel; _scan_results[_scan_count++] = WiFiAccessPoint(ap); } if (scan_result->is_complete == 0) _scan_wait = 1; } int TypeYDInterface::scan(WiFiAccessPoint *res, unsigned count) { _scan_results = res; _scan_limit = count; _scan_count = 0; int ret = _snic.scan(NULL, NULL, scan_results_callback); if (ret == 0) { _scan_wait = 0; while(_scan_wait == 0) { wait(1); } } return _scan_count; } nsapi_error_t TypeYDInterface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) { int ret; unsigned char ipaddr[4]; ret = _snic.resolveName(name, ipaddr); if (ret != 0) { tr_error("DNS failure\n"); return NSAPI_ERROR_DNS_FAILURE; } tr_info("DNS res:%u.%u.%u.%u\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); address->set_ip_bytes(ipaddr, NSAPI_IPv4); return NSAPI_ERROR_OK; } int TypeYDInterface::socket_open(void **handle, nsapi_protocol_t proto) { tr_info("socket_open"); struct managed_socket *socket = new struct managed_socket; if (!socket) { return NSAPI_ERROR_NO_SOCKET; } socket->proto = proto; socket->connected = false; socket->snic_socket = NULL; socket->callback = NULL; socket->data = NULL; *handle = socket; return 0; } int TypeYDInterface::socket_close(void *handle) { struct managed_socket *socket = (struct managed_socket *)handle; tr_info("socket_close"); int err = 0; if (socket->snic_socket != NULL) { err = socket->snic_socket->close(); delete socket->snic_socket; } delete socket; return err; } int TypeYDInterface::socket_bind(void *handle, const SocketAddress &address) { int ret; uint16_t port; struct managed_socket *socket = (struct managed_socket *)handle; port = address.get_port(); if (port == 0) { #if defined(ST) srand(HAL_GetTick()); #else srand(0); #endif port = (rand() % 10240) + 20000; } tr_info("socket_bind IP:%s:%u\n", address.get_ip_address(), port); if (socket->proto == NSAPI_UDP) { SnicUDPSocket *udp = new SnicUDPSocket(); socket->snic_socket = udp; if (socket->snic_socket == NULL) { return NSAPI_ERROR_DEVICE_ERROR; } socket->snic_socket->socket_attach(socket->callback, socket->data); ret = udp->bind(port); if (ret != 0) { tr_info("bind err %d\n", ret); return NSAPI_ERROR_DEVICE_ERROR; } socket->connected = true; } else { TCPSocketConnection *tcp = new TCPSocketConnection(); socket->snic_socket = tcp; if (socket->snic_socket == NULL) { tr_error("tcp bind err\n"); return NSAPI_ERROR_DEVICE_ERROR; } socket->snic_socket->socket_attach(socket->callback, socket->data); ret = tcp->bind(port); if (ret != 0) { tr_error("tcp bind err %d\n", ret); return NSAPI_ERROR_DEVICE_ERROR; } socket->connected = false; } return ret; } int TypeYDInterface::socket_listen(void *handle, int backlog) { int ret; struct managed_socket *socket = (struct managed_socket *)handle; if (socket->proto == NSAPI_UDP) { tr_info("unsupport:socket_listen\n"); return NSAPI_ERROR_UNSUPPORTED; } else { TCPSocketServer* tcp; #ifdef USE_DYNAMIC_CAST tcp = dynamic_cast<TCPSocketServer*>(socket->snic_socket); if (tcp == NULL){ return NSAPI_ERROR_DEVICE_ERROR; } #else tcp = (TCPSocketServer*)(socket->snic_socket); #endif ret = tcp->listen(backlog); if (ret != 0) { tr_error("tcp listen err %d\n",ret); return NSAPI_ERROR_DEVICE_ERROR; } } return 0; } int TypeYDInterface::socket_connect(void *handle, const SocketAddress &addr) { struct managed_socket *socket = (struct managed_socket *)handle; //tr_info("socket_connect(%d)\n",socket->proto); if (socket->proto == NSAPI_UDP) { tr_error("un sup:socket_connect"); return NSAPI_ERROR_DEVICE_ERROR; } else { TCPSocketConnection *tcp; if (socket->snic_socket == NULL) { tcp = new TCPSocketConnection(); socket->snic_socket = tcp; if (socket->snic_socket == NULL) { tr_error("tcp connect err\n"); return NSAPI_ERROR_DEVICE_ERROR; } socket->snic_socket->socket_attach(socket->callback, socket->data); } else { #ifdef USE_DYNAMIC_CAST tcp = dynamic_cast<TCPSocketConnection*>(socket->snic_socket); if (tcp == NULL){ return NSAPI_ERROR_DEVICE_ERROR; } #else tcp = (TCPSocketConnection*)(socket->snic_socket); #endif } tr_info("socket_connect IP:%s:%u\n", addr.get_ip_address(), addr.get_port()); if (tcp->connect(addr.get_ip_address(), addr.get_port()) != 0) { return NSAPI_ERROR_DEVICE_ERROR; } } //tr_info("socket_connect success\n"); socket->connected = true; return 0; } int TypeYDInterface::socket_accept(void *handle, void **client_socket, SocketAddress *addr) { int ret; struct managed_socket *server = (struct managed_socket *)handle; if (server->proto == NSAPI_UDP) { tr_info("unsupport:accept"); return NSAPI_ERROR_UNSUPPORTED; } else { TCPSocketServer *tcp; #ifdef USE_DYNAMIC_CAST tcp = dynamic_cast<TCPSocketServer*>(server->snic_socket); if (tcp == NULL){ return NSAPI_ERROR_DEVICE_ERROR; } #else tcp = (TCPSocketServer*)(server->snic_socket); #endif socket_open(client_socket, NSAPI_TCP); struct managed_socket *client = (struct managed_socket *)*client_socket; TCPSocketConnection *conn = new TCPSocketConnection(); client->snic_socket = conn; if (client->snic_socket == NULL) { tr_error("tcp accept err\n"); return NSAPI_ERROR_DEVICE_ERROR; } ret = tcp->accept(*conn, addr); if (ret != 0) { tr_error("tcp listen err %d",ret); return NSAPI_ERROR_DEVICE_ERROR; } } return 0; } int TypeYDInterface::socket_send(void *handle, const void *data, unsigned size) { struct managed_socket *socket = (struct managed_socket *)handle; //tr_info("socket_send"); if (socket->proto != NSAPI_TCP) { tr_error("un sup:socket_send"); return NSAPI_ERROR_DEVICE_ERROR; } #ifdef USE_DYNAMIC_CAST TCPSocketConnection *tcp = dynamic_cast<TCPSocketConnection*>(socket->snic_socket); if ((tcp == NULL) || ) { return NSAPI_ERROR_DEVICE_ERROR; } #else TCPSocketConnection *tcp = (TCPSocketConnection*)(socket->snic_socket); #endif if (tcp->send((char*)data, size) < 0) { tr_error("socket_send"); return NSAPI_ERROR_DEVICE_ERROR; } return size; } int TypeYDInterface::socket_recv(void *handle, void *data, unsigned size) { struct managed_socket *socket = (struct managed_socket *)handle; //tr_info("socket_recv"); if (socket->proto != NSAPI_TCP) { tr_error("not sup:socket_recv"); return NSAPI_ERROR_DEVICE_ERROR; } int recv; #ifdef USE_DYNAMIC_CAST TCPSocketConnection *tcp = dynamic_cast<TCPSocketConnection*>(socket->snic_socket); if (tcp == NULL){ return NSAPI_ERROR_DEVICE_ERROR; } #else TCPSocketConnection *tcp = (TCPSocketConnection*)(socket->snic_socket); #endif if ((recv = tcp->receive((char*)data, size)) < 0) { return NSAPI_ERROR_WOULD_BLOCK; } return recv; } int TypeYDInterface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size) { struct managed_socket *socket = (struct managed_socket *)handle; int ret; //tr_info("socket_sendto"); if (!socket->connected) { int err = socket_connect(socket, addr); if (err < 0) { return err; } } if (socket->proto == NSAPI_UDP) { Endpoint remote; remote.set_address(addr.get_ip_address(), addr.get_port()); #ifdef USE_DYNAMIC_CAST SnicUDPSocket *udp = dynamic_cast<SnicUDPSocket*>(socket->snic_socket); if (udp == NULL) { return NSAPI_ERROR_DEVICE_ERROR; } #else SnicUDPSocket *udp = (SnicUDPSocket*)(socket->snic_socket); #endif ret = udp->sendTo(remote, (char*)data, size); } else { tr_error("TCP sendto\n"); return -1; } return ret; } int TypeYDInterface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size) { struct managed_socket *socket = (struct managed_socket *)handle; int recv; //tr_info("socket_recvfrom"); if (socket->proto == NSAPI_UDP) { Endpoint remote; #ifdef USE_DYNAMIC_CAST SnicUDPSocket *udp = dynamic_cast<SnicUDPSocket*>(socket->snic_socket); if (udp == NULL) { return NSAPI_ERROR_DEVICE_ERROR; } #else SnicUDPSocket *udp = (SnicUDPSocket*)(socket->snic_socket); #endif recv = udp->receiveFrom(remote, (char*)data, size); if (recv > 0) { addr->set_ip_address(remote.get_address()); addr->set_port(remote.get_port()); } } else { tr_error("TCP recvfrom\n"); return -1; } return recv; } void TypeYDInterface::socket_attach(void *handle, void (*callback)(void *), void *data) { struct managed_socket *socket = (struct managed_socket *)handle; //tr_info("socket_attach"); socket->callback = callback; socket->data = data; if (socket->snic_socket != NULL) { socket->snic_socket->socket_attach(callback, data); } }