379 lines
14 KiB
C
379 lines
14 KiB
C
/*
|
|
* ESPRSSIF MIT License
|
|
*
|
|
* Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
|
*
|
|
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
|
|
* it is free of charge, to any person obtaining a copy of this software and associated
|
|
* documentation files (the "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
|
|
* to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all copies or
|
|
* substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
#include "esp_common.h"
|
|
#include "espconn.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
#include "soft_ap.h"
|
|
#include "log.h"
|
|
#include "user_main.h"
|
|
#include "sniffer.h"
|
|
#include "cfg.h"
|
|
|
|
static int g_isNetReady = FALSE;
|
|
#if 0
|
|
#define DEMO_AP_SSID "WT_TEST"
|
|
#define DEMO_AP_PASSWORD "1234567abc"
|
|
#define SOFT_AP_SSID "DEMO_AP"
|
|
#define SOFT_AP_PASSWORD "12345678"
|
|
|
|
void wifi_handle_event_cb(System_Event_t *evt)
|
|
{
|
|
printf("event %x\n", evt->event_id);
|
|
|
|
switch (evt->event_id) {
|
|
case EVENT_STAMODE_CONNECTED:
|
|
printf("connect to ssid %s, channel %d\n", evt->event_info.connected.ssid,
|
|
evt->event_info.connected.channel);
|
|
break;
|
|
case EVENT_STAMODE_DISCONNECTED:
|
|
printf("disconnect from ssid %s, reason %d\n", evt->event_info.disconnected.ssid,
|
|
evt->event_info.disconnected.reason);
|
|
break;
|
|
case EVENT_STAMODE_AUTHMODE_CHANGE:
|
|
printf("mode: %d -> %d\n", evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode);
|
|
break;
|
|
case EVENT_STAMODE_GOT_IP:
|
|
printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR, IP2STR(&evt->event_info.got_ip.ip),
|
|
IP2STR(&evt->event_info.got_ip.mask), IP2STR(&evt->event_info.got_ip.gw));
|
|
printf("\n");
|
|
break;
|
|
case EVENT_SOFTAPMODE_STACONNECTED:
|
|
printf("station: " MACSTR "join, AID = %d\n", MAC2STR(evt->event_info.sta_connected.mac),
|
|
evt->event_info.sta_connected.aid);
|
|
break;
|
|
case EVENT_SOFTAPMODE_STADISCONNECTED:
|
|
printf("station: " MACSTR "leave, AID = %d\n", MAC2STR(evt->event_info.sta_disconnected.mac),
|
|
evt->event_info.sta_disconnected.aid);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void conn_ap_init(void)
|
|
{
|
|
wifi_set_opmode(STATIONAP_MODE);
|
|
struct station_config config;
|
|
memset(&config,0,sizeof(config)); //set value of config from address of &config to width of size to be value '0'
|
|
sprintf(config.ssid, DEMO_AP_SSID);
|
|
sprintf(config.password, DEMO_AP_PASSWORD);
|
|
wifi_station_set_config(&config);
|
|
wifi_set_event_handler_cb(wifi_handle_event_cb);
|
|
wifi_station_connect();
|
|
}
|
|
#endif
|
|
|
|
void wifi_event_handler_cb(System_Event_t *evt)
|
|
{
|
|
if (evt == NULL) {
|
|
return;
|
|
}
|
|
|
|
//LOG_EX(LOG_Debug, "WIFI event = %d\n", evt->event_id);
|
|
|
|
switch (evt->event_id) {
|
|
case EVENT_STAMODE_CONNECTED:
|
|
LOG_EX(LOG_Debug, "connect to ssid %s, channel %d\n", evt->event_info.connected.ssid,
|
|
evt->event_info.connected.channel);
|
|
break;
|
|
case EVENT_STAMODE_DISCONNECTED:
|
|
LOG_EX(LOG_Debug, "disconnect from ssid %s, reason %d\n", evt->event_info.disconnected.ssid,
|
|
evt->event_info.disconnected.reason);
|
|
g_isNetReady = FALSE;
|
|
wifi_station_connect();
|
|
break;
|
|
case EVENT_STAMODE_AUTHMODE_CHANGE:
|
|
LOG_EX(LOG_Debug, "mode: %d -> %d\n", evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode);
|
|
break;
|
|
case EVENT_STAMODE_GOT_IP:
|
|
LOG_EX(LOG_Debug, "ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR, IP2STR(&evt->event_info.got_ip.ip),
|
|
IP2STR(&evt->event_info.got_ip.mask), IP2STR(&evt->event_info.got_ip.gw));
|
|
//init_sntp();
|
|
g_isNetReady = TRUE;
|
|
break;
|
|
case EVENT_SOFTAPMODE_STACONNECTED:
|
|
LOG_EX(LOG_Debug, "station: " MACSTR "join, AID = %d\n", MAC2STR(evt->event_info.sta_connected.mac),
|
|
evt->event_info.sta_connected.aid);
|
|
break;
|
|
case EVENT_SOFTAPMODE_STADISCONNECTED:
|
|
LOG_EX(LOG_Debug, "station: " MACSTR "leave, AID = %d\n", MAC2STR(evt->event_info.sta_disconnected.mac),
|
|
evt->event_info.sta_disconnected.aid);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
os_timer_t channel_timer;
|
|
uint8 current_channel;
|
|
uint16 channel_bits;
|
|
os_timer_t check_sniffer;
|
|
os_timer_t check_sniffer_2;
|
|
|
|
SLIST_HEAD(router_info_head, router_info) router_list;
|
|
|
|
void ICACHE_FLASH_ATTR
|
|
sniffer_wifi_promiscuous_rx(uint8 *buf, uint16 buf_len)
|
|
{
|
|
uint8 *data;
|
|
uint16 i;
|
|
uint16 len;
|
|
uint16 cnt = 0;
|
|
|
|
if (buf_len == sizeof(struct RxControl)) {
|
|
struct RxControl * rxCtrl = (struct RxControl *) buf;
|
|
os_printf("[%sM%d%s] rssi%d, len%d\n", rxCtrl->CWB ? "H4" : "H2", rxCtrl->MCS, rxCtrl->FEC_CODING ? "L " : "",
|
|
rxCtrl->rssi, rxCtrl->HT_length);
|
|
return;
|
|
} else if (buf_len == sizeof(struct sniffer_buf2)) {
|
|
return; //manage pack
|
|
} else {
|
|
struct router_info *info = NULL;
|
|
struct sniffer_buf * sniffer = (struct sniffer_buf *) buf;
|
|
data = buf + sizeof(struct RxControl);
|
|
|
|
SLIST_FOREACH(info, &router_list, next)
|
|
{
|
|
if ((data[1] & 0x01) == 0x01) { // just toDS
|
|
if (memcmp(info->bssid, data + 4, 6) == 0) {
|
|
if (current_channel - 1 != info->channel) { // check channel
|
|
return;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (info == NULL) {
|
|
return;
|
|
}
|
|
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) data;
|
|
if (sniffer->cnt == 1) {
|
|
len = sniffer->ampdu_info[0].length;
|
|
//get ieee80211_hdr/data len to do user task
|
|
os_printf("[len] %d, rssi %d\n", len, sniffer->rx_ctrl.rssi);
|
|
} else {
|
|
int i;
|
|
os_printf("rx ampdu %d\n", sniffer->cnt);
|
|
for (i = 0; i < sniffer->cnt; i++) {
|
|
hdr->seq_ctrl = sniffer->ampdu_info[i].seq;
|
|
memcpy(&hdr->addr3, sniffer->ampdu_info[i].address3, 6);
|
|
len = sniffer->ampdu_info[i].length;
|
|
//get ieee80211_hdr/data len to do user task
|
|
os_printf("[LEN] %d, RSSI %d\n", len, sniffer->rx_ctrl.rssi);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ICACHE_FLASH_ATTR
|
|
sniffer_channel_timer_cb(void *arg)
|
|
{
|
|
uint8 i;
|
|
|
|
for (i = current_channel; i < 14; i++) {
|
|
if ((channel_bits & (1 << i)) != 0) {
|
|
current_channel = i + 1;
|
|
wifi_set_channel(i);
|
|
os_printf("current channel %d--------------------------------------------%d\n", i, system_get_time());
|
|
os_timer_arm(&channel_timer, 1000, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == 14) {
|
|
current_channel = 1;
|
|
for (i = current_channel; i < 14; i++) {
|
|
if ((channel_bits & (1 << i)) != 0) {
|
|
current_channel = i + 1;
|
|
wifi_set_channel(i);
|
|
os_printf("current channel %d--------------------------------------------%d\n", i, system_get_time());
|
|
os_timer_arm(&channel_timer, 1000, 0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ICACHE_FLASH_ATTR
|
|
sniffer_wifi_scan_done(void *arg, STATUS status)
|
|
{
|
|
uint8 ssid[33];
|
|
channel_bits = 0;
|
|
current_channel = 1;
|
|
struct router_info *info = NULL;
|
|
|
|
os_printf("%s(%d)\n", __FUNCTION__, __LINE__);
|
|
while ((info = SLIST_FIRST(&router_list)) != NULL) {
|
|
SLIST_REMOVE_HEAD(&router_list, next);
|
|
free(info);
|
|
}
|
|
|
|
os_printf("%s(%d)\n", __FUNCTION__, __LINE__);
|
|
if (status == OK) {
|
|
uint8 i;
|
|
struct bss_info *bss = (struct bss_info *) arg;
|
|
while (bss != NULL) {
|
|
if (bss->channel != 0) {
|
|
struct router_info *info = NULL;
|
|
os_printf("ssid %s, channel %d, authmode %d, rssi %d\n", bss->ssid, bss->channel, bss->authmode,
|
|
bss->rssi);
|
|
IHW_LOG_BUF(LOG_Debug, "***AP", bss->ssid, strlen(bss->ssid));
|
|
channel_bits |= 1 << (bss->channel);
|
|
info = (struct router_info *) malloc(sizeof(struct router_info));
|
|
info->authmode = bss->authmode;
|
|
info->channel = bss->channel;
|
|
memcpy(info->bssid, bss->bssid, 6);
|
|
SLIST_INSERT_HEAD(&router_list, info, next);
|
|
}
|
|
bss = STAILQ_NEXT(bss, next);
|
|
}
|
|
for (i = current_channel; i < 14; i++) {
|
|
if ((channel_bits & (1 << i)) != 0) {
|
|
current_channel = i + 1;
|
|
wifi_set_channel(i);
|
|
os_printf("current channel1 %d--------------------------------------------%d\n", i, system_get_time());
|
|
break;
|
|
}
|
|
}
|
|
wifi_set_channel(1);
|
|
wifi_promiscuous_enable(0);
|
|
wifi_set_promiscuous_rx_cb(sniffer_wifi_promiscuous_rx);
|
|
wifi_promiscuous_enable(1);
|
|
os_timer_disarm(&channel_timer);
|
|
os_timer_setfn(&channel_timer, sniffer_channel_timer_cb, NULL);
|
|
os_timer_arm(&channel_timer, 1000, 0);
|
|
} else {
|
|
os_printf("err, scan status %d\n", status);
|
|
}
|
|
|
|
os_printf("%s(%d)\n", __FUNCTION__, __LINE__);
|
|
}
|
|
|
|
|
|
void wifi_connect_ap(const char* pSSID, int lenSSID, const char* pPasswd, int lenPasswd)
|
|
{
|
|
char buf[24];
|
|
#if 0
|
|
wifi_set_opmode(STATION_MODE);
|
|
|
|
SLIST_INIT(&router_list);
|
|
if(wifi_station_scan(NULL,sniffer_wifi_scan_done)){
|
|
os_printf("wifi_station_scan ok\n");
|
|
}
|
|
return;
|
|
#endif
|
|
memset(buf, 0x3f, 24);
|
|
wifi_set_opmode(STATION_MODE);
|
|
wifi_set_event_handler_cb(wifi_event_handler_cb);
|
|
wifi_station_set_auto_connect(1);
|
|
|
|
if (pSSID && lenSSID > 0 && lenSSID < 32) {
|
|
struct station_config config;
|
|
//wifi_station_get_config(&config);
|
|
bzero(&config, sizeof(struct station_config));
|
|
|
|
memcpy(config.ssid, pSSID, lenSSID);
|
|
|
|
|
|
if (pPasswd && lenPasswd > 0 && lenPasswd < 64) {
|
|
memcpy(config.password, pPasswd, lenPasswd);
|
|
}
|
|
|
|
wifi_station_set_config(&config);
|
|
|
|
LOG_EX(LOG_Debug, "WIFI Conect: AP = [%s], Password = [%s]\n", pSSID, pPasswd);
|
|
|
|
IHW_LOG_BUF(LOG_Debug, "AP", (char*)pSSID, strlen(pSSID));
|
|
IHW_LOG_BUF(LOG_Debug, "PD", (char*)pPasswd, strlen(pPasswd));
|
|
|
|
wifi_station_connect();
|
|
}
|
|
else
|
|
{
|
|
LOG_EX(LOG_Debug, "WIFI Reconect......\n");
|
|
wifi_station_connect();
|
|
}
|
|
}
|
|
|
|
int soft_ap_network_ready(void)
|
|
{
|
|
return g_isNetReady;
|
|
}
|
|
|
|
void soft_ap_init(void)
|
|
{
|
|
u8_t mac[6];
|
|
uint8_t r_buf[] = {0x3c, 0xf3, 0xff, 0x07, 0x00, 0x03, 0x01, 0x00, 0x00, 0x02};
|
|
wifi_set_event_handler_cb(NULL);
|
|
wifi_set_opmode(STATIONAP_MODE);
|
|
struct softap_config *config = (struct softap_config *) zalloc(sizeof(struct softap_config)); // initialization
|
|
wifi_get_macaddr(SOFTAP_IF, mac);
|
|
|
|
wifi_softap_get_config(config); // Get soft-AP config first.
|
|
sprintf(config->ssid, USR_CFG_SOFTAP(SoftAPFormat), mac[4], mac[5]);
|
|
|
|
//sprintf(config->password, SOFT_AP_PASSWORD);
|
|
//config->authmode = AUTH_WPA_WPA2_PSK;
|
|
config->authmode = AUTH_OPEN;
|
|
config->ssid_len = 0; // or its actual SSID length
|
|
config->max_connection = 4;
|
|
wifi_softap_set_config(config); // Set ESP8266 soft-AP config
|
|
|
|
LOG_EX(LOG_Info, "SSID: [%s], AUTH = NONE\n", config->ssid);
|
|
|
|
free(config);
|
|
|
|
struct station_info * station = wifi_softap_get_station_info();
|
|
|
|
while (station) {
|
|
LOG_EX(LOG_Info, "bssid : MACSTR, ip : IPSTR/n", MAC2STR(station->bssid), IP2STR(&station->ip));
|
|
station = STAILQ_NEXT(station, next);
|
|
}
|
|
wifi_softap_free_station_info(); // Free it by calling functionss
|
|
wifi_softap_dhcps_stop(); // disable soft-AP DHCP server
|
|
struct ip_info info;
|
|
info.ip.addr = ipaddr_addr(USR_CFG_SOFTAP_DHCP(IPAddr));
|
|
info.gw.addr = ipaddr_addr(USR_CFG_SOFTAP_DHCP(Gatway));
|
|
info.netmask.addr = ipaddr_addr(USR_CFG_SOFTAP_DHCP(Netmask));
|
|
// IP4_ADDR(&info.ip, 192, 168, 5, 1); // set IP
|
|
// IP4_ADDR(&info.gw, 192, 168, 5, 1); // set gateway
|
|
// IP4_ADDR(&info.netmask, 255, 255, 255, 0); // set netmask
|
|
wifi_set_ip_info(SOFTAP_IF, &info);
|
|
struct dhcps_lease dhcp_lease;
|
|
dhcp_lease.start_ip.addr = ipaddr_addr(USR_CFG_SOFTAP_DHCP(DHCPStartIP));
|
|
dhcp_lease.end_ip.addr = ipaddr_addr(USR_CFG_SOFTAP_DHCP(DHCPEndIP));
|
|
// IP4_ADDR(&dhcp_lease.start_ip, 192, 168, 5, 100);
|
|
// IP4_ADDR(&dhcp_lease.end_ip, 192, 168, 5, 105);
|
|
wifi_softap_set_dhcps_lease(&dhcp_lease);
|
|
wifi_softap_dhcps_start(); // enable soft-AP DHCP server
|
|
ne_general_write(NULL, r_buf, sizeof(r_buf) / sizeof(r_buf[0]));
|
|
}
|
|
|