<commit_before>// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "lwip/netif.h"
#include "lwip/tcpip.h"
#include "lwip/dhcp.h"
#include "lwip/dhcpserver.h"
#include "netif/etharp.h"
#include "esp_wifi.h"
#include "esp_timer.h"
#include "esp_misc.h"
#include "tcpip_adapter.h"

/* Avoid warning. No header file has include these function */
err_t ethernetif_init(struct netif* netif);
void system_station_got_ip_set();
void netif_create_ip4_linklocal_address(struct netif* netif);

static os_timer_t* get_ip_timer;
static uint8_t dhcp_fail_time;
static bool dhcps_flag = true;
static bool dhcpc_flag = true;
static struct ip_info esp_ip[TCPIP_ADAPTER_IF_MAX];

void esp_wifi_station_dhcpc_event(uint8_t netif_index)
{
    if (TCPIP_ADAPTER_IF_VALID(netif_index)) {
        TCPIP_ATAPTER_LOG("wifi station dhcpc start\n");
        dhcp_stop(esp_netif[netif_index]);
        dhcp_cleanup(esp_netif[netif_index]);
        dhcp_inform(esp_netif[netif_index]);
    } else {
        TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index);
    }
}

static void tcpip_adapter_dhcpc_done()
{
#define DHCP_BOUND        10
    os_timer_disarm(get_ip_timer);

    if (esp_netif[TCPIP_ADAPTER_IF_STA]->dhcp->state == DHCP_BOUND) {
        /*send event here*/
        system_station_got_ip_set();
        printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR "\n", IP2STR(&(esp_netif[0]->ip_addr)),
               IP2STR(&(esp_netif[0]->netmask)), IP2STR(&(esp_netif[0]->gw)));
    } else if (dhcp_fail_time < 30) {
        TCPIP_ATAPTER_LOG("dhcpc time(ms): %d\n", dhcp_fail_time * 200);
        dhcp_fail_time ++;
        os_timer_setfn(get_ip_timer, tcpip_adapter_dhcpc_done, NULL);
        os_timer_arm(get_ip_timer, 200, 1);
    } else {
        TCPIP_ATAPTER_LOG("ERROR dhcp get ip error\n");
        free(get_ip_timer);
    }
}

static void tcpip_adapter_station_dhcp_start()
{
    err_t ret;
    get_ip_timer = (os_timer_t*)malloc(sizeof(*get_ip_timer));

    if (get_ip_timer == NULL) {
        TCPIP_ATAPTER_LOG("ERROR NO MEMORY\n");
    }

    TCPIP_ATAPTER_LOG("dhcpc start\n");
    ret = dhcp_start(esp_netif[TCPIP_ADAPTER_IF_STA]);
    dhcp_fail_time = 0;

    if (ret == 0) {
        os_timer_disarm(get_ip_timer);
        os_timer_setfn(get_ip_timer, tcpip_adapter_dhcpc_done, NULL);
        os_timer_arm(get_ip_timer, 100, 1);
    }
}

void tcpip_adapter_start(uint8_t netif_index, bool authed)
{
    if (!TCPIP_ADAPTER_IF_VALID(netif_index)) {
        TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index);
        return;
    }

    TCPIP_ATAPTER_LOG("start netif[%d]\n", netif_index);

    if (netif_index == TCPIP_ADAPTER_IF_STA) {
        if (authed == 0) {
            if (esp_netif[netif_index] == NULL) {
                esp_netif[netif_index] = (struct netif*)os_malloc(sizeof(*esp_netif[netif_index]));
                TCPIP_ATAPTER_LOG("Malloc netif:%d\n", netif_index);
                TCPIP_ATAPTER_LOG("Add netif:%d\n", netif_index);
                netif_add(esp_netif[netif_index], NULL, NULL, NULL, NULL, ethernetif_init, tcpip_input);
            }
        } else {
            if ((esp_netif[netif_index]->flags & NETIF_FLAG_DHCP) == 0) {
                if (dhcpc_flag) {
                    printf("dhcp client start...\n");
                    tcpip_adapter_station_dhcp_start();
                } else {
                    if (esp_ip[TCPIP_ADAPTER_IF_STA].ip.addr != 0) {
                        netif_set_addr(esp_netif[netif_index], &esp_ip[TCPIP_ADAPTER_IF_STA].ip,
                                       &esp_ip[TCPIP_ADAPTER_IF_STA].netmask, &esp_ip[TCPIP_ADAPTER_IF_STA].gw);
                        netif_set_up(esp_netif[netif_index]);
                        system_station_got_ip_set();
                        printf("ip: 0.0.0.0,mask: 0.0.0.0,gw: 0.0.0.0\n");
                    } else {
                        printf("check your static ip\n");
                    }
                }

            }

        }
    } else if (netif_index == TCPIP_ADAPTER_IF_AP) {
        if (dhcps_flag) {
            IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].ip, 192, 168 , 4, 1);
            IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].gw, 192, 168 , 4, 1);
            IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, 255, 255 , 255, 0);
        }

        if (esp_netif[netif_index] == NULL) {
            TCPIP_ATAPTER_LOG("Malloc netif:%d\n", netif_index);
            esp_netif[netif_index] = (struct netif*)os_malloc(sizeof(*esp_netif[netif_index]));
            netif_add(esp_netif[netif_index], &esp_ip[TCPIP_ADAPTER_IF_AP].ip,
                      &esp_ip[TCPIP_ADAPTER_IF_AP].netmask, &esp_ip[TCPIP_ADAPTER_IF_AP].gw, NULL, ethernetif_init, tcpip_input);
        }

        if (dhcps_flag) {
            dhcps_start(&esp_ip[TCPIP_ADAPTER_IF_AP]);
            printf("dhcp server start:(");
            printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR, IP2STR(&(esp_netif[TCPIP_ADAPTER_IF_AP]->ip_addr)),
                   IP2STR(&(esp_netif[TCPIP_ADAPTER_IF_AP]->netmask)), IP2STR(&(esp_netif[TCPIP_ADAPTER_IF_AP]->gw)));
            printf(")\n");
        }

        netif_set_up(esp_netif[netif_index]);
        netif_set_default(esp_netif[netif_index]);
    }

    uint8_t opmode = wifi_get_opmode();

    if (opmode == STATION_MODE) {
        netif_set_default(esp_netif[netif_index]);
    }
}

void tcpip_adapter_stop(uint8_t netif_index)
{
    if (!TCPIP_ADAPTER_IF_VALID(netif_index)) {
        TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index);
        return;
    }
    if (esp_netif[netif_index == NULL])
        return;

    if (netif_index == TCPIP_ADAPTER_IF_STA) {
        TCPIP_ATAPTER_LOG("dhcp stop netif index:%d\n", netif_index);
        dhcp_stop(esp_netif[netif_index]);
    }

    if (netif_index == TCPIP_ADAPTER_IF_AP) {
        if(dhcps_flag){
            TCPIP_ATAPTER_LOG("dhcp stop netif index:%d\n", netif_index);
            dhcps_stop();
        }
    }

    TCPIP_ATAPTER_LOG("stop netif[%d]\n", netif_index);
    netif_remove(esp_netif[netif_index]);
    os_free(esp_netif[netif_index]);
    esp_netif[netif_index] = NULL;
}

void ieee80211_input(uint8_t netif_index, uint8_t* input, uint16_t len)
{
    struct pbuf* pb;

    if (!TCPIP_ADAPTER_IF_VALID(netif_index)) {
        TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index);
        return;
    }
<commit_msg>fix(tcpip_adapter): Fix crash when wifi changed to station from softap<commit_after>// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "lwip/netif.h"
#include "lwip/tcpip.h"
#include "lwip/dhcp.h"
#include "lwip/dhcpserver.h"
#include "netif/etharp.h"
#include "esp_wifi.h"
#include "esp_timer.h"
#include "esp_misc.h"
#include "tcpip_adapter.h"

/* Avoid warning. No header file has include these function */
err_t ethernetif_init(struct netif* netif);
void system_station_got_ip_set();
void netif_create_ip4_linklocal_address(struct netif* netif);

static os_timer_t* get_ip_timer;
static uint8_t dhcp_fail_time;
static bool dhcps_flag = true;
static bool dhcpc_flag = true;
static struct ip_info esp_ip[TCPIP_ADAPTER_IF_MAX];

void esp_wifi_station_dhcpc_event(uint8_t netif_index)
{
    if (TCPIP_ADAPTER_IF_VALID(netif_index)) {
        TCPIP_ATAPTER_LOG("wifi station dhcpc start\n");
        dhcp_stop(esp_netif[netif_index]);
        dhcp_cleanup(esp_netif[netif_index]);
        dhcp_inform(esp_netif[netif_index]);
    } else {
        TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index);
    }
}

static void tcpip_adapter_dhcpc_done()
{
#define DHCP_BOUND        10
    os_timer_disarm(get_ip_timer);

    if (esp_netif[TCPIP_ADAPTER_IF_STA]->dhcp->state == DHCP_BOUND) {
        /*send event here*/
        system_station_got_ip_set();
        printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR "\n", IP2STR(&(esp_netif[0]->ip_addr)),
               IP2STR(&(esp_netif[0]->netmask)), IP2STR(&(esp_netif[0]->gw)));
    } else if (dhcp_fail_time < 30) {
        TCPIP_ATAPTER_LOG("dhcpc time(ms): %d\n", dhcp_fail_time * 200);
        dhcp_fail_time ++;
        os_timer_setfn(get_ip_timer, tcpip_adapter_dhcpc_done, NULL);
        os_timer_arm(get_ip_timer, 200, 1);
    } else {
        TCPIP_ATAPTER_LOG("ERROR dhcp get ip error\n");
        free(get_ip_timer);
    }
}

static void tcpip_adapter_station_dhcp_start()
{
    err_t ret;
    get_ip_timer = (os_timer_t*)malloc(sizeof(*get_ip_timer));

    if (get_ip_timer == NULL) {
        TCPIP_ATAPTER_LOG("ERROR NO MEMORY\n");
    }

    TCPIP_ATAPTER_LOG("dhcpc start\n");
    ret = dhcp_start(esp_netif[TCPIP_ADAPTER_IF_STA]);
    dhcp_fail_time = 0;

    if (ret == 0) {
        os_timer_disarm(get_ip_timer);
        os_timer_setfn(get_ip_timer, tcpip_adapter_dhcpc_done, NULL);
        os_timer_arm(get_ip_timer, 100, 1);
    }
}

void tcpip_adapter_start(uint8_t netif_index, bool authed)
{
    if (!TCPIP_ADAPTER_IF_VALID(netif_index)) {
        TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index);
        return;
    }

    TCPIP_ATAPTER_LOG("start netif[%d]\n", netif_index);

    if (netif_index == TCPIP_ADAPTER_IF_STA) {
        if (authed == 0) {
            if (esp_netif[netif_index] == NULL) {
                esp_netif[netif_index] = (struct netif*)os_malloc(sizeof(*esp_netif[netif_index]));
                TCPIP_ATAPTER_LOG("Malloc netif:%d\n", netif_index);
                TCPIP_ATAPTER_LOG("Add netif:%d\n", netif_index);
                netif_add(esp_netif[netif_index], NULL, NULL, NULL, NULL, ethernetif_init, tcpip_input);
            }
        } else {
            if ((esp_netif[netif_index]->flags & NETIF_FLAG_DHCP) == 0) {
                if (dhcpc_flag) {
                    printf("dhcp client start...\n");
                    tcpip_adapter_station_dhcp_start();
                } else {
                    if (esp_ip[TCPIP_ADAPTER_IF_STA].ip.addr != 0) {
                        netif_set_addr(esp_netif[netif_index], &esp_ip[TCPIP_ADAPTER_IF_STA].ip,
                                       &esp_ip[TCPIP_ADAPTER_IF_STA].netmask, &esp_ip[TCPIP_ADAPTER_IF_STA].gw);
                        netif_set_up(esp_netif[netif_index]);
                        system_station_got_ip_set();
                        printf("ip: 0.0.0.0,mask: 0.0.0.0,gw: 0.0.0.0\n");
                    } else {
                        printf("check your static ip\n");
                    }
                }

            }

        }
    } else if (netif_index == TCPIP_ADAPTER_IF_AP) {
        if (dhcps_flag) {
            IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].ip, 192, 168 , 4, 1);
            IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].gw, 192, 168 , 4, 1);
            IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, 255, 255 , 255, 0);
        }

        if (esp_netif[netif_index] == NULL) {
            TCPIP_ATAPTER_LOG("Malloc netif:%d\n", netif_index);
            esp_netif[netif_index] = (struct netif*)os_malloc(sizeof(*esp_netif[netif_index]));
            netif_add(esp_netif[netif_index], &esp_ip[TCPIP_ADAPTER_IF_AP].ip,
                      &esp_ip[TCPIP_ADAPTER_IF_AP].netmask, &esp_ip[TCPIP_ADAPTER_IF_AP].gw, NULL, ethernetif_init, tcpip_input);
        }

        if (dhcps_flag) {
            dhcps_start(&esp_ip[TCPIP_ADAPTER_IF_AP]);
            printf("dhcp server start:(");
            printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR, IP2STR(&(esp_netif[TCPIP_ADAPTER_IF_AP]->ip_addr)),
                   IP2STR(&(esp_netif[TCPIP_ADAPTER_IF_AP]->netmask)), IP2STR(&(esp_netif[TCPIP_ADAPTER_IF_AP]->gw)));
            printf(")\n");
        }

        netif_set_up(esp_netif[netif_index]);
        netif_set_default(esp_netif[netif_index]);
    }

    uint8_t opmode = wifi_get_opmode();

    if (opmode == STATION_MODE) {
        netif_set_default(esp_netif[netif_index]);
    }
}

void tcpip_adapter_stop(uint8_t netif_index)
{
    if (!TCPIP_ADAPTER_IF_VALID(netif_index)) {
        TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index);
        return;
    }
    if (esp_netif[netif_index] == NULL)
        return;

    if (netif_index == TCPIP_ADAPTER_IF_STA) {
        TCPIP_ATAPTER_LOG("dhcp stop netif index:%d\n", netif_index);
        dhcp_stop(esp_netif[netif_index]);
    }

    if (netif_index == TCPIP_ADAPTER_IF_AP) {
        if(dhcps_flag){
            TCPIP_ATAPTER_LOG("dhcp stop netif index:%d\n", netif_index);
            dhcps_stop();
        }
    }

    TCPIP_ATAPTER_LOG("stop netif[%d]\n", netif_index);
    netif_remove(esp_netif[netif_index]);
    os_free(esp_netif[netif_index]);
    esp_netif[netif_index] = NULL;
}

void ieee80211_input(uint8_t netif_index, uint8_t* input, uint16_t len)
{
    struct pbuf* pb;

    if (!TCPIP_ADAPTER_IF_VALID(netif_index)) {
        TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index);
        return;
    }

{'fraction_non_alphanumeric': 0.12112270600935589, 'fraction_numerical': 0.013386110111550917, 'mean_word_length': 2.877232142857143, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 6, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1360491', 'n_tokens_mistral': 5337, 'n_tokens_neox': 5091, 'n_words': 863}