From: Ivan Date: Sun, 26 Mar 2017 09:13:34 +0000 (+0900) Subject: apps: add artikwifi application X-Git-Tag: 1.1_Public_Release~614^2~248 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=81e79e74682bf4ba356b629d78d06305b43a7b26;p=rtos%2Ftinyara.git apps: add artikwifi application Application 'artikwifi' is added. Change-Id: I6c82a39065ccae37ac6ef7dd1591fae5b7b0a8cd Signed-off-by: Ivan Signed-off-by: Siwon Kang [Shin: split the original commit into two separated commits] Signed-off-by: Heesub Shin [Kim: fix coding style] Signed-off-by: Jin-Seong Kim --- diff --git a/apps/examples/Kconfig b/apps/examples/Kconfig index 223647b..527afd1 100644 --- a/apps/examples/Kconfig +++ b/apps/examples/Kconfig @@ -73,4 +73,5 @@ source "$APPSDIR/examples/webserver/Kconfig" source "$APPSDIR/examples/websocket/Kconfig" source "$APPSDIR/examples/workqueue/Kconfig" source "$APPSDIR/examples/artik_demo/Kconfig" +source "$APPSDIR/examples/slsiwifi/Kconfig" endmenu diff --git a/apps/examples/artik_demo/artik_demo.c b/apps/examples/artik_demo/artik_demo.c index 42aa101..6d14b2d 100644 --- a/apps/examples/artik_demo/artik_demo.c +++ b/apps/examples/artik_demo/artik_demo.c @@ -233,7 +233,6 @@ static char NET_DEVNAME[10]; static int app_dhcp_main(void) { - uint32_t timeleft = 15000; struct dhcpc_state state; void *dhcp_handle; int ret; diff --git a/apps/examples/slsiwifi/Kconfig b/apps/examples/slsiwifi/Kconfig new file mode 100755 index 0000000..7578018 --- /dev/null +++ b/apps/examples/slsiwifi/Kconfig @@ -0,0 +1,31 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_SLSIWIFI + bool "S.LSI WIFI Control application" + default n + depends on NETUTILS_WIFI + ---help--- + Enable the Samsung LSI WiFi Control Application + +if EXAMPLES_SLSIWIFI + +config EXAMPLES_SLSIWIFI_PROGNAME + string "Program name" + default "slsiwifi" + depends on BUILD_KERNEL + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +config EXAMPLES_SLSIWIFI_PRIORITY + int "wifi app task priority" + default 50 + +config EXAMPLES_SLSIWIFI_STACKSIZE + int "wifi app stack size" + default 2048 + +endif diff --git a/apps/examples/slsiwifi/Makefile b/apps/examples/slsiwifi/Makefile new file mode 100755 index 0000000..eb366fe --- /dev/null +++ b/apps/examples/slsiwifi/Makefile @@ -0,0 +1,151 @@ +########################################################################### +# +# Copyright 2016 Samsung Electronics All Rights Reserved. +# +# 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. +# +########################################################################### +############################################################################ +# apps/examples/slsidemo/Makefile +# +# Copyright (C) 2008, 2010-2013 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + + +CONFIG_EXAMPLES_SLSIWIFI_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_EXAMPLES_SLSIWIFI_STACKSIZE ?= 2048 + +APPNAME = slsiwifi +PRIORITY = $(CONFIG_EXAMPLES_SLSIWIFI_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_SLSIWIFI_STACKSIZE) + +ASRCS = +CSRCS += \ + output_functions.c #\ +# nettest_functions.c # disabled temporarily +MAINSRC = slsiwifi_main.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) +OBJS = $(AOBJS) $(COBJS) + +CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_FIFO +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)$(DELIM)include$(DELIM)netutils$(DELIM)wifi} + + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJS += $(MAINOBJ) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +CONFIG_EXAMPLES_SLSIWIFI_PROGNAME ?= slsiwifi$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_SLSIWIFI_PROGNAME) + +ROOTDEPPATH = --dep-path . + +# Common build + +all: .built +.PHONY: clean depend distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) + +else +install: + +endif + +context: + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep + diff --git a/apps/examples/slsiwifi/nettest_functions.c b/apps/examples/slsiwifi/nettest_functions.c new file mode 100644 index 0000000..7643a18 --- /dev/null +++ b/apps/examples/slsiwifi/nettest_functions.c @@ -0,0 +1,1124 @@ +/** + * @file apps/example/slsiwifi/nettest_functions.c + * + * Copyright (c) 2016 Samsung Electronics, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include "slsiwifi_main.h" + +#ifdef CONFIG_NET_LWIP +#include +#include "net/lwip/mem.h" +#include "net/lwip/raw.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "net/lwip/ipv4/icmp.h" +#include "net/lwip/ipv4/ip.h" +#include "net/lwip/timers.h" +#include "net/lwip/ipv4/inet_chksum.h" +#include "net/lwip/err.h" +#include "net/lwip/opt.h" +#endif + +#define SLSI_SANITY_DHCP_TIMEOUT 15000 +extern bool inAuto; +extern bool wifiStarted; +extern sem_t ap_conn_sem; +extern sem_t g_sem_join; +extern char *g_client_ip_str; +static struct dhcp g_dhcp_handle; +static int32_t timeleft = SLSI_SANITY_DHCP_TIMEOUT; +static struct timespec g_dhcp_timer_start; +static struct timespec g_dhcp_timer_end; +static struct netif *g_netif; +static ip_addr_t client_ip; +#define SANITY_LOOP_COUNT 20 + +#define SANITY_AP_OPEN_SSID "t20_sanity_open" +#define SANITY_AP_OPEN_SSID_LEN strlen(SANITY_AP_OPEN_SSID) + +#define SANITY_AP_WPA_SSID "t20_sanity_wpa_wpa2" +#define SANITY_AP_WPA_SSID_LEN strlen(SANITY_AP_WPA_SSID) +#define SANITY_AP_WPA_PASS "0123456789" + +#define SANITY_AP_WPA2_SSID "t20_sanity_wpa_wpa2" +#define SANITY_AP_WPA2_SSID_LEN strlen(SANITY_AP_WPA2_SSID) +#define SANITY_AP_WPA2_PASS "0123456789" + +#define SANITY_AP_WEP_SSID "t20_sanity_wep" +#define SANITY_AP_WEP_SSID_LEN strlen(SANITY_AP_WEP_SSID) +#define SANITY_AP_WEP_PASS "0123456789" + +#define SANITY_SOFTAP_WPA2_SSID "t20_sanity_ap_wpa2" +#define SANITY_SOFTAP_WPA2_SSID_LEN strlen(SANITY_SOFTAP_WPA2_SSID) +#define SANITY_SOFTAP_WPA2_PASS "0123456789" +#define SANITY_SOFTAP_OPEN_SSID "t20_sanity_ap_open" +#define SANITY_SOFTAP_OPEN_SSID_LEN strlen(SANITY_SOFTAP_OPEN_SSID) + +static int8_t tc = 1; +#define TESTPRINT(fmt, ...) \ + printf("\n\n**************************************************************************\n" \ + "[TESTCASE %d] " fmt "\n**************************************************************************\n" \ + ,tc++, ##__VA_ARGS__) + +#define PING_MAX_TRY_COUNTER 10 + +static int ping_recv_counter = 0; +static int ping_try_counter = 0; + +#define PING_RCV_TIMEO 10 +#define PING_DELAY 1000 +#define PING_ID 0xAFAF + +#define PING_DATA_SIZE 32 +#define PING_RESULT(ping_ok) + +static u16_t ping_seq_num; +static systime_t ping_time; + +u16_t g_ping_counter = PING_MAX_TRY_COUNTER; + +static uint8_t doPing(ip_addr_t ip, int pingcount); + +static void clear_timers(void) { + g_dhcp_timer_end.tv_nsec = 0; + g_dhcp_timer_end.tv_sec = 0; + g_dhcp_timer_start.tv_nsec = 0; + g_dhcp_timer_start.tv_sec = 0; +} +static uint8_t doDhcpStart(WiFi_InterFace_ID_t mode){ + + uint8_t result = SLSI_STATUS_ERROR; + ip_addr_t local_ipaddr, local_netmask, local_gateway; + + g_netif = netif_find(CTRL_IFNAME); + if (g_netif == NULL) { + printf("doDhcpStart No network interface\n"); + return SLSI_STATUS_ERROR; + } + if(mode == SLSI_WIFI_STATION_IF) { + if(g_netif->dhcp != NULL){ + g_netif->dhcp = NULL; //it will be set to g_dhcp_handle on next dhcp start + } + dhcp_set_struct(g_netif, &g_dhcp_handle ); + + local_ipaddr.addr = IPADDR_ANY; + local_netmask.addr = IPADDR_BROADCAST; + local_gateway.addr = IPADDR_ANY; + + netif_set_addr(g_netif, &local_ipaddr, &local_netmask, &local_gateway); + err_t res = dhcp_start(g_netif); + if (res) { + printf("doDhcpStart dhcp_start result %d\n", res); + return SLSI_STATUS_ERROR; + } + printf("doDhcpStart start success state %d result %d\n", + g_dhcp_handle.state, res); + + // To give time frtikwifior connection to establishment first + clock_gettime(CLOCK_REALTIME,&g_dhcp_timer_start); //start dhcp timing + timeleft = SLSI_SANITY_DHCP_TIMEOUT; + printf("DHCP: Awaiting ip address...(max %d seconds)\n", (timeleft/1000)); + while (g_dhcp_handle.state != DHCP_BOUND) { + usleep(10); + timeleft -= 10; + if (timeleft <= 0) + break; + } + + if(g_dhcp_timer_start.tv_nsec != 0 && g_dhcp_timer_start.tv_sec != 0) { + clock_gettime(CLOCK_REALTIME,&g_dhcp_timer_end); //stop dhcp timing, started in linkup + // Calculate time it took + int accum = ( g_dhcp_timer_end.tv_sec - g_dhcp_timer_start.tv_sec ); + unsigned long accum2 = (unsigned long)(( g_dhcp_timer_end.tv_nsec - g_dhcp_timer_start.tv_nsec ) / 1000000); + printf( "DHCP request took: %d.%ul seconds\n", accum, accum2 ); + clear_timers(); + } + if (g_dhcp_handle.state == DHCP_BOUND) { + result = SLSI_STATUS_SUCCESS; + printf("DHCP Client - got IP address %u.%u.%u.%u\n", + (unsigned char) ( ( htonl( g_netif->ip_addr.addr ) >> 24 ) & 0xff ), + (unsigned char) ( ( htonl( g_netif->ip_addr.addr ) >> 16 ) & 0xff ), + (unsigned char) ( ( htonl( g_netif->ip_addr.addr ) >> 8 ) & 0xff ), + (unsigned char) ( ( htonl( g_netif->ip_addr.addr ) >> 0 ) & 0xff )); + local_ipaddr.addr = g_netif->ip_addr.addr; + local_netmask.addr = g_netif->netmask.addr; + local_gateway.addr = g_netif->gw.addr; + netif_set_addr(g_netif, &local_ipaddr, &local_netmask, &local_gateway); + netif_set_up(g_netif); + + } else { + if (timeleft <= 0) { + printf("DHCP Client - Timeout fail to get ip address\n"); + } + } + + } else if (mode == SLSI_WIFI_SOFT_AP_IF) { + // Setting static IP as 192.168.47.1 in AP mode + local_ipaddr.addr = 0x012FA8C0; + local_netmask.addr = 0x00FFFFFF; + local_gateway.addr = 0x012FA8C0; + netif_set_addr(g_netif, &local_ipaddr, &local_netmask, &local_gateway); + netif_set_up(g_netif); + printf("doDhcpStart - dhcps_start\n"); + if(dhcps_start(g_netif) == ERR_OK) { + result = SLSI_STATUS_SUCCESS; + printf("DHCP Server - started success\n"); + } + } + return result; +} + +static uint8_t doDhcpStop(WiFi_InterFace_ID_t mode){ + uint8_t result = SLSI_STATUS_ERROR; + + if(g_netif == NULL) { + // Nothing to take down + printf("doDhcpStop - nothing to stop\n"); + result = SLSI_STATUS_SUCCESS; + } else { + struct netif * l_netif = g_netif; + printf("doDhcpStop\n"); + + if(mode == SLSI_WIFI_STATION_IF) { + if (l_netif->dhcp != NULL) { + dhcp_stop(l_netif); + printf("DHCP Client stopped \n"); + } + } else if(mode == SLSI_WIFI_SOFT_AP_IF) { + if (l_netif->dhcps_pcb != NULL) { + dhcps_stop(l_netif); + printf("DHCP Server stopped \n"); + } + } + g_netif = NULL; + result = SLSI_STATUS_SUCCESS; + } + return result; +} + + +int8_t doStaJoinLeaveTest(int iterations, char *ap, char *sec, char *pass){ + /* Join */ + int loop = 0; + TESTPRINT("Try to join/leave AP with name \"%s\" and secmode %s %d times\n", + ap, sec, iterations); + for (loop = 0; loop < iterations; loop++){ + printf("==> Trial: %d\n",loop+1); + if(doJoin((uint8_t*)ap, strlen(ap),/*bssid*/NULL, + sec, pass) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc-1; + } + /* Leave */ + // printf("[TESTCASE %d] Leave network\n",tc++); + if(doLeave() == SLSI_STATUS_ERROR){ + inAuto = false; + return tc-1; + } + } + return SLSI_STATUS_SUCCESS; +} + + +/***********************************************/ +/* DATAPATH TEST */ +/***********************************************/ + +int8_t doDataPathTest(int pingcount){ + inAuto = true; + if(pingcount == 0) { + pingcount = SANITY_LOOP_COUNT; + } + /********* START STA **********/ + TESTPRINT("start station mode and join AP with name %s\n", SANITY_AP_WPA2_SSID); + if(doStartSta() == SLSI_STATUS_ERROR){ + inAuto = false; + return tc-1; + } + printf("Joining\n"); + if(doJoin((uint8_t*)SANITY_AP_WPA2_SSID, SANITY_AP_WPA2_SSID_LEN,/*bssid*/NULL, + "wpa2_aes", SANITY_AP_WPA2_PASS) + != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc-1; + } + + + TESTPRINT("Start DHCPC for Station mode"); + if(doDhcpStart(SLSI_WIFI_STATION_IF) == SLSI_STATUS_SUCCESS){ + printf("DHCP success\n"); + }else { + printf("DHCP failed\n"); + return tc-1; + } + // AP is the gateway (gw) so we can use that to ping + client_ip.addr = g_netif->gw.addr; + TESTPRINT("Ping gateway ip address %s", ipaddr_ntoa(&client_ip)); + if(doPing(client_ip, pingcount) == SLSI_STATUS_SUCCESS){ + printf("Successfully pinged\n"); + } else { + printf("Failed to ping\n"); + return tc-1; + } + + TESTPRINT("Stop DHCPC for Station mode"); + if(doDhcpStop(SLSI_WIFI_STATION_IF) == SLSI_STATUS_SUCCESS){ + printf("DHCP stop success\n"); + }else { + printf("DHCP stop failed\n"); + return tc-1; + } + /* Leave */ + if(doLeave() == SLSI_STATUS_ERROR){ + inAuto = false; + return tc-1; + } + return 0; +} + +static int8_t doStopTest(void){ + /* Stop */ + TESTPRINT("Stop STA mode\n"); + + if(doStop() == SLSI_STATUS_ERROR){ + inAuto = false; + return tc-1; + }else { + // we need to Register Link Callback handlers again as they are + // unregistered in doStop + WiFiRegisterLinkCallback(&sw_linkUpHandler, &sw_linkDownHandler); + } + return SLSI_STATUS_SUCCESS; +} + +static int8_t doStaApModeSwitchTest(int iterations, char *sta_ap, char *ap, char *sta_sec, + char *ap_sec, char *sta_pass, char *ap_pass, int ap_chan){ + int loop = 0; + uint8_t result; + sem_init(&ap_conn_sem,0,0); // need to make sure it is cleared it the sta has reconnected twice + /********* START STA, JOIN, MODESWITCH TO AP LOOP **********/ + /* Join */ + TESTPRINT("Try to modeswitch between STA mode(%s) and AP mode(%s) %d times", sta_sec, ap_sec, + iterations); + for (loop = 0; loop < iterations; loop++){ + printf("==> Trial: %d\n",loop+1); + result = doStartSta(); + if(!(result == SLSI_STATUS_SUCCESS || + result == SLSI_STATUS_ALREADY_STARTED)){ + inAuto = false; + return tc-1; + } + if(doJoin((uint8_t*)sta_ap, strlen(sta_ap),/*bssid*/NULL, sta_sec, + sta_pass) != SLSI_STATUS_SUCCESS){ + inAuto = false; + sem_post(&ap_conn_sem); + sem_destroy(&ap_conn_sem); + return tc-1; + } + /* mode switch */ + if(doStartAP(ap, ap_sec, ap_pass, ap_chan) == SLSI_STATUS_ERROR){ + inAuto = false; + sem_post(&ap_conn_sem); + sem_destroy(&ap_conn_sem); + return tc-1; + }else { + printf("Waiting for STA to connect\n"); + sem_wait(&ap_conn_sem); + } + } + /********* STOP STA **********/ + if(doStopTest() != SLSI_STATUS_SUCCESS){ + inAuto = false; + sem_post(&ap_conn_sem); + sem_destroy(&ap_conn_sem); + return tc-1; + } + sem_post(&ap_conn_sem); + sem_destroy(&ap_conn_sem); + + return SLSI_STATUS_SUCCESS; +} +static int8_t doApStartStopTest(int iterations, char *ap, char *sec, char *pass, int chan){ + sem_init(&ap_conn_sem, 0, 0); + TESTPRINT("Start softAP mode with SSID: \"%s\" and %s security (channel: %d)\n", ap, sec, chan); + if(doStartAP(ap, sec, pass, chan) + == SLSI_STATUS_ERROR){ + inAuto = false; + sem_destroy(&ap_conn_sem); + return tc-1; + }else { + printf("Waiting for STA to connect\n"); + sem_wait(&ap_conn_sem); + } + /*********** STOP **************/ + TESTPRINT("Stop softAP mode\n"); + if(doStop() == SLSI_STATUS_ERROR){ + inAuto = false; + sem_post(&ap_conn_sem); + sem_destroy(&ap_conn_sem); + return tc-1; + } else { + // we need to Register Link Callback handlers again as they are + // unregistered in doStop + WiFiRegisterLinkCallback(&sw_linkUpHandler, &sw_linkDownHandler); + + } + sem_post(&ap_conn_sem); + sem_destroy(&ap_conn_sem); + return SLSI_STATUS_SUCCESS; +} + +/***********************************************/ +/* SANITY BADCASE TEST */ +/***********************************************/ + +int8_t doSanityBadCaseTest(int iterations){ + uint8_t result; + inAuto = true; + if(iterations == 0) { + iterations = SANITY_LOOP_COUNT; + } + /********* START STA **********/ + TESTPRINT("start station mode\n"); + result = doStartSta(); + if(result != SLSI_STATUS_SUCCESS && result != SLSI_STATUS_ALREADY_STARTED){ + inAuto = false; + return tc-1; + } + /********* JOIN OPEN AP WITH SEC SET, JOIN CORRECTLY, LEAVE **********/ + if (doStaJoinLeaveTest(1,SANITY_AP_OPEN_SSID, "wpa_aes", SANITY_AP_WPA_PASS) == SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + if (doStaJoinLeaveTest(1,SANITY_AP_OPEN_SSID, "open", NULL) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /********* JOIN WPA2 AP WITHOUT PASS, JOIN CORRECTLY, LEAVE **********/ + if (doStaJoinLeaveTest(1,SANITY_AP_WPA2_SSID, "wpa2_aes", NULL) == SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + if (doStaJoinLeaveTest(1,SANITY_AP_WPA2_SSID, "wpa2_aes", SANITY_AP_WPA2_PASS) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /********* JOIN WPA2 AP WITH WRONG PASS, JOIN CORRECTLY, LEAVE **********/ + if (doStaJoinLeaveTest(1,SANITY_AP_WPA2_SSID, "wpa2_aes", "WRONGWRONG") == SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + if (doStaJoinLeaveTest(1, SANITY_AP_WPA2_SSID, "wpa2_aes", SANITY_AP_WPA2_PASS) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /********* STARTAP FOR ALL CHANNELS - COUNTRY=00 **********/ + int channel = 1; + WiFiSetCountryCode("00"); + for (channel = 1; channel <= 14; channel++){ + if (doApStartStopTest(1, SANITY_SOFTAP_WPA2_SSID, "wpa2_mixed", + SANITY_SOFTAP_WPA2_PASS, channel) != SLSI_STATUS_SUCCESS){ + if(channel < 12) { //not allowed for country "00" so expect it to fail + inAuto = false; + return tc-1; + } + } + } + + /********* STARTAP FOR ALL CHANNELS - COUNTRY=KR **********/ + WiFiSetCountryCode("KR"); + for (channel = 1; channel <= 14; channel++){ + printf("Testing on Channel %d\n", channel); + if (doApStartStopTest(1, SANITY_SOFTAP_WPA2_SSID, "wpa2_mixed", + SANITY_SOFTAP_WPA2_PASS, channel) != SLSI_STATUS_SUCCESS){ + if(channel != 14) { //not allowed for country "KR" so expect it to fail + inAuto = false; + return tc-1; + } + } + } + /********* STARTAP FOR ALL CHANNELS - COUNTRY=JP **********/ + WiFiSetCountryCode("JP"); + for (channel = 1; channel <= 14; channel++){ + if (doApStartStopTest(1, SANITY_SOFTAP_WPA2_SSID, "wpa2_mixed", + SANITY_SOFTAP_WPA2_PASS, 6) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc-1; + } + } + + + return SLSI_STATUS_SUCCESS; +} +/***********************************************/ +/* NIGHTLY SANITY TESTS */ +/***********************************************/ + +int8_t doNightlyTest(int iterations){ + inAuto = true; + tc = 0; + if(iterations == 0) { + iterations = SANITY_LOOP_COUNT; + } + if (doSanityTest(iterations) != SLSI_STATUS_SUCCESS) { + inAuto = false; + return tc-1; + } + if (doSanityBadCaseTest(iterations) != SLSI_STATUS_SUCCESS) { + inAuto = false; + return tc-1; + } + inAuto = false; + return SLSI_STATUS_SUCCESS; +} + +/***********************************************/ +/* SANITY TEST */ +/***********************************************/ + +int8_t doSanityTest(int iterations){ + uint8_t result; + inAuto = true; + tc = 0; + if(iterations == 0) { + iterations = SANITY_LOOP_COUNT; + } + if(wifiStarted) { + /* we need to cleanp before starting the test */ + printf("need to stop running wpa_supplicant before start\n"); + doStop(); + // we need to Register Link Callback handlers again as they are + // unregistered in doStop + WiFiRegisterLinkCallback(&sw_linkUpHandler, &sw_linkDownHandler); + + } + /*(1-4)********* DATAPATH TESTS ************/ + if(doDataPathTest(iterations) != SLSI_STATUS_SUCCESS) { + inAuto = false; + return tc-1; + } + + /*(5)******** START STA **********/ + TESTPRINT("start station mode\n"); + result = doStartSta(); + if(result != SLSI_STATUS_SUCCESS && result != SLSI_STATUS_ALREADY_STARTED){ + inAuto = false; + return tc-1; + } + /*(6)******** SCAN **********/ + TESTPRINT("start scan for devices\n"); + if(doScan() != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc-1; + } + /*(7)******** JOIN OPEN, LEAVE LOOP **********/ + if (doStaJoinLeaveTest(iterations,SANITY_AP_OPEN_SSID, "open", NULL) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /*(8)******** JOIN WEP, LEAVE LOOP **********/ + if (doStaJoinLeaveTest(iterations,SANITY_AP_WEP_SSID, "wep", SANITY_AP_WEP_PASS) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /*(9)******** JOIN WPA_TKIP, LEAVE LOOP **********/ + if (doStaJoinLeaveTest(iterations,SANITY_AP_WPA_SSID, "wpa_tkip", SANITY_AP_WPA_PASS) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /*(10)******** JOIN WPA_AES, LEAVE LOOP **********/ + if (doStaJoinLeaveTest(iterations,SANITY_AP_WPA_SSID, "wpa_aes", SANITY_AP_WPA_PASS) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /*(11)******** JOIN WPA_MIXED, LEAVE LOOP **********/ + if (doStaJoinLeaveTest(iterations,SANITY_AP_WPA_SSID, "wpa_mixed", SANITY_AP_WPA_PASS) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /*(12)******** JOIN WPA2_AES, LEAVE LOOP **********/ + if (doStaJoinLeaveTest(iterations,SANITY_AP_WPA2_SSID, "wpa2_aes", SANITY_AP_WPA2_PASS) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + /*(13)******** JOIN WPA2_MIXED, LEAVE LOOP **********/ + if (doStaJoinLeaveTest(iterations,SANITY_AP_WPA2_SSID, "wpa2_mixed", SANITY_AP_WPA2_PASS) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc=1; + } + + /*(14)******** STOP STA **********/ + if (doStopTest() != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc-1; + }else { + // we need to Register Link Callback handlers again as they are + // unregistered in doStop + WiFiRegisterLinkCallback(&sw_linkUpHandler, &sw_linkDownHandler); + } + + sem_init(&ap_conn_sem,0,0); // need to make sure it is cleared it the sta has reconnected twice + /*(15)******** START STA, JOIN, MODESWITCH TO AP LOOP **********/ + if( doStaApModeSwitchTest(iterations, SANITY_AP_WPA2_SSID, SANITY_SOFTAP_OPEN_SSID, "wpa2_aes", + "open", SANITY_AP_WPA2_PASS, NULL, 6) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc-1; + } + /*(16-17)************ START AP, STOP AP LOOP, CHANNEL 6 ********/ + + if (doApStartStopTest(iterations, SANITY_SOFTAP_WPA2_SSID, "wpa2_mixed", + SANITY_SOFTAP_WPA2_PASS, 6) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return tc-1; + } + + inAuto = false; + return SLSI_STATUS_SUCCESS; +} + + +int8_t doAutoTest(char *filename){ + int8_t result = SLSI_STATUS_ERROR; + inAuto = true; + if(wifiStarted) { + /* we need to cleanp before starting the test */ + printf("need to stop running wpa_supplicant before start\n"); + doStop(); + // we need to Register Link Callback handlers again as they are + // unregistered in doStop + WiFiRegisterLinkCallback(&sw_linkUpHandler, &sw_linkDownHandler); + } + if(filename){ + FILE * fp; + char line[250]; + size_t len = 250; + ssize_t read; + + fp = fopen(filename, "r"); + if (fp == NULL){ + printf("could not open test input file\n"); + inAuto = false; + return result; + } + + while ((read = readline(&line, len, fp, stdout)) != -1) { + printf("%s\n", line); + char *args = strtok(line," "); + char *pArgs = args; + int8_t count = 0; + while(pArgs++) count++; + parseCmdLine(count,&args); + } + + fclose(fp); + + }else { + /* Station mode */ + printf("[1] start station mode\n"); + if(doStartSta() == SLSI_STATUS_ERROR){ + inAuto = false; + return result; + } + /* Scan */ + printf("[2] start scan for devices\n"); + if(doScan() != SLSI_STATUS_SUCCESS){ + inAuto = false; + return result; + } + /* Join */ + printf("[3] Try to join AP with name \"setup\"\n"); + if(doJoin((uint8_t*)"setup", 5,/*bssid*/NULL, "open", 0) != SLSI_STATUS_SUCCESS){ + inAuto = false; + return result; + } + /* Leave */ + printf("[4] Leave network\n"); + if(doLeave() == SLSI_STATUS_ERROR){ + inAuto = false; + return result; + } + /* Stop */ + printf("[5] Stop station mode\n"); + + if(doStop() == SLSI_STATUS_ERROR){ + inAuto = false; + return result; + } else { + // we need to Register Link Callback handlers again as they are + // unregistered in doStop + WiFiRegisterLinkCallback(&sw_linkUpHandler, &sw_linkDownHandler); + } + /* AP mode */ + printf("[6] Start softAP mode with SSID: \"t20_auto_test\" and open security\n"); + if(doStartAP("t20_auto_test", "open", NULL, 6) == SLSI_STATUS_ERROR){ + inAuto = false; + return result; + } + /* Stop */ + printf("[7] Stop softAP mode\n"); + if(doStop() == SLSI_STATUS_ERROR){ + inAuto = false; + return result; + } + + + } + printf("\n\tWiFi Auto Test Result : SUCCESS\n\n"); + inAuto = false; + return SLSI_STATUS_SUCCESS; +} + +int slsi_tcp_server(void) +{ + int socket_desc , client_sock , c , read_size; + struct sockaddr_in server , client; + char client_message[100]; + + //Create socket + socket_desc = socket(AF_INET , SOCK_STREAM , 0); + if (socket_desc == -1) { + printf("Could not create socket"); + return -1; + } + printf("Socket created"); + + //Prepare the sockaddr_in structure + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = htons( 8888 ); + + //Bind + if (bind(socket_desc, (struct sockaddr *)&server , sizeof(server)) < 0) { + //print the error message + perror("bind failed. Error"); + close(socket_desc); + return 1; + } + printf("bind done"); + + //Listen + if (listen(socket_desc , 3) < 0 ) { + printf("listen failed\n"); + close(socket_desc); + return 1; + } + + //Accept and incoming connection + printf("Waiting for incoming connections..."); + c = sizeof(struct sockaddr_in); + + //accept connection from an incoming client + client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c); + if (client_sock < 0) { + perror("accept failed"); + close(socket_desc); + return 1; + } + printf("Connection accepted"); + + //Receive a message from client + while ( (read_size = recv(client_sock , client_message , 100 , 0)) > 0 ) { + //Send the message back to client + printf("recv message %s\n", client_message); + if (send(client_sock , client_message , strlen(client_message), 0) < 0) { + printf("failed to send message\n"); + break; + } + } + + if (read_size == 0) { + printf("client disconnected"); + } else if (read_size == -1) { + printf("recv failed"); + } + + close(client_sock); + close(socket_desc); + + return 0; +} + + +int slsi_udp_server(void) +{ + int udpSocket, nBytes; + char buffer[100]; + struct sockaddr_in serverAddr; + struct sockaddr_in serverStorage; + socklen_t addr_size; + + /*Create UDP socket*/ + udpSocket = socket(PF_INET, SOCK_DGRAM, 0); + if (udpSocket == -1) { + nlldbg("Could not create socket"); + return -1; + } + + /*Configure settings in address struct*/ + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(7891); + serverAddr.sin_addr.s_addr = INADDR_ANY; + + /*Bind socket with address struct*/ + if (bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0) { + printf("failed to bind\n"); + close(udpSocket); + return 0; + } + + /*Initialize size variable to be used later on*/ + addr_size = sizeof serverStorage; + + while (1) { + /* Try to receive any incoming UDP datagram. Address and port of + requesting client will be stored on serverStorage variable */ + nBytes = recvfrom(udpSocket, buffer, 100, 0, (struct sockaddr *)&serverStorage, + &addr_size); + + /*Send uppercase message back to client, using serverStorage as the address*/ + if (sendto(udpSocket, buffer, nBytes, 0, (struct sockaddr *)&serverStorage, + addr_size) < 0) { + printf("failed to sendto\n"); + break; + } + } + + close(udpSocket); + return 0; +} + +int slsi_tcp_client(void) +{ + int sock; + struct sockaddr_in server; + char message[100] , server_reply[100]; + + nlldbg("start tcp client...\n"); + //Create socket + sock = socket(AF_INET , SOCK_STREAM , 0); + if (sock == -1) { + nlldbg("Could not create socket"); + return -1; + } + nlldbg("Socket created"); + + server.sin_addr.s_addr = inet_addr("192.168.0.219"); + server.sin_family = AF_INET; + server.sin_port = htons( 8888 ); + + //Connect to remote server + if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { + nlldbg("connect failed. Error"); + close(sock); + return 1; + } + + nlldbg("Connected\n"); + + //keep communicating with server + //while(1) + { + printf("Enter message : "); + strncpy(message, "message", sizeof(message)-1); + + //Send some data + if ( send(sock , message , strlen(message) , 0) < 0) { + printf("Send failed"); + close(sock); + return 1; + } + + //Receive a reply from the server + if ( recv(sock , server_reply , 100 , 0) < 0) { + printf("recv failed"); + } + + printf("Server reply %s:", server_reply); + } + + close(sock); + return 0; +} + +int slsi_udp_client(void) +{ + int clientSocket, nBytes; + char buffer[100]; + struct sockaddr_in serverAddr; + socklen_t addr_size; + + nlldbg("start udpclient\n"); + + /*Create UDP socket*/ + clientSocket = socket(PF_INET, SOCK_DGRAM, 0); + + if (clientSocket == -1) { + nlldbg("Could not create socket"); + return -1; + } + /*Configure settings in address struct*/ + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(7891); + serverAddr.sin_addr.s_addr = inet_addr("192.168.0.219"); + //memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero); + + /*Initialize size variable to be used later on*/ + addr_size = sizeof serverAddr; + + while (1) { + nlldbg("Type a sentence to send to server:\n"); + strncpy(buffer, "test hello\n",11); + nlldbg("You typed: %s", buffer); + + nBytes = strlen(buffer) + 1; + + /*Send message to server*/ + if (sendto(clientSocket, buffer, nBytes, 0, (struct sockaddr *)&serverAddr, + addr_size) < 0) { + printf("failed to sendto UDP server\n"); + break; + } + + /*Receive message from server*/ + if ( (nBytes = recvfrom(clientSocket, buffer, 100, 0, NULL, NULL)) < 0 ) { + printf("failed to recvfrom UDP server\n"); + break; + } + UNUSED(nBytes); + nlldbg("Received from server: %s\n", buffer); + up_mdelay(3000); + + } + close(clientSocket); + return 0; +} + + +/** Prepare a echo ICMP request */ +static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len) +{ + size_t i; + size_t data_len = len - sizeof(struct icmp_echo_hdr); + + ICMPH_TYPE_SET(iecho, ICMP_ECHO); + ICMPH_CODE_SET(iecho, 0); + iecho->chksum = 0; + iecho->id = PING_ID; + iecho->seqno = htons(++ping_seq_num); + + /* fill the additional data buffer with some data */ + for (i = 0; i < data_len; i++) { + ((char *)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; + } + + iecho->chksum = inet_chksum(iecho, len); +} + + +/* Ping using the socket ip */ +static err_t ping_send(int s, ip_addr_t *addr) +{ + int err; + struct icmp_echo_hdr *iecho; + struct sockaddr_in to; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff); + iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size); + if (!iecho) { + return ERR_MEM; + } + + ping_prepare_echo(iecho, (u16_t)ping_size); + + to.sin_len = sizeof(to); + to.sin_family = AF_INET; + inet_addr_from_ipaddr(&to.sin_addr, addr); + + err = sendto(s, iecho, ping_size, 0, (struct sockaddr *)&to, sizeof(to)); + + mem_free(iecho); + + return (err ? ERR_OK : ERR_VAL); +} + + +static uint8_t ping_recv(int s) +{ + char *buf; + int fromlen, len=0; + struct sockaddr_in from; + struct ip_hdr *iphdr; + struct icmp_echo_hdr *iecho; + int ping_size = sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + + fromlen = sizeof(struct sockaddr_in); + + buf = (char *)mem_malloc(sizeof(char)*ping_size); + if (!buf) + { + printf("failed to allocate memory\n"); + return SLSI_STATUS_ERROR; + } + + len = recvfrom(s, buf, ping_size, 0, (struct sockaddr *)&from, (socklen_t *)&fromlen); + if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr))) + { + ip_addr_t fromaddr; + + iphdr = (struct ip_hdr *)buf; + iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); + + if (iecho->type == ICMP_ER) { + inet_addr_to_ipaddr(&fromaddr, &from.sin_addr); + ping_recv_counter++; +#ifdef CONFIG_SYSTEM_TIME64 + printf(" %d bytes from %d.%d.%d.%d: icmp_seq=%d ttl=255 time=%llu ms\n", len, + fromaddr.addr >> 0 & 0xff, + fromaddr.addr >> 8 & 0xff, + fromaddr.addr >> 16 & 0xff, + fromaddr.addr >> 24 & 0xff, + ping_recv_counter, + ((sys_now() - ping_time) * USEC_PER_TICK) / 1000); +#else + printf(" %d bytes from %d.%d.%d.%d: icmp_seq=%d ttl=255 time=%d ms\n", len, + fromaddr.addr >> 0 & 0xff, + fromaddr.addr >> 8 & 0xff, + fromaddr.addr >> 16 & 0xff, + fromaddr.addr >> 24 & 0xff, + ping_recv_counter, + ((sys_now() - ping_time) * USEC_PER_TICK) / 1000); +#endif + + if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) { + /* do some ping result processing */ + PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER)); + if (buf) + mem_free(buf); + return SLSI_STATUS_SUCCESS; + } else { + printf("drop\n"); + return SLSI_STATUS_ERROR; + } + } + } + mem_free(buf); + + if (len <= 0){ + printf("ping: recv timeout\n"); + return SLSI_STATUS_ERROR; + } + /* do some ping result processing */ + PING_RESULT(0); + return SLSI_STATUS_SUCCESS; +} + + +static uint8_t ping_thread(ip_addr_t ping_target) { + int s; + struct timeval tv; + int ret; + int fail_count = 0; + int max_fail; + + if(g_ping_counter < 10){ + max_fail = 1; + }else { + max_fail = 5; + } + + + if ((s = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { + printf("fail to create raw socket...\n"); + return SLSI_STATUS_ERROR; + } + + tv.tv_sec = PING_RCV_TIMEO; + tv.tv_usec = 0; + + ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv, sizeof(struct timeval)); + if (ret < 0) { + printf("fail to setsockopt ret:%d\n", ret); + close(s); + return SLSI_STATUS_ERROR; + } + + while (1) { + ping_try_counter++; + + if (ping_send(s, &ping_target) == ERR_OK) { + ping_time = sys_now(); + if(ping_recv(s) != SLSI_STATUS_SUCCESS) { + fail_count++; + if(fail_count == max_fail){ + close(s); + return SLSI_STATUS_ERROR; + }else { + printf("failure %d of %d allowed\n", fail_count, max_fail); + } + } + } + + //sys_msleep(PING_DELAY); + usleep(1000 * PING_DELAY); + if (ping_try_counter == g_ping_counter) + break; + } + + close(s); + return SLSI_STATUS_SUCCESS; +} + +static uint8_t doPing(ip_addr_t ip, int pingcount) { + ping_recv_counter = 0; + ping_try_counter = 0; + g_ping_counter = pingcount; + return ping_thread(ip); +} + diff --git a/apps/examples/slsiwifi/nettest_functions.h b/apps/examples/slsiwifi/nettest_functions.h new file mode 100644 index 0000000..1679d30 --- /dev/null +++ b/apps/examples/slsiwifi/nettest_functions.h @@ -0,0 +1,46 @@ +/** + * @file apps/example/slsiwifi/nettest_functions.h + * + * Copyright (c) 2016 Samsung Electronics, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +int8_t doAutoTest(char *filename); +int8_t doSanityTest(int iterations); +int8_t doNightlyTest(int iterations); +int slsi_tcp_server(void); +int slsi_tcp_client(void); +int slsi_udp_server(void); +int slsi_udp_client(void); diff --git a/apps/examples/slsiwifi/output_functions.c b/apps/examples/slsiwifi/output_functions.c new file mode 100755 index 0000000..5e6c171 --- /dev/null +++ b/apps/examples/slsiwifi/output_functions.c @@ -0,0 +1,170 @@ + +/** + * @file apps/example/slsiwifi/output_functions.c + * + * Copyright (c) 2016 Samsung Electronics, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#define DEBUG 0 + +void sw_printHeader(void) +{ + printf("*****************************************************************\n"); + printf("* Samsung System LSI wifi application for t20 *\n"); + printf("*****************************************************************\n"); + +} + +void sw_printFooter(void) +{ + printf("*****************************************************************\n"); +} + +void sw_printHelp(void) +{ + printf("Available commands:\n"); + printf(" join\n"); + printf(" leave\n"); + printf(" scan\n"); + printf(" startsta\n"); + printf(" startap\n"); + printf(" stop\n"); + printf(" status\n"); + printf(" opmode\n"); + printf(" country\n"); + printf(" txpower\n"); + printf(" auto\n"); + printf(" help\n"); + printf("use the command help to get extended help about arguments for the\n"); + printf("different commands\n"); + sw_printFooter(); +} + +void sw_printJoinHelp(void) +{ + + printf("artikwifi join [ ]\n"); + printf("You will as a minimum need to have 1 argument after join\n"); + printf(" : name of Wi-Fi AP (maximum 32 bytes)\n"); + printf(" : passphrase (format depends on security mode)\n"); + printf(" : type of security, Choose between:\n"); + printf(" open, wep, wep_shared, wpa2_tkip, wpa2_aes,\n"); + printf(" wpa2_mixed, wpa_aes, wpa_tkip, wpa_mixed\n"); + printf("\nIf is omitted, then security mode \"open\" is expected\n"); + printf("If or contains a space then encapsulate it with quotes \"\"\n"); +} + +void sw_printStartapHelp(void) +{ + + printf("artikwifi startap \n"); + printf(" : name of Wi-Fi AP (maximum 32 bytes)\n"); + printf(" : passphrase(format depends on the security mode)\n"); + printf(" : type of security, Choose between:\n"); + printf(" open, wpa_aes, wpa_tkip, wpa_mixed,\n"); + printf(" wpa2_tkip, wpa2_aes, wpa2_mixed\n"); + printf(" : channel to use (range depends on country)\n"); +} + +void sw_printFullHelp(void) +{ + printf("Available commands with full description for each:\n"); + printf("join\n----\n"); + sw_printJoinHelp(); + printf("\n"); + printf("leave\n-----\n"); + printf("artikwifi leave\n No arguments\n"); + printf("\n"); + printf("scan\n----\n"); + printf("artikwifi scan\n No arguments\n"); + printf("\n"); + printf("startsta\n--------\n"); + printf("artikwifi startsta\n No arguments\n"); + printf("\n"); + printf("startap\n-------\n"); + sw_printStartapHelp(); + printf("\n"); + printf("stop\n----\n"); + printf("artikwifi stop\n No arguments\n"); + printf(" Stops the running mode (STA or AP)\n"); + printf("\n"); + printf("country\n--------\n"); + printf("artikwifi country []\n"); + printf(" is capital two letters\n"); + printf(" if country code is not set, it will return country code from NVdata\n"); + printf(" Note that\n"); + printf(" to set country code, Wi-Fi should be off\n"); + printf(" to get country code, Wi-Fi should be on\n"); + printf("\n"); + printf("opmode\n--------\n"); + printf("artikwifi opmode\n"); + printf(" returns Wi-Fi operation mode (among NONE, STA and SOFTAP)\n"); + printf("\n"); + printf("txpower\n--------\n"); + printf("artikwifi txpower \n"); + printf(" sets the tx power to dbm (value between 12-30).\n"); + printf("\n"); + printf("ie\n--------\n"); + printf("artikwifi ie \n"); + printf(" Sets the vendor specific IE data + OUI for the next time \n"); + printf(" the AP mode is started.\n"); + printf(" : the Organizational Unique Id in hex (format: xxxxxx)\n"); + printf(" : the IE data as string representation\n"); + printf("\n"); + printf("status\n--------\n"); + printf("artikwifi status\n"); + printf(" returns Wi-Fi connection status\n"); + printf(" STA : it returns whether Wi-Fi is connected or not\n"); + printf(" soft AP : it returns whether connected number of STAs\n"); + printf("\n"); + printf("auto\n----\n"); + printf("artikwifi auto []\n"); + printf(" is optional and is the full path to a file\n"); + printf(" containing the command line arguments to\n"); + printf(" execute sequentially - on command per line\n"); + printf(" omitting the \"artikwifi\" part\n"); + printf("\n"); + printf("help\n This help\n"); + printf("use the command help to get extended help about arguments for the\n"); + printf("different commands\n"); + sw_printFooter(); +} diff --git a/apps/examples/slsiwifi/output_functions.h b/apps/examples/slsiwifi/output_functions.h new file mode 100644 index 0000000..6499872 --- /dev/null +++ b/apps/examples/slsiwifi/output_functions.h @@ -0,0 +1,52 @@ +/** + * @file apps/example/slsiwifi/output_functions.h + * + * Copyright (c) 2016 Samsung Electronics, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 + +void sw_printFullHelp(void); +void sw_printHelp(void); +void sw_printJoinHelp(void); +void sw_printHeader(void); +void sw_printFooter(void); diff --git a/apps/examples/slsiwifi/slsiwifi_main.c b/apps/examples/slsiwifi/slsiwifi_main.c new file mode 100644 index 0000000..72da206 --- /dev/null +++ b/apps/examples/slsiwifi/slsiwifi_main.c @@ -0,0 +1,757 @@ +/** + * @file apps/example/slsiwifi/app_main.c + * + * Copyright (c) 2016 Samsung Electronics, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "output_functions.h" +// the mm functions are badly guarded with CONFIG_DEBUG +#ifndef CONFIG_DEBUG +#undef CONFIG_EXAMPLES_SLSIDEMO_MEM_CHECK +#endif +#ifdef CONFIG_EXAMPLES_SLSIDEMO_MEM_CHECK +#include +#endif + +#include "slsiwifi_main.h" + +#define DEBUG 0 +/* connections states */ +#define STATE_DISCONNECTED 0 +#define STATE_CONNECTED 1 + +//static bool wifiStarted = false; +//static bool inAuto = false; +bool inAuto = false; +bool wifiStarted = false; +char *g_client_ip_str = NULL; +static int g_connection_state = STATE_DISCONNECTED; +static WiFi_InterFace_ID_t g_mode; +static uint8_t numStations = 0; +static slsi_vendor_ie_t *g_vsie = NULL; +sem_t ap_conn_sem; +sem_t g_sem_result; +sem_t g_sem_join; +static uint8_t g_join_result = 0; +#define WPA_MAX_SSID_LEN (4*32+1) /* SSID encoded in a string - worst case is all 4-octet hex digits + '\0' */ + +/**************************************************************************** + * Defines + ****************************************************************************/ +#define SLSI_AP_MODE_NAME "SLSI Test AP" +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define MAXLEN(a, b) (((a) > (b)) ? (a) : (b)) +#define MODE_STRING_MAX 100 +#define TOUPPER(character) (((character) >= 'a') && ((character) <= 'z') ? ((character) - 0x20) : (character)) +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ***************************************************************************/ + +static bool hex2uint8(const char *str, u8 *ret) +{ + uint16_t idx = 0; + + *ret = 0; + if ((str[idx] == '0') && (TOUPPER(str[idx + 1]) == 'X')) { + str += 2; + } + if (((str[idx] >= '0') && (str[idx] <= '9')) || ((TOUPPER(str[idx]) >= 'A') && + (TOUPPER(str[idx]) <= 'F'))) { + while (((str[idx] >= '0') && (str[idx] <= '9')) || ((TOUPPER(str[idx]) >= 'A') && + (TOUPPER(str[idx]) <= 'F'))) { + *ret = (u8)(*ret * 16 + (((str[idx] >= '0') && (str[idx] <= '9')) ? str[idx] - '0' : TOUPPER(str[idx]) - 'A' + 10)); + idx++; + if (idx >= 2) { + break; + } + } + return true; + } + return false; +} + +#ifdef CONFIG_EXAMPLES_SLSIDEMO_MEM_CHECK +static struct mm_heap_s *g_user_heap; +int g_memstat_total = 0; +static int getMemUsage(void) +{ + g_user_heap = mm_get_heap_info(); + printf("\n\tCurrent memory usage (total): %d bytes\n", g_user_heap->total_alloc_size); + return g_user_heap->total_alloc_size; +} + +int getMemLeaks(void) +{ + usleep(100000); + int memFinal = getMemUsage(); + int result = memFinal - g_memstat_total; + if (result < -128 || result > 0) { // 128 is the number of bytes we have seen being there in + // situations where the the blocks are freed while + // exiting + //print heapinfo + heapinfo_parse(mm_get_heap_info(), HEAPINFO_TRACE); + printf(" ______________________________________________________________ \n"); + printf("| |\n"); + printf("| WARNING: %6.6d bytes leaked during this run |\n", result); + printf("| Use the command 'heapinfo -v' to see the leaking address |\n"); + printf("|______________________________________________________________|\n"); + } else { + result = SLSI_STATUS_SUCCESS; + } + return result; +} +#endif + +static bool check_security_str(char *sec) +{ + bool ret = FALSE; + if (!sec) { + return ret; + } + int len = 0; + int i = 0; + char *m[] = { "open", + "wep", "wep_shared", + "wpa_tkip", "wpa_aes", "wpa_mixed", + "wpa2_tkip", "wpa2_aes", "wpa2_mixed" + }; + len = sizeof(m) / sizeof(m[0]); + for (i = 0; i < len; ++i) { + if (!strncmp(m[i], sec, strlen(sec))) { + ret = TRUE; + break; + } + } + return ret; +} + +void sw_linkUpHandler(slsi_reason_t *reason) +{ + g_connection_state = STATE_CONNECTED; + if (g_mode == SLSI_WIFI_STATION_IF) { + g_join_result = reason->reason_code; // store result code for main thread + char connectedApName[WPA_MAX_SSID_LEN]; + memset(connectedApName, 0, WPA_MAX_SSID_LEN); + printf_encode(connectedApName, WPA_MAX_SSID_LEN, reason->ssid, reason->ssid_len); + printf("Connected to network: bssid: %s, ssid: %s\n", reason->bssid, connectedApName); + sem_post(&g_sem_join); //tell the main thread to move on + } else { + printf("New Station connected bssid: %s \n", reason->bssid); + WiFiIsConnected(&numStations, NULL); + if (inAuto) { // we need to post to the sanity test that we have a connection + sem_post(&ap_conn_sem); + } + } +} + +void sw_linkDownHandler(slsi_reason_t *reason) +{ + g_connection_state = STATE_DISCONNECTED; + if (g_mode == SLSI_WIFI_STATION_IF) { + if (reason) { + printf("Disconnected from network %s reason_code: %d %s\n", reason->bssid, reason->reason_code, reason->locally_generated ? "(locally_generated)" : ""); + } else { + printf("Disconnected from network\n"); + } + sem_post(&g_sem_join); // need to tell the system that we have a link-down. Needed for doLeave() + } else if (g_mode == SLSI_WIFI_SOFT_AP_IF) { + printf("Station disconnected from network. bssid: %s\n", reason->bssid); + WiFiIsConnected(&numStations, NULL); + } +} + +int8_t swScanResultHandler(slsi_reason_t *reason) +{ + + if (reason->reason_code == 0) { + slsi_scan_info_t *results; + WiFiGetScanResults(&results); + printScanResult(results); + WiFiFreeScanResults(&results); + } else { + printf("Scan failed reason: %d, locally_generated: %d\n", reason->reason_code, reason->locally_generated); + } + sem_post(&g_sem_result); + return SLSI_STATUS_SUCCESS; +} + +int8_t doStartSta(void) +{ + int8_t result = SLSI_STATUS_ERROR; + + result = WiFiStart(SLSI_WIFI_STATION_IF, NULL); + if (result == SLSI_STATUS_SUCCESS) { + printf("STA mode started successfully\n"); + g_mode = SLSI_WIFI_STATION_IF; + wifiStarted = true; + } else if (result == SLSI_STATUS_ALREADY_STARTED) { + g_mode = SLSI_WIFI_STATION_IF; + wifiStarted = true; + printf("STA mode already started\n"); + } else { + printf("Failed to start STA mode (error: %d)\n", result); + } + return result; +} + +int8_t doStop(void) +{ + int8_t result = SLSI_STATUS_ERROR; + if (WiFiStop() == SLSI_STATUS_SUCCESS) { + wifiStarted = false; + g_mode = SLSI_WIFI_NONE; + g_connection_state = STATE_DISCONNECTED; + result = SLSI_STATUS_SUCCESS; + WiFiRegisterLinkCallback(NULL, NULL); + WiFiRegisterScanCallback(NULL); + if (g_vsie) { + if (g_vsie->content) { + free(g_vsie->content); + } + free(g_vsie); + g_vsie = NULL; + } + printf("Stopped STA/SoftAP mode\n"); + + } else { + printf("Failed to stop STA/SoftAP mode (not started?)\n"); + } + return result; +} + +/* @ssid - An ASCII character str - hence will not ssid's with e.g. 0 */ +int8_t doJoin(uint8_t *ssid, uint8_t ssid_len, uint8_t *bssid, char *sec, char *passphrase) +{ + int8_t result = SLSI_STATUS_ERROR; + sem_init(&g_sem_join, 0, 0); + char *quotedpass = NULL; + + /* We need to check if the passphrase is ascii if we are using wep/wep_shared */ + if (strncmp("wep", sec, 3) == 0) { //covers both wep and wep_shared + if (strlen(passphrase) == 5 || strlen(passphrase) == 13) { + //we expect it to be ascii in WEP mode -- add quotes + int passlen = strlen(passphrase); + quotedpass = (char *)zalloc(passlen + 3); //make room for quotes + if (!quotedpass) { + return result; + } + quotedpass[0] = '"'; + memcpy("edpass[1], passphrase, passlen); + quotedpass[passlen + 1] = '"'; + quotedpass[passlen + 2] = '\0'; + passphrase = quotedpass; + } + } + slsi_security_config_t *conf = getSecurityConfig(sec, passphrase, g_mode); + result = (WiFiNetworkJoin(ssid, ssid_len, bssid, conf)); + if (wifiStarted && result == SLSI_STATUS_SUCCESS) { + result = SLSI_STATUS_SUCCESS; + sem_wait(&g_sem_join); // wait for it to join + if (!g_join_result) { + printf("Successfully joined the network with SSID %s\n", ssid); + } else { + printf("Join failed - reason %d\n", g_join_result); + result = g_join_result; + } + } else { + printf("Failed to join the network %s. Maybe you forgot to do \"startsta\" (error code: %d)\n", ssid, result); + result = g_join_result; + } + free(conf); + free(quotedpass); + sem_destroy(&g_sem_join); + return result; +} + +int8_t doLeave(void) +{ + int8_t result = SLSI_STATUS_ERROR; + sem_init(&g_sem_join, 0, 0); + if (wifiStarted && WiFiNetworkLeave() == SLSI_STATUS_SUCCESS) { + sem_wait(&g_sem_join); + result = SLSI_STATUS_SUCCESS; + printf("Left network\n"); + } else { + printf("Failed to leave network or no network to leave. Maybe you forgot to do \"startsta\"\n"); + } + sem_destroy(&g_sem_join); + return result; +} + +int8_t doScan(void) +{ + int8_t result = SLSI_STATUS_ERROR; + sem_init(&g_sem_result, 0, 0); + WiFiRegisterScanCallback(swScanResultHandler); + if (wifiStarted && WiFiScanNetwork() == SLSI_STATUS_SUCCESS) { + result = SLSI_STATUS_SUCCESS; + printf("Successfully started scan...waiting for result!\n"); + sem_wait(&g_sem_result); + } else { + printf("Failed to start scan for networks. maybe you forgot to do \"startsta/startap\"\n"); + } + sem_destroy(&g_sem_result); + return result; +} + +int8_t doStartAP(char *ssid, char *sec, char *passphrase, uint8_t channel) +{ + int8_t result = SLSI_STATUS_ERROR; + slsi_ap_config_t *ap_config = (slsi_ap_config_t *)zalloc(sizeof(slsi_ap_config_t)); + if (!ap_config) { + return result; + } + /* add initialization code as slsi_app */ + ap_config->beacon_period = 100; + ap_config->DTIM = 2; + ap_config->phy_mode = 1; + ap_config->vsie = g_vsie; + if (WiFiRegisterLinkCallback(&sw_linkUpHandler, &sw_linkDownHandler)) { + printf("Link call back handles registered - status failed !\n"); + free(ap_config); + return result; + } + + if (channel > 14 || channel < 1) { + printf("Channel needs to be between 1 and 14 (highest channel depends on country)\n"); + free(ap_config); + return result; + } else { + ap_config->channel = channel; + } + + if (ssid != NULL) { + // NOTE: Here the implementation assumes a plain '\0' terminated ascii-str - hence a subset of valid SSID's + memcpy(&ap_config->ssid, ssid, strlen(ssid)); + ap_config->ssid_len = strlen(ssid); + } else { + sw_printStartapHelp(); + free(ap_config); + return result; + } + + if (sec != NULL) { + if (!check_security_str(sec)) { + sw_printStartapHelp(); + printf("Security mode not supported: %s\n", sec); + free(ap_config); + return result; + } else { + ap_config->security = getSecurityConfig(sec, passphrase, SLSI_WIFI_SOFT_AP_IF); + } + } else { + sw_printStartapHelp(); + } + + result = WiFiStart(SLSI_WIFI_SOFT_AP_IF, ap_config); + if (result == SLSI_STATUS_SUCCESS || result == SLSI_STATUS_ALREADY_STARTED) { + wifiStarted = TRUE; + g_mode = SLSI_WIFI_SOFT_AP_IF; + if (sec && ssid && result != SLSI_STATUS_ALREADY_STARTED) { + printf("SoftAP with SSID: %s and security: %s successfully started!\n", ssid, sec); + } else { + printf("SoftAP was already started so it will continue to run with previous configuration\n"); + } + result = SLSI_STATUS_SUCCESS; + } else { + printf("Failed to start SoftAP making sure supplicant is stopped\n"); + if (WiFiStop()) { + printf("failed to stop supplicant\n"); + } + g_mode = SLSI_WIFI_NONE; + } + if (ap_config) { + if (ap_config->security) { + free(ap_config->security); + ap_config->security = NULL; + } + free(ap_config); + ap_config = NULL; + } + return result; +} + +void doIsConnected(void) +{ + uint8_t result; + + if (WiFiIsConnected(&result, NULL) != SLSI_STATUS_SUCCESS) { + printf("failed to WifiIsConnected\n"); + return; + } + + if (result > 0) { + printf("Wi-Fi status - Connected : %d\n", result); + } else { + printf("Wi-Fi status - Not Connected\n"); + } +} + +int8_t parseCmdLine(int argc, char *argv[]) +{ + int8_t result = SLSI_STATUS_ERROR; + uint8_t ssid_len = 0; + if (strncmp("join", argv[0], strlen(argv[0])) == 0) { + char *secmode = SLSI_WIFI_SECURITY_OPEN; + char *passphrase = NULL; + /*slsiwifi join + : name of Wi-Fi AP (maximum 32 bytes) + : type of security, open, wep, wep_shared, wpa2_tkip, wpa2_aes, wpa2_mixed, wpa_aes, wpa_tkip, wpa_mixed + : passphrase + */ + if (argc <= 1) { + sw_printJoinHelp(); + return result; + } else { + ssid_len = strlen(argv[1]); + if (argc == 2) { + secmode = SLSI_WIFI_SECURITY_OPEN; + } else if (argc == 3) { + if (strncmp(SLSI_WIFI_SECURITY_OPEN, argv[2], strlen(argv[2])) == 0) { + secmode = SLSI_WIFI_SECURITY_OPEN; + } else { // we expect it to be a passphrase in argv[2] so use default security mode of wpa2_aes + secmode = SLSI_WIFI_SECURITY_WPA2_AES; + passphrase = argv[2]; + } + } else if (argc == 4) { + passphrase = argv[2]; + secmode = argv[3]; + } else { + sw_printJoinHelp(); + return result; + } + } + + /* An SSID is 32 octets, we assume all ascii here and can safely type-cast to correct data type. + * as this interface only supports a subset of possible SSID's*/ + printf("Joining network %s\n", argv[1]); + printf("Security: %s\n", secmode); + if (passphrase) { + printf("Passphrase: %s\n", passphrase); + } + if (!check_security_str(secmode)) { + sw_printJoinHelp(); + printf("Security mode not supported: %s\n", secmode); + } else { + (void)doJoin((uint8_t *) argv[1], ssid_len, NULL /*bssid */ , secmode, passphrase); + } + } else if (strncmp("startsta", argv[0], MAXLEN(8, strlen(argv[0]))) == 0) { + /*no more arguments - just start sta mode */ + (void)doStartSta(); + } else if (strncmp("stop", argv[0], MAXLEN(4, strlen(argv[0]))) == 0) { + /*no more arguments - just stop sta/softap mode */ + (void)doStop(); +#ifdef CONFIG_EXAMPLES_SLSIDEMO_MEM_CHECK + getMemLeaks(); +#endif + } else if (strncmp("opmode", argv[0], MAXLEN(6, strlen(argv[0]))) == 0) { + if (g_mode == SLSI_WIFI_STATION_IF) { + printf("System is in STA mode\n"); + } else if (g_mode == SLSI_WIFI_SOFT_AP_IF) { + printf("System is in Soft AP mode\n"); + } else { + printf("WiFi is not yet started\n"); + } + } else if (strncmp("leave", argv[0], MAXLEN(5, strlen(argv[0]))) == 0) { + /*no more arguments - just leave */ + (void)doLeave(); + } else if (strncmp("country", argv[0], MAXLEN(7, strlen(argv[0]))) == 0) { + if (!argv[1] || strlen(argv[1]) != 2) { + sw_printHelp(); + } else { + WiFiSetCountryCode(argv[1]); + } + } else if (strncmp("txpower", argv[0], MAXLEN(7, strlen(argv[0]))) == 0) { + if (!argv[1] || strlen(argv[1]) != 2) { + sw_printHelp(); + } else { + uint8_t tx_power = (uint8_t) atoi(argv[1]); + if (tx_power >= 12 && tx_power <= 30) { + printf("Setting tx power to %ddBm\n", tx_power); + WiFiSetTxPower(&tx_power); + } else { + sw_printHelp(); + } + } + } else if (strncmp("scan", argv[0], MAXLEN(4, strlen(argv[0]))) == 0) { + /*no more arguments - just scan */ + (void)doScan(); + } else if (strncmp("startap", argv[0], MAXLEN(7, strlen(argv[0]))) == 0) { + //slsiwifi startap + if (argc >= 2 && strlen(argv[1]) > 32) { + printf("SSID cannot be longer than 32 characters\n"); + return result; + } + uint8_t channel = 1; + char *sec = "open"; + char *passphrase = NULL; + /*Options for argc = 2: + * startap + * channel defaults to 1 + * security defaults to open + * */ + if (argc == 2) { + //fallthrough + } else if (argc == 3) { + /*Options for argc = 3: + * startap + * startap open + * startap + * channel defaults to 1 + * security defaults to wpa2_aes for passphrase only + * */ + if (strlen(argv[2]) <= 3) { //We expect it to be a number = channel + channel = atoi(argv[2]); + } else if (strncmp("open", argv[2], MAXLEN(4, strlen(argv[2]))) == 0) { + //use defualt settings + } else { //expect passphrase + sec = SLSI_WIFI_SECURITY_WPA2_AES; + passphrase = argv[2]; + } + } else if (argc == 4) { + /*Options for argc = 4: + * startap open + * startap + * startap + * channel defaults to 1 + * security defaults to wpa2_aes for passphrase only + * */ + if (strncmp("open", argv[2], MAXLEN(4, strlen(argv[2]))) == 0) { + //use default settings + if (strlen(argv[3]) <= 3) { //We expect it to be a number = channel + channel = atoi(argv[3]); + } else { + printf("%s does not look like a channel number\n", argv[3]); + } + } else if (strncmp("wep", argv[3], MAXLEN(3, strlen(argv[3]))) == 0 || + strncmp("wep_shared", argv[3], MAXLEN(10, strlen(argv[3]))) == 0) { + printf("wep security is not allowed for Soft AP\n"); + sw_printStartapHelp(); + return result; + } else { //expect passphrase + sec = SLSI_WIFI_SECURITY_WPA2_AES; + passphrase = argv[2]; + if (strlen(argv[3]) <= 3) { //We expect it to be a number = channel + channel = atoi(argv[2]); + } else { //we expect it to be a passphrase + sec = argv[3]; + } + } + } else if (argc == 5) { + passphrase = argv[2]; + sec = argv[3]; + channel = atoi(argv[4]); + } else { + sw_printStartapHelp(); + return result; + } + result = doStartAP(argv[1], sec, passphrase, channel); + } else if (strncmp("status", argv[0], MAXLEN(6, strlen(argv[0]))) == 0) { + (void)doIsConnected(); + /* + }else if (strncmp(argv[0], "tcpserver", MAXLEN(9, strlen(argv[0]))) == 0) { + if(slsi_tcp_server() != 0){ + printf("TCP server failed\n"); + } + }else if (strncmp(argv[0], "tcpclient", MAXLEN(9, strlen(argv[0]))) == 0) { + if(slsi_tcp_client() != 0){ + printf("TCP Client failed\n"); + } + }else if (strncmp(argv[0], "udpserver", MAXLEN(9,strlen(argv[0]))) == 0) { + if(slsi_udp_server() != 0){ + printf("UDP Server failed\n"); + } + */ + } else if (strncmp(argv[0], "ie", MAXLEN(2, strlen(argv[0]))) == 0) { + if (argv[1] != NULL && argv[2] != NULL && strlen(argv[1]) == 6 && strlen(argv[2]) <= 253) { + printf("Storing new OUI=%s IE=%s\n", argv[1], argv[2]); + if (g_vsie == NULL) { + g_vsie = (slsi_vendor_ie_t *)zalloc(sizeof(slsi_vendor_ie_t)); + if (g_vsie == NULL) { + printf("Could not allocate buffer for vendor IE\n"); + return result; + } + } + char *poui = argv[1]; + if (hex2uint8(poui, &g_vsie->oui[0]) != TRUE || + hex2uint8(poui + 2, &g_vsie->oui[1]) != TRUE || + hex2uint8(poui + 4, &g_vsie->oui[2]) != TRUE) { + printf("OUI hex representation not valid\n"); + return result; + } + if (g_vsie->content != NULL) { + free(g_vsie->content); + } + g_vsie->content = (uint8_t *)zalloc(strlen(argv[2])); + if (g_vsie->content == NULL) { + printf("Could not allocate buffer for vendor IE\n"); + return result; + } + g_vsie->content_length = strlen(argv[2]); + memcpy(g_vsie->content, argv[2], strlen(argv[2])); + + } + /* + }else if (strncmp(argv[0], "udpclient", MAXLEN(9,strlen(argv[0]))) == 0) { + if(slsi_udp_client() != 0){ + printf("UDP Client failed\n"); + } + }else if (strncmp(argv[0], "auto", MAXLEN(4, strlen(argv[0]))) == 0 && inAuto == false){ + sem_init(&ap_conn_sem, 0, 0); + if(argc > 1) + result = doAutoTest(argv[1]); //filename if not null + else + result = doAutoTest(NULL); + sem_destroy(&ap_conn_sem); + if(result == SLSI_STATUS_SUCCESS) return 0; + else return 1; + }else if (strncmp(argv[0], "sanity", MAXLEN(6,strlen(argv[0]))) == 0 && inAuto == false){ + int iterations = 0; + sem_init(&ap_conn_sem, 0, 0); + if(argc > 1){ + iterations = atoi(argv[1]); + } + result = doSanityTest(iterations); + sem_destroy(&ap_conn_sem); + if(result != SLSI_STATUS_SUCCESS) { + //we need to do some cleanup and make sure the supplicant is stopped + (void)doStop(); + printf("STATUS:\n\ttests passed: %d\n",result); + } + #ifdef CONFIG_EXAMPLES_SLSIDEMO_MEM_CHECK + int leakresult = getMemLeaks(); + if(leakresult != SLSI_STATUS_SUCCESS || result != SLSI_STATUS_SUCCESS){ + #else + if (result != SLSI_STATUS_SUCCESS){ + #endif + //needed for CI systems to parse for SUCCESS/FAILED + printf("\n\tWiFi Sanity Test result: FAILED\n\n"); + }else { + printf("\n\tWiFi Sanity Test Result : SUCCESS\n\n"); + } + + if(result == SLSI_STATUS_SUCCESS) return 0; + else return 1; + return 0; + }else if (strncmp(argv[0], "nightly", MAXLEN(7,strlen(argv[0]))) == 0 && inAuto == false){ + int iterations = 0; + sem_init(&ap_conn_sem, 0, 0); + if(argc > 1){ + iterations = atoi(argv[1]); + } + result = doNightlyTest(iterations); + sem_destroy(&ap_conn_sem); + if(result != SLSI_STATUS_SUCCESS) { + //we need to do some cleanup and make sure the supplicant is stopped + (void)doStop(); + printf("STATUS:\n\ttests passed: %d\n",result); + } + #ifdef CONFIG_EXAMPLES_SLSIDEMO_MEM_CHECK + int leakresult = getMemLeaks(); + if(leakresult != SLSI_STATUS_SUCCESS || result != SLSI_STATUS_SUCCESS){ + #else + if (result != SLSI_STATUS_SUCCESS){ + #endif + //needed for CI systems to parse for SUCCESS/FAILED + printf("\n\tWiFi Nightly Test result: FAILED\n\n"); + }else { + printf("\n\tWiFi Nightly Test Result : SUCCESS\n\n"); + } + + if(result == SLSI_STATUS_SUCCESS) return 0; + else return 1; + return 0; + */ + } else if (strncmp(argv[0], "help", MAXLEN(4, strlen(argv[0]))) == 0) { + sw_printFullHelp(); + } else { + sw_printHelp(); + } + + return result; +} + +/**************************************************************************** + * app_main + ****************************************************************************/ +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, char *argv[]) +{ +#else +int slsi_wifi_main(int argc, char *argv[]) +{ +#endif +#ifdef CONFIG_EXAMPLES_SLSIDEMO_MEM_CHECK + if (!wifiStarted) { + g_memstat_total = getMemUsage(); + } +#endif + int8_t result = SLSI_STATUS_ERROR; + sw_printHeader(); + if (argc == 1) { + sw_printHelp(); + return result; + } else { + /*we have no way of knowing if the link up/down handlers have been + * changed behind our back so we will always re-register them here. + * They are critical for the system to work*/ + if (!WiFiRegisterLinkCallback(&sw_linkUpHandler, &sw_linkDownHandler)) { + printf("Link call back handles registered - per default!\n"); + } else { + printf("Link call back handles registered - Cannot continue !\n"); + return result; + } + + result = parseCmdLine(argc - 1, &argv[1]); + } + return result; +} diff --git a/apps/examples/slsiwifi/slsiwifi_main.h b/apps/examples/slsiwifi/slsiwifi_main.h new file mode 100644 index 0000000..2b6d6c0 --- /dev/null +++ b/apps/examples/slsiwifi/slsiwifi_main.h @@ -0,0 +1,47 @@ +/** + * @file apps/example/slsiwifi/nettest_functions.h + * + * Copyright (c) 2016 Samsung Electronics, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef __SLSIWIFI_MAIN_H +#define __SLSIWIFI_MAIN_H + +#include +#include +#include +#include "slsi_wifi_api.h" +// #include "nettest_functions.h" // temporarily disable until dhcp functions being done refactoring + +void sw_linkUpHandler(slsi_reason_t *reason); +void sw_linkDownHandler(slsi_reason_t *reason); + +#endif diff --git a/apps/include/netutils/wifi/slsi_wifi_api.h b/apps/include/netutils/wifi/slsi_wifi_api.h new file mode 100644 index 0000000..bb1a6f4 --- /dev/null +++ b/apps/include/netutils/wifi/slsi_wifi_api.h @@ -0,0 +1,393 @@ +/** +* @defgroup WiFi WiFi +* SLSI WiFi API for TinyAra +* @{ +* +* @brief S.LSI WiFi API for TinyARA. +* +* This is the Samsung LSI WiFi API for TinyARA OS. It contains support for both station and soft-ap +* mode on the 2.4Ghz frequency. +* The API has support for security modes WPA/WPA2/WEP with various ciphers. +*/ + +#ifndef SLSI_WIFI_API_H_ +#define SLSI_WIFI_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* interface name to use */ +#define CTRL_IFNAME "wl1" + +#ifndef BIT +#define BIT(x) (1 << (x)) +#endif + + +typedef enum { + SLSI_SEC_MODE_OPEN = 0, // 00000000 + SLSI_SEC_MODE_WEP = BIT(1), // 00000001 + SLSI_SEC_MODE_WEP_SHARED = BIT(2), // 00000010 + SLSI_SEC_MODE_WPA_TKIP = BIT(3), // 00000100 + SLSI_SEC_MODE_WPA_CCMP = BIT(4), // 00001000 + SLSI_SEC_MODE_WPA_MIXED = (BIT(3)|BIT(4)), // 00001100 + SLSI_SEC_MODE_WPA2_TKIP = BIT(5), // 00010000 + SLSI_SEC_MODE_WPA2_CCMP = BIT(6), // 00100000 + SLSI_SEC_MODE_WPA2_MIXED = (BIT(5)|BIT(6)), // 00110000 + SLSI_SEC_MODE_EAP = BIT(7) // 01000000 +} slsi_security_mode_t; + +/* Length defines */ +#define SLSI_MACADDR_LEN 6 +/* The maximum length of an SSID - excluding '\0' is case of all characters used */ +#define SLSI_SSID_LEN 32 +#define SLSI_PASSPHRASE_LEN 64 + +/* SLSI return values */ +#define SLSI_STATUS_SUCCESS 0 // Successfully completed +#define SLSI_STATUS_ERROR 1 // Error - unspecified +#define SLSI_STATUS_COMMAND_FAILED 2 // Failed - command failed +#define SLSI_STATUS_COMMAND_UNKNOWN 3 // Failed - command unknown +#define SLSI_STATUS_NOT_STARTED 4 // Failed - mode never initiated +#define SLSI_STATUS_ALREADY_STARTED 5 // Failed - mode already started +#define SLSI_STATUS_SUPPLICANT_START_FAILED 6 // Failed - start up of wpa_supplicant failed +#define SLSI_STATUS_PARAM_FAILED 7 // Failed - parameter specified not valid +#define SLSI_STATUS_ALREADY_CONNECTED 8 // Failed - WiFi already connected +#define SLSI_STATUS_NOT_CONNECTED 9 // Failed - WiFi not connected +#define SLSI_STATUS_SECURITY_FAILED 10 // Failed - security setup failed + +/* SLSI reason codes */ +/* Return values used from ieee802_11_defs.h + * (Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) + * SLSI Wi-Fi own defined reason codes are starting from 200 + */ +/* Added in Join failed scenarios:*/ +#define SLSI_REASON_NETWORK_CONFIGURATION_NOT_FOUND 201 +#define SLSI_REASON_NETWORK_AUTHENTICATION_FAILED 202 +#define SLSI_REASON_ASSOCIATION_REQ_FAILED 203 + +/** + * Specify interval between scans performed by lower layers + * Value is in seconds (default is 30 seconds) + */ +#define SLSI_SCAN_INTERVAL 30 + +/** + * Specify expiration of scans results in lower layers + * Value is in seconds (default is 120 seconds) + */ +#define SLSI_BSS_EXPIRE_AGE 120 + +/** + * Specify whether lower Wi-Fi layers should handle automatic reconnect + * in station mode. + * Values: enabled - 1, disabled - 0 (default is enabled 1) + */ +#define SLSI_STA_AUTOCONNECT 1 + +/** + * Specify whether API layers should wait for multiple scan for network + * attempts if device not found first time in station mode. Raising the + * count will hold the link_up response for a longer period + * Values: 3 is default + */ +#define SLSI_STA_JOIN_SCAN_ATTEMPT 3 + +/* slsi wifi network interface - api parameter defines */ +typedef enum WiFi_InterFace_ID { + SLSI_WIFI_NONE, + SLSI_WIFI_STATION_IF, // Station mode (turns on wpa_supplicant) + SLSI_WIFI_SOFT_AP_IF, // Soft AP mode (turns on hostapd) + SLSI_WIFI_P2P_IF // P2P mode (turns on wpa_supplicant) +} WiFi_InterFace_ID_t; + +/* Capabilities bit mask + * Return values defined in ieee802_11_defs.h + #define HT_CAP_INFO_LDPC_CODING_CAP ((u16) BIT(0)) + #define HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET ((u16) BIT(1)) + #define HT_CAP_INFO_SMPS_MASK ((u16) (BIT(2) | BIT(3))) + #define HT_CAP_INFO_SMPS_STATIC ((u16) 0) + #define HT_CAP_INFO_SMPS_DYNAMIC ((u16) BIT(2)) + #define HT_CAP_INFO_SMPS_DISABLED ((u16) (BIT(2) | BIT(3))) + #define HT_CAP_INFO_GREEN_FIELD ((u16) BIT(4)) + #define HT_CAP_INFO_SHORT_GI20MHZ ((u16) BIT(5)) + #define HT_CAP_INFO_SHORT_GI40MHZ ((u16) BIT(6)) + #define HT_CAP_INFO_TX_STBC ((u16) BIT(7)) + #define HT_CAP_INFO_RX_STBC_MASK ((u16) (BIT(8) | BIT(9))) + #define HT_CAP_INFO_RX_STBC_1 ((u16) BIT(8)) + #define HT_CAP_INFO_RX_STBC_12 ((u16) BIT(9)) + #define HT_CAP_INFO_RX_STBC_123 ((u16) (BIT(8) | BIT(9))) + #define HT_CAP_INFO_DELAYED_BA ((u16) BIT(10)) + #define HT_CAP_INFO_MAX_AMSDU_SIZE ((u16) BIT(11)) + #define HT_CAP_INFO_DSSS_CCK40MHZ ((u16) BIT(12)) + // B13 - Reserved (was PSMP support during P802.11n development) + #define HT_CAP_INFO_40MHZ_INTOLERANT ((u16) BIT(14)) + #define HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT ((u16) BIT(15))*/ + +typedef struct slsi_ht_config { + uint16_t ht_capab_info; // Supported fields: HT_CAP_INFO_GREEN_FIELD, HT_CAP_INFO_SHORT_GI20MHZ + uint8_t mcs_index[10]; // 0 uses default, supported HT-MCS rates - in ASCII hex: 0xffff0000000000000000 +} slsi_ht_config_t; + +typedef struct slsi_security_config { + uint32_t secmode; + char passphrase[SLSI_PASSPHRASE_LEN]; +} slsi_security_config_t; + + +typedef struct slsi_vendor_ie { + uint8_t oui[3]; // Organizational Unique ID + uint8_t *content; // the ponter to the data allocated for the Vendor IE block + uint8_t content_length; // total size of the allocated buffer +} slsi_vendor_ie_t; + +typedef struct slsi_ap_config { + uint8_t ssid[SLSI_SSID_LEN+1]; // 802.11 spec defined unspecified or uint8 + int8_t ssid_len; // length of ssid - # of valid octets + uint32_t beacon_period; // beacon period, default 100 TU + uint32_t DTIM; // Delivery Traffic Information Message (range 1..255), default 2 + uint8_t channel; // channel/frequency + uint8_t phy_mode; // 0:legacy 1: 11N HT + slsi_ht_config_t ht_mode; // requires CONFIG_HT_OVERRIDES enabled, see slsi_ht_config_t + slsi_security_config_t *security; // use NULL if security mode is open + slsi_vendor_ie_t *vsie; // Vender specific IE block +} slsi_ap_config_t; + + +typedef struct slsi_scan_info { + uint8_t ssid[SLSI_SSID_LEN+1]; // 802.11 spec defined unspecified or uint8 + char bssid[18]; // char string e.g. xx:xx:xx:xx:xx:xx + int8_t ssid_len; // length of ssid - # of valid octets + int8_t rssi; // rssi level of scanned device + uint32_t beacon_period; // beacon period used (default 100) + uint8_t channel; // channel/frequency + uint8_t phy_mode; // 0:legacy 1: 11N HT + uint8_t bss_type; // 0:infrastructure, 1:independent + uint8_t wps_support; // boolean 1 supported, 0 not supported + uint8_t num_sec_modes; // number of elements of security modes in sec_mode + slsi_ht_config_t ht_mode; // See slsi_ht_config_t + slsi_security_config_t *sec_modes; // list of security modes + struct slsi_scan_info* next; +} slsi_scan_info_t; + + +typedef struct slsi_reason { + uint32_t reason_code; // Reason codes - 0 for success - error code see 'SLSI reason codes' above + uint8_t locally_generated; // Which side cause link down, 1 = locally, 0 = remotely - valid for STA mode only + int8_t ssid_len; // length of ssid - # of valid octets + uint8_t ssid[SLSI_SSID_LEN+1]; // 802.11 spec defined up to 32 octets of data + char bssid[18]; // BSS identification, char string e.g. xx:xx:xx:xx:xx:xx +} slsi_reason_t; + +typedef int8_t (*network_scan_result_handler_t)(slsi_reason_t* reason); +typedef void (*slsi_network_link_callback_t)(slsi_reason_t* reason); + +/** + * Set the network configuration and start Wi-Fi interface + * @interface_id interface id to use (STATION_IF = 0 or SOFT_AP_IF = 1) + * @ap_config network configurations needed if SOFT_AP_IF is selected as + * WiFi_InterFace_ID_t else NULL. The caller owns this structure. + * Return: Completed successfully or failed + * + * Set the network configuration and start Wi-Fi interface in either AP mode or + * Station Mode. Will start either Hostapd or wpa_supplicant process depending on the mode + * selected. + * A WiFiStart implies the init of the Wi-Fi stack + driver + IP stack if + * not already running. + * The hostapd will activate the AP automatically when started. + * In case the application invokes WiFiStart multiple times (i.e. with + * STATION_IF in the first and SOFTAP_IF in the second) the sequential + * requests will be met with an error response. + * This is because the Wi-Fi sub system cannot run in both station and SoftAP + * mode at the same time. + * This function will use the chosen channel to select the proper mode for + * phy_mode=legacy using the following rules: + * - If channel=0 the Automatic Channel Selection(ACS) in hostapd will be + * enabled and the hardware mode will be set to 11G. + * - If channel=[1-13] the channel will be set as selected and the hardware + * mode will be set to 11G + * - If channel=14 then the channel will be set as select and the hardware + * mode will be set to 11B (only allowed in Japan). + * - If channel=[36-161] the channel will be set as selected and hardware + * mode will be set to 11A (unless HT_mode specified then 11N) + */ +int8_t WiFiStart(WiFi_InterFace_ID_t interface_id, + const slsi_ap_config_t *ap_config); + +/** + * Stop the Wi-Fi interface + * Return: Completed successfully or failed + * + * Stop the interface that currently associated AP, or abort the current + * connection process. A WiFiStop implies a stop of the Wi-Fi stack, + * driver and IP stack if nothing else needs it. + * If the selected interface is not running, the function will return success + */ +int8_t WiFiStop(void); + +/** + * Register callback functions for WiFi link + * @link_up callback function to register for the link up event + * @link_down callback function to register for the link down event + * Return: Completed successfully or failed + * + * Register callback functions that gets called when a change in network link + * status occurs, these carry a slsi_reason_t to tell why link is up or down + */ +int8_t WiFiRegisterLinkCallback(slsi_network_link_callback_t link_up, + slsi_network_link_callback_t link_down); + +/** + * Register callback functions for WiFi scan + * @scan_result_handler callback function to register for the link up event + * Return: Completed successfully or failed + * + * Register callback functions that gets called when a scan trigger gets + * response for its request has done. + */ +int8_t WiFiRegisterScanCallback( + network_scan_result_handler_t scan_result_handler); + +/** + * Scan for Wi-Fi network + * @results_handler A function pointer for the handler that will process + * the scan complete. + * + * Return: Scan initiated successfully or failed + * + * Start a scan for Wi-Fi AP in the surroundings. Result is returned via + * callback to a result handler: Scan complete event or Scan aborted. + * The scan results are retrieved using WiFiGetScanResults(). + */ +int8_t WiFiScanNetwork(void); + +/** + * Return current scan results list + * @scan_results A pointer to a linked list of scan results + * The caller takes owner responsibility of this list, + * and must free each item on the list after use. + * For convince the function WiFiFreeScanResults() can + * be used to free the list. + * + * Return: Completed successfully or failed + * + * Request available list of scan results for Wi-Fi AP in the surroundings. The + * results are returned as the list of structure slsi_ap_info_t linked via next + * pointer. + * The list must be freed by the caller, hence passing an existing list to this + * function will cause a memory leak. + */ +int8_t WiFiGetScanResults(slsi_scan_info_t **scan_results); + +/** + * Free the result list returned by WifiGetScanResults. + * Does nothing if a NULL pointer is passed. + * Sets *scan_results to NULL after operation is done. + * @scan_results A pointer to the linked list to free + * Return: Always success + */ +int8_t WiFiFreeScanResults(slsi_scan_info_t **scan_results); + +/** + * Join a known Wi-Fi AP + * @ssid SSID to be used for the AP + * @ssid_len Length of SSID (# of valid octets in @ssid) + * @bssid preferred BSSID to be used when multiple APs has same SSID. + * Set to NULL for best effort + * @security_config a pointer to data to slsi_security_config_t containing passphrase, keymgmt and cipher. + * The caller owns this struct, use NULL if open security is requred. + * Return: Completed successfully or failed + * + * Join a known Wi-Fi AP with specified SSID and security key. The authentication + * type needed will automatically be resolved by the Wi-Fi stack. + * The function will return after the connection is tried. + */ +int8_t WiFiNetworkJoin(uint8_t* ssid, uint8_t ssid_len, uint8_t* bssid, + const slsi_security_config_t *security_config); + +/** + * Leave a connected AP + * Return: Completed successfully or failed + * + * Close the connection to a connected AP. This will not close down the Wi-Fi + * stack but simply disconnect. + */ +int8_t WiFiNetworkLeave(void); + +/** + * Request get tx power. + * @dbm: a pointer to data to return value in dbm. + * Return: success or failure + */ +int8_t WiFiGetTxPower(uint8_t *dbm); + +/** + * Request set tx power + * @dbm: a pointer to value between 12 and 30 dbm + * Return: success or failure + */ +int8_t WiFiSetTxPower(uint8_t *dbm); + +/** + * Request get own mac address + * @mac: a pointer to data to return mac address (xx:xx:xx:xx:xx:xx) + * Return: success or failure + */ +int8_t WiFiGetMac(uint8_t *mac); + +/** + * Request rssi level of connection + * @rssi: a pointer to data to return level of rssi + * Return: success or failure + */ +int8_t WiFiGetRssi(int8_t *rssi); + +/** + * Request channel of connection + * @channel: a pointer to data to return channel of current connection + * Return: success or failure + */ +int8_t WiFiGetChannel(int8_t *channel); + +/** + * Request connected status: + * In STA mode: + * @count 1 for connected in STA mode, count of connected devices in AP mode + * if count > 1 details are updated, otherwise NULL + * 0 for disconnected + * @details a pointer to a data structure which will be filled in with + * BSSID and SSID of AP if connected. Set to NULL if this + * information is not needed + * In AP mode: + * @details unused - PASS NULL + * @count the number of currently connected stations. + * + * Return: success or failure + * In case of failure count will be set to the last know information and + * details will be filled as best effort (hence all values that could not + * be extracted will have the value 0) + */ +int8_t WiFiIsConnected(uint8_t *count, slsi_reason_t *details); + +/** + * Request the current mode of operation. + * @mode: sets to one of SLSI_WIFI_NONE, SLSI_WIFI_STATION_IF, SLSI_WIFI_SOFT_AP_IF + * Return: success or failure + */ +int8_t WiFiGetOpMode(WiFi_InterFace_ID_t* mode); + +/** + * Request to set country code + * @country_code a pointer to data to containing a two capital letter country code + * Return: Completed successfully or failed + */ +int8_t WiFiSetCountryCode(const char *country_code); + +#ifdef __cplusplus +} +#endif + +#endif /* SLSI_WIFI_API_H_ */ + +/**@} */ //end of doxygen defgroup diff --git a/apps/include/netutils/wifi/slsi_wifi_nvmap.h b/apps/include/netutils/wifi/slsi_wifi_nvmap.h new file mode 100644 index 0000000..eb3fa5d --- /dev/null +++ b/apps/include/netutils/wifi/slsi_wifi_nvmap.h @@ -0,0 +1,43 @@ +#ifndef SLSI_WIFI_NVMAP_H_ +#define SLSI_WIFI_NVMAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif +#include + + +/* struct containing all the values that needs to be read/written + * from/to the non-volatile memory. + * New values needs to be added to the end of the structure and needs to be + * of byte aligned sizes. + * + * */ + +typedef struct slsi_wifi_nv_data { + char initialized[5]; + char country_code[3]; //two asci chars + null + uint8_t tx_power; +} slsi_wifi_nv_data_t; + +/* change default values in menu config or use sane defaults*/ +#ifdef CONFIG_SLSI_WIFI_DEFAULT_WLAN_COUNTRY_CODE +#define SLSI_WIFI_NV_DEFAULT_COUNTRY_CODE CONFIG_SLSI_WIFI_DEFAULT_WLAN_COUNTRY_CODE +#else +#define SLSI_WIFI_NV_DEFAULT_COUNTRY_CODE "00" +#endif +#ifdef CONFIG_SLSI_WIFI_DEFAULT_WLAN_TX_POWER +#define SLSI_WIFI_NV_DEFAULT_TX_POWER CONFIG_SLSI_WIFI_DEFAULT_WLAN_TX_POWER +#else +#define SLSI_WIFI_NV_DEFAULT_TX_POWER (uint8_t)30 +#endif + +#define SLSI_WIFI_NV_DATA_START (CONFIG_NVRAM_WIFI_START) +#define SLSI_WIFI_NV_DATA_SIZE (sizeof(slsi_wifi_nv_data_t)) + +#ifdef __cplusplus +} +#endif + + +#endif // SLSI_WIFI_NVMAP_H_ diff --git a/apps/include/netutils/wifi/slsi_wifi_utils.h b/apps/include/netutils/wifi/slsi_wifi_utils.h new file mode 100644 index 0000000..61cf617 --- /dev/null +++ b/apps/include/netutils/wifi/slsi_wifi_utils.h @@ -0,0 +1,52 @@ +/** +* @defgroup WiFi WiFi +* SLSI WiFi utility functions for TinyAra +* @{ +* +* @brief S.LSI WiFi utility functions for TinyARA. +* +* This is the utility functions available for the Samsung LSI WiFi API for TinyARA OS. +*/ + +#ifndef __SLSI_WIFI_UTILS_H__ +#define __SLSI_WIFI_UTILS_H__ + +#include +#include +#include +#include +#include +#include "slsi_wifi_api.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* Supported security modes as string */ +#define SLSI_WIFI_SECURITY_OPEN "open" +#define SLSI_WIFI_SECURITY_WEP_OPEN "wep" +#define SLSI_WIFI_SECURITY_WEP_SHARED "wep_shared" +#define SLSI_WIFI_SECURITY_WPA_MIXED "wpa_mixed" +#define SLSI_WIFI_SECURITY_WPA_TKIP "wpa_tkip" +#define SLSI_WIFI_SECURITY_WPA_AES "wpa_aes" +#define SLSI_WIFI_SECURITY_WPA2_MIXED "wpa2_mixed" +#define SLSI_WIFI_SECURITY_WPA2_TKIP "wpa2_tkip" +#define SLSI_WIFI_SECURITY_WPA2_AES "wpa2_aes" + + +#define MODE_STRING_MAX 100 +#define MAX_SSID_LEN (4*32+1) + +/*return a security config struct depending on the mode, and the input security string (see above + * defines. + */ +slsi_security_config_t *getSecurityConfig(char *sec_type, char *psk, WiFi_InterFace_ID_t mode); +/* prints a nicely ordered list of the scan results from the scan_info list + */ + +void printScanResult(slsi_scan_info_t *list); + +#ifdef __cplusplus +} +#endif +#endif /* __SLSI_WIFI_UTILS_H +*/