luckfox-pico-sdk/sysdrv/drv_ko/wifi/atbm/hal_apollo/smartconfig.c
2023-08-08 20:36:47 +08:00

705 lines
21 KiB
C

/* -*-C-*-
*******************************************************************************
* altobeam
* Reproduction and Communication of this document is strictly prohibited
* unless specifically authorized in writing by altobeam
******************************************************************************/
#include <linux/skbuff.h>
#include <net/atbm_mac80211.h>
#include <linux/kthread.h>
#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,"<ERROR> 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