1.参考官方例程:examples\protocols\static_ip
void wifi_init_sta(void)
{
s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
sta_netif,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
sta_netif,
&instance_got_ip));
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
/* Setting a password implies station will connect to all security modes including WEP/WPA.
* However these modes are deprecated and not advisable to be used. Incase your Access point
* doesn't support WPA2, these mode can be enabled by commenting below line */
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_LOGI(TAG, "wifi_init_sta finished.");
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
EXAMPLE_WIFI_SSID, EXAMPLE_WIFI_PASS);
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
EXAMPLE_WIFI_SSID, EXAMPLE_WIFI_PASS);
} else {
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
#ifdef CONFIG_EXAMPLE_STATIC_DNS_RESOLVE_TEST
struct addrinfo *address_info;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int res = getaddrinfo(EXAMPLE_RESOLVE_DOMAIN, NULL, &hints, &address_info);
if (res != 0 || address_info == NULL) {
ESP_LOGE(TAG, "couldn't get hostname for :%s: "
"getaddrinfo() returns %d, addrinfo=%p", EXAMPLE_RESOLVE_DOMAIN, res, address_info);
} else {
if (address_info->ai_family == AF_INET) {
struct sockaddr_in *p = (struct sockaddr_in *)address_info->ai_addr;
ESP_LOGI(TAG, "Resolved IPv4 address: %s", ipaddr_ntoa((const ip_addr_t*)&p->sin_addr.s_addr));
}
#if CONFIG_LWIP_IPV6
else if (address_info->ai_family == AF_INET6) {
struct sockaddr_in6 *p = (struct sockaddr_in6 *)address_info->ai_addr;
ESP_LOGI(TAG, "Resolved IPv6 address: %s", ip6addr_ntoa((const ip6_addr_t*)&p->sin6_addr));
}
#endif
}
#endif
/* The event will not be processed after unregister */
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
vEventGroupDelete(s_wifi_event_group);
}
2.对比动态ip获取的关键点,网络参数结构体指针的传递
2.1动态获取ip的例程中,没有传递指针
2.2注册的回调函数中,添加多一次判断
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
example_set_static_ip(arg);
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < EXAMPLE_MAXIMUM_RETRY) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
} else {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
ESP_LOGI(TAG,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "static ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
3.实际操作流程
3.1以station例程为模板,定义网络参数结构体指针,获取指针地址,作为参数传入回调函数
3.2在回调函数中,加入静态ip设置,先停止DHCP,再设置
3.3复制静态设置函数
static esp_err_t example_set_dns_server(esp_netif_t *netif, uint32_t addr, esp_netif_dns_type_t type)
{
if (addr && (addr != IPADDR_NONE))
{
esp_netif_dns_info_t dns;
dns.ip.u_addr.ip4.addr = addr;
dns.ip.type = IPADDR_TYPE_V4;
ESP_ERROR_CHECK(esp_netif_set_dns_info(netif, type, &dns));
}
return ESP_OK;
}
static void example_set_static_ip(esp_netif_t *netif)
{
ESP_LOGE(TAG, "example_set_static_ip");
if (esp_netif_dhcpc_stop(netif) != ESP_OK)
{
ESP_LOGE(TAG, "Failed to stop dhcp client");
return;
}
esp_netif_ip_info_t ip;
memset(&ip, 0, sizeof(esp_netif_ip_info_t));
ip.ip.addr = ipaddr_addr("192.168.3.22");
ip.netmask.addr = ipaddr_addr("255.255.255.0");
ip.gw.addr = ipaddr_addr("192.168.3.1");
if (esp_netif_set_ip_info(netif, &ip) != ESP_OK)
{
ESP_LOGE(TAG, "Failed to set ip info");
return;
}
//ESP_LOGD(TAG, "Success to set static ip: %s, netmask: %s, gw: %s", EXAMPLE_STATIC_IP_ADDR, EXAMPLE_STATIC_NETMASK_ADDR, EXAMPLE_STATIC_GW_ADDR);
//ESP_ERROR_CHECK(example_set_dns_server(netif, ipaddr_addr(EXAMPLE_MAIN_DNS_SERVER), ESP_NETIF_DNS_MAIN));
//ESP_ERROR_CHECK(example_set_dns_server(netif, ipaddr_addr(EXAMPLE_BACKUP_DNS_SERVER), ESP_NETIF_DNS_BACKUP));
}