add basic wifi with station and AP modes
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									f3762ff598
								
							
						
					
					
						commit
						2a55d69ac4
					
				
					 3 changed files with 365 additions and 4 deletions
				
			
		|  | @ -1,13 +1,15 @@ | |||
| #include <espressif/esp_common.h> | ||||
| #include <esp/uart.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "system.h" | ||||
| #include "wifi.h" | ||||
| #include "web.h" | ||||
| #include "mqtt.h" | ||||
| #include "lux.h" | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <FreeRTOS.h> | ||||
| #include <task.h> | ||||
| 
 | ||||
| #include <espressif/esp_common.h> | ||||
| #include <esp/uart.h> | ||||
| 
 | ||||
| void user_init(void) | ||||
| { | ||||
|  | @ -17,4 +19,7 @@ void user_init(void) | |||
|     sdk_wifi_set_sleep_type(WIFI_SLEEP_MODEM); | ||||
| 
 | ||||
|     system_init_config(); | ||||
| 
 | ||||
|     xTaskCreate(wifi_task, "wifi_task", 512, NULL, 2, NULL); | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -3,3 +3,357 @@ | |||
| //
 | ||||
| 
 | ||||
| #include "wifi.h" | ||||
| 
 | ||||
| #include <cstdlib> | ||||
| #include <cstring> | ||||
| #include <FreeRTOS.h> | ||||
| #include <task.h> | ||||
| #include <sockets.h> | ||||
| 
 | ||||
| extern "C" { | ||||
| #include <sysparam.h> | ||||
| #include <lwipopts.h> | ||||
| #include <espressif/user_interface.h> | ||||
| } | ||||
| 
 | ||||
| #include <espressif/esp_wifi.h> | ||||
| #include <espressif/esp_sta.h> | ||||
| #include <espressif/esp_softap.h> | ||||
| #include <dhcpserver.h> | ||||
| 
 | ||||
| const char *wificfg_default_ssid = "fiatlux_%02X%02X%02X"; | ||||
| const char *wificfg_default_password = "fiatlux02"; | ||||
| const char *wificfg_default_hostname = "fiatlux-%02x%02x%02x"; | ||||
| 
 | ||||
| char *wifi_sta_ssid = nullptr; | ||||
| char *wifi_sta_password = nullptr; | ||||
| char *wifi_ap_ssid = nullptr; | ||||
| char *wifi_ap_password = nullptr; | ||||
| 
 | ||||
| 
 | ||||
| [[noreturn]] static void dns_task(void *pvParameters) { | ||||
|     char *wifi_ap_ip_addr = nullptr; | ||||
|     sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); | ||||
|     if(!wifi_ap_ip_addr) { | ||||
|         printf("dns: no ip address\n"); | ||||
|         vTaskDelete(nullptr); | ||||
|     } | ||||
|     ip4_addr_t server_addr; | ||||
|     server_addr.addr = ipaddr_addr(wifi_ap_ip_addr); | ||||
| 
 | ||||
| #if LWIP_IPV6 | ||||
|     int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); | ||||
|     sockaddr_in6 serv_addr; | ||||
|     memset(&serv_addr, '0', sizeof(serv_addr)); | ||||
|     serv_addr.sin6_family = AF_INET6; | ||||
|     serv_addr.sin6_port = htons(53); | ||||
|     serv_addr.sin6_flowinfo = 0; | ||||
|     serv_addr.sin6_addr = in6addr_any; | ||||
|     serv_addr.sin6_scope_id = IP6_NO_ZONE; | ||||
| #else | ||||
|     int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||||
|     sockaddr_in serv_addr; | ||||
|     memset(&serv_addr, '0', sizeof(serv_addr)); | ||||
|     serv_addr.sin_family = AF_INET; | ||||
|     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
|     serv_addr.sin_port = htons(53); | ||||
| #endif | ||||
|     bind(fd, (sockaddr *) &serv_addr, sizeof(serv_addr)); | ||||
| 
 | ||||
|     const ifreq ifreq0 = {"en0"}; | ||||
|     const ifreq ifreq1 = {"en1"}; | ||||
|     setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, | ||||
|                sdk_wifi_get_opmode() == STATIONAP_MODE ? &ifreq1 : &ifreq0, | ||||
|                sizeof(ifreq0)); | ||||
| 
 | ||||
|     for (;;) { | ||||
|         uint8_t buffer[96]; | ||||
|         sockaddr_storage src_addr; | ||||
|         socklen_t src_addr_len = sizeof(src_addr); | ||||
|         ssize_t count = recvfrom(fd, buffer, sizeof(buffer), 0, (sockaddr *) &src_addr, &src_addr_len); | ||||
| 
 | ||||
|         /* Drop messages that are too large to send a response in the buffer */ | ||||
|         if(count > 0 && count + 16 <= (ssize_t) sizeof(buffer)) { | ||||
|             size_t qname_len = strlen((const char *) (buffer + 12)) + 1; | ||||
|             uint32_t reply_len = 2 + 10 + qname_len + 16 + 4; | ||||
| 
 | ||||
|             uint8_t *head = buffer + 2; | ||||
|             *head++ = 0x80; // Flags
 | ||||
|             *head++ = 0x00; | ||||
|             *head++ = 0x00; // Q count
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // A count
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // Auth count
 | ||||
|             *head++ = 0x00; | ||||
|             *head++ = 0x00; // Add count
 | ||||
|             *head++ = 0x00; | ||||
|             head += qname_len; | ||||
|             *head++ = 0x00; // Q type
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // Q class
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0xC0; // LBL offs
 | ||||
|             *head++ = 0x0C; | ||||
|             *head++ = 0x00; // Type
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // Class
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // TTL
 | ||||
|             *head++ = 0x00; | ||||
|             *head++ = 0x00; | ||||
|             *head++ = 0x78; | ||||
|             *head++ = 0x00; // RD len
 | ||||
|             *head++ = 0x04; | ||||
|             *head++ = ip4_addr1(&server_addr); | ||||
|             *head++ = ip4_addr2(&server_addr); | ||||
|             *head++ = ip4_addr3(&server_addr); | ||||
|             *head++ = ip4_addr4(&server_addr); | ||||
| 
 | ||||
|             sendto(fd, buffer, reply_len, 0, (sockaddr *) &src_addr, src_addr_len); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| extern "C" [[noreturn]] void wifi_task(void *pvParameters) { | ||||
|     (void) pvParameters; | ||||
|     /* Default a hostname. */ | ||||
|     char *hostname = nullptr; | ||||
|     sysparam_get_string("hostname", &hostname); | ||||
|     if(!hostname && wificfg_default_hostname) { | ||||
|         uint8_t macaddr[6]; | ||||
|         char name[32]; | ||||
|         sdk_wifi_get_macaddr(1, macaddr); | ||||
|         snprintf(name, sizeof(name), wificfg_default_hostname, macaddr[3], | ||||
|                  macaddr[4], macaddr[5]); | ||||
|         sysparam_set_string("hostname", name); | ||||
|     } | ||||
|     if(hostname) { | ||||
|         free(hostname); | ||||
|     } | ||||
| 
 | ||||
|     sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid); | ||||
|     sysparam_get_string("wifi_ap_password", &wifi_ap_password); | ||||
|     sysparam_get_string("wifi_sta_ssid", &wifi_sta_ssid); | ||||
|     sysparam_get_string("wifi_sta_password", &wifi_sta_password); | ||||
| 
 | ||||
|     int8_t wifi_sta_enable = 1; | ||||
|     int8_t wifi_ap_enable = 1; | ||||
|     sysparam_get_int8("wifi_sta_enable", &wifi_sta_enable); | ||||
|     sysparam_get_int8("wifi_ap_enable", &wifi_ap_enable); | ||||
| 
 | ||||
|     if(!wifi_sta_enable) | ||||
|         wifi_ap_enable = 1; | ||||
| 
 | ||||
|     int8_t wifi_sta_disabled_restarts = 0; | ||||
|     sysparam_get_int8("wifi_sta_disabled_restarts", &wifi_sta_disabled_restarts); | ||||
|     if(wifi_sta_disabled_restarts > 0) { | ||||
|         wifi_sta_enable = 0; | ||||
|         wifi_sta_disabled_restarts--; | ||||
|         sysparam_set_int8("wifi_sta_disabled_restarts", wifi_sta_disabled_restarts); | ||||
|     } | ||||
| 
 | ||||
|     int8_t wifi_ap_disabled_restarts = 0; | ||||
|     sysparam_get_int8("wifi_ap_disabled_restarts", &wifi_ap_disabled_restarts); | ||||
|     if(wifi_ap_disabled_restarts > 0) { | ||||
|         wifi_ap_enable = 0; | ||||
|         wifi_ap_disabled_restarts--; | ||||
|         sysparam_set_int8("wifi_ap_disabled_restarts", wifi_ap_disabled_restarts); | ||||
|     } | ||||
| 
 | ||||
|     /* Validate the configuration. */ | ||||
| 
 | ||||
|     if(wifi_sta_enable && (!wifi_sta_ssid || !wifi_sta_password || | ||||
|                            strlen(wifi_sta_ssid) < 1 || | ||||
|                            strlen(wifi_sta_ssid) > 32 || | ||||
|                            !wifi_sta_password || | ||||
|                            strlen(wifi_sta_password) < 8 || | ||||
|                            strlen(wifi_sta_password) >= 64)) { | ||||
|         wifi_sta_enable = 0; | ||||
|     } | ||||
| 
 | ||||
|     if(wifi_ap_enable) { | ||||
|         /* Default AP ssid and password. */ | ||||
|         if(!wifi_ap_ssid && wificfg_default_ssid) { | ||||
|             uint8_t macaddr[6]; | ||||
|             char ssid[32]; | ||||
|             sdk_wifi_get_macaddr(1, macaddr); | ||||
|             snprintf(ssid, sizeof(ssid), wificfg_default_ssid, macaddr[3], | ||||
|                      macaddr[4], macaddr[5]); | ||||
|             sysparam_set_string("wifi_ap_ssid", ssid); | ||||
|             sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid); | ||||
| 
 | ||||
|             if(!wifi_ap_password && wificfg_default_password) { | ||||
|                 sysparam_set_string("wifi_ap_password", wificfg_default_password); | ||||
|                 sysparam_get_string("wifi_ap_password", &wifi_ap_password); | ||||
|             } | ||||
|         } | ||||
|         printf("ssid: %s\n", wifi_ap_ssid); | ||||
| 
 | ||||
|         /* If the ssid and password are not valid then disable the AP interface. */ | ||||
|         if(!wifi_ap_ssid || strlen(wifi_ap_ssid) < 1 || strlen(wifi_ap_ssid) >= 32 || | ||||
|            !wifi_ap_password || strlen(wifi_ap_password) < 8 || strlen(wifi_ap_password) >= 64) { | ||||
|             printf("len err\n"); | ||||
|             wifi_ap_enable = 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     int8_t wifi_mode = NULL_MODE; | ||||
|     if(wifi_sta_enable && wifi_ap_enable) | ||||
|         wifi_mode = STATIONAP_MODE; | ||||
|     else if(wifi_sta_enable) | ||||
|         wifi_mode = STATION_MODE; | ||||
|     else if(wifi_ap_enable) | ||||
|         wifi_mode = SOFTAP_MODE; | ||||
|     sdk_wifi_set_opmode(wifi_mode); | ||||
| 
 | ||||
|     if(wifi_sta_enable) { | ||||
|         printf("try STA Mode: %s %s\n", wifi_sta_ssid, wifi_sta_password); | ||||
|         sdk_station_config config; | ||||
|         strcpy((char *) config.ssid, wifi_sta_ssid); | ||||
|         strcpy((char *) config.password, wifi_sta_password); | ||||
|         config.bssid_set = 0; | ||||
| 
 | ||||
|         int8_t wifi_sta_dhcp = 1; | ||||
|         sysparam_get_int8("wifi_sta_dhcp", &wifi_sta_dhcp); | ||||
| 
 | ||||
|         if(!wifi_sta_dhcp) { | ||||
|             char *wifi_sta_ip_addr = nullptr; | ||||
|             char *wifi_sta_netmask = nullptr; | ||||
|             char *wifi_sta_gateway = nullptr; | ||||
|             sysparam_get_string("wifi_sta_ip_addr", &wifi_sta_ip_addr); | ||||
|             sysparam_get_string("wifi_sta_netmask", &wifi_sta_netmask); | ||||
|             sysparam_get_string("wifi_sta_gateway", &wifi_sta_gateway); | ||||
| 
 | ||||
|             if(wifi_sta_ip_addr && strlen(wifi_sta_ip_addr) > 4 && | ||||
|                wifi_sta_netmask && strlen(wifi_sta_netmask) > 4 && | ||||
|                wifi_sta_gateway && strlen(wifi_sta_gateway) > 4) { | ||||
|                 sdk_wifi_station_dhcpc_stop(); | ||||
|                 ip_info info; | ||||
|                 memset(&info, 0x0, sizeof(info)); | ||||
|                 info.ip.addr = ipaddr_addr(wifi_sta_ip_addr); | ||||
|                 info.netmask.addr = ipaddr_addr(wifi_sta_netmask); | ||||
|                 info.gw.addr = ipaddr_addr(wifi_sta_gateway); | ||||
|                 sdk_wifi_set_ip_info(STATION_IF, &info); | ||||
|             } | ||||
|             if(wifi_sta_ip_addr) free(wifi_sta_ip_addr); | ||||
|             if(wifi_sta_netmask) free(wifi_sta_netmask); | ||||
|             if(wifi_sta_gateway) free(wifi_sta_gateway); | ||||
|         } | ||||
| 
 | ||||
|         sdk_wifi_station_set_config(&config); | ||||
|     } | ||||
| 
 | ||||
|     if(wifi_ap_enable) { | ||||
|         printf("try AP Mode: %s %s\n", wifi_ap_ssid, wifi_ap_password); | ||||
| /* Read and validate paramenters. */ | ||||
|         int8_t wifi_ap_ssid_hidden = 0; | ||||
|         sysparam_get_int8("wifi_ap_ssid_hidden", &wifi_ap_ssid_hidden); | ||||
|         if(wifi_ap_ssid_hidden < 0 || wifi_ap_ssid_hidden > 1) { | ||||
|             wifi_ap_ssid_hidden = 1; | ||||
|         } | ||||
| 
 | ||||
|         int8_t wifi_ap_channel = 6; | ||||
|         sysparam_get_int8("wifi_ap_channel", &wifi_ap_channel); | ||||
| 
 | ||||
| #if 0 | ||||
|         /* AU does not allow channels above 13, although 14 works. */ | ||||
|         if(wifi_ap_channel > 13) { | ||||
|             wifi_ap_channel = 13; | ||||
|         } | ||||
|         /* US does not allow channels above 11, although they work. */ | ||||
|         if (wifi_ap_channel > 11) { | ||||
|             wifi_ap_channel = 11; | ||||
|         } | ||||
| #endif | ||||
|         if(wifi_ap_channel < 1 || wifi_ap_channel > 14) { | ||||
|             wifi_ap_channel = 6; | ||||
|         } | ||||
| 
 | ||||
|         int8_t wifi_ap_authmode = AUTH_WPA_WPA2_PSK; | ||||
|         sysparam_get_int8("wifi_ap_authmode", &wifi_ap_authmode); | ||||
|         if(wifi_ap_authmode != AUTH_OPEN && wifi_ap_authmode != AUTH_WPA_PSK && | ||||
|            wifi_ap_authmode != AUTH_WPA2_PSK && wifi_ap_authmode != AUTH_WPA_WPA2_PSK) { | ||||
|             wifi_ap_authmode = AUTH_WPA_WPA2_PSK; | ||||
|         } | ||||
| 
 | ||||
|         int8_t wifi_ap_max_conn = 3; | ||||
|         sysparam_get_int8("wifi_ap_max_conn", &wifi_ap_max_conn); | ||||
|         if(wifi_ap_max_conn < 1 || wifi_ap_max_conn > 8) { | ||||
|             wifi_ap_max_conn = 3; | ||||
|         } | ||||
| 
 | ||||
|         int32_t wifi_ap_beacon_interval = 100; | ||||
|         sysparam_get_int32("wifi_ap_beacon_interval", &wifi_ap_beacon_interval); | ||||
|         if(wifi_ap_beacon_interval < 0 || wifi_ap_beacon_interval > 1000) { | ||||
|             wifi_ap_beacon_interval = 100; | ||||
|         } | ||||
| 
 | ||||
|         /* Default AP IP address and netmask. */ | ||||
|         char *wifi_ap_ip_addr = nullptr; | ||||
|         sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); | ||||
|         if(!wifi_ap_ip_addr) { | ||||
|             sysparam_set_string("wifi_ap_ip_addr", "172.16.0.1"); | ||||
|             sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); | ||||
|         } | ||||
|         char *wifi_ap_netmask = nullptr; | ||||
|         sysparam_get_string("wifi_ap_netmask", &wifi_ap_netmask); | ||||
|         if(!wifi_ap_netmask) { | ||||
|             sysparam_set_string("wifi_ap_netmask", "255.255.0.0"); | ||||
|             sysparam_get_string("wifi_ap_netmask", &wifi_ap_netmask); | ||||
|         } | ||||
| 
 | ||||
|         if(strlen(wifi_ap_ip_addr) >= 7 && strlen(wifi_ap_netmask) >= 7) { | ||||
|             ip_info ap_ip; | ||||
|             ap_ip.ip.addr = ipaddr_addr(wifi_ap_ip_addr); | ||||
|             ap_ip.netmask.addr = ipaddr_addr(wifi_ap_netmask); | ||||
|             IP4_ADDR(&ap_ip.gw, 0, 0, 0, 0); | ||||
|             sdk_wifi_set_ip_info(1, &ap_ip); | ||||
| 
 | ||||
|             sdk_softap_config ap_config; | ||||
|             strcpy((char *) ap_config.ssid, wifi_ap_ssid); | ||||
|             ap_config.ssid_len = strlen(wifi_ap_ssid); | ||||
|             strcpy((char *) ap_config.password, wifi_ap_password); | ||||
|             ap_config.channel = static_cast<uint8_t>(wifi_ap_channel); | ||||
|             ap_config.authmode = static_cast<AUTH_MODE>(wifi_ap_authmode); | ||||
|             ap_config.ssid_hidden = static_cast<uint8_t>(wifi_ap_ssid_hidden); | ||||
|             ap_config.max_connection = static_cast<uint8_t>(wifi_ap_max_conn); | ||||
|             ap_config.beacon_interval = static_cast<uint16_t>(wifi_ap_beacon_interval); | ||||
| 
 | ||||
|             sdk_wifi_softap_set_config(&ap_config); | ||||
| 
 | ||||
|             int8_t wifi_ap_dhcp_leases = 4; | ||||
|             sysparam_get_int8("wifi_ap_dhcp_leases", &wifi_ap_dhcp_leases); | ||||
| 
 | ||||
|             if(wifi_ap_dhcp_leases) { | ||||
|                 ip4_addr_t first_client_ip; | ||||
|                 first_client_ip.addr = ap_ip.ip.addr + htonl(1); | ||||
| 
 | ||||
|                 int8_t wifi_ap_dns = 1; | ||||
|                 sysparam_get_int8("wifi_ap_dns", &wifi_ap_dns); | ||||
|                 if(wifi_ap_dns < 0 || wifi_ap_dns > 1) | ||||
|                     wifi_ap_dns = 1; | ||||
| 
 | ||||
|                 dhcpserver_start(&first_client_ip, wifi_ap_dhcp_leases); | ||||
|                 dhcpserver_set_router(&ap_ip.ip); | ||||
|                 if(wifi_ap_dns) { | ||||
|                     dhcpserver_set_dns(&ap_ip.ip); | ||||
|                     xTaskCreate(dns_task, "dns_task", 384, nullptr, 2, nullptr); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         free(wifi_ap_ip_addr); | ||||
|         free(wifi_ap_netmask); | ||||
|     } | ||||
| 
 | ||||
|     if(wifi_sta_ssid) free(wifi_sta_ssid); | ||||
|     if(wifi_sta_password) free(wifi_sta_password); | ||||
|     if(wifi_ap_ssid) free(wifi_ap_ssid); | ||||
|     if(wifi_ap_password) free(wifi_ap_password); | ||||
| 
 | ||||
|     while (1) { | ||||
|         //monitor connection here
 | ||||
|         vTaskDelay(5000); | ||||
|     } | ||||
| } | ||||
|  | @ -9,6 +9,8 @@ | |||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| void wifi_task(void *pvParameters); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue