Skip to content

Commit fa2d6b6

Browse files
samples: boards : Wi-Fi SiWx91x sample app
This application demonstrates support for SiWx91x ICMP and DNS protocols Co-authored-by: Swami Das Nampalli <[email protected]> Signed-off-by: Swami Das Nampalli <[email protected]> Signed-off-by: Rahul Gurram <[email protected]>
1 parent c261d24 commit fa2d6b6

File tree

6 files changed

+347
-0
lines changed

6 files changed

+347
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(siwx91x_sample_app)
7+
8+
target_sources(app PRIVATE src/main.c)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
.. zephyr:code-sample:: siwx91x_sample_app
2+
:name: siwx91x sample app
3+
4+
Overview
5+
********
6+
7+
A sample application that demonstrates the DNS client and ICMP functionality.
8+
This program will get the IP address of the given hostname and the ICMP will
9+
initiate a PING request to the address obtained from the DNS client.
10+
11+
Requirements
12+
************
13+
14+
* Windows PC (Remote PC).
15+
* SiWx91x Wi-Fi Evaluation Kit(SoC).
16+
17+
Configuration Parameters
18+
************************
19+
The below confgurations are available in app_config.h file
20+
21+
#define SSID "SiWx91x_AP" // Wi-Fi Network Name
22+
#define PSK "12345678" // Wi-Fi Password
23+
#define SECURITY_TYPE WIFI_SECURITY_TYPE_PSK // Wi-Fi Security Type: WIFI_SECURITY_TYPE_NONE/WIFI_SECURITY_TYPE_WPA_PSK/WIFI_SECURITY_TYPE_PSK
24+
#define CHANNEL_NO WIFI_CHANNEL_ANY // Wi-Fi channel
25+
#define HOSTNAME "www.zephyrproject.org" //Hostname to ping
26+
27+
Building and Running
28+
********************
29+
30+
* This sample can be found under :zephyr_file:`zephyr/samples/boards/siwx91x/siwx91x_sample_app` in the Zephyr tree.
31+
32+
* Build:- west build -b siwx917_rb4338a samples/boards/siwx91x/siwx91x_sample_app/ -p
33+
34+
* Flash:- west flash
35+
36+
Test the Application
37+
********************
38+
* Open any serial console to view logs.
39+
* After program gets executed, SiWx91x EVK will be connected to an Access Point with configured **SSID** and **PSK**
40+
* The device will start sending ping requests to the given hostname and the response can be seen in network_event_handler().
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CONFIG_WIFI=y
2+
CONFIG_NETWORKING=y
3+
CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_OFFLOAD=y
4+
CONFIG_NET_IPV4=y
5+
CONFIG_NET_DHCPV4=y
6+
CONFIG_NET_IPV6=n
7+
CONFIG_NET_DHCPV6=n
8+
CONFIG_MAIN_STACK_SIZE=2048
9+
CONFIG_WIFI_SILABS_SIWX91X_PING=y
10+
CONFIG_WIFI_SILABS_SIWX91X_DNS_CLIENT=y
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
sample:
2+
name: siwx91x sample app
3+
description: Demonstrates ICMP functionality
4+
tests:
5+
sample.boards.siwx91x.siwx91x_sample_app:
6+
harness: Wi-Fi
7+
platform_allow:
8+
- siwx917_rb4338a
9+
tags: Wi-Fi
10+
integration_platforms:
11+
- siwx917_rb4338a
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#ifndef _CONFIG_H_
2+
#define _CONFIG_H_
3+
4+
/* Wi-Fi Network Name */
5+
#define SSID "SiWx91x_AP"
6+
/* Wi-Fi Password */
7+
#define PSK "12345678"
8+
/* Wi-Fi Security Type:
9+
* WIFI_SECURITY_TYPE_NONE/WIFI_SECURITY_TYPE_WPA_PSK/WIFI_SECURITY_TYPE_PSK
10+
*/
11+
#define SECURITY_TYPE WIFI_SECURITY_TYPE_PSK
12+
/* Wi-Fi channel */
13+
#define CHANNEL_NO WIFI_CHANNEL_ANY
14+
#define STACK_SIZE 4096
15+
#define STATUS_OK 0
16+
#define STATUS_FAIL -1
17+
#define CMD_WAIT_TIME 180000
18+
19+
/* Hostname to ping */
20+
#define HOSTNAME "www.zephyrproject.org"
21+
#define DNS_TIMEOUT (20 * MSEC_PER_SEC)
22+
#define PING_PACKET_SIZE 64
23+
#define PING_PACKETS 30
24+
25+
static struct {
26+
const struct shell *sh;
27+
uint32_t scan_result;
28+
29+
union {
30+
struct {
31+
uint8_t connecting: 1;
32+
uint8_t disconnecting: 1;
33+
uint8_t _unused: 6;
34+
};
35+
uint8_t all;
36+
};
37+
} context;
38+
39+
#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_CONNECT_RESULT)
40+
41+
#endif /* _CONFIG_H_ */
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
/*
2+
* Copyright (c) 2012-2014 Wind River Systems, Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdio.h>
8+
#include <stdlib.h>
9+
#include <zephyr/net/wifi_mgmt.h>
10+
#include <zephyr/net/net_if.h>
11+
12+
#include "sl_net_ip_types.h"
13+
#include "sl_si91x_types.h"
14+
#include "sl_net_si91x.h"
15+
#include "sl_net_dns.h"
16+
#ifdef CONFIG_WIFI_SILABS_SIWX91X_PING
17+
#include "sl_net_ping.h"
18+
#endif
19+
#include "sl_net.h"
20+
#include "app_config.h"
21+
22+
volatile uint8_t state = 0;
23+
static K_SEM_DEFINE(wlan_sem, 0, 1);
24+
K_THREAD_STACK_DEFINE(wifi_stack, STACK_SIZE);
25+
26+
typedef enum siwx91x_app_state_e {
27+
SIWX91X_WIFI_CONNECT_STATE = 0,
28+
SIWX91X_IP_CONFIG_STATE,
29+
SIWX91X_PING_HOSTNAME_STATE
30+
} siwx91x_app_state_t;
31+
32+
void application_start(void);
33+
static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
34+
struct net_if *iface);
35+
static void handle_wifi_connect_result(struct net_mgmt_event_callback *cb);
36+
static sl_status_t network_event_handler(sl_net_event_t event, sl_status_t status, void *data,
37+
uint32_t data_length);
38+
39+
static void dhcp_callback_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
40+
struct net_if *iface)
41+
{
42+
uint8_t ipv4_addr[NET_IPV4_ADDR_LEN] = {0};
43+
uint8_t subnet[NET_IPV4_ADDR_LEN] = {0};
44+
uint8_t gateway[NET_IPV4_ADDR_LEN] = {0};
45+
int i = 0;
46+
47+
if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) {
48+
return;
49+
}
50+
51+
for (i = 0; i < ARRAY_SIZE(iface->config.ip.ipv4->unicast); i++) {
52+
53+
if (iface->config.ip.ipv4->unicast[i].ipv4.addr_type != NET_ADDR_DHCP) {
54+
continue;
55+
}
56+
57+
printf("Address[%d]: %s", net_if_get_by_iface(iface),
58+
net_addr_ntop(AF_INET,
59+
&iface->config.ip.ipv4->unicast[i].ipv4.address.in_addr,
60+
ipv4_addr, sizeof(ipv4_addr)));
61+
printf(" Subnet[%d]: %s", net_if_get_by_iface(iface),
62+
net_addr_ntop(AF_INET, &iface->config.ip.ipv4->unicast[i].netmask, subnet,
63+
sizeof(subnet)));
64+
printf(" Router[%d]: %s", net_if_get_by_iface(iface),
65+
net_addr_ntop(AF_INET, &iface->config.ip.ipv4->gw, gateway,
66+
sizeof(gateway)));
67+
68+
k_sem_give(&wlan_sem);
69+
}
70+
}
71+
72+
void application_start(void)
73+
{
74+
int32_t status = -1;
75+
uint8_t ping_count = 0;
76+
struct net_if *iface;
77+
78+
printf("\r\nApplication started\r\n");
79+
state = SIWX91X_WIFI_CONNECT_STATE;
80+
81+
while (1) {
82+
switch (state) {
83+
case SIWX91X_WIFI_CONNECT_STATE: {
84+
struct wifi_connect_req_params cnx_params;
85+
86+
iface = net_if_get_first_wifi();
87+
memset(&cnx_params, 0, sizeof(struct wifi_connect_req_params));
88+
context.connecting = true;
89+
cnx_params.channel = CHANNEL_NO;
90+
cnx_params.band = 0;
91+
cnx_params.security = SECURITY_TYPE;
92+
cnx_params.psk_length = strlen(PSK);
93+
cnx_params.psk = PSK;
94+
cnx_params.ssid_length = strlen(SSID);
95+
cnx_params.ssid = SSID;
96+
97+
status = net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &cnx_params,
98+
sizeof(struct wifi_connect_req_params));
99+
if (status != STATUS_OK) {
100+
printf("Connection request failed with error: %d\n", status);
101+
context.connecting = false;
102+
state = SIWX91X_WIFI_CONNECT_STATE;
103+
break;
104+
}
105+
printf("Connection requested\n");
106+
107+
if (k_sem_take(&wlan_sem, K_MSEC(CMD_WAIT_TIME)) != STATUS_OK) {
108+
printf("\r\nWi-Fi connect failed\r\n");
109+
state = SIWX91X_WIFI_CONNECT_STATE;
110+
}
111+
} break;
112+
case SIWX91X_IP_CONFIG_STATE: {
113+
if (k_sem_take(&wlan_sem, K_MSEC(CMD_WAIT_TIME)) != STATUS_OK) {
114+
printf("\r\nIP config failed\r\n");
115+
state = SIWX91X_IP_CONFIG_STATE;
116+
break;
117+
}
118+
state = SIWX91X_PING_HOSTNAME_STATE;
119+
} break;
120+
case SIWX91X_PING_HOSTNAME_STATE: {
121+
sl_ip_address_t dns_ip = {0};
122+
sli_net_register_event_handler(network_event_handler);
123+
dns_ip.type = SL_IPV4;
124+
status = sl_net_dns_resolve_hostname(HOSTNAME, DNS_TIMEOUT,
125+
SL_NET_DNS_TYPE_IPV4, &dns_ip);
126+
if (status != STATUS_OK) {
127+
printf("\r\nDNS Query failed:0x%x\r\n", status);
128+
break;
129+
}
130+
printf("\r\nDNS Query successful\r\n");
131+
printf("\r\nIP address = %d.%d.%d.%d\r\n", dns_ip.ip.v4.bytes[0],
132+
dns_ip.ip.v4.bytes[1], dns_ip.ip.v4.bytes[2], dns_ip.ip.v4.bytes[3]);
133+
while (ping_count < PING_PACKETS) {
134+
status = sl_si91x_send_ping(dns_ip, PING_PACKET_SIZE);
135+
if (status != SL_STATUS_IN_PROGRESS) {
136+
printf("\r\nPing request failed with status 0x%X\r\n",
137+
status);
138+
return;
139+
}
140+
ping_count++;
141+
k_sleep(K_MSEC(1000));
142+
}
143+
return;
144+
} break;
145+
}
146+
}
147+
}
148+
149+
static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
150+
struct net_if *iface)
151+
{
152+
switch (mgmt_event) {
153+
case NET_EVENT_WIFI_CONNECT_RESULT:
154+
handle_wifi_connect_result(cb);
155+
break;
156+
case NET_EVENT_WIFI_DISCONNECT_RESULT:
157+
break;
158+
default:
159+
break;
160+
}
161+
}
162+
163+
static void handle_wifi_connect_result(struct net_mgmt_event_callback *cb)
164+
{
165+
const struct wifi_status *status = (const struct wifi_status *)cb->info;
166+
int st = status->status;
167+
168+
if (st) {
169+
if (st < 0) {
170+
/* Errno values are negative, try to map to
171+
* wifi status values.
172+
*/
173+
if (st == -ETIMEDOUT) {
174+
st = WIFI_STATUS_CONN_TIMEOUT;
175+
}
176+
}
177+
178+
printf("Connection request failed (%s/%d)\n", wifi_conn_status_txt(st), st);
179+
state = SIWX91X_WIFI_CONNECT_STATE;
180+
} else {
181+
printf("Connected to Wi-Fi\n");
182+
state = SIWX91X_IP_CONFIG_STATE;
183+
}
184+
185+
context.connecting = false;
186+
k_sem_give(&wlan_sem);
187+
}
188+
189+
static sl_status_t network_event_handler(sl_net_event_t event, sl_status_t status, void *data,
190+
uint32_t data_length)
191+
{
192+
UNUSED_PARAMETER(data_length);
193+
switch (event) {
194+
case SL_NET_PING_RESPONSE_EVENT: {
195+
sl_si91x_ping_response_t *response = (sl_si91x_ping_response_t *)data;
196+
197+
if (status != SL_STATUS_OK) {
198+
printf("\r\nPing request failed!\r\n");
199+
return status;
200+
}
201+
printf("\n%u bytes received from %u.%u.%u.%u\n", response->ping_size,
202+
response->ping_address.ipv4_address[0],
203+
response->ping_address.ipv4_address[1],
204+
response->ping_address.ipv4_address[2],
205+
response->ping_address.ipv4_address[3]);
206+
break;
207+
}
208+
default:
209+
break;
210+
}
211+
212+
return SL_STATUS_OK;
213+
}
214+
215+
int main(void)
216+
{
217+
struct net_mgmt_event_callback wifi_mgmt_cb;
218+
struct net_mgmt_event_callback mgmt_cb;
219+
struct k_thread wifi_task_handle;
220+
221+
printf("siwx91x sample application for ICMP\r\n");
222+
net_mgmt_init_event_callback(&wifi_mgmt_cb, wifi_mgmt_event_handler,
223+
(WIFI_SHELL_MGMT_EVENTS));
224+
net_mgmt_add_event_callback(&wifi_mgmt_cb);
225+
net_mgmt_init_event_callback(&mgmt_cb, dhcp_callback_handler, NET_EVENT_IPV4_ADDR_ADD);
226+
227+
net_mgmt_add_event_callback(&mgmt_cb);
228+
229+
k_tid_t application_tid = k_thread_create(&wifi_task_handle, wifi_stack, STACK_SIZE,
230+
(k_thread_entry_t)application_start, NULL, NULL,
231+
NULL, K_PRIO_PREEMPT(10), 0, K_NO_WAIT);
232+
233+
k_thread_start(application_tid);
234+
k_thread_join(application_tid, K_FOREVER);
235+
printf("\r\nApplication exit\r\n");
236+
return 0;
237+
}

0 commit comments

Comments
 (0)