void event_normal_connected(void *data)
{
    char ip[16];

    set_device_network_state(GOT_IP_NORMAL_WORK);

	app_network_ip_get(ip);
	LOG_DEBUG("Connected to provisioned network with ip address =%s\r\n", ip);
    
    if(is_factory_mode_enable())wmprintf(FACTORY_JOINAP_PASS);

    LOG_DEBUG("Starting mdns\r\n");
    app_mdns_start(dhcp_name_strval);

    {
        void *iface_handle;
        iface_handle = net_get_sta_handle();

        if (!mdns_announced) {
            hp_mdns_announce(iface_handle, UP);
            mdns_announced = 1;
        } else {
            hp_mdns_down_up(iface_handle);
        }
    }


	OTN_NETIF_CHANGE();

    //start nb
    void *msg;
    msg = (void *)NB_OPERATION;
    os_queue_send(&main_thread_sched_queue,&msg,OS_NO_WAIT);
}
int wpa2_ent_connect(struct wlan_network *wpa2_network)
{
	struct wpa2_command *wpa2_cmd = NULL;

	wpa2_cmd = (struct wpa2_command *)
			wps_mem_malloc(sizeof(struct wpa2_command));

	if (wpa2_cmd == NULL) {
		wmprintf("Failed to allocated memory for wpa2 command\r\n");
		return -WM_FAIL;
	}

	memset(wpa2_cmd, 0, sizeof(struct wpa2_command));

	memcpy(&wpa2_cmd->wpa2_network, wpa2_network,
			sizeof(struct wlan_network));

	if (os_queue_send(&wps.cmd_queue, &wpa2_cmd, OS_NO_WAIT) != WM_SUCCESS)
		return -WM_FAIL;
	return WM_SUCCESS;

}
int wps_connect(enum wps_session_command pbc, uint32_t pin,
			struct wlan_scan_result *res)
{
	struct wps_command *wps_cmd = NULL;

	wps_cmd = (struct wps_command *)
			wps_mem_malloc(sizeof(struct wps_command));

	if (wps_cmd == NULL) {
		wmprintf("Failed to allocated memory for wps command\r\n");
		return -WM_FAIL;
	}

	memset(wps_cmd, 0, sizeof(struct wps_command));

	wps_cmd->command = pbc;
	wps_cmd->wps_pin = pin;
	memcpy(&wps_cmd->res, res, sizeof(struct wlan_scan_result));

	if (os_queue_send(&wps.cmd_queue, &wps_cmd, OS_NO_WAIT) != WM_SUCCESS)
		return -WM_FAIL;
	return WM_SUCCESS;

}
void event_wlan_init_done(void *data)
{
	int ret;
	char temp[20];
    
    //init cfg_struct from otp
    config_cfg_struct();
    
    //print did & mac
    uint32_t digital_did = get_device_did_digital();
    
    //for factory check did and mac
    wmprintf("digital_did is %d \r\n", digital_did);
    snprintf_safe(temp,sizeof(temp),"%.2x%.2x%.2x%.2x%.2x%.2x",
                    cfg_struct.mac_address[0],
                    cfg_struct.mac_address[1],
                    cfg_struct.mac_address[2],
                    cfg_struct.mac_address[3],
                    cfg_struct.mac_address[4],
                    cfg_struct.mac_address[5]
                    );
    wmprintf("mac address is %s\r\n",temp);//for factory checking
    wmprintf("last four byte of key is %.2x%.2x%.2x%.2x\r\n",cfg_struct.key[OT_PROTO_DEVICE_KEY_SIZE -4],
                                                               cfg_struct.key[OT_PROTO_DEVICE_KEY_SIZE -3],
                                                               cfg_struct.key[OT_PROTO_DEVICE_KEY_SIZE -2],
                                                               cfg_struct.key[OT_PROTO_DEVICE_KEY_SIZE -1]
                                                               );

    //print chip boot status info
    if (is_factory_mode_enable()) {
        wmprintf(FACTORY_STARTUP_PASS);
    } else {
        wmprintf(FACTORY_NORMAL_BOOT);
    }

    //gen token
    deal_with_token(false); 

    //set wifi work channel 
    wlan_set_country(COUNTRY_CN);

#ifndef RELEASE
    LOG_DEBUG("dump token value\r\n");
    xiaomi_dump_hex(token,16);
#endif

    ret = netif_add_udp_broadcast_filter(fixed_cfg_data.lport);
    if (ret != WM_SUCCESS) {
        LOG_ERROR("Failed to add ot local port to boardcast filter \r\n");
    }

    //ot start as idle
    start_otd();


#ifdef MIIO_COMMANDS
    OTN_ONLINE(mum_online_notifier);
    OTN_OFFLINE(mum_offline_notifier);
#endif
    OTN_ONLINE(ot_online_notifier);
    OTN_ONLINE(ot_offline_notifier);

    //generate dhcp name
    strcpy(dhcp_name_strval,cfg_struct.model);
    char *c = dhcp_name_strval;
    while(*c) {
        if('.' == *c) {
            *c = '-';
        }
        c++;
    }

    strcat(dhcp_name_strval,"_miio");
    snprintf_safe(temp,20,"%lu",digital_did);
    strcat(dhcp_name_strval,temp);

    /*
     * Start mDNS and advertize our hostname using mDNS
     */
    init_mdns_service_struct(dhcp_name_strval);


    ret = is_factory_mode_enable();

    //factory mode,connect to miio_default
    if(ret) {
        wmprintf("in factory mode, will auto connect to miio_default\r\n");

        struct wlan_network factory_net;

        memset(&factory_net,0,sizeof(struct wlan_network));
        strcpy(factory_net.name,FACTORY_NET_SSID);
        strcpy(factory_net.ssid,FACTORY_NET_SSID); 

        factory_net.security.type = WLAN_SECURITY_WPA2;
        
        factory_net.security.psk_len = strlen(FACTORY_NET_PASSPHASE);
        memcpy(factory_net.security.psk,FACTORY_NET_PASSPHASE,strlen(FACTORY_NET_PASSPHASE));

        factory_net.ip.ipv4.addr_type = 1; //use dhcp
        
        //will connect to miio_default
        app_sta_start_by_network(&factory_net);

	    goto safe_exit;

    }

    g_provisioned.state = (int) data;
    //already provisioned
    if(APP_NETWORK_PROVISIONED == g_provisioned.state) {
        LOG_DEBUG("already provisioned \r\n");
        set_device_network_state(SMT_CONNECTING);
        app_sta_start(); //just start sta mode , & it will auto connect to network
	    goto safe_exit;
     }

    //not provisioned & should start uap
    //Note: this interface only should be used for testing
    if(ENABLE_UAP == get_trigger_uap_info()) {
        wmprintf("should start UAP \r\n");
        
        app_uap_start_on_channel_with_dhcp(construct_ssid_for_smt_cfg(), NULL,DEFAULT_AP_CHANNEL);
        goto safe_exit;
    }


#if defined(ENABLE_AIRKISS) && (ENABLE_AIRKISS == 1)
    //not yet provisioned,start kuailian
    set_device_network_state(WAIT_SMT_TRIGGER);

    //trigger prov
	app_ctrl_notify_event(AF_EVT_INTERNAL_PROV_REQUESTED, (void *)NULL);

    //trigger scan
    void * msg;
    msg = (void *)SCAN_ROUTER;
    os_queue_send(&main_thread_sched_queue, &msg, OS_NO_WAIT);

#else
    LOG_DEBUG("start uap mode for smart config \r\n");
    app_uap_start_on_channel_with_dhcp(construct_ssid_for_smt_cfg(), NULL,DEFAULT_AP_CHANNEL);
    
    //start monitor timer 
    if(smt_cfg_monitor_init() ==WM_SUCCESS) {
        smt_cfg_monitor_start();
    }
#endif

safe_exit:
    return;

}