Skip to content

Commit 623719a

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 <swami.das@silabs.com> Signed-off-by: Swami Das Nampalli <swami.das@silabs.com> Signed-off-by: Rahul Gurram <rahul.gurram@silabs.com>
1 parent 1ea219f commit 623719a

File tree

6 files changed

+348
-0
lines changed

6 files changed

+348
-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: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
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+
123+
sli_net_register_event_handler(network_event_handler);
124+
dns_ip.type = SL_IPV4;
125+
status = sl_net_dns_resolve_hostname(HOSTNAME, DNS_TIMEOUT,
126+
SL_NET_DNS_TYPE_IPV4, &dns_ip);
127+
if (status != STATUS_OK) {
128+
printf("\r\nDNS Query failed:0x%x\r\n", status);
129+
break;
130+
}
131+
printf("\r\nDNS Query successful\r\n");
132+
printf("\r\nIP address = %d.%d.%d.%d\r\n", dns_ip.ip.v4.bytes[0],
133+
dns_ip.ip.v4.bytes[1], dns_ip.ip.v4.bytes[2], dns_ip.ip.v4.bytes[3]);
134+
while (ping_count < PING_PACKETS) {
135+
status = sl_si91x_send_ping(dns_ip, PING_PACKET_SIZE);
136+
if (status != SL_STATUS_IN_PROGRESS) {
137+
printf("\r\nPing request failed with status 0x%X\r\n",
138+
status);
139+
return;
140+
}
141+
ping_count++;
142+
k_sleep(K_MSEC(1000));
143+
}
144+
return;
145+
} break;
146+
}
147+
}
148+
}
149+
150+
static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
151+
struct net_if *iface)
152+
{
153+
switch (mgmt_event) {
154+
case NET_EVENT_WIFI_CONNECT_RESULT:
155+
handle_wifi_connect_result(cb);
156+
break;
157+
case NET_EVENT_WIFI_DISCONNECT_RESULT:
158+
break;
159+
default:
160+
break;
161+
}
162+
}
163+
164+
static void handle_wifi_connect_result(struct net_mgmt_event_callback *cb)
165+
{
166+
const struct wifi_status *status = (const struct wifi_status *)cb->info;
167+
int st = status->status;
168+
169+
if (st) {
170+
if (st < 0) {
171+
/* Errno values are negative, try to map to
172+
* wifi status values.
173+
*/
174+
if (st == -ETIMEDOUT) {
175+
st = WIFI_STATUS_CONN_TIMEOUT;
176+
}
177+
}
178+
179+
printf("Connection request failed (%s/%d)\n", wifi_conn_status_txt(st), st);
180+
state = SIWX91X_WIFI_CONNECT_STATE;
181+
} else {
182+
printf("Connected to Wi-Fi\n");
183+
state = SIWX91X_IP_CONFIG_STATE;
184+
}
185+
186+
context.connecting = false;
187+
k_sem_give(&wlan_sem);
188+
}
189+
190+
static sl_status_t network_event_handler(sl_net_event_t event, sl_status_t status, void *data,
191+
uint32_t data_length)
192+
{
193+
UNUSED_PARAMETER(data_length);
194+
switch (event) {
195+
case SL_NET_PING_RESPONSE_EVENT: {
196+
sl_si91x_ping_response_t *response = (sl_si91x_ping_response_t *)data;
197+
198+
if (status != SL_STATUS_OK) {
199+
printf("\r\nPing request failed!\r\n");
200+
return status;
201+
}
202+
printf("\n%u bytes received from %u.%u.%u.%u\n", response->ping_size,
203+
response->ping_address.ipv4_address[0],
204+
response->ping_address.ipv4_address[1],
205+
response->ping_address.ipv4_address[2],
206+
response->ping_address.ipv4_address[3]);
207+
break;
208+
}
209+
default:
210+
break;
211+
}
212+
213+
return SL_STATUS_OK;
214+
}
215+
216+
int main(void)
217+
{
218+
struct net_mgmt_event_callback wifi_mgmt_cb;
219+
struct net_mgmt_event_callback mgmt_cb;
220+
struct k_thread wifi_task_handle;
221+
222+
printf("siwx91x sample application for ICMP\r\n");
223+
net_mgmt_init_event_callback(&wifi_mgmt_cb, wifi_mgmt_event_handler,
224+
(WIFI_SHELL_MGMT_EVENTS));
225+
net_mgmt_add_event_callback(&wifi_mgmt_cb);
226+
net_mgmt_init_event_callback(&mgmt_cb, dhcp_callback_handler, NET_EVENT_IPV4_ADDR_ADD);
227+
228+
net_mgmt_add_event_callback(&mgmt_cb);
229+
230+
k_tid_t application_tid = k_thread_create(&wifi_task_handle, wifi_stack, STACK_SIZE,
231+
(k_thread_entry_t)application_start, NULL, NULL,
232+
NULL, K_PRIO_PREEMPT(10), 0, K_NO_WAIT);
233+
234+
k_thread_start(application_tid);
235+
k_thread_join(application_tid, K_FOREVER);
236+
printf("\r\nApplication exit\r\n");
237+
return 0;
238+
}

0 commit comments

Comments
 (0)