Add the initial version of Wi-Fi Manager
authorSeongil Hahm <seongil.hahm@samsung.com>
Sun, 3 Sep 2017 14:00:36 +0000 (07:00 -0700)
committerSeongil Hahm <seongil.hahm@samsung.com>
Tue, 5 Sep 2017 09:11:06 +0000 (02:11 -0700)
Wi-Fi Manager is introduced to provide easy APIs for applications to easily manipulate Wi-Fi features

18 files changed:
apps/system/utils/netcmd_dhcpd.c
external/dhcpd/dhcpd.c
external/include/protocols/dhcpd.h
framework/Makefile
framework/include/wifi_manager/wifi_manager.h [new file with mode: 0644]
framework/src/wifi_manager/Kconfig [new file with mode: 0644]
framework/src/wifi_manager/Make.defs [new file with mode: 0644]
framework/src/wifi_manager/wifi_common.h [new file with mode: 0644]
framework/src/wifi_manager/wifi_manager.c [new file with mode: 0644]
framework/src/wifi_manager/wifi_mutex.c [new file with mode: 0644]
framework/src/wifi_manager/wifi_mutex.h [new file with mode: 0644]
framework/src/wifi_manager/wifi_net.c [new file with mode: 0644]
framework/src/wifi_manager/wifi_net.h [new file with mode: 0644]
framework/src/wifi_manager/wifi_semaphore.c [new file with mode: 0644]
framework/src/wifi_manager/wifi_semaphore.h [new file with mode: 0644]
framework/src/wifi_manager/wifi_utils.c [new file with mode: 0644]
framework/src/wifi_manager/wifi_utils.h [new file with mode: 0644]
os/net/Kconfig

index 6cab704..44eb7f5 100644 (file)
@@ -148,7 +148,7 @@ int cmd_dhcpd(int argc, char *argv[])
                        }
                }
 
-               if (dhcpd_start(argv[2]) != 0) {
+               if (dhcpd_start(argv[2], NULL) != 0) {
                        printf("%s : failed to start dhcpd\n", __FUNCTION__);
                        goto done;
                }
index e6ee3c9..e7c462d 100644 (file)
 #include <tinyara/compiler.h>  /* For CONFIG_CPP_HAVE_WARNING */
 #include <arch/irq.h>                  /* For irqstore() and friends -- REVISIT */
 #include <tinyara/net/net.h>   /* For net_lock() and friends */
+#ifndef CONFIG_NET_LWIP
+#include <tinyara/net/arp.h>   /* For low-level ARP interfaces -- REVISIT */
+#endif
 #include <protocols/dhcpd.h>   /* Advertised DHCPD APIs */
-#endif /* CONFIG_NETUTILS_DHCPD_HOST */
+#undef nvdbg
+#undef ndbg
+#define ndbg(...) printf(__VA_ARGS__)
+#define nvdbg(...) printf(__VA_ARGS__)
+#endif                                                 /* CONFIG_NETUTILS_DHCPD_HOST */
 
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <semaphore.h>
 
 /****************************************************************************
  * Global Data
  ****************************************************************************/
+sem_t g_dhcpd_sem;
 
 /****************************************************************************
  * Private Data
@@ -300,15 +309,18 @@ static struct dhcpd_state_s g_state;
 
 static int g_dhcpd_running = 0;
 static int g_dhcpd_quit = 0;
+static int g_dhcpd_sockfd = -1;
 
 static pthread_t g_tid = 0;
 
-static char DHCPD_IFNAME[IFNAMSIZ] = {0,};
+static char DHCPD_IFNAME[IFNAMSIZ] = { 0, };
 
 #if DHCPD_SELECT
-static struct timeval g_select_timeout = {10, 0};
+static struct timeval g_select_timeout = { 1, 0 };
 #endif
 
+static dhcp_sta_joined g_dhcp_sta_joined;
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -333,7 +345,7 @@ static inline void dhcpd_arpupdate(uint16_t *pipaddr, uint8_t *phwaddr)
 }
 #else
 #define dhcpd_arpupdate(pipaddr, phwaddr)
-#endif /* CONFIG_NET_LWIP */
+#endif                                                 /* CONFIG_NET_LWIP */
 #else
 #define dhcpd_arpupdate(pipaddr, phwaddr)
 #endif
@@ -484,10 +496,10 @@ static in_addr_t dhcpd_allocipaddr(void)
                if ((lease == NULL || dhcpd_leaseexpired(lease))) {
                        ndbg("lease pass!!\n");
 #ifdef CONFIG_CPP_HAVE_WARNING
-/**
-#warning "FIXME: Should check if anything responds to an ARP request or ping"
-#warning "       to verify that there is no other user of this IP address"
-**/
+                       /**
+                       #warning "FIXME: Should check if anything responds to an ARP request or ping"
+                       #warning "       to verify that there is no other user of this IP address"
+                       **/
 #endif
 
                        ndbg("leases talbe = %d %d \n", ipaddr - CONFIG_NETUTILS_DHCPD_STARTIP, g_state.ds_leases[ipaddr - CONFIG_NETUTILS_DHCPD_STARTIP].allocated);
@@ -558,7 +570,7 @@ static inline bool dhcpd_parseoptions(void)
                 */
 
                switch (ptr[DHCPD_OPTION_CODE]) {
-               /* Skip over any padding bytes */
+                       /* Skip over any padding bytes */
 
                case DHCP_OPTION_PAD:
                        optlen = 1;
@@ -833,42 +845,6 @@ static inline int dhcpd_socket(void)
 }
 
 /****************************************************************************
- * Name: dhcpd_openresponder
- ****************************************************************************/
-
-static inline int dhcpd_openresponder(void)
-{
-       struct sockaddr_in addr;
-       int sockfd;
-       int ret;
-
-       nvdbg("Responder: %08lx\n", ntohl(g_state.ds_serverip));
-
-       /* Create a socket to listen for requests from DHCP clients */
-
-       sockfd = dhcpd_socket();
-       if (sockfd < 0) {
-               ndbg("socket failed: %d\n", errno);
-               return ERROR;
-       }
-
-       /* Bind the socket to a local port. */
-
-       addr.sin_family = AF_INET;
-       addr.sin_port = HTONS(DHCP_SERVER_PORT);
-       addr.sin_addr.s_addr = g_state.ds_serverip;
-
-       ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
-       if (ret < 0) {
-               ndbg("bind failed, port=%d addr=%08lx: %d\n", addr.sin_port, (long)addr.sin_addr.s_addr, errno);
-               close(sockfd);
-               return ERROR;
-       }
-
-       return sockfd;
-}
-
-/****************************************************************************
  * Name: dhcpd_initpacket
  ****************************************************************************/
 
@@ -911,7 +887,6 @@ static int dhcpd_sendpacket(int bbroadcast)
 {
        struct sockaddr_in addr;
        in_addr_t ipaddr;
-       int sockfd;
        int len;
        int ret = ERROR;
 
@@ -955,25 +930,22 @@ static int dhcpd_sendpacket(int bbroadcast)
        /* Create a socket to respond with a packet to the client.  We
         * cannot re-use the listener socket because it is not bound correctly
         */
+       if (g_dhcpd_sockfd == -1) {
+               ndbg("socket is not valid\n");
+       }
 
-       sockfd = dhcpd_openresponder();
-       if (sockfd >= 0) {
-               /* Then send the reponse to the DHCP client port at that address */
+       /* Then send the reponse to the DHCP client port at that address */
 
-               memset(&addr, 0, sizeof(struct sockaddr_in));
-               addr.sin_family = AF_INET;
-               addr.sin_port = HTONS(DHCP_CLIENT_PORT);
-               addr.sin_addr.s_addr = ipaddr;
+       memset(&addr, 0, sizeof(struct sockaddr_in));
+       addr.sin_family = AF_INET;
+       addr.sin_port = HTONS(DHCP_CLIENT_PORT);
+       addr.sin_addr.s_addr = ipaddr;
 
-               /* Send the minimum sized packet that includes the END option */
+       /* Send the minimum sized packet that includes the END option */
 
-               len = (g_state.ds_optend - (uint8_t *)&g_state.ds_outpacket) + 1;
-               nvdbg("sendto %08lx:%04x len=%d\n", (long)ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), len);
-               ret = sendto(sockfd, &g_state.ds_outpacket, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
-               close(sockfd);
-       } else {
-               ndbg("create socket failed : %d\n", sockfd);
-       }
+       len = (g_state.ds_optend - (uint8_t *)&g_state.ds_outpacket) + 1;
+       nvdbg("sendto %08lx:%04x len=%d\n", (long)ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), len);
+       ret = sendto(g_dhcpd_sockfd, &g_state.ds_outpacket, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
 
        return ret;
 }
@@ -986,7 +958,6 @@ static int dhcpd_send_offerpacket(void)
 {
        struct sockaddr_in addr;
        in_addr_t ipaddr;
-       int sockfd;
        int len;
        int ret = ERROR;
 
@@ -1001,29 +972,25 @@ static int dhcpd_send_offerpacket(void)
        ipaddr = htonl(IPADDR_BROADCAST);
 #endif
 
-       sockfd = dhcpd_openresponder();
-       if (sockfd >= 0) {
-               /* Then send the reponse to the DHCP client port at that address */
+       if (g_dhcpd_sockfd == -1) {
+               ndbg("dhcpd socket is not valid\n");
+       }
+       /* Then send the reponse to the DHCP client port at that address */
 
-               memset(&addr, 0, sizeof(struct sockaddr_in));
-               addr.sin_family = AF_INET;
-               addr.sin_port = HTONS(DHCP_CLIENT_PORT);
-               addr.sin_addr.s_addr = ipaddr;
+       memset(&addr, 0, sizeof(struct sockaddr_in));
+       addr.sin_family = AF_INET;
+       addr.sin_port = HTONS(DHCP_CLIENT_PORT);
+       addr.sin_addr.s_addr = ipaddr;
 
-               /* Send the minimum sized packet that includes the END option */
+       /* Send the minimum sized packet that includes the END option */
 
-               len = (g_state.ds_optend - (uint8_t *)&g_state.ds_outpacket) + 1;
-               nvdbg("dhcp offer sendto %08lx:%04x len=%d\n", (long)ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), len);
-               ret = sendto(sockfd, &g_state.ds_outpacket, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
-               close(sockfd);
-       } else {
-               ndbg("create socket failed : %d\n", sockfd);
-       }
+       len = (g_state.ds_optend - (uint8_t *)&g_state.ds_outpacket) + 1;
+       nvdbg("dhcp offer sendto %08lx:%04x len=%d\n", (long)ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), len);
+       ret = sendto(g_dhcpd_sockfd, &g_state.ds_outpacket, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
 
        return ret;
 }
 
-
 /****************************************************************************
  * Name: dhcpd_sendoffer
  ****************************************************************************/
@@ -1123,6 +1090,10 @@ int dhcpd_sendack(in_addr_t ipaddr)
        }
 
        dhcpd_setlease(g_state.ds_inpacket.chaddr, ipaddr, leasetime);
+       /* TODO: new callback way up to application to inform a new STA has called
+        * dhcp client
+        */
+       g_dhcp_sta_joined();
        return OK;
 }
 
@@ -1414,7 +1385,6 @@ static inline int dhcpd_openlistener(void)
        return sockfd;
 }
 
-
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -1446,29 +1416,16 @@ static int dhcpd_netif_init(char *intf)
 
        ndbg("\n");
 
-       ndbg("Server IP address set : %u.%u.%u.%u\n",
-               (unsigned char)((htonl(server_ipaddr.s_addr) >> 24) & 0xff),
-               (unsigned char)((htonl(server_ipaddr.s_addr) >> 16) & 0xff),
-               (unsigned char)((htonl(server_ipaddr.s_addr) >> 8) & 0xff),
-               (unsigned char)((htonl(server_ipaddr.s_addr) >> 0) & 0xff));
+       ndbg("Server IP address set : %u.%u.%u.%u\n", (unsigned char)((htonl(server_ipaddr.s_addr) >> 24) & 0xff), (unsigned char)((htonl(server_ipaddr.s_addr) >> 16) & 0xff), (unsigned char)((htonl(server_ipaddr.s_addr) >> 8) & 0xff), (unsigned char)((htonl(server_ipaddr.s_addr) >> 0) & 0xff));
 
-       ndbg("Server netmask address set : %u.%u.%u.%u\n",
-               (unsigned char)((htonl(netmask_ipaddr.s_addr) >> 24) & 0xff),
-               (unsigned char)((htonl(netmask_ipaddr.s_addr) >> 16) & 0xff),
-               (unsigned char)((htonl(netmask_ipaddr.s_addr) >> 8) & 0xff),
-               (unsigned char)((htonl(netmask_ipaddr.s_addr) >> 0) & 0xff));
+       ndbg("Server netmask address set : %u.%u.%u.%u\n", (unsigned char)((htonl(netmask_ipaddr.s_addr) >> 24) & 0xff), (unsigned char)((htonl(netmask_ipaddr.s_addr) >> 16) & 0xff), (unsigned char)((htonl(netmask_ipaddr.s_addr) >> 8) & 0xff), (unsigned char)((htonl(netmask_ipaddr.s_addr) >> 0) & 0xff));
 
-       ndbg("Server default gateway address set : %u.%u.%u.%u\n",
-               (unsigned char)((htonl(server_ipaddr.s_addr) >> 24) & 0xff),
-               (unsigned char)((htonl(server_ipaddr.s_addr) >> 16) & 0xff),
-               (unsigned char)((htonl(server_ipaddr.s_addr) >> 8) & 0xff),
-               (unsigned char)((htonl(server_ipaddr.s_addr) >> 0) & 0xff));
+       ndbg("Server default gateway address set : %u.%u.%u.%u\n", (unsigned char)((htonl(server_ipaddr.s_addr) >> 24) & 0xff), (unsigned char)((htonl(server_ipaddr.s_addr) >> 16) & 0xff), (unsigned char)((htonl(server_ipaddr.s_addr) >> 8) & 0xff), (unsigned char)((htonl(server_ipaddr.s_addr) >> 0) & 0xff));
 
        ndbg("\n");
        return 0;
 }
 
-
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -1501,7 +1458,6 @@ static int dhcpd_netif_deinit(char *intf)
        return 0;
 }
 
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -1521,13 +1477,33 @@ int dhcpd_status(void)
  ****************************************************************************/
 void dhcpd_stop(void)
 {
+       int ret = -1;
+       if (g_dhcpd_running == 0) {
+               return;
+       }
+
        g_dhcpd_quit = 1;
+       while (ret != OK) {
+               ret = sem_wait(&g_dhcpd_sem);
+               if (ret != OK) {
+                       ndbg("ERR: sem_wait for dhcpd failed\n");
+                       if (errno == EINTR) {
+                               ndbg("ERR: EINTR for sem_wait in dhcpd\n");
+                               continue;
+                       }
+                       return;
+               }
+       }
+       ret = sem_destroy(&g_dhcpd_sem);
+       if (ret != OK) {
+               ndbg("ERR: sem_destroy for dhcpd failed\n");
+               return;
+       }
 #if DHCPD_SELECT
        ndbg("WARN : dhcpd will be stopped after %d seconds\n", g_select_timeout.tv_sec);
 #endif
 }
 
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -1537,7 +1513,6 @@ void dhcpd_stop(void)
 
 int dhcpd_run(void *arg)
 {
-       int sockfd;
        int nbytes;
 #if DHCPD_SELECT
        int ret = OK;
@@ -1546,7 +1521,6 @@ int dhcpd_run(void *arg)
        ndbg("Started on %s\n", DHCPD_IFNAME);
 
        /* Initialize everything to zero */
-
        memset(&g_state, 0, sizeof(struct dhcpd_state_s));
 
        /* Initialize netif address (ip address, netmask, default gateway) */
@@ -1559,55 +1533,52 @@ int dhcpd_run(void *arg)
 
        /* Now loop indefinitely, reading packets from the DHCP server socket */
 
-       sockfd = -1;
+       g_dhcpd_sockfd = -1;
 
        g_dhcpd_quit = 0;
        g_dhcpd_running = 1;
 
-       while (!g_dhcpd_quit) {
-               /* Create a socket to listen for requests from DHCP clients */
-
-               /* TODO : Need to add cancellation point */
+       /* Create a socket to listen for requests from DHCP clients */
+       /* TODO : Need to add cancellation point */
+       g_dhcpd_sockfd = dhcpd_openlistener();
+       if (g_dhcpd_sockfd < 0) {
+               ndbg("Failed to create socket\n");
+               ret = ERROR;
+               goto exit_with_error;
+       }
 
-               if (sockfd < 0) {
-                       sockfd = dhcpd_openlistener();
-                       if (sockfd < 0) {
-                               ndbg("Failed to create socket\n");
-                               ret = ERROR;
-                               break;
-                       }
-               }
+       while (!g_dhcpd_quit) {
 #if DHCPD_SELECT
                nbytes = -1;
                FD_ZERO(&sockfd_set);
-               FD_SET(sockfd, &sockfd_set);
+               FD_SET(g_dhcpd_sockfd, &sockfd_set);
 
-               ret = select(sockfd+1, &sockfd_set, NULL, NULL, &g_select_timeout);
-               if ((ret > 0) && FD_ISSET(sockfd, &sockfd_set)) {
+               ret = select(g_dhcpd_sockfd + 1, &sockfd_set, NULL, NULL, &g_select_timeout);
+               if ((ret > 0) && FD_ISSET(g_dhcpd_sockfd, &sockfd_set)) {
                        /* Read the next g_state.ds_outpacket */
-                       nbytes = recv(sockfd, &g_state.ds_inpacket, sizeof(struct dhcpmsg_s), 0);
+                       nbytes = recv(g_dhcpd_sockfd, &g_state.ds_inpacket, sizeof(struct dhcpmsg_s), 0);
                } else if (ret == 0) {
-                       if (!g_dhcpd_quit)
+                       if (!g_dhcpd_quit) {
                                continue;
-                       else {
+                       else {
                                ndbg("select timeout exit\n");
                                break;
                        }
                } else {
-                       /* Debugging purpose : Error case*/
+                       /* Debugging purpose : Error case */
                        ndbg("ERROR, select ret %d [errno %d]\n", ret, errno);
                        break;
                }
 #else
-               nbytes = recv(sockfd, &g_state.ds_inpacket, sizeof(struct dhcpmsg_s), 0);
+               nbytes = recv(g_dhcpd_sockfd, &g_state.ds_inpacket, sizeof(struct dhcpmsg_s), 0);
 #endif
                if (nbytes < 0) {
                        /* On errors (other EINTR), close the socket and try again */
 
                        ndbg("recv failed: %d\n", errno);
                        if (errno != EINTR) {
-                               close(sockfd);
-                               sockfd = -1;
+                               close(g_dhcpd_sockfd);
+                               g_dhcpd_sockfd = -1;
                        }
                        continue;
                }
@@ -1632,9 +1603,7 @@ int dhcpd_run(void *arg)
                switch (g_state.ds_optmsgtype) {
                case DHCPDISCOVER:
                        ndbg("DHCPDISCOVER\n");
-                       if (dhcpd_discover() == ERROR) {
-                               ndbg("DHCPDISCOVER : Failed to send DHCP Discover, errno %d\n", errno);
-                       }
+                       dhcpd_discover();
                        break;
 
                case DHCPREQUEST:
@@ -1659,9 +1628,12 @@ int dhcpd_run(void *arg)
                }
        }
 
-       if (sockfd != -1) {
-               close(sockfd);
+       if (g_dhcpd_sockfd != -1) {
+               close(g_dhcpd_sockfd);
        }
+       sem_post(&g_dhcpd_sem);
+
+exit_with_error:
        g_dhcpd_running = 0;
 
        /* de-initialize netif address (ip address, netmask, default gateway) */
@@ -1673,7 +1645,6 @@ int dhcpd_run(void *arg)
        return ret;
 }
 
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -1685,12 +1656,17 @@ int dhcpd_run(void *arg)
 #define DHCPD_SCHED_PRI                        100
 #define DHCPD_SCHED_POLICY             SCHED_RR
 
-int dhcpd_start(char *intf)
+int dhcpd_start(char *intf, dhcp_sta_joined dhcp_join_cb)
 {
        pthread_attr_t attr;
        int status;
+       int ret;
        struct sched_param sparam;
-
+       ret = sem_init(&g_dhcpd_sem, 0, 0);
+       if (ret != OK) {
+               ndbg("failed to initialize semaphore\n");
+               goto err_exit;
+       }
        /* Set network interface name for DHCPD */
        if (intf) {
                strncpy(DHCPD_IFNAME, intf, strlen(intf));
@@ -1707,25 +1683,26 @@ int dhcpd_start(char *intf)
        sparam.sched_priority = DHCPD_SCHED_PRI;
        status = pthread_attr_setschedparam(&attr, &sparam);
        if (status != 0) {
-               ndbg("failed to pthread_attr_setschedparam, ret %d, errno %d\n",
-                                               status, errno);
+               ndbg("failed to pthread_attr_setschedparam, ret %d, errno %d\n", status, errno);
                goto err_exit;
        }
 
        status = pthread_attr_setschedpolicy(&attr, DHCPD_SCHED_POLICY);
        if (status != 0) {
-               ndbg("failed to pthread_attr_setchedpolicy, ret %d, errno %d\n",
-                                               status, errno);
+               ndbg("failed to pthread_attr_setchedpolicy, ret %d, errno %d\n", status, errno);
                goto err_exit;
        }
 
        status = pthread_attr_setstacksize(&attr, DHCPD_STACK_SIZE);
        if (status != 0) {
-               ndbg("failed to pthread_attr_setstacksize, ret %d, errno %d\n",
-                                               status, errno);
+               ndbg("failed to pthread_attr_setstacksize, ret %d, errno %d\n", status, errno);
                goto err_exit;
        }
 
+       if (dhcp_join_cb) {
+               g_dhcp_sta_joined = dhcp_join_cb;
+       }
+
        status = pthread_create(&g_tid, &attr, (pthread_startroutine_t)dhcpd_run, NULL);
        if (status != 0) {
                ndbg("failed to start dhcpd\n");
index fb2531f..2a1f5bf 100644 (file)
@@ -88,6 +88,8 @@ extern "C" {
 #define EXTERN extern
 #endif
 
+typedef void (*dhcp_sta_joined)(void);
+
 /**
  * @brief Starts DHCP server which is attached given network interface.
  *
@@ -102,7 +104,7 @@ int dhcpd_run(void *arg);
  * @param[in] intf the name of network interface to run DHCP server
  * @return On success, 0. On failure, returns -1
 */
-int dhcpd_start(char *intf);
+int dhcpd_start(char *intf, dhcp_sta_joined dhcp_join_cb);
 
 #undef EXTERN
 #ifdef __cplusplus
index 47f11cc..f56df3b 100644 (file)
@@ -42,6 +42,10 @@ ifeq ($(CONFIG_NETUTILS_MQTT), y)
 include src$(DELIM)mqtt$(DELIM)Make.defs
 endif
 
+ifeq ($(CONFIG_WIFI_MANAGER), y)
+include src$(DELIM)wifi_manager$(DELIM)Make.defs
+endif
+
 AOBJS = $(ASRCS:.S=$(OBJEXT))
 COBJS = $(CSRCS:.c=$(OBJEXT))
 
diff --git a/framework/include/wifi_manager/wifi_manager.h b/framework/include/wifi_manager/wifi_manager.h
new file mode 100644 (file)
index 0000000..9f3a8ef
--- /dev/null
@@ -0,0 +1,167 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+/**
+ * @defgroup Wi-Fi_Manager Wi-Fi_Manager
+ * @ingroup Wi-Fi_Manager
+ * @brief Provides APIs for Wi-Fi Manager
+ * @{
+ */
+
+#ifndef WIFI_MANAGER_H
+#define WIFI_MANAGER_H
+
+typedef enum {
+       // STA mode status
+       AP_DISCONNECTED,
+       AP_CONNECTED,
+
+       // SOFT AP mode status
+       CLIENT_CONNECTED,
+       CLIENT_DISCONNECTED
+} connect_status_e;
+
+/**
+ * @brief <b> wifi result type FAIL, SUCCESS, INVALID ARGS</b>
+ */
+typedef enum {
+       WIFI_MANAGER_FAIL = -1,
+       WIFI_MANAGER_SUCCESS,
+       WIFI_MANAGER_INVALID_ARGS,
+       WIFI_MANAGER_TIMEOUT,
+       WIFI_MANAGER_BUSY,
+} wifi_manager_result_e;
+
+typedef enum {
+       STA_MODE,
+       SOFT_AP_MODE
+} wifi_manager_mode_e;
+
+typedef struct {
+       void (*sta_connected)(void);
+       void (*sta_disconnected)(void);
+       void (*softap_sta_join)(void);
+       void (*softap_sta_leave)(void);
+} wifi_manager_cb_s;
+
+typedef struct {
+       char ip4_address[18];
+       char ssid[32];
+       int rssi;
+       connect_status_e status;
+       wifi_manager_mode_e mode;
+       wifi_manager_cb_s *wmcb;
+} wifi_manager_info_s;
+
+typedef struct {
+       char ssid[32];
+       uint16_t channel;
+       char passphrase[32];
+} wifi_manager_softap_config_s;
+
+/**
+ * @brief <b> wifi authentication type WPA, WPA2, WPS</b>
+ */
+typedef enum {
+       WIFI_MANAGER_AUTH_OPEN,                                    /**<  open mode                      */
+       WIFI_MANAGER_AUTH_WEP_SHARED,                      /**<  use shared key (wep key)       */
+       WIFI_MANAGER_AUTH_WPA_PSK,                                 /**<  WPA_PSK mode                   */
+       WIFI_MANAGER_AUTH_WPA2_PSK,                                /**<  WPA2_PSK mode                  */
+       WIFI_MANAGER_AUTH_WPA_AND_WPA2_PSK,                /**<  WPA_PSK and WPA_PSK mixed mode */
+       WIFI_MANAGER_AUTH_UNKNOWN,                                 /**<  unknown type                   */
+} wifi_manager_ap_auth_type_e;
+
+/**
+ * @brief wifi encryption type WEP, AES, TKIP
+ */
+typedef enum {
+       WIFI_MANAGER_CRYPTO_NONE,                                  /**<  none encryption                */
+       WIFI_MANAGER_CRYPTO_WEP_64,                                /**<  WEP encryption wep-40          */
+       WIFI_MANAGER_CRYPTO_WEP_128,                       /**<  WEP encryption wep-104         */
+       WIFI_MANAGER_CRYPTO_AES,                                   /**<  AES encryption                 */
+       WIFI_MANAGER_CRYPTO_TKIP,                                  /**<  TKIP encryption                */
+       WIFI_MANAGER_CRYPTO_TKIP_AND_AES,                  /**<  TKIP and AES mixed encryption  */
+       WIFI_MANAGER_CRYPTO_UNKNOWN,                       /**<  unknown encryption             */
+} wifi_manager_ap_crypto_type_e;
+
+/**
+ * @brief wifi ap connect config
+ */
+typedef struct {
+       char ssid[32];                                                   /**<  Service Set Identification         */
+       unsigned int ssid_length;                                /**<  Service Set Identification Length  */
+       char passphrase[64];                                     /**<  ap passphrase(password)            */
+       unsigned int passphrase_length;                  /**<  ap passphrase length               */
+       wifi_manager_ap_auth_type_e ap_auth_type;         /**<  @ref wifi_utils_ap_auth_type   */
+       wifi_manager_ap_crypto_type_e ap_crypto_type;  /**<  @ref wifi_utils_ap_crypto_type */
+} wifi_manager_ap_config_s;
+
+/**
+ * @brief Initialize Wi-Fi Manager including starting Wi-Fi interface.
+ * @param[in] callback functions called when wi-fi events happen
+ * @return On success, WIFI_MANAGER_SUCCESS (i.e., 0) is returned. On failure, non-zero value is returned.
+ * @since Tizen RT v1.1
+ */
+wifi_manager_result_e wifi_manager_init(wifi_manager_cb_s *wmcb);
+
+/**
+ * @brief Deinitialize Wi-Fi Manager including stoping Wi-Fi interface.
+ * @param[in] none
+ * @return On success, WIFI_MANAGER_SUCCESS (i.e., 0) is returned. On failure, non-zero value is returned.
+ * @since Tizen RT v1.1
+ */
+wifi_manager_result_e wifi_manager_deinit(void);
+
+/**
+ * @brief Change the Wi-Fi mode to station or AP.
+ * @param[in] Wi-Fi mode (station or AP)
+ * @param[in] In case of AP mode, AP configuration infomation should be given including ssid, channel, and passphrase.
+ * @return On success, WIFI_MANAGER_SUCCESS (i.e., 0) is returned. On failure, non-zero value is returned.
+ * @since Tizen RT v1.1
+ */
+wifi_manager_result_e wifi_manager_set_mode(wifi_manager_mode_e mode, wifi_manager_softap_config_s *config);
+
+/**
+ * @brief Retrieve current status of Wi-Fi interface including mode, connection status, ssid, received signal strengh indication, and ip address.
+ * @param[out] retrieved information including  mode, connection s    tatus, ssid, received signal strengh indication, and ip address.
+ * @return On success, WIFI_MANAGER_SUCCESS (i.e., 0) is returned. On failure, non-zero value is returned.
+ * @since Tizen RT v1.1
+ */
+wifi_manager_result_e wifi_manager_get_info(wifi_manager_info_s *info);
+
+/**
+ * @brief Connect to an access point.
+ * @param[in] ssid, passphrase, authentication type, and cryto type of the access point which the wi-fi interface connect to.
+ * @return On success, WIFI_MANAGER_SUCCESS (i.e., 0) is returned. On failure, non-zero value is returned.
+ * @since Tizen RT v1.1
+ */
+wifi_manager_result_e wifi_manager_connect_ap(wifi_manager_ap_config_s *config);
+
+/**
+ * @brief Disconnect from the connected access point
+ * @param[in] none
+ * @return On success, WIFI_MANAGER_SUCCESS (i.e., 0) is returned. On failure, non-zero value is returned.
+ * @since Tizen RT v1.1
+ */
+wifi_manager_result_e wifi_manager_disconnect_ap(void);
+
+#endif
+
+/**
+ *@}
+ */
diff --git a/framework/src/wifi_manager/Kconfig b/framework/src/wifi_manager/Kconfig
new file mode 100644 (file)
index 0000000..aec8102
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# For a description of the syntax of this configuration file,
+# see kconfig-language at https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
+#
+
+config WIFI_MANAGER
+    bool "Enable Wi-Fi Manager"
+    default n
+    ---help---
+        Easy APIs for applications to use and control Wi-Fi features
+
+if WIFI_MANAGER
+source "$EXTERNALDIR/slsi_wifi/Kconfig"
+endif #WIFI_MANAGER
diff --git a/framework/src/wifi_manager/Make.defs b/framework/src/wifi_manager/Make.defs
new file mode 100644 (file)
index 0000000..417972f
--- /dev/null
@@ -0,0 +1,23 @@
+###########################################################################
+#
+# Copyright 2017 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.
+#
+###########################################################################
+
+CSRCS += wifi_manager.c wifi_utils.c wifi_net.c wifi_mutex.c wifi_semaphore.c
+
+DEPPATH += --dep-path src/wifi_manager
+VPATH += :src/wifi_manager
+
diff --git a/framework/src/wifi_manager/wifi_common.h b/framework/src/wifi_manager/wifi_common.h
new file mode 100644 (file)
index 0000000..c9395f1
--- /dev/null
@@ -0,0 +1,44 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef WIFI_COMMON_H
+#define WIFI_COMMON_H
+
+
+/**
+ * @brief time out option (used by message queue, uart, semaphore, mutex)
+ *
+ */
+typedef enum {
+       WIFI_UTILS_NO_WAIT = 0,   /**<  no wait contant          */
+       WIFI_UTILS_FOREVER = -1,  /**<  wait until job finished  */
+} wifi_utils_timeout_option;
+
+/**
+ * @brief <b> wifi result type FAIL, SUCCESS, INVALID ARGS</b>
+ */ 
+typedef enum {
+       WIFI_UTILS_FAIL = -1,
+       WIFI_UTILS_SUCCESS,
+       WIFI_UTILS_INVALID_ARGS,
+       WIFI_UTILS_TIMEOUT,
+       WIFI_UTILS_BUSY,
+} wifi_utils_result_e;
+
+
+#endif //WIFI_COMMON_H
diff --git a/framework/src/wifi_manager/wifi_manager.c b/framework/src/wifi_manager/wifi_manager.c
new file mode 100644 (file)
index 0000000..82b29c9
--- /dev/null
@@ -0,0 +1,422 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#include <tinyara/config.h>
+#include <debug.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <wifi_manager/wifi_manager.h>
+#include <protocols/dhcpc.h>
+#include <protocols/dhcpd.h>
+#include <slsi_wifi/slsi_wifi_api.h>
+#include <semaphore.h>
+#include "wifi_utils.h"
+#include "wifi_mutex.h"
+#include "wifi_net.h"
+
+static void *g_dhcp_handle = NULL;
+static dhcp_sta_joined g_new_sta_join = NULL;
+#ifdef CONFIG_ENABLE_IOTIVITY
+mqd_t g_dw_nwevent_mqfd;
+#endif
+
+/*
+ * Iotivity stack receives network events from wifi manager module
+ * this will be changed later
+ */
+#ifdef CONFIG_ENABLE_IOTIVITY
+void __tizenrt_manual_linkset(const char *msg)
+{
+       int ret = mq_send(g_dw_nwevent_mqfd, msg, 3, 42);
+       if (ret < 0) {
+               ndbg("send message fail\n");
+               return;
+       }
+}
+#endif
+
+static wifi_manager_info_s g_manager_info;
+
+static wifi_mutex w_mutex;
+
+static wifi_utils_result_e start_dhcp_client(void)
+{
+       struct dhcpc_state state;
+       int ret;
+
+       g_dhcp_handle = dhcpc_open(CTRL_IFNAME);
+       if (g_dhcp_handle == NULL) {
+               ndbg("Invalid dhcp handle\n");
+               return WIFI_UTILS_FAIL;
+       }
+       ret = dhcpc_request(g_dhcp_handle, &state);
+       if (ret != OK) {
+               dhcpc_close(g_dhcp_handle);
+               return WIFI_UTILS_FAIL;
+       }
+
+       netlib_set_ipv4addr(CTRL_IFNAME, &state.ipaddr);
+       netlib_set_ipv4netmask(CTRL_IFNAME, &state.netmask);
+       netlib_set_dripv4addr(CTRL_IFNAME, &state.default_router);
+
+       nvdbg("IP address : %s ----\n", inet_ntoa(state.ipaddr));
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+static wifi_utils_result_e stop_dhcp_client(void)
+{
+       if (g_dhcp_handle == NULL) {
+               return WIFI_UTILS_FAIL;
+       } else {
+               dhcpc_close(g_dhcp_handle);
+               g_dhcp_handle = NULL;
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+static wifi_utils_result_e start_dhcp_server(void)
+{
+       struct in_addr in = {.s_addr = 0x012fa8c0 };
+       netlib_set_ipv4addr(CTRL_IFNAME, &in);
+       in.s_addr = 0x00ffffff;
+       netlib_set_ipv4netmask(CTRL_IFNAME, &in);
+       in.s_addr = 0x012fa8c0;
+       netlib_set_dripv4addr(CTRL_IFNAME, &in);
+
+       if (dhcpd_start(CTRL_IFNAME, g_new_sta_join) < 0) {
+               ndbg("DHCP Server - started fail\n");
+               return WIFI_UTILS_FAIL;
+       }
+
+       nvdbg("DHCP Server - started success\n");
+       return WIFI_UTILS_SUCCESS;
+}
+
+static wifi_utils_result_e stop_dhcp_server(void)
+{
+       struct in_addr in = { .s_addr = INADDR_NONE };
+       netlib_set_ipv4addr(CTRL_IFNAME, &in);
+       netlib_set_ipv4netmask(CTRL_IFNAME, &in);
+       netlib_set_dripv4addr(CTRL_IFNAME, &in);
+
+       dhcpd_stop();
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+static void wifi_status_set(connect_status_e status)
+{
+#ifdef CONFIG_DEBUG_NET_INFO
+       static char connect_status_str[5][25] = {
+               // STA mode
+               "AP_DISCONNECTED",
+               "AP_CONNECTED",
+
+               // SOFTAP mode
+               "CLIENT_CONNECTED",
+               "CLIENT_DISCONNECTED"
+       };
+#endif
+
+       if (g_manager_info.status != status) {
+               nvdbg("Wifi Network Status Changes from [%s] to [%s]", connect_status_str[g_manager_info.status], connect_status_str[status]);
+               g_manager_info.status = status;
+       }
+}
+
+static void ap_connect_event_func(void)
+{
+       wifi_manager_cb_s *wifi_cb = g_manager_info.wmcb;
+       if (g_manager_info.mode == STA_MODE) {
+               nvdbg("WIFI CONNECTED AP - STA MODE");
+               wifi_status_set(AP_CONNECTED);
+
+               /* Perform DHCP client */
+               if (start_dhcp_client() != WIFI_UTILS_SUCCESS) {
+                       ndbg("DHCP client start failed\n");
+                       return;
+               }
+               if (stop_dhcp_client() != WIFI_UTILS_SUCCESS) {
+                       ndbg("DHCP client stop failed\n");
+               }
+
+               if (wifi_cb != NULL && wifi_cb->sta_connected) {
+                       wifi_cb->sta_connected();
+               } else {
+                       ndbg("Callback wifimanager ap_connect failed\n");
+               }
+       } else if (g_manager_info.mode == SOFT_AP_MODE) {
+               nvdbg("CONNECTED FROM CLIENT - SOFT AP MODE");
+               wifi_status_set(CLIENT_CONNECTED);
+
+               /* No callbacks here, in case new client joins, we invoke callback
+                * from DHCP server instead
+                */
+       }
+#ifdef CONFIG_ENABLE_IOTIVITY
+       __tizenrt_manual_linkset("gen");
+#endif
+       /* TODO: Import files from source
+        * sendStatusTrigger (TRIGGER_NETWORK_CHANGED, DAWIT_NW_CHANGED_UP);
+        */
+}
+
+static void ap_disconnect_event_func(void)
+{
+       wifi_manager_cb_s *wifi_cb = g_manager_info.wmcb;
+       if (g_manager_info.mode == STA_MODE) {
+               nvdbg("WIFI DISCONNECTED AP - STA MODE");
+               strncpy(g_manager_info.ssid, "", 32);
+               strcpy(g_manager_info.ip4_address, "");
+               g_manager_info.rssi = 0;
+               wifi_status_set(AP_DISCONNECTED);
+
+               if (wifi_cb != NULL && wifi_cb->sta_disconnected) {
+                       wifi_cb->sta_disconnected();
+               } else {
+                       ndbg("Callback wifimanager ap_disconnected failed\n");
+               }
+       } else if (g_manager_info.mode == SOFT_AP_MODE) {
+               nvdbg("DISCONNECTED FROM CLIENT - SOFT AP MODE");
+               wifi_status_set(CLIENT_DISCONNECTED);
+               if (wifi_cb != NULL && wifi_cb->softap_sta_leave) {
+                       wifi_cb->softap_sta_leave();
+               } else {
+                       ndbg("Callback wifimanager ap_disconnected failed\n");
+               }
+       }
+#ifdef CONFIG_ENABLE_IOTIVITY
+       __tizenrt_manual_linkset("del");
+#endif
+
+       /* TODO: Import files from source
+        * sendStatusTrigger(TRIGGER_NETWORK_CHANGED, DAWIT_NW_CHANGED_DOWN);
+        */
+}
+
+/**
+ * Public API
+ */
+
+wifi_manager_result_e wifi_manager_connect_ap(wifi_manager_ap_config_s *config)
+{
+       if (config == NULL) {
+               return WIFI_MANAGER_INVALID_ARGS;
+       }
+
+       wifi_utils_info info;
+       wifi_utils_ap_config_s util_config;
+
+       wifi_utils_get_info(&info);
+
+       if (info.wifi_status == WIFI_UTILS_SOFT_AP_MODE) {
+               ndbg("Current mode soft ap mode, can not connect ap");
+               return WIFI_MANAGER_FAIL;
+       }
+
+       wifi_mutex_acquire(&w_mutex, WIFI_UTILS_FOREVER);
+
+       strncpy(util_config.ssid, config->ssid, config->ssid_length);
+       util_config.ssid_length = config->ssid_length;
+       strncpy(util_config.passphrase, config->passphrase, config->passphrase_length);
+       util_config.passphrase_length = config->passphrase_length;
+       util_config.ap_auth_type = config->ap_auth_type;
+       util_config.ap_crypto_type = config->ap_crypto_type;
+
+       wifi_utils_result_e result = wifi_utils_connect_ap(&util_config);
+       if (result != WIFI_UTILS_SUCCESS) {
+               ndbg("Wifi AP connect fail");
+               wifi_mutex_release(&w_mutex);
+               return WIFI_MANAGER_FAIL;
+       }
+
+       /* g_manager_info.wmcb->sta_connected(); */
+       wifi_utils_get_info(&info);
+
+       char ip4_add_str[18] = { 0, };
+       wifi_net_ip4_addr_to_ip4_str(info.ip4_address, ip4_add_str);
+       strncpy(g_manager_info.ssid, config->ssid, 32);
+       strcpy(g_manager_info.ip4_address, ip4_add_str);
+       g_manager_info.rssi = info.rssi;
+
+       wifi_mutex_release(&w_mutex);
+
+       return WIFI_MANAGER_SUCCESS;
+}
+
+wifi_manager_result_e wifi_manager_disconnect_ap(void)
+{
+       wifi_utils_result_e result = WIFI_UTILS_SUCCESS;
+
+       wifi_mutex_acquire(&w_mutex, WIFI_UTILS_FOREVER);
+       result = wifi_utils_disconnect_ap();
+       wifi_mutex_release(&w_mutex);
+
+       return result;
+}
+
+wifi_manager_result_e wifi_manager_init(wifi_manager_cb_s *wmcb)
+{
+       wifi_utils_result_e result = WIFI_UTILS_SUCCESS;
+
+       result = wifi_mutex_create(&w_mutex);
+       if (result != WIFI_UTILS_SUCCESS) {
+               ndbg("wifi_mutex_create fail");
+               return WIFI_MANAGER_FAIL;
+       }
+
+       result = wifi_utils_init();
+
+       if (result != WIFI_UTILS_SUCCESS) {
+               ndbg("wifi_utils_init fail");
+               return WIFI_MANAGER_FAIL;
+       }
+
+       wifi_utils_register_connection_callback(ap_connect_event_func, ap_disconnect_event_func);
+       strncpy(g_manager_info.ip4_address, "", 18);
+       strcpy(g_manager_info.ssid, "");
+       g_manager_info.rssi = 0;
+       g_manager_info.mode = STA_MODE;
+       g_manager_info.mode = AP_DISCONNECTED;
+       g_manager_info.wmcb = wmcb;
+
+#ifdef CONFIG_ENABLE_IOTIVITY
+       struct mq_attr lq_attr;
+       lq_attr.mq_maxmsg = 10;
+       lq_attr.mq_msgsize = 4;
+       lq_attr.mq_flags = 0;
+       g_dw_nwevent_mqfd = mq_open("netlink_evtq", O_WRONLY | O_CREAT, 0666, &lq_attr);
+
+       if (g_dw_nwevent_mqfd == (mqd_t)ERROR) {
+               ndbg("iotivity connect event message queue init fail");
+               return WIFI_MANAGER_FAIL;
+       }
+#endif
+
+       return WIFI_MANAGER_SUCCESS;
+}
+
+wifi_manager_result_e wifi_manager_deinit()
+{
+       wifi_utils_result_e result = WIFI_UTILS_SUCCESS;
+
+       if ((g_manager_info.mode == SOFT_AP_MODE) && (stop_dhcp_server() != WIFI_UTILS_SUCCESS)) {
+               ndbg("dhcp server stop fail\n");
+               return WIFI_MANAGER_FAIL;
+       }
+
+       result = wifi_mutex_destroy(&w_mutex);
+       if (result != WIFI_UTILS_SUCCESS) {
+               ndbg("wifi_mutex_destroy fail");
+               return WIFI_MANAGER_FAIL;
+       }
+
+       result = wifi_utils_deinit();
+
+       if (result != WIFI_UTILS_SUCCESS) {
+               ndbg("wifi_utils_deinit fail");
+               return WIFI_MANAGER_FAIL;
+       }
+
+       return WIFI_MANAGER_SUCCESS;
+}
+
+wifi_manager_result_e wifi_manager_set_mode(wifi_manager_mode_e mode, wifi_manager_softap_config_s *config)
+{
+       wifi_utils_result_e result = WIFI_UTILS_SUCCESS;
+
+       if (mode != STA_MODE && mode != SOFT_AP_MODE) {
+               return WIFI_MANAGER_INVALID_ARGS;
+       }
+       // STA mode -> SOFT AP mode
+       if (g_manager_info.mode == STA_MODE && mode == SOFT_AP_MODE) {
+               wifi_utils_softap_config_s soft_ap_config;
+
+               soft_ap_config.channel = config->channel;
+               soft_ap_config.ap_crypto_type = WIFI_UTILS_CRYPTO_AES;
+               soft_ap_config.ap_auth_type = WIFI_UTILS_AUTH_WPA2_PSK;
+               strncpy(soft_ap_config.ssid, config->ssid, sizeof(config->ssid));
+               soft_ap_config.ssid_length = strlen(config->ssid);
+               strncpy(soft_ap_config.passphrase, config->passphrase, sizeof(config->passphrase));
+               soft_ap_config.passphrase_length = strlen(config->passphrase);
+               soft_ap_config.inform_new_sta_join = g_manager_info.wmcb->softap_sta_join;
+
+               wifi_mutex_acquire(&w_mutex, WIFI_UTILS_FOREVER);
+
+               g_new_sta_join = soft_ap_config.inform_new_sta_join;
+               result = wifi_utils_start_soft_ap(&soft_ap_config);
+
+               if (result != WIFI_UTILS_SUCCESS) {
+                       ndbg("Start soft ap mode fail");
+                       wifi_mutex_release(&w_mutex);
+                       return WIFI_MANAGER_FAIL;
+               }
+
+               if (start_dhcp_server() != WIFI_UTILS_SUCCESS) {
+                       ndbg("start DHCP server Failed\n");
+                       return WIFI_MANAGER_FAIL;
+               }
+
+               g_manager_info.mode = SOFT_AP_MODE;
+               g_manager_info.status = CLIENT_DISCONNECTED;
+               wifi_mutex_release(&w_mutex);
+
+               nvdbg("Wifi Change STA MODE -> SOFT AP MODE");
+       }
+       // SOFT AP mode -> STA mode
+       else if (g_manager_info.mode == SOFT_AP_MODE && mode == STA_MODE) {
+               wifi_mutex_acquire(&w_mutex, WIFI_UTILS_FOREVER);
+
+               result = wifi_utils_stop();
+               if (result != WIFI_UTILS_SUCCESS) {
+                       ndbg("Wifi stop fail");
+                       wifi_mutex_release(&w_mutex);
+                       return WIFI_MANAGER_FAIL;
+               }
+
+               stop_dhcp_server();
+
+               result = wifi_utils_start_sta();
+               if (result != WIFI_UTILS_SUCCESS) {
+                       ndbg("start STA fail (change STA mode fail)");
+                       wifi_mutex_release(&w_mutex);
+                       return WIFI_MANAGER_FAIL;
+               }
+
+               g_manager_info.mode = STA_MODE;
+               g_manager_info.status = AP_DISCONNECTED;
+               wifi_mutex_release(&w_mutex);
+
+               nvdbg("Wifi Chnage SOFT AP MODE -> STA MODE");
+       }
+
+       return WIFI_MANAGER_SUCCESS;
+}
+
+wifi_manager_result_e wifi_manager_get_info(wifi_manager_info_s *info)
+{
+       wifi_mutex_acquire(&w_mutex, WIFI_UTILS_FOREVER);
+       *info = g_manager_info;
+       wifi_mutex_release(&w_mutex);
+
+       return WIFI_MANAGER_SUCCESS;
+}
diff --git a/framework/src/wifi_manager/wifi_mutex.c b/framework/src/wifi_manager/wifi_mutex.c
new file mode 100644 (file)
index 0000000..d621ce1
--- /dev/null
@@ -0,0 +1,40 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#include "wifi_mutex.h"
+#include "wifi_semaphore.h"
+
+wifi_utils_result_e wifi_mutex_create(wifi_mutex *mutex)
+{
+       return wifi_semaphore_create((wifi_semaphore *)mutex, 1);
+}
+
+wifi_utils_result_e wifi_mutex_acquire(wifi_mutex *mutex, int time_out)
+{
+       return wifi_semaphore_acquire((wifi_semaphore *)mutex, time_out);
+}
+
+wifi_utils_result_e wifi_mutex_release(wifi_mutex *mutex)
+{
+       return wifi_semaphore_release((wifi_semaphore *)mutex);
+}
+
+wifi_utils_result_e wifi_mutex_destroy(wifi_mutex *mutex)
+{
+       return wifi_semaphore_destroy((wifi_semaphore *)mutex);
+}
diff --git a/framework/src/wifi_manager/wifi_mutex.h b/framework/src/wifi_manager/wifi_mutex.h
new file mode 100644 (file)
index 0000000..9bd7a29
--- /dev/null
@@ -0,0 +1,71 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef WIFI_MUTEX_H
+#define WIFI_MUTEX_H
+#include <semaphore.h>
+#include "wifi_common.h"
+typedef sem_t wifi_mutex;
+
+/**
+ * @brief create mutex
+ *
+ * @param[in]  mutex  :  wifi_mutex
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_mutex_create(wifi_mutex *mutex);
+
+/**
+ * @brief acquire the lock a mutex
+ *
+ * @param[in]  mutex     :  wifi_mutex
+ * @param[in]  time_out  :  set time out, WIFI_UTILS_NO_WAIT, WIFI_UTILS_FOREVER, or wait milliseconds
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ * @return WIFI_UTILS_TIMEOUT       :  occur timeout
+  */
+wifi_utils_result_e wifi_mutex_acquire(wifi_mutex *mutex, int time_out);
+
+/**
+ * @brief release the lock on a mutex
+ *
+ * @param[in]  mutex  :  wifi_mutex
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+  */
+wifi_utils_result_e wifi_mutex_release(wifi_mutex *mutex);
+
+/**
+ * @brief destroy a mutex
+ *
+ * @param[in]  mutex  :  wifi_mutex
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_mutex_destroy(wifi_mutex *mutex);
+
+#endif                                                 //WIFI_MUTEX_H
diff --git a/framework/src/wifi_manager/wifi_net.c b/framework/src/wifi_manager/wifi_net.c
new file mode 100644 (file)
index 0000000..a79ffa3
--- /dev/null
@@ -0,0 +1,220 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#include <tinyara/config.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sched.h>
+#include <errno.h>
+#include <debug.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include "wifi_utils.h"
+#include "wifi_net.h"
+
+#define ptr2uint32(ptr) (uint32_t)ptr[3] |     \
+                               ((uint32_t)ptr[2] << 8)  |     \
+                               ((uint32_t)ptr[1] << 16) |     \
+                               ((uint32_t)ptr[0] << 24)
+
+#define NTP2UNIX_TRANLSLATION 2208988800u
+#define NTP_VERSION           3
+static void convert_ntp_time(FAR uint8_t *timestamp, unsigned int *sec, unsigned int *usec)
+{
+       time_t seconds;
+       uint32_t frac;
+       uint32_t nsec;
+#ifdef CONFIG_HAVE_LONG_LONG
+       uint64_t tmp;
+#else
+       uint32_t a16;
+       uint32_t b0;
+       uint32_t t32;
+       uint32_t t16;
+       uint32_t t0;
+#endif
+
+       /* NTP timestamps are represented as a 64-bit fixed-point number, in
+        * seconds relative to 0000 UT on 1 January 1900.  The integer part is
+        * in the first 32 bits and the fraction part in the last 32 bits, as
+        * shown in the following diagram.
+        *
+        *    0                   1                   2                   3
+        *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+        *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        *   |                         Integer Part                          |
+        *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        *   |                         Fraction Part                         |
+        *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        */
+
+       seconds = ptr2uint32(timestamp);
+
+       /* Translate seconds to account for the difference in the origin time */
+
+       if (seconds > NTP2UNIX_TRANLSLATION) {
+               seconds -= NTP2UNIX_TRANLSLATION;
+       }
+
+       /* Conversion of the fractional part to nanoseconds:
+        *
+        *  NSec = (f * 1,000,000,000) / 4,294,967,296
+        *       = (f * (5**9 * 2**9) / (2**32)
+        *       = (f * 5**9) / (2**23)
+        *       = (f * 1,953,125) / 8,388,608
+        */
+
+       frac = ptr2uint32((timestamp + 4));
+#ifdef CONFIG_HAVE_LONG_LONG
+       /* if we have 64-bit long long values, then the computation is easy */
+
+       tmp = ((uint64_t)frac * 1953125) >> 23;
+       nsec = (uint32_t)tmp;
+
+#else
+       /* If we don't have 64 bit integer types, then the calculation is a little
+        * more complex:
+        *
+        * Let f         = a    << 16 + b
+        *     1,953,125 = 0x1d << 16 + 0xcd65
+        * NSec << 23 =  ((a << 16) + b) * ((0x1d << 16) + 0xcd65)
+        *            = (a << 16) * 0x1d << 16) +
+        *              (a << 16) * 0xcd65 +
+        *              b         * 0x1d << 16) +
+        *              b         * 0xcd65;
+        */
+
+       /* Break the fractional part up into two values */
+
+       a16 = frac >> 16;
+       b0 = frac & 0xffff;
+
+       /* Get the b32 and b0 terms
+        *
+        * t32 = (a << 16) * 0x1d << 16)
+        * t0  = b * 0xcd65
+        */
+
+       t32 = 0x001d * a16;
+       t0 = 0xcd65 * b0;
+
+       /* Get the first b16 term
+        *
+        * (a << 16) * 0xcd65
+        */
+
+       t16 = 0xcd65 * a16;
+
+       /* Add the upper 16-bits to the b32 accumulator */
+
+       t32 += (t16 >> 16);
+
+       /* Add the lower 16-bits to the b0 accumulator, handling carry to the b32
+        * accumulator
+        */
+
+       t16 <<= 16;
+       if (t0 > (0xffffffff - t16)) {
+               t32++;
+       }
+
+       t0 += t16;
+
+       /* Get the second b16 term
+        *
+        * b * (0x1d << 16)
+        */
+
+       t16 = 0x001d * b0;
+
+       /* Add the upper 16-bits to the b32 accumulator */
+
+       t32 += (t16 >> 16);
+
+       /* Add the lower 16-bits to the b0 accumulator, handling carry to the b32
+        * accumulator
+        */
+
+       t16 <<= 16;
+       if (t0 > (0xffffffff - t16)) {
+               t32++;
+       }
+
+       t0 += t16;
+
+       /* t32 and t0 represent the 64 bit product.  Now shift right by 23 bits to
+        * accomplish the divide by by 2**23.
+        */
+
+       nsec = (t32 << (32 - 23)) + (t0 >> 23);
+#endif
+       *sec = seconds;
+       *usec = nsec / 1000;
+       ndbg(" %lu seconds, %lu usec\n", (uint32_t)seconds, (uint32_t)nsec / 1000);
+
+}
+
+wifi_utils_result_e wifi_net_hostname_to_ip4(char *hostname, unsigned int *ip4_address)
+{
+       if (hostname == NULL || ip4_address == NULL) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       struct hostent *shost;
+
+       shost = gethostbyname((const char *)hostname);
+       if (shost == NULL) {
+               ndbg("gethostbyname fail %d\n", shost);
+               return WIFI_UTILS_FAIL;
+       }
+
+       memcpy(ip4_address, shost->h_addr, sizeof(in_addr_t));
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_net_ip4_addr_to_ip4_str(unsigned int ip4_addr, char ip4_str[18])
+{
+       if (ip4_addr <= 0 || ip4_str == NULL) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       unsigned char bytes[4];
+       bytes[0] = ip4_addr & 0xFF;
+       bytes[1] = (ip4_addr >> 8) & 0xFF;
+       bytes[2] = (ip4_addr >> 16) & 0xFF;
+       bytes[3] = (ip4_addr >> 24) & 0xFF;
+
+       sprintf(ip4_str, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_net_mac_addr_to_mac_str(unsigned char mac_addr[6], char mac_str[20])
+{
+       if (!mac_addr || !mac_str) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       snprintf(mac_str, 18, "%02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
+       return WIFI_UTILS_SUCCESS;
+}
diff --git a/framework/src/wifi_manager/wifi_net.h b/framework/src/wifi_manager/wifi_net.h
new file mode 100644 (file)
index 0000000..dcae6d2
--- /dev/null
@@ -0,0 +1,64 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef WIFI_NET_H
+#define WIFI_NET_H
+#include "wifi_common.h"
+
+/**
+ * @file wifi_net.h
+ * @brief network utility (dns, ntp) API
+ */
+
+/**
+ * @brief host name to IP4 address
+ *
+ * @param[in]   hostname     :  host name string (ex - www.google.co.kr)
+ * @param[out]  ip4_address  :  host ip4 address (32bit)
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_utils_hostname_to_ip4(char *hostname, unsigned int *ip4_address);
+
+/**
+ * @brief convert ip4 address (32bit) to ip4 address string (123.123.123.123)
+ *
+ * @param[in]   ip4_addr  :  ip4 address 32bit
+ * @param[out]  ip4_str   :  ip4 address string
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_utils_ip4_addr_to_ip4_str(unsigned int ip4_addr, char ip4_str[18]);
+
+/**
+ * @brief convert mac address (48bit) to mac address string (FF:FF:FF:FF:FF:FF)
+ *
+ * @param[in]  mac_addr  :  mac address 48bit
+ * @param[out] mac_str   :  mac address string
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_utils_mac_addr_to_mac_str(unsigned char mac_addr[6], char mac_str[20]);
+
+#endif //WIFI_NET_H
diff --git a/framework/src/wifi_manager/wifi_semaphore.c b/framework/src/wifi_manager/wifi_semaphore.c
new file mode 100644 (file)
index 0000000..47658d6
--- /dev/null
@@ -0,0 +1,104 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#include <semaphore.h>
+#include <errno.h>
+#include <time.h>
+#include "wifi_semaphore.h"
+
+wifi_utils_result_e wifi_semaphore_create(wifi_semaphore *semaphore, unsigned int init_value)
+{
+       if (!semaphore) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       if (sem_init((sem_t *)semaphore, 0, init_value)) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_semaphore_acquire(wifi_semaphore *semaphore, int time_out)
+{
+       int result;
+
+       if (!semaphore || time_out < -1) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       if (time_out == WIFI_UTILS_FOREVER) {
+               result = sem_wait((sem_t *)semaphore);
+       } else if (time_out == WIFI_UTILS_NO_WAIT) {
+               result = sem_trywait((sem_t *)semaphore);
+       } else {
+               time_t sec;
+               uint32_t nsec;
+               struct timespec abstime;
+
+               sec = time_out / 1000;
+               nsec = (time_out - 1000 * sec) * 1000000;
+
+               clock_gettime(CLOCK_REALTIME, &abstime);
+
+               abstime.tv_sec += sec;
+               abstime.tv_nsec += nsec;
+               if (abstime.tv_nsec >= 1000000000) {
+                       abstime.tv_sec++;
+                       abstime.tv_nsec -= 1000000000;
+               }
+
+               result = sem_timedwait((sem_t *)semaphore, &abstime);
+       }
+
+       if (result == 0) {
+               return WIFI_UTILS_SUCCESS;
+       }
+
+       if (get_errno() == ETIMEDOUT) {
+               return WIFI_UTILS_TIMEOUT;
+       }
+
+       return WIFI_UTILS_FAIL;
+}
+
+wifi_utils_result_e wifi_semaphore_release(wifi_semaphore *semaphore)
+{
+       if (!semaphore) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       if (sem_post((sem_t *)semaphore)) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_semaphore_destroy(wifi_semaphore *semaphore)
+{
+       if (!semaphore) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       if (sem_destroy((sem_t *)semaphore)) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
diff --git a/framework/src/wifi_manager/wifi_semaphore.h b/framework/src/wifi_manager/wifi_semaphore.h
new file mode 100644 (file)
index 0000000..dbc8e4a
--- /dev/null
@@ -0,0 +1,86 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef WIFI_SEMAPHORE_H
+#define WIFI_SEMAPHORE_H
+
+#include <semaphore.h>
+#include "wifi_common.h"
+
+/**
+ * @file wifi_semaphore.h
+ * @brief semaphore API
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief wifi_semaphore struct
+ */
+typedef vendor_semapore wifi_semaphore;
+#else
+typedef sem_t wifi_semaphore;
+#endif
+
+/**
+ * @brief  create semaphore
+ *
+ * @param[in]  semaphore   :  wifi semaphore
+ * @param[in]  init_value  :  initial value of the semaphore (resource size)
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_semaphore_create(wifi_semaphore *semaphore, unsigned int init_value);
+
+/**
+ * @brief acquire semaphore
+ *
+ * @param[in]  semaphore  :  wifi semaphore
+ * @param[in]  time_out   :  set time out, WIFI_UTILS_NO_WAIT, WIFI_UTILS_FOREVER, or wait milliseconds
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ * @return WIFI_UTILS_TIMEOUT       :  occur timeout
+ */
+wifi_utils_result_e wifi_semaphore_acquire(wifi_semaphore *semaphore, int time_out);
+
+/**
+ * @brief releases semaphore
+ *
+ * @param[in]  semaphore  :  wifi semaphore
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_semaphore_release(wifi_semaphore *semaphore);
+
+/**
+ * @brief destroy semaphore
+ *
+ * @param[in]  semaphore :  wifi semaphore
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_semaphore_destroy(wifi_semaphore *semaphore);
+
+#endif                                                 //WIFI_SEMAPHORE_H
diff --git a/framework/src/wifi_manager/wifi_utils.c b/framework/src/wifi_manager/wifi_utils.c
new file mode 100644 (file)
index 0000000..0b7a2b9
--- /dev/null
@@ -0,0 +1,466 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#include <tinyara/config.h>
+#include <debug.h>
+#include <stdio.h>
+#include <slsi_wifi/slsi_wifi_api.h>
+#include "wifi_utils.h"
+
+#include <net/lwip/netif.h>            // to be fixed
+
+#define MACADDR_LENGTH                 6
+#define SSID_LENGTH_MAX                        32
+#define PASSPHRASE_LENGTH_MAX  64
+#define DHCP_RETRY_COUNT               1
+
+typedef void (*link_up_handler)(void *params);
+typedef void (*link_down_handler)(void *params);
+
+static sem_t g_sem_scan_result;
+static WiFi_InterFace_ID_t g_mode;
+static uint8_t g_join_result;
+static link_up_handler g_linkup = NULL;
+static link_down_handler g_linkdown = NULL;
+
+void LinkUpHandlerCb(slsi_reason_t *reason)
+{
+       g_join_result = reason->reason_code;
+       if ((reason->reason_code == SLSI_STATUS_SUCCESS) && g_linkup) {
+               g_linkup(NULL);
+       }
+}
+
+void LinkDownHandlerCb(slsi_reason_t *reason)
+{
+       if (g_linkdown) {
+               g_linkdown(NULL);
+       }
+}
+
+wifi_utils_result_e wifi_utils_init(void)
+{
+       if (g_mode != SLSI_WIFI_NONE) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       int ret;
+
+       ret = WiFiStart(SLSI_WIFI_STATION_IF, NULL);
+       if (ret != SLSI_STATUS_SUCCESS) {
+               ndbg("Failed to start STA mode\n");
+               return WIFI_UTILS_FAIL;
+       }
+       g_mode = SLSI_WIFI_STATION_IF;
+
+       ret = WiFiRegisterLinkCallback(&LinkUpHandlerCb, &LinkDownHandlerCb);
+       if (ret != SLSI_STATUS_SUCCESS) {
+               ndbg("Link callback handles: register failed !\n");
+               return WIFI_UTILS_FAIL;
+       } else {
+               nvdbg("Link callback handles: registered\n");
+       }
+       sem_init(&g_sem_scan_result, 0, 0);
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_utils_deinit(void)
+{
+       int ret;
+
+       ret = WiFiStop();
+       if (ret != SLSI_STATUS_SUCCESS) {
+               ndbg("Failed to stop STA mode\n");
+               return WIFI_UTILS_FAIL;
+       }
+       g_mode = SLSI_WIFI_NONE;
+
+       g_linkup = NULL;
+       g_linkdown = NULL;
+       g_join_result = 0;
+       sem_destroy(&g_sem_scan_result);
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+int8_t ScanResultHandlerCb(slsi_reason_t *reason)
+{
+       if (reason->reason_code == 0) {
+               /* Scan succeeded */
+       } else {
+               ndbg("Scan failed reason: %d, locally_generated: %d\n", reason->reason_code, reason->locally_generated);
+       }
+
+       sem_post(&g_sem_scan_result);
+       return 0;
+}
+
+wifi_utils_result_e wifi_utils_scan_ap(wifi_utils_ap_scan_info_s *ap_list, unsigned int list_size, unsigned int *found_ap_count)
+{
+       if (!ap_list || (list_size == 0) || !found_ap_count) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       int ret;
+       unsigned int bss_count = 0;
+       slsi_scan_info_t *results = NULL;
+       slsi_scan_info_t *head = NULL;
+
+       // issue a scan request command and wait for the message return
+       WiFiRegisterScanCallback(ScanResultHandlerCb);
+       ret = WiFiScanNetwork();
+       if (ret != SLSI_STATUS_SUCCESS) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       sem_wait(&g_sem_scan_result);
+
+       // get scan results when message arrives
+       ret = WiFiGetScanResults(&results);
+       if (ret != SLSI_STATUS_SUCCESS || !results) {
+               return WIFI_UTILS_FAIL;
+       }
+       head = results;
+
+       do {
+               ap_list[bss_count].channel = results->channel;
+               snprintf(ap_list[bss_count].ssid, SLSI_SSID_LEN + 1, "%s", results->ssid);
+               ap_list[bss_count].ssid_length = (unsigned int)(results->ssid_len);
+               hwaddr_aton(results->bssid, ap_list[bss_count].bssid);
+               ap_list[bss_count].rssi = results->rssi;
+
+               if (!results->sec_modes) {
+                       ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_OPEN;
+                       ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_NONE;
+               } else {
+                       if (results->sec_modes->secmode == SLSI_SEC_MODE_WEP || results->sec_modes->secmode == SLSI_SEC_MODE_WEP_SHARED || results->sec_modes->secmode == (SLSI_SEC_MODE_WEP | SLSI_SEC_MODE_WEP_SHARED)) {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_WEP_SHARED;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_WEP_64;
+                       } else if (results->num_sec_modes == 2 && results->sec_modes[0].secmode == SLSI_SEC_MODE_WPA_MIXED && results->sec_modes[1].secmode == SLSI_SEC_MODE_WPA2_MIXED) {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_WPA_AND_WPA2_PSK;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_TKIP_AND_AES;
+                       } else if (results->sec_modes->secmode == SLSI_SEC_MODE_WPA2_MIXED) {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_WPA2_PSK;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_TKIP_AND_AES;
+                       } else if (results->sec_modes->secmode == SLSI_SEC_MODE_WPA2_CCMP) {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_WPA2_PSK;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_AES;
+                       } else if (results->sec_modes->secmode == SLSI_SEC_MODE_WPA2_TKIP) {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_WPA2_PSK;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_TKIP;
+                       } else if (results->sec_modes->secmode == SLSI_SEC_MODE_WPA_MIXED) {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_WPA_PSK;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_TKIP_AND_AES;
+                       } else if (results->sec_modes->secmode == SLSI_SEC_MODE_WPA_CCMP) {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_WPA_PSK;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_AES;
+                       } else if (results->sec_modes->secmode == SLSI_SEC_MODE_WPA_TKIP) {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_WPA_PSK;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_TKIP;
+                       } else {
+                               ap_list[bss_count].ap_auth_type = WIFI_UTILS_AUTH_UNKNOWN;
+                               ap_list[bss_count].ap_crypto_type = WIFI_UTILS_CRYPTO_UNKNOWN;
+                       }
+               }
+
+               results = results->next;
+               if (ap_list[bss_count].ap_auth_type != WIFI_UTILS_AUTH_UNKNOWN && ap_list[bss_count].ap_crypto_type != WIFI_UTILS_CRYPTO_UNKNOWN) {
+                       bss_count++;
+               }
+       } while (results->next && bss_count < list_size);
+
+       *found_ap_count = bss_count;
+       results = head;
+       WiFiFreeScanResults(&results);
+
+       int i;
+       for (i = 0; i < *found_ap_count && i < list_size; i++) {
+               int j;
+               int max = i;
+               for (j = i + 1; j < *found_ap_count && i < list_size; j++) {
+                       if (ap_list[max].rssi < ap_list[j].rssi) {
+                               max = j;
+                       }
+               }
+
+               wifi_utils_ap_scan_info_s tmp;
+               tmp = ap_list[i];
+               ap_list[i] = ap_list[max];
+               ap_list[max] = tmp;
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_utils_register_connection_callback(void *connect_event_func, void *disconnect_event_func)
+{
+       g_linkup = connect_event_func;
+       g_linkdown = disconnect_event_func;
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_utils_connect_ap(wifi_utils_ap_config_s *ap_connect_config)
+{
+       if (!ap_connect_config) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       int ret;
+       wifi_utils_result_e result = WIFI_UTILS_FAIL;
+       slsi_security_config_t *config = NULL;
+
+       if (ap_connect_config->passphrase && ap_connect_config->passphrase_length) {
+               config = (slsi_security_config_t *)zalloc(sizeof(slsi_security_config_t));
+               if (!config) {
+                       ndbg("Memory allocation failed!\n");
+                       goto connect_ap_fail;
+               }
+
+               if ((ap_connect_config->ap_auth_type == WIFI_UTILS_AUTH_WEP_SHARED) && (ap_connect_config->passphrase_length == 5 || ap_connect_config->passphrase_length == 13)) {
+                       config->passphrase[0] = '"';
+                       memcpy(&config->passphrase[1], ap_connect_config->passphrase, ap_connect_config->passphrase_length);
+                       config->passphrase[ap_connect_config->passphrase_length + 1] = '"';
+                       config->passphrase[ap_connect_config->passphrase_length + 2] = '\0';
+               } else {
+                       memcpy(config->passphrase, ap_connect_config->passphrase, ap_connect_config->passphrase_length);
+               }
+
+               if (ap_connect_config->ap_auth_type == WIFI_UTILS_AUTH_WEP_SHARED) {
+                       config->secmode = SLSI_SEC_MODE_WEP_SHARED;
+               } else if (ap_connect_config->ap_auth_type == WIFI_UTILS_AUTH_WPA_PSK) {
+                       if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_AES) {
+                               config->secmode = SLSI_SEC_MODE_WPA_CCMP;
+                       } else if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_TKIP) {
+                               config->secmode = SLSI_SEC_MODE_WPA_TKIP;
+                       } else if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_TKIP_AND_AES) {
+                               config->secmode = SLSI_SEC_MODE_WPA_MIXED;
+                       }
+               } else if (ap_connect_config->ap_auth_type == WIFI_UTILS_AUTH_WPA2_PSK) {
+                       if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_AES) {
+                               config->secmode = SLSI_SEC_MODE_WPA2_CCMP;
+                       } else if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_TKIP) {
+                               config->secmode = SLSI_SEC_MODE_WPA2_TKIP;
+                       } else if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_TKIP_AND_AES) {
+                               config->secmode = SLSI_SEC_MODE_WPA2_MIXED;
+                       }
+               } else if (ap_connect_config->ap_auth_type == WIFI_UTILS_AUTH_WPA_AND_WPA2_PSK) {
+                       if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_AES) {
+                               config->secmode = (SLSI_SEC_MODE_WPA_CCMP | SLSI_SEC_MODE_WPA2_CCMP);
+                       } else if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_TKIP) {
+                               config->secmode = (SLSI_SEC_MODE_WPA_TKIP | SLSI_SEC_MODE_WPA2_TKIP);
+                       } else if (ap_connect_config->ap_crypto_type == WIFI_UTILS_CRYPTO_TKIP_AND_AES) {
+                               config->secmode = (SLSI_SEC_MODE_WPA_MIXED | SLSI_SEC_MODE_WPA2_MIXED);
+                       }
+               } else {
+                       /* wrong security type */
+                       ndbg("Wrong security type\n");
+                       goto connect_ap_fail;
+               }
+       }
+
+       ret = WiFiNetworkJoin((uint8_t *)ap_connect_config->ssid, ap_connect_config->ssid_length, NULL, config);
+       if (ret != SLSI_STATUS_SUCCESS) {
+               if (ret == SLSI_STATUS_ALREADY_CONNECTED) {
+                       nvdbg("WiFiNetworkJoin already connected\n");
+                       result = WIFI_UTILS_SUCCESS;
+               } else {
+                       ndbg("WiFiNetworkJoin failed: %d, %s\n", ret, ap_connect_config->ssid);
+                       goto connect_ap_fail;
+               }
+       } else {
+               result = WIFI_UTILS_SUCCESS;
+               nvdbg("Successfully joined the network: %s\n", ap_connect_config->ssid);
+       }
+
+connect_ap_fail:
+       if (config) {
+               free(config);
+               config = NULL;
+       }
+
+       return result;
+}
+
+wifi_utils_result_e wifi_utils_disconnect_ap(void)
+{
+       int ret;
+
+       ret = WiFiNetworkLeave();
+       if (ret != SLSI_STATUS_SUCCESS) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_utils_get_info(wifi_utils_info *wifi_info)
+{
+       if (!wifi_info) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+       if (g_mode == SLSI_WIFI_NONE) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       struct netif *netif;
+
+       netif = netif_find(CTRL_IFNAME);        /* to be changed pkes */
+       wifi_info->ip4_address = netif->ip_addr.addr;
+
+       int ret;
+
+       ret = WiFiGetMac(wifi_info->mac_address);
+       if (ret != SLSI_STATUS_SUCCESS) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       wifi_info->rssi = (int)0;
+
+       if (g_mode == SLSI_WIFI_SOFT_AP_IF) {
+               wifi_info->wifi_status = WIFI_UTILS_SOFT_AP_MODE;
+       } else if (g_mode == SLSI_WIFI_STATION_IF) {
+               uint8_t isConnected;
+               if (WiFiIsConnected(&isConnected, NULL) == SLSI_STATUS_SUCCESS) {
+                       int8_t rssi;
+                       wifi_info->wifi_status = WIFI_UTILS_CONNECTED;
+                       if (WiFiGetRssi(&rssi) == SLSI_STATUS_SUCCESS) {
+                               wifi_info->rssi = (int)rssi;
+                       }
+               } else {
+                       wifi_info->wifi_status = WIFI_UTILS_DISCONNECTED;
+               }
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_utils_start_soft_ap(wifi_utils_softap_config_s *soft_ap_config)
+{
+       if (!soft_ap_config) {
+               return WIFI_UTILS_INVALID_ARGS;
+       }
+
+       if (g_mode != SLSI_WIFI_STATION_IF) {
+               ndbg("start softap failed: g_mode = %d\n", g_mode);
+               return WIFI_UTILS_FAIL;
+       }
+
+       wifi_utils_result_e ret = WIFI_UTILS_FAIL;
+       slsi_ap_config_t *ap_config = NULL;
+       slsi_security_config_t *security_config = NULL;
+
+       ap_config = (slsi_ap_config_t *)zalloc(sizeof(slsi_ap_config_t));
+       if (!ap_config) {
+               ndbg("Memory allocation failed!\n");
+               return WIFI_UTILS_FAIL;
+       }
+
+       /* add initialization code as slsi_app */
+       ap_config->beacon_period = 100;
+       ap_config->DTIM = 1;
+       ap_config->phy_mode = 1;
+
+       if (soft_ap_config->channel > 14 || soft_ap_config->channel < 1) {
+               ndbg("Channel needs to be between 1 and 14" " (highest channel depends on regulatory of countries)\n");
+               goto start_soft_ap_fail;
+       } else {
+               ap_config->channel = soft_ap_config->channel;
+       }
+
+       if (soft_ap_config->ssid == NULL) {
+               goto start_soft_ap_fail;
+       } else {
+               memcpy(&ap_config->ssid, soft_ap_config->ssid, soft_ap_config->ssid_length);
+               ap_config->ssid_len = soft_ap_config->ssid_length;
+       }
+
+       if (!soft_ap_config->passphrase || !soft_ap_config->passphrase_length) {
+               goto start_soft_ap_fail;
+       } else {
+               security_config = (slsi_security_config_t *)zalloc(sizeof(slsi_security_config_t));
+               if (!security_config) {
+                       ndbg("Memory allocation failed!\n");
+                       goto start_soft_ap_fail;
+               }
+               memcpy(security_config->passphrase, soft_ap_config->passphrase, soft_ap_config->passphrase_length);
+       }
+
+       if ((soft_ap_config->ap_auth_type == WIFI_UTILS_AUTH_WPA_PSK) && (soft_ap_config->ap_crypto_type == WIFI_UTILS_CRYPTO_TKIP)) {
+               security_config->secmode = SLSI_SEC_MODE_WPA_TKIP;
+       } else if ((soft_ap_config->ap_auth_type == WIFI_UTILS_AUTH_WPA2_PSK) && (soft_ap_config->ap_crypto_type == WIFI_UTILS_CRYPTO_AES)) {
+               security_config->secmode = SLSI_SEC_MODE_WPA2_CCMP;
+       } else if ((soft_ap_config->ap_auth_type == WIFI_UTILS_AUTH_WPA_AND_WPA2_PSK) && (soft_ap_config->ap_crypto_type == WIFI_UTILS_CRYPTO_TKIP_AND_AES)) {
+               security_config->secmode = (SLSI_SEC_MODE_WPA_MIXED | SLSI_SEC_MODE_WPA2_MIXED);
+       } else {
+               // if not WPA-TKIP, WPA2-AES, WPA/WPA2 TKIP/AES/MIXED, return fail.
+               ndbg("Wrong security config. Match proper auth and crypto.\n");
+               goto start_soft_ap_fail;
+       }
+       ap_config->security = security_config;
+
+       if (WiFiStart(SLSI_WIFI_SOFT_AP_IF, ap_config) != SLSI_STATUS_SUCCESS) {
+               ndbg("Failed to start AP mode\n");
+               goto start_soft_ap_fail;
+       }
+       g_mode = SLSI_WIFI_SOFT_AP_IF;
+       nvdbg("SoftAP with SSID: %s has successfully started!\n", soft_ap_config->ssid);
+
+       ret = WIFI_UTILS_SUCCESS;
+start_soft_ap_fail:
+       if (ap_config) {
+               free(ap_config);
+               ap_config = NULL;
+       }
+       if (security_config) {
+               free(security_config);
+               security_config = NULL;
+       }
+       return ret;
+}
+
+wifi_utils_result_e wifi_utils_start_sta(void)
+{
+       g_mode = SLSI_WIFI_NONE;
+
+       g_join_result = 0;
+
+       if (wifi_utils_init() != WIFI_UTILS_SUCCESS) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
+
+wifi_utils_result_e wifi_utils_stop(void)
+{
+       int ret;
+
+       if (g_mode != SLSI_WIFI_SOFT_AP_IF) {
+               return WIFI_UTILS_FAIL;
+       }
+
+       ret = WiFiStop();
+       if (ret != SLSI_STATUS_SUCCESS) {
+               ndbg("Failed to stop AP mode\n");
+               return WIFI_UTILS_FAIL;
+       }
+
+       return WIFI_UTILS_SUCCESS;
+}
diff --git a/framework/src/wifi_manager/wifi_utils.h b/framework/src/wifi_manager/wifi_utils.h
new file mode 100644 (file)
index 0000000..528268b
--- /dev/null
@@ -0,0 +1,206 @@
+/****************************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ****************************************************************************/
+
+#ifndef WIFI_UTILS_H
+#define WIFI_UTILS_H
+
+#include "wifi_common.h"
+
+/**
+ * @brief <b> wifi authentication type WPA, WPA2, WPS</b>
+ */
+typedef enum {
+       WIFI_UTILS_AUTH_OPEN,                                    /**<  open mode                      */
+       WIFI_UTILS_AUTH_WEP_SHARED,                              /**<  use shared key (wep key)       */
+       WIFI_UTILS_AUTH_WPA_PSK,                                 /**<  WPA_PSK mode                   */
+       WIFI_UTILS_AUTH_WPA2_PSK,                                /**<  WPA2_PSK mode                  */
+       WIFI_UTILS_AUTH_WPA_AND_WPA2_PSK,                /**<  WPA_PSK and WPA_PSK mixed mode */
+       WIFI_UTILS_AUTH_UNKNOWN,                                 /**<  unknown type                   */
+} wifi_utils_ap_auth_type_e;
+
+/**
+ * @brief wifi encryption type WEP, AES, TKIP
+ */
+typedef enum {
+       WIFI_UTILS_CRYPTO_NONE,                                  /**<  none encryption                */
+       WIFI_UTILS_CRYPTO_WEP_64,                                /**<  WEP encryption wep-40          */
+       WIFI_UTILS_CRYPTO_WEP_128,                               /**<  WEP encryption wep-104         */
+       WIFI_UTILS_CRYPTO_AES,                                   /**<  AES encryption                 */
+       WIFI_UTILS_CRYPTO_TKIP,                                  /**<  TKIP encryption                */
+       WIFI_UTILS_CRYPTO_TKIP_AND_AES,                  /**<  TKIP and AES mixed encryption  */
+       WIFI_UTILS_CRYPTO_UNKNOWN,                               /**<  unknown encryption             */
+} wifi_utils_ap_crypto_type_e;
+
+/**
+ * @brief wifi status (connected, dis_connected, soft_ap)
+ */
+typedef enum {
+       WIFI_UTILS_DISCONNECTED,                        /**<  wifi is disconnected  */
+       WIFI_UTILS_CONNECTED,                           /**<  connected             */
+       WIFI_UTILS_SOFT_AP_MODE,                        /**<  soft ap mode          */
+} wifi_utils_status_e;
+
+/**
+ * @brief wifi access point information
+ */
+typedef struct {
+       unsigned int channel;                             /**<  Radio channel that the AP beacon was received on       */
+       char ssid[32];                                            /**<  Service Set Identification (i.e. Name of Access Point) */
+       unsigned int ssid_length;                         /**<  The length of Service Set Identification               */
+       unsigned char bssid[6];                           /**<  MAC address of Access Point                            */
+       unsigned int max_rate;                            /**<  Maximum data rate in kilobits/s                        */
+       int rssi;                                                         /**<  Receive Signal Strength Indication in dBm              */
+       wifi_utils_ap_auth_type_e ap_auth_type;    /**<  @ref wifi_utils_ap_auth_type                                */
+       wifi_utils_ap_crypto_type_e ap_crypto_type;  /**<  @ref wifi_utils_ap_crypto_type                              */
+} wifi_utils_ap_scan_info_s;
+
+/**
+ * @brief wifi ap connect config
+ */
+typedef struct {
+       char ssid[32];                                                   /**<  Service Set Identification         */
+       unsigned int ssid_length;                                /**<  Service Set Identification Length  */
+       char passphrase[64];                                     /**<  ap passphrase(password)            */
+       unsigned int passphrase_length;                  /**<  ap passphrase length               */
+       wifi_utils_ap_auth_type_e ap_auth_type;           /**<  @ref wifi_utils_ap_auth_type            */
+       wifi_utils_ap_crypto_type_e ap_crypto_type;       /**<  @ref wifi_utils_ap_crypto_type          */
+} wifi_utils_ap_config_s;
+
+/**
+ * @brief soft ap mode config
+ */
+typedef struct {
+       unsigned int channel;                                    /**<  soft ap wifi channel               */
+       char ssid[32];                                                   /**<  Service Set Identification         */
+       unsigned int ssid_length;                                /**<  Service Set Identification Length  */
+       char passphrase[64];                                     /**<  ap passphrase(password)            */
+       unsigned int passphrase_length;                  /**<  ap passphrase length               */
+       wifi_utils_ap_auth_type_e ap_auth_type;           /**<  @ref wifi_utils_ap_auth_type            */
+       wifi_utils_ap_crypto_type_e ap_crypto_type;       /**<  @ref wifi_utils_ap_crypto_type          */
+       void (*inform_new_sta_join)(void);              /**< @ref inform application about new station joining softAP */
+} wifi_utils_softap_config_s;
+
+/**
+ * @brief wifi information (ip address, mac address)
+ */
+typedef struct {
+       uint32_t ip4_address;                      /**<  ip4 address                               */
+       unsigned char mac_address[6];      /**<  MAC address of wifi interface             */
+       int rssi;                                                  /**<  Receive Signal Strength Indication in dBm */
+       wifi_utils_status_e wifi_status;           /**<  @ref wifi_utils_status                    */
+} wifi_utils_info;
+
+/**
+ * @brief wifi interface init
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ */
+wifi_utils_result_e wifi_utils_init(void);
+
+/**
+ * @brief wifi interface deinit
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ */
+wifi_utils_result_e wifi_utils_deinit(void);
+
+/**
+ * @brief scans access point list
+ *
+ * @param[in]   ap_list        :  pre declared wifi_utils_ap_scan_info_s array pointer
+ * @param[in]   list_size      :  ap_list size (wifi_utils_ap_info array)
+ * @param[out]  found_ap_count :  found ap count
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_utils_scan_ap(wifi_utils_ap_scan_info_s *ap_list, unsigned int list_size, unsigned int *found_ap_count);
+
+/**
+ * @brief wifi connect access point
+ *
+ * @param[in]   ap_connect_config  :  target ap connect config
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_utils_connect_ap(wifi_utils_ap_config_s *ap_connect_config);
+
+/**
+ * @brief wifi disconnect access point
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ */
+wifi_utils_result_e wifi_utils_disconnect_ap(void);
+
+/**
+ * @brief get wifi information (IP address, MAC address)
+ *
+ * @param[out]  wifi_info      :  @ref wifi_utils_info
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_utils_get_info(wifi_utils_info *wifi_info);
+
+/**
+ * @brief register wifi connection event callback (connect/disconnect event)
+ *
+ * @param[in]   connect_event_func    :  when wifi connect event received, function start
+ * @param[in]   disconnect_event_func :  when wifi disconnect event received, function start
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_utils_register_connection_callback(void *connect_event_func, void *disconnect_event_func);
+
+/**
+ * @brief wifi start soft ap mode
+ *
+ * @param[in]   soft_ap_config :  @ref  wifi_utils_softap_config_s
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ * @return WIFI_UTILS_INVALID_ARGS  :  input parameter invalid
+ */
+wifi_utils_result_e wifi_utils_start_soft_ap(wifi_utils_softap_config_s *soft_ap_config);
+
+/**
+ * @brief start wifi sta mode
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ */
+wifi_utils_result_e wifi_utils_start_sta(void);
+
+/**
+ * @brief stop wifi
+ *
+ * @return WIFI_UTILS_SUCCESS       :  success
+ * @return WIFI_UTILS_FAIL          :  fail
+ */
+wifi_utils_result_e wifi_utils_stop(void);
+
+#endif                                                 //WIFI_UTILS_H
index 8db346c..6fdd66e 100644 (file)
@@ -133,6 +133,12 @@ endif #NET_SECURITY_TLS
 
 endmenu #Protocols
 
+menu "Wireless"
+
+source ../framework/src/wifi_manager/Kconfig
+
+endmenu #Wireless
+
 menu "Network utilities"
 
 source "$EXTERNALDIR/netutils/Kconfig.netutil"