/* -*-C-*- ******************************************************************************* * altobeam * Reproduction and Communication of this document is strictly prohibited * unless specifically authorized in writing by altobeam ******************************************************************************/ #include #include #include #include "apollo.h" #include "wsm.h" #include "bh.h" #include "debug.h" #include "hwio.h" #include "sbus.h" #ifdef ATBM_SUPPORT_SMARTCONFIG int baselen = 0; short * st_payload_buf= NULL; static int flag = 0; #define FLAG_ORIGINAL_VALUE 0 #define FLAG_RECEIVE_BROADCAST 1 #define FLAG_RECEIVE_MULTICAST 2 #define ORIGINAL_NUM_OF_CNT 0 #define WAIT_NUM_OF_CNT 10 //extern struct hmac_configure hmac_cfg; extern int smartconfig_scan(struct atbm_common *priv); extern int fun_recv_magic(struct atbm_common *hw_priv,short rxdata); extern int fun_recv_payload(short rxdata, int turn_id); extern int atbm_smartconfig_stop(struct atbm_common *hw_priv); int atbm_smart_scan_start(struct atbm_vif *priv, struct wsm_scan *scan) { int ret, i; int tmo = 5000; struct atbm_common *hw_priv = ABwifi_vifpriv_to_hwpriv(priv); for (i = 0; i < scan->numOfChannels; ++i) tmo += scan->ch[i].maxChannelTime + 10; atomic_set(&hw_priv->scan.in_progress, 1); #ifdef CONFIG_PM atbm_pm_stay_awake(&hw_priv->pm_state, tmo * HZ / 1000); #endif ret = wsm_scan(hw_priv, scan, priv->if_id); if (unlikely(ret)) { atomic_set(&hw_priv->scan.in_progress, 0); } return ret; } void atbm_smart_scan_work(struct atbm_work_struct *work) { struct atbm_common *hw_priv = container_of(work, struct atbm_common, scan.smartwork); int i; struct atbm_vif *priv; //struct atbm_vif *vif; //const u32 ProbeRequestTime = 2; //const u32 ChannelRemainTime = 15; struct wsm_scan scan = { .scanType = WSM_SCAN_TYPE_FOREGROUND, .scanFlags =0, .numOfProbeRequests = 1, .probeDelay = 100, .numOfChannels = 14, }; priv = __ABwifi_hwpriv_to_vifpriv(hw_priv, hw_priv->scan.if_id); /*TODO: COMBO: introduce locking so vif is not removed in meanwhile */ if (!priv) { atbm_printk_scan("%s:[SCAN] interface removed\n",__func__); return ; } hw_priv->scan.status = 0; hw_priv->scan.if_id = 0; scan.maxTransmitRate = WSM_TRANSMIT_RATE_1; mutex_lock(&hw_priv->conf_mutex); if (hw_priv->scan.direct_probe) scan.maxTransmitRate = WSM_TRANSMIT_RATE_6; scan.band = WSM_PHY_BAND_2_4G; if (priv->join_status == ATBM_APOLLO_JOIN_STATUS_STA) { scan.scanType = WSM_SCAN_TYPE_BACKGROUND; scan.scanFlags = WSM_SCAN_FLAG_FORCE_BACKGROUND; if (priv->if_id) scan.scanFlags |= WSM_FLAG_MAC_INSTANCE_1; else scan.scanFlags &= ~WSM_FLAG_MAC_INSTANCE_1; } scan.autoScanInterval = (0xba << 24)|(120 * 1024); /* 30 seconds, -70 rssi */ scan.numOfSSIDs = 1; scan.ssids = &hw_priv->scan.ssids[0]; //if scan_smartconfig scan not send probereq frame if(hw_priv->scan.scan_smartconfig){ scan.numOfProbeRequests = 0; scan.scanFlags |= WSM_FLAG_START_SMARTCONFIG; } scan.ch = atbm_kzalloc(sizeof(struct wsm_scan_ch[scan.numOfChannels]),GFP_KERNEL); if (!scan.ch) { hw_priv->scan.status = -ENOMEM; goto fail; } for (i = 0; i < scan.numOfChannels; i++) { if(hw_priv->scan.scan_smartconfig){ scan.ch[i].minChannelTime = hw_priv->st_cfg.magic_time; scan.ch[i].maxChannelTime = hw_priv->st_cfg.magic_time+5; } else { scan.ch[i].minChannelTime = 45; scan.ch[i].maxChannelTime = 75; } scan.ch[i].number =i+1;//atbm_band_2ghz.channels[i].hw_value; scan.ch[i].txPowerLevel =30; //atbm_band_2ghz.channels[i].max_power; } hw_priv->scan.status = atbm_smart_scan_start(priv, &scan); if (WARN_ON(hw_priv->scan.status)) goto fail; atbm_kfree(scan.ch); mutex_unlock(&hw_priv->conf_mutex); return ; fail: mutex_unlock(&hw_priv->conf_mutex); atbm_hw_priv_queue_work(hw_priv, &hw_priv->scan.smartwork); return ; } void atbm_smart_setchan_work(struct atbm_work_struct *work) { struct atbm_common *hw_priv = container_of(work, struct atbm_common, scan.smartsetChanwork); struct wsm_set_chantype arg = { .band = 0, //0:2.4G,1:5G .flag = BIT(WSM_SET_CHANTYPE_FLAGS__SMARTCONFIG), //no use .channelNumber = hw_priv->st_configchannel, // channel number .channelType = NL80211_CHAN_HT20, // channel type }; atbm_printk_smt("hw_priv->st_configchannel = %d flag %x\n", hw_priv->st_configchannel,arg.flag); wsm_set_chantype_func(hw_priv,&arg,0); } void atbm_smart_stop_work(struct atbm_work_struct *work) { struct atbm_common *hw_priv = container_of(work, struct atbm_common, scan.smartstopwork); //printk("%s:%d\n",__func__,__LINE__); struct wsm_reset reset; hw_priv->st_status = CONFIG_ST_IDLE; hw_priv->scan.scan_smartconfig = 0; reset.reset_statistics = true; atbm_del_timer_sync(&hw_priv->smartconfig_expire_timer); if(st_payload_buf){ atbm_kfree(st_payload_buf); st_payload_buf= NULL; } wsm_reset(hw_priv,&reset,0); return ; } void smartconfig_scan_start(struct atbm_common *hw_priv) { //printk("%s %d\n", __FUNCTION__, __LINE__); struct atbm_vif *priv = ABwifi_hwpriv_to_vifpriv(hw_priv,hw_priv->scan.if_id); if (unlikely(!priv)) { WARN_ON(1); return; } atbm_priv_vif_list_read_unlock(&priv->vif_lock); hw_priv->scan_ret.len = 0; priv->scan_expire = 2; priv->scan_no_connect_back = 1; priv->scan_no_connect = 1; /*start smartconfig*/ hw_priv->scan.scan_smartconfig = 1; hw_priv->st_status = CONFIG_ST_START; baselen=0; if(st_payload_buf==NULL){ st_payload_buf = atbm_kmalloc(sizeof(short)*ST_PAYLOAD_BUF_SZ,GFP_KERNEL | GFP_DMA); } else { memset(st_payload_buf,0,sizeof(short)*ST_PAYLOAD_BUF_SZ); } atbm_hw_priv_queue_work(hw_priv, &hw_priv->scan.smartwork); hw_priv->st_status = CONFIG_ST_GET_MAGIC; //printk("%s:%d\n",__func__,__LINE__); } int smartconfig_start(struct atbm_common *hw_priv,struct smartconfig_config * st_cfg) { //printk("%s:%d\n",__func__,__LINE__); //int Istate=0; if(st_cfg == NULL){ atbm_printk_err("unsupport smartconfig st_cfg NULL!"); return CONFIG_ST_STARTCONFIG_ERR; } if((st_cfg->magic_cnt<1)||(st_cfg->magic_cnt>10)){ atbm_printk_err("unsupport smartconfig imagic_cnt %d!",st_cfg->magic_cnt); return CONFIG_ST_STARTCONFIG_ERR; } if((st_cfg->magic_time<20)||(st_cfg->magic_time>500)){ atbm_printk_err("unsupport smartconfig magic_time!"); return CONFIG_ST_STARTCONFIG_ERR; } if((st_cfg->payload_time<500)||(st_cfg->payload_time>30000)){ atbm_printk_err("unsupport smartconfig payload_time!"); return CONFIG_ST_STARTCONFIG_ERR; } memcpy(&hw_priv->st_cfg,st_cfg,sizeof(struct smartconfig_config )); /*disconnect AP*/ // AT_WDisConnect(NULL); atbm_mod_timer(&hw_priv->smartconfig_expire_timer,st_cfg->payload_time + st_cfg->magic_time*14); atbm_printk_err("st_cfg->payload_time + st_cfg->magic_time*14 = %d\n", (st_cfg->payload_time + st_cfg->magic_time*14)); if(hw_priv->scan_ret.info){ spin_lock_bh(&hw_priv->spinlock_smart); hw_priv->scan_ret.info = NULL; hw_priv->scan_ret.len =0; spin_unlock_bh(&hw_priv->spinlock_smart); } smartconfig_scan_start(hw_priv); return CONFIG_ST_START; } int atbm_smartconfig_start(struct atbm_common *hw_priv,int enable) { if (enable){ atbm_printk_smt("%s %d\n", __func__, hw_priv->scan.scan_smartconfig); if(hw_priv->scan.scan_smartconfig){ atbm_printk_smt("scan_smartconfig now!please try later!\n"); return 0 ; }else { struct smartconfig_config st_cfg = { .type = CONFIG_TP_ATBM_SMART, .magic_cnt = 1, .magic_time = 50, .payload_time = 8000, }; smartconfig_start(hw_priv,&st_cfg); } }else{ atbm_smartconfig_stop(hw_priv); } return 0; } int atbm_smartconfig_stop(struct atbm_common *hw_priv) { atbm_printk_smt("%s:%d\n",__func__,__LINE__); if(hw_priv->scan.scan_smartconfig){ smartconfig_stop(hw_priv); } return 0; } /*cnt : 2 ~ 100*/ int smartconfig_magic_channel_cnt(int cnt) { return 0; } /*ms : 20ms ~ 1000ms*/ int smartconfig_magic_channel_timeout(int ms) { return 0; } /*ms : 500ms ~ 10000ms*/ int smartconfig_payload_timeout(int ms) { return 0; } int smartconfig_stop(struct atbm_common *hw_priv) { atbm_printk_smt("%s:%d\n",__func__,__LINE__); atbm_hw_priv_queue_work(hw_priv, &hw_priv->scan.smartstopwork); return hw_priv->st_status; } int smartconfig_status(struct atbm_common *hw_priv) { return hw_priv->st_status; } int smartconfig_start_timer_func(struct atbm_common *hw_priv ) { atbm_printk_smt("smartconfig timeout\n"); if(hw_priv->scan.scan_smartconfig){ //cancel smartconfig atbm_hw_priv_queue_work(hw_priv, &hw_priv->scan.smartstopwork); hw_priv->st_status = CONFIG_ST_DONE_FAIL; } return 1; } int smartconfig_magic_scan_done(struct atbm_common *hw_priv) { //printk("smartconfig_magic_scan_done %d\n",hw_priv->st_status); if(hw_priv->st_status == CONFIG_ST_SWITCH_PAYLOAD_CH ){ atbm_printk_smt("st_configchannel %d\n",hw_priv->st_configchannel); atbm_hw_priv_queue_work(hw_priv, &hw_priv->scan.smartsetChanwork); hw_priv->st_status = CONFIG_ST_GET_PAYLOAD; } else { //printk("st_status %d\n",hw_priv->st_status); if(hw_priv->st_status == CONFIG_ST_GET_MAGIC){ //may need start scan again atomic_set(&hw_priv->scan.in_progress, 0); smartconfig_scan_start(hw_priv); } } return 0; } const u8 atbm_smart_config_magic_mac[4][6] ={ {0x01,0x00,0x5e,0x7f,0xff,0x01},//magic {0x01,0x00,0x5e,0x7f,0xff,0x02}, //checksum {0x01,0x00,0x5e,0x7f,0xff,0x03}, //payload {0x01,0x00,0x5e,0x7f,0xff,0xfa} //payload }; int atbm_ieee80211_build_preq_ies(struct atbm_vif *priv,u8 *buffer, const u8 *ie, size_t ie_len, u8 channel) { u8 *pos; pos = buffer; /* SSID */ *pos++ = WLAN_EID_SSID; *pos++ = 0; return pos - buffer; } struct sk_buff *atbm_ieee80211_build_probe_req(struct atbm_vif *priv, u8 *dst, const u8 *ie, size_t ie_len) { struct atbm_common * hw_priv = priv->hw_priv; struct sk_buff *skb=NULL; struct atbm_ieee80211_mgmt *mgmt; //size_t buf_len; //u8 *buf; struct ieee80211_hdr_3addr *hdr; skb = atbm_dev_alloc_skb(1024); if (!skb) return NULL; hdr = (struct ieee80211_hdr_3addr *) atbm_skb_put(skb, sizeof(*hdr)); //printk("hmac:build_probe_req ++<%p>\n",hdr); memset(hdr, 0, sizeof(*hdr)); hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); memcpy(hdr->addr2, hw_priv->mac_addr, ETH_ALEN); hdr->seq_ctrl = 0; hdr->duration_id = 0; if (dst) { mgmt = (struct atbm_ieee80211_mgmt *) hdr; memcpy(mgmt->da, dst, ETH_ALEN); memcpy(mgmt->bssid, dst, ETH_ALEN); } else { memset(hdr->addr1, 0xff, ETH_ALEN); memset(hdr->addr3, 0xff, ETH_ALEN); } //buf = (u8 *)(hdr + 1); //buf_len = atbm_ieee80211_build_preq_ies(priv, buf, ie, ie_len, // hw_priv->st_configchannel); // atbm_skb_put(skb, buf_len); IEEE80211_SKB_CB(skb)->flags = IEEE80211_TX_INTFL_DONT_ENCRYPT; return skb; } struct sk_buff * atbm_ieee80211_send_probe_req(struct atbm_vif *priv, u8 *dst, const u8 *ie, size_t ie_len, bool no_cck) { struct sk_buff *skb; skb = atbm_ieee80211_build_probe_req(priv, dst,ie, ie_len); if (skb) { if (no_cck) IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_NO_CCK_RATE; } return skb; } int smartconfig_scan(struct atbm_common *hw_priv) { //printk("%s:%d\n",__func__,__LINE__); int ret; struct atbm_vif *priv; struct wsm_template_frame frame = { .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST, }; priv = ABwifi_hwpriv_to_vifpriv(hw_priv, hw_priv->scan.if_id); if (unlikely(!priv)) { atbm_printk_err("%s:%d\n",__func__,__LINE__); return 0; } atbm_priv_vif_list_read_unlock(&priv->vif_lock); //printk("hmac:sta_scan ++ scan_expire %ds\n",priv->scan_expire); if (priv->join_status == ATBM_APOLLO_JOIN_STATUS_STA) return -EOPNOTSUPP; frame.skb = atbm_ieee80211_send_probe_req(priv,NULL,NULL,0,0); //printk("%s:%d\n",__func__,__LINE__); if (!frame.skb) return -ENOMEM; ret = wsm_set_template_frame(hw_priv, &frame, priv->if_id); atbm_hw_priv_queue_work(hw_priv, &hw_priv->scan.smartwork); if (frame.skb) atbm_dev_kfree_skb(frame.skb); return ret; } #if 0 int start_connect_ap(struct atbm_vif*priv,u8 *essid,int essid_len,u8 *key,int key_len,int key_mgmt,int keyid) { //struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)priv->appdata; struct hmac_configure *config = priv->hw_priv->config; //int essid_len = strlen((const char*)essid); //int key_len = strlen((const char*)key); //wifi_printk(WIFI_WPA,"wpa (%s) key(%d)\n",essid,key_mgmt); priv->scan_no_connect_back = priv->scan_no_connect = 0; priv->auto_connect_when_lost = 1; if(essid_len>IEEE80211_MAX_SSID_LEN) { essid_len = IEEE80211_MAX_SSID_LEN; } if(key_len>32) { key_len = 32; } if(key != NULL){ memcpy(config->password,key,key_len); config->password[key_len] = 0; config->password_len = key_len; } if(essid!= NULL){ memcpy(config->ssid,essid,essid_len); os_memcpy(priv->ssid,config->ssid ,essid_len); config->ssid[essid_len] = 0; priv->ssid[essid_len] = 0; config->ssid_len = essid_len; priv->ssid_length = config->ssid_len; } if(key_mgmt == KEY_WPA) { config->key_mgmt = WPA_KEY_MGMT_PSK; config->wpa = WPA_PROTO_WPA; config->auth_alg = WLAN_AUTH_OPEN; config->pairwise_cipher = WPA_CIPHER_TKIP; config->group_cipher = WPA_CIPHER_TKIP; } else if(key_mgmt == KEY_WPA2) { config->key_mgmt = WPA_KEY_MGMT_PSK; config->wpa = WPA_PROTO_RSN; config->auth_alg = WLAN_AUTH_OPEN; config->pairwise_cipher = WPA_CIPHER_CCMP; config->group_cipher = WPA_CIPHER_CCMP; } else if((key_mgmt == KEY_WEP) ||(key_mgmt == KEY_WEP_SHARE)) { if((key_len == 5)||(key_len == 13)) { config->auth_alg = (key_mgmt == KEY_WEP)? WLAN_AUTH_OPEN:WLAN_AUTH_SHARED_KEY; config->group_cipher = (key_len == 5) ? WPA_CIPHER_WEP40 : WPA_CIPHER_WEP104; wpa_common_install_wepkey(priv,(char *)key,config->group_cipher,keyid); wifi_printk(WIFI_WPA,"wpa scan (%s),auth(%x),gcipher(%x)\n", priv->ssid,config->auth_alg,config->group_cipher); } } else { config->key_mgmt = WPA_KEY_MGMT_NONE; config->wpa = 0; config->auth_alg = WLAN_AUTH_OPEN; config->pairwise_cipher = WPA_CIPHER_NONE; config->group_cipher = WPA_CIPHER_NONE; if((key_len > 0)||(key_mgmt != KEY_NONE)){ wifi_printk(WIFI_WPA," connect_ap keymgm(%d) keyl(%d) ERR!\n", key_mgmt,key_len); return -1; } } if (config->key_mgmt & WPA_KEY_MGMT_PSK) { //pbkdf2_sha1((const char*)ssid->psk, (const char*)ssid->ssid, ssid->ssid_len, 8, wpa_s->wpa->pmksa[0].id, PMKID_LEN); config->psk_set = 0; if(config->psk_set){ memcpy(config->psk,config->password,PMK_LEN); } else { wifi_printk(WIFI_WPA,"psk pwd(%s),ssid(%s)\n",config->password,config->ssid); pbkdf2_sha1((const char*)config->password, (const char*)config->ssid, config->ssid_len,4096,config->psk, PMK_LEN); } config->psk_set = 1; } smartconfig_scan(priv); //os_free(priv->extra_ie); priv->extra_ie = NULL; priv->extra_ie_len = 0; return 0; } #endif int smartconfig_step_1(struct atbm_common *hw_priv,struct sk_buff *skb,int channel ) { int len = skb->len; char * data = skb->data; static int CNT_BROAD = 0; //printk("step_1_rx len %d %x\n",len,data[4+12]); //add code to get magic if((memcmp(atbm_smart_config_magic_mac[0],&data[4+12],6)) && (memcmp(atbm_smart_config_magic_mac[0],&data[4],6))){ //printk("rxmac %x %x %x %x %x %x\n",data[4+12],data[4+13],data[4+14],data[4+15],data[4+16],data[4+17]); return 0; } if(flag == FLAG_ORIGINAL_VALUE) CNT_BROAD++; if((flag == FLAG_ORIGINAL_VALUE) && (!memcmp(atbm_smart_config_magic_mac[0],&data[4],6))){ flag = FLAG_RECEIVE_BROADCAST; CNT_BROAD = ORIGINAL_NUM_OF_CNT; atbm_printk_smt("smartconfig:FLAG_RECEIVE_BROADCAST \n"); } else if((flag == FLAG_ORIGINAL_VALUE) && (CNT_BROAD > WAIT_NUM_OF_CNT)){ flag = FLAG_RECEIVE_MULTICAST; CNT_BROAD = ORIGINAL_NUM_OF_CNT; atbm_printk_smt("smartconfig:FLAG_RECEIVE_MULTICAST \n"); } //printk("******** counter: %d********\n", CNT_BROAD); if((flag == FLAG_ORIGINAL_VALUE) && (CNT_BROAD <= WAIT_NUM_OF_CNT)) return 0; //fun_recv_magic(hw_priv,len); if((flag == FLAG_RECEIVE_BROADCAST) && (!memcmp(atbm_smart_config_magic_mac[0],&data[4],6))){ if(fun_recv_magic(hw_priv,len)/*magic done*/){ hw_priv->st_status = CONFIG_ST_SWITCH_PAYLOAD_CH; hw_priv->st_configchannel = channel; atbm_printk_smt("FLAG_RECEIVE_BROADCAST\n"); } } else if((flag == FLAG_RECEIVE_MULTICAST) && (!memcmp(atbm_smart_config_magic_mac[0],&data[4+12],6))){ if(fun_recv_magic(hw_priv,len)/*magic done*/){ hw_priv->st_status = CONFIG_ST_SWITCH_PAYLOAD_CH; hw_priv->st_configchannel = channel; //printk("CONFIG_ST_SWITCH_PAYLOAD_CH\n"); } } //fun_recv_magic(hw_priv,len); // //if(fun_recv_magic(hw_priv,len)/*magic done*/){ //hw_priv->st_status = CONFIG_ST_SWITCH_PAYLOAD_CH; //hw_priv->st_configchannel = channel; //} return 0; } int smartconfig_step_2(struct atbm_common *hw_priv,struct sk_buff *skb) { int turn_id = 0; int len = skb->len; char * data = skb->data; struct atbm_vif *priv = ABwifi_hwpriv_to_vifpriv(hw_priv, hw_priv->scan.if_id); if (unlikely(!priv)) { WARN_ON(1); return 0; } atbm_priv_vif_list_read_unlock(&priv->vif_lock); //add code to get payload if((memcmp(atbm_smart_config_magic_mac[1],&data[4+12],5)) && (memcmp(atbm_smart_config_magic_mac[1],&data[4],5))){ //printk("rxmac %x %x %x %x %x %x\n",data[4+12],data[4+13],data[4+14],data[4+15],data[4+16],data[4+17]); return -1; } if((!memcmp(atbm_smart_config_magic_mac[3], &data[4+12], 6))){ //printk("rxmac %x %x %x %x %x %x\n",data[4+12],data[4+13],data[4+14],data[4+15],data[4+16],data[4+17]); return -1; } if((!memcmp(atbm_smart_config_magic_mac[3], &data[4], 6))) return -1; atbm_printk_smt("data: %x %x %x %x %x %x\n",data[4],data[4+1],data[4+2],data[4+3],data[4+4],data[4+5]); //printk("data: %x %x %x %x %x %x\n",data[4+12],data[4+13],data[4+14],data[4+15],data[4+16],data[4+17]); //printk("step_2_rx len %x \n",len); #if 1 if(flag == FLAG_RECEIVE_BROADCAST){ if(memcmp(atbm_smart_config_magic_mac[2],&data[4],5)) return -1; if((!memcmp(atbm_smart_config_magic_mac[2],&data[4],5)) && (data[4+5] >= atbm_smart_config_magic_mac[2][5])) { turn_id = data[4+5] - atbm_smart_config_magic_mac[2][5]; //iot_printf("1\n"); atbm_printk_smt("receive broadcast\n"); } } else if(flag == FLAG_RECEIVE_MULTICAST){ if(memcmp(atbm_smart_config_magic_mac[2],&data[4+12],5)) return -1; if((!memcmp(atbm_smart_config_magic_mac[2],&data[4+12],5)) && (data[4+17] >= atbm_smart_config_magic_mac[2][5])) { turn_id = data[4+17] - atbm_smart_config_magic_mac[2][5]; //iot_printf("2\n"); atbm_printk_smt("receive multicast\n"); } } #else if(data[4+17] >= atbm_smart_config_magic_mac[2][5]){ turn_id = data[4+17] - atbm_smart_config_magic_mac[2][5]; if(turn_id >= 10) return -1; } #endif atbm_printk_smt("step_2_rx len %d %d,turn_id = %d\n",len,data[4+17],turn_id); if( fun_recv_payload((short)(len-baselen+1), turn_id)== CONFIG_ST_DONE_SUCCESS/*payload done*/){ atbm_printk_smt("SMART_SUCCESS \n"); //cancel smartconfig atbm_hw_priv_queue_work(hw_priv, &hw_priv->scan.smartstopwork); hw_priv->st_status = CONFIG_ST_DONE_SUCCESS; //connect AP //start_connect_ap(priv,hmac_cfg.ssid,hmac_cfg.ssid_len,hmac_cfg.password,hmac_cfg.password_len,hmac_cfg.key_mgmt,hmac_cfg.key_id ); //smartconfig_scan(hw_priv); } return 0; } int smartconfig_start_rx(struct atbm_common *hw_priv,struct sk_buff *skb,int channel ) { if(hw_priv->st_status == CONFIG_ST_GET_MAGIC){ smartconfig_step_1(hw_priv,skb,channel); } else if(hw_priv->st_status == CONFIG_ST_GET_PAYLOAD){ smartconfig_step_2(hw_priv,skb); } return 0; } void atbm_smartconfig_expire_timer(unsigned long arg) { //printk("%s:%d\n",__func__,__LINE__); struct atbm_common *hw_priv = (struct atbm_common *)arg; if (atomic_read(&hw_priv->scan.in_progress)){ atbm_printk_smt("%s:%d\n",__func__,__LINE__); //cancel smartconfig atbm_hw_priv_queue_work(hw_priv, &hw_priv->scan.smartstopwork); } } #endif