2016-05-26 10:36:20 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2014-12-22 12:35:05 +01:00
|
|
|
#include "user_interface.h"
|
2016-06-09 10:40:56 +02:00
|
|
|
#include "user_config.h"
|
2014-12-22 12:35:05 +01:00
|
|
|
#include "smart.h"
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
#include "esp_wifi.h"
|
2016-06-09 10:40:56 +02:00
|
|
|
#include "esp_libc.h"
|
2014-12-22 12:35:05 +01:00
|
|
|
|
|
|
|
#define ADDR_MAP_NUM 10
|
|
|
|
|
|
|
|
static os_timer_t smart_timer;
|
|
|
|
|
|
|
|
static smart_addr_map *am[ADDR_MAP_NUM];
|
|
|
|
|
|
|
|
static smart_addr_map *matched = NULL;
|
|
|
|
|
|
|
|
static struct station_config *sta_conf;
|
|
|
|
|
|
|
|
static int cur_channel = 1;
|
|
|
|
|
|
|
|
static uint8_t mode = STATION_MODE;
|
|
|
|
|
|
|
|
static uint8_t alldone = 0;
|
|
|
|
|
|
|
|
// 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000(LSB)
|
|
|
|
// when the bit is set, means the ssid byte is got
|
|
|
|
static uint8_t *got_ssid = NULL;
|
|
|
|
static uint8_t *got_password = NULL;
|
|
|
|
|
|
|
|
static uint8_t *ssid_nibble = NULL;
|
|
|
|
static uint8_t *password_nibble = NULL;
|
|
|
|
|
|
|
|
static smart_succeed succeed = NULL;
|
|
|
|
static void *smart_succeed_arg = NULL;
|
|
|
|
|
|
|
|
void smart_end();
|
2015-01-05 03:09:51 +01:00
|
|
|
int smart_check(uint8_t *nibble, uint16_t len, uint8_t *dst, uint8_t *got){
|
2014-12-22 12:35:05 +01:00
|
|
|
if(len == 0)
|
|
|
|
return 0;
|
|
|
|
uint16_t dst_len = len/NIBBLE_PER_BYTE;
|
|
|
|
uint16_t byte_num = 0, bit_num = 0;
|
|
|
|
int i = 0, res = 1; // assume ok.
|
2016-05-26 10:36:20 +02:00
|
|
|
memset(dst,0,dst_len);
|
2014-12-22 12:35:05 +01:00
|
|
|
|
|
|
|
if(NIBBLE_PER_BYTE==1){
|
|
|
|
for(i=0;i<len;i++){
|
|
|
|
byte_num = (i) / 8;
|
|
|
|
bit_num = (i) % 8;
|
|
|
|
if(0x20>nibble[i] || nibble[i]>=0x7F){ // not printable
|
|
|
|
NODE_DBG("Smart: got np byte %d:%02x\n", i, nibble[i]);
|
|
|
|
nibble[i] = 0;
|
|
|
|
got[byte_num] &= ~(0x1 << bit_num); // clear the bit
|
|
|
|
res = 0; // not ok
|
|
|
|
} else {
|
|
|
|
dst[i] = nibble[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NIBBLE_PER_BYTE == 2
|
|
|
|
if((len%NIBBLE_PER_BYTE) != 0){
|
|
|
|
// this should not happen
|
|
|
|
NODE_DBG("Smart: smart_check got odd len\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(len == 2){
|
|
|
|
// only one byte
|
|
|
|
if(nibble[0]<=0xF && ((nibble[0]^0x1)&0xF == (nibble[1]>>4)) ){
|
|
|
|
dst[0] = ((nibble[0]&0xF)<<4) + (nibble[1]&0xF);
|
|
|
|
res = 1;
|
|
|
|
}else{
|
|
|
|
nibble[0] = 0;
|
|
|
|
nibble[1] = 0;
|
|
|
|
got[0] &= ~(0x3 << 0); // clear the 0 bit
|
|
|
|
res = 0; // not ok
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = 1; // assume ok.
|
|
|
|
for(i=len-2;i>0;i--){
|
|
|
|
bool forward = ( ((nibble[i]&0xF)^((i+1)&0xF)) == (nibble[i+1]>>4) );
|
|
|
|
bool back = ( ((nibble[i-1]&0xF)^(i&0xF)) == (nibble[i]>>4) );
|
|
|
|
if(!forward || !back){
|
|
|
|
// wrong forward, or wrong back, replace i-1, i and i+1, until get right back, forward
|
|
|
|
NODE_DBG("check: wf %d:%02x %02x %02x\n",i,nibble[i-1],nibble[i], nibble[i+1]);
|
|
|
|
byte_num = (i-1) / 8;
|
|
|
|
bit_num = (i-1) % 8;
|
|
|
|
nibble[i-1] = 0;
|
|
|
|
got[byte_num] &= ~(0x1 << bit_num); // clear the bit
|
|
|
|
|
|
|
|
byte_num = (i) / 8;
|
|
|
|
bit_num = (i) % 8;
|
|
|
|
nibble[i] = 0;
|
|
|
|
got[byte_num] &= ~(0x1 << bit_num); // clear the bit
|
|
|
|
|
|
|
|
byte_num = (i+1) / 8;
|
|
|
|
bit_num = (i+1) % 8;
|
|
|
|
nibble[i+1] = 0;
|
|
|
|
got[byte_num] &= ~(0x1 << bit_num); // clear the bit
|
|
|
|
res = 0;
|
|
|
|
return res; // once there is error,
|
|
|
|
}
|
|
|
|
|
|
|
|
if((i%NIBBLE_PER_BYTE) == 0) { // i == even
|
|
|
|
dst[i/NIBBLE_PER_BYTE] = ((nibble[i]&0xF)<<4) + (nibble[i+1]&0xF);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(i==0){
|
|
|
|
dst[0] = ((nibble[0]&0xF)<<4) + (nibble[1]&0xF);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i=0;i<dst_len;i++){ // check for non-printable byte
|
|
|
|
// NODE_DBG("nibble %d:%02x %02x->%02x\n", i, nibble[i*NIBBLE_PER_BYTE], nibble[i*NIBBLE_PER_BYTE+1], dst[i]);
|
|
|
|
byte_num = (i*NIBBLE_PER_BYTE) / 8;
|
|
|
|
bit_num = (i*NIBBLE_PER_BYTE) % 8;
|
|
|
|
if(0x20>dst[i] || dst[i]>=0x7F){ // not printable
|
|
|
|
NODE_DBG("Smart: got np byte %d:%02x\n", i, dst[i]);
|
|
|
|
dst[i] = 0; // reset byte
|
|
|
|
nibble[i*NIBBLE_PER_BYTE] = 0; // reset hi-nibble
|
|
|
|
nibble[i*NIBBLE_PER_BYTE+1] = 0; // reset lo-nibble
|
|
|
|
got[byte_num] &= ~(0x3 << bit_num); // clear the bit
|
|
|
|
res = 0; // not ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2015-03-20 12:42:10 +01:00
|
|
|
void detect(uint8 *arg, uint16 len){
|
2014-12-22 12:35:05 +01:00
|
|
|
uint16_t seq;
|
|
|
|
int16_t seq_delta = 0;
|
|
|
|
uint16_t byte_num = 0, bit_num = 0;
|
|
|
|
int16_t c = 0;
|
2015-03-20 12:42:10 +01:00
|
|
|
uint8 *buf = NULL;
|
|
|
|
if( len == 12 ){
|
|
|
|
return;
|
|
|
|
} else if (len >= 64){
|
|
|
|
buf = arg + sizeof(struct RxControl);
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
2014-12-22 12:35:05 +01:00
|
|
|
if( ( (buf[0]) & TYPE_SUBTYPE_MASK) != TYPE_SUBTYPE_QOS_DATA){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if( (buf[1] & DS_RETRY_MASK) != NO_RETRY )
|
|
|
|
return;
|
|
|
|
if( buf[SEQ_ADDR] & 0xF != 0 ) // Fragment Number should = 0
|
|
|
|
return;
|
|
|
|
// calculate current seq number
|
|
|
|
seq = buf[SEQ_ADDR+1];
|
|
|
|
seq = seq<<4;
|
|
|
|
seq += buf[SEQ_ADDR]>>4;
|
|
|
|
|
|
|
|
if(!matched){ // cur_base_seq is ref to flag[0] when finding the patern
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ADDR_MAP_NUM; i++) // for each source-dest adress pair in the map
|
|
|
|
{
|
|
|
|
if ( am[i]->flag_match_num == 0 ){ // not in the map yet
|
|
|
|
if ( len - am[i]->base_len == am[i]->flag[0]) // store new source-dest adress pair to the map until flag[0] is got
|
|
|
|
{
|
|
|
|
// BSSID, SA, DA, store the SA, DA
|
2016-05-26 10:36:20 +02:00
|
|
|
memcpy(am[i]->addr, &buf[ADDR_MATCH_START], ADDR_MATCH_LENGTH);
|
2014-12-22 12:35:05 +01:00
|
|
|
am[i]->flag_match_num++; // =1
|
|
|
|
am[i]->cur_base_seq = seq; // assume the first seq is found
|
|
|
|
am[i]->base_seq_valid = 1;
|
|
|
|
// NODE_DBG("Smart: new addr pair found\n");
|
|
|
|
}
|
|
|
|
break; // break any way for the next packet to come
|
|
|
|
}
|
2016-05-26 10:36:20 +02:00
|
|
|
else if(0 == memcmp(am[i]->addr, &buf[ADDR_MATCH_START], ADDR_MATCH_LENGTH)){ // source-dest adress pair match
|
2014-12-22 12:35:05 +01:00
|
|
|
if(am[i]->base_seq_valid == 0){
|
|
|
|
if ( len - am[i]->base_len == am[i]->flag[0]) { // found the new flag[0]
|
|
|
|
// here flag_match_num is already = 1
|
|
|
|
am[i]->cur_base_seq = seq;
|
|
|
|
am[i]->base_seq_valid = 1; // the seq number is valid now
|
|
|
|
// NODE_DBG("Smart: new base_seq found\n");
|
|
|
|
}
|
|
|
|
break; // break any way for the next packet to come
|
|
|
|
}
|
|
|
|
|
|
|
|
// base seq number is valid, cal the delta
|
|
|
|
if(seq >= am[i]->cur_base_seq){
|
|
|
|
seq_delta = seq - am[i]->cur_base_seq;
|
|
|
|
} else {
|
|
|
|
seq_delta = SEQ_MAX - am[i]->cur_base_seq + seq;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(seq_delta < 0){ // this should never happen
|
|
|
|
am[i]->base_seq_valid = 0; // the seq number is not valid
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(seq_delta == 0){ // base_seq is not valid any more
|
|
|
|
if ( len - am[i]->base_len != am[i]->flag[0]) { // lost the flag[0]
|
|
|
|
am[i]->base_seq_valid = 0; // the seq number is not valid
|
|
|
|
}
|
|
|
|
break; // break any way for the next packet to come
|
|
|
|
}
|
|
|
|
|
|
|
|
// delta is out of range, need to find the next flag[0] to start again
|
|
|
|
if (seq_delta>=FLAG_NUM){
|
|
|
|
am[i]->flag_match_num = 1; // reset to 1
|
|
|
|
if ( len - am[i]->base_len == am[i]->flag[0]) { // found the new flag[0]
|
|
|
|
// here flag_match_num is already = 1
|
|
|
|
am[i]->cur_base_seq = seq;
|
|
|
|
am[i]->base_seq_valid = 1; // the seq number is valid now
|
|
|
|
} else {
|
|
|
|
am[i]->base_seq_valid = 0;
|
|
|
|
}
|
|
|
|
break; // done for this packet
|
|
|
|
}
|
|
|
|
|
|
|
|
// NODE_DBG("Smart: match_num:%d seq_delta:%d len:%d\n",am[i]->flag_match_num,seq_delta,len-am[i]->base_len);
|
|
|
|
// seq_delta now from 1 to FLAG_NUM-1
|
|
|
|
// flag[] == 0 ,means skip this flag.
|
|
|
|
if ( (am[i]->flag_match_num==seq_delta) && \
|
|
|
|
( (am[i]->flag[am[i]->flag_match_num]==len-am[i]->base_len) || (am[i]->flag[am[i]->flag_match_num]==0) ) ){
|
|
|
|
am[i]->flag_match_num++;
|
|
|
|
if(am[i]->flag_match_num == FLAG_MATCH_NUM){ //every thing is match.
|
|
|
|
NODE_ERR("Smart: got matched sender\n");
|
|
|
|
matched = am[i]; // got the matched source-dest adress pair who is sending the udp data
|
|
|
|
matched->base_seq_valid = 0; // set to 0, and start to reference to the SSID_FLAG from now on
|
|
|
|
os_timer_disarm(&smart_timer); // note: may start a longer timeout
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// non match, reset, need to find next flag[0] to start again
|
|
|
|
am[i]->flag_match_num = 1;
|
|
|
|
am[i]->base_seq_valid = 0;
|
|
|
|
break;
|
|
|
|
} // non-match source-dest adress pair, continue to next pair in the map.
|
|
|
|
} // for loop
|
|
|
|
// break out, or loop done.
|
|
|
|
goto end;
|
|
|
|
} else { // cur_base_seq is ref to SSID_FLAG when patern is alread found
|
2016-05-26 10:36:20 +02:00
|
|
|
if(0 != memcmp(matched->addr, &buf[ADDR_MATCH_START], ADDR_MATCH_LENGTH)){ // source-dest adress pair not match, ignore it
|
2014-12-22 12:35:05 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (matched->base_seq_valid == 0){ // SSID_FLAG seq invalid, need to find the next valid seq number
|
|
|
|
// base_seq not valid, find it
|
|
|
|
if (len - matched->base_len == SSID_FLAG){
|
|
|
|
matched->cur_base_seq = seq;
|
|
|
|
matched->base_seq_valid = 1;
|
|
|
|
}
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(seq >= matched->cur_base_seq){
|
|
|
|
seq_delta = seq - matched->cur_base_seq;
|
|
|
|
} else {
|
|
|
|
seq_delta = SEQ_MAX - matched->cur_base_seq + seq;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(seq_delta < 0){ // this should never happen
|
|
|
|
matched->base_seq_valid = 0; // the seq number is not valid
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(seq_delta == 0){ // base_seq is not valid any more
|
|
|
|
if ( len - matched->base_len != SSID_FLAG) { // lost the SSID_FLAG
|
|
|
|
matched->base_seq_valid = 0; // the seq number is not valid
|
|
|
|
}
|
|
|
|
goto end; // exit for the next packet to come
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( seq_delta > (SEP_NUM + 1)*(1+NIBBLE_PER_BYTE*matched->ssid_len) +\
|
|
|
|
1 + (SEP_NUM + 1)*(1+NIBBLE_PER_BYTE*matched->pwd_len) ){
|
|
|
|
// delta out of the range
|
|
|
|
if (len - matched->base_len == SSID_FLAG){
|
|
|
|
matched->cur_base_seq = seq;
|
|
|
|
matched->base_seq_valid = 1;
|
|
|
|
} else {
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
}
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
// delta in the range
|
|
|
|
if (seq_delta==1){
|
|
|
|
int16_t ssid_len = len - matched->base_len - L_FLAG;
|
|
|
|
if ( matched->ssid_len == 0 ){ // update the ssid_len
|
|
|
|
if ( (ssid_len <=32) && (ssid_len >0) ){
|
|
|
|
matched->ssid_len = ssid_len;
|
|
|
|
NODE_DBG("Smart: found the ssid_len %d\n", matched->ssid_len);
|
|
|
|
}
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
if (ssid_len != matched->ssid_len){ // ssid_len not match
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
// note: not match, save the new one or old one? for now save the new one.
|
|
|
|
matched->ssid_len = ssid_len;
|
|
|
|
NODE_DBG("Smart: ssid_len not match\n");
|
|
|
|
}
|
|
|
|
goto end; // to the next packet
|
|
|
|
}
|
|
|
|
|
|
|
|
if( (SEP_NUM==2)&&(seq_delta==2 || seq_delta==3) ) {
|
|
|
|
if (len - matched->base_len != matched->flag[seq_delta-2+SEP_1_INDEX]){ // SEP not match
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
NODE_DBG("Smart: SEP-L not match\n");
|
|
|
|
}
|
|
|
|
goto end; // to the next packet
|
|
|
|
}
|
|
|
|
|
|
|
|
if( seq_delta==(SEP_NUM + 1)*(1+NIBBLE_PER_BYTE*matched->ssid_len) + 1) {
|
|
|
|
if (len - matched->base_len != PWD_FLAG){ // PWD_FLAG not match
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
NODE_DBG("Smart: PWD_FLAG not match\n");
|
|
|
|
}
|
|
|
|
goto end; // to the next packet
|
|
|
|
}
|
|
|
|
|
|
|
|
if (seq_delta==(SEP_NUM + 1)*(1+NIBBLE_PER_BYTE*matched->ssid_len) + 1 + 1){
|
|
|
|
int16_t pwd_len = len - matched->base_len - L_FLAG;
|
|
|
|
if ( matched->pwd_len == 0){
|
|
|
|
if ( (pwd_len <=64) && (pwd_len>0)){
|
|
|
|
matched->pwd_len = pwd_len;
|
|
|
|
NODE_DBG("Smart: found the pwd_len %d\n", matched->pwd_len);
|
|
|
|
}
|
|
|
|
goto end; // to the next packet
|
|
|
|
}
|
|
|
|
if (pwd_len != matched->pwd_len){ // pwd_len not match
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
// note: not match, save the new one or old one? for now save the new one.
|
|
|
|
matched->pwd_len = pwd_len; // reset pwd_len to 0
|
|
|
|
NODE_DBG("Smart: pwd_len not match\n");
|
|
|
|
}
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (seq_delta <= (SEP_NUM + 1)*(1+NIBBLE_PER_BYTE*matched->ssid_len) ){ // in the ssid zone
|
|
|
|
uint16_t it = (seq_delta-1-SEP_NUM-1) / (SEP_NUM + 1); // the number of ssid nibble: 0~31 or 0~63
|
|
|
|
uint16_t m = (seq_delta-1-SEP_NUM-1) % (SEP_NUM + 1); // 0~2
|
|
|
|
switch(m){
|
|
|
|
case 0: // the ssid hi/lo-nibble itself
|
|
|
|
c = (int16_t)(len - matched->base_len - C_FLAG);
|
|
|
|
if (c>255 || c<0){
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
NODE_DBG("Smart: wrong ssid nibble\n");
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
byte_num = it / 8; // 0~7
|
|
|
|
bit_num = it % 8; // 0~7
|
|
|
|
if( (got_ssid[byte_num] & (0x1 << bit_num)) == 0){
|
|
|
|
got_ssid[byte_num] |= 0x1 << bit_num; // set the bit
|
|
|
|
ssid_nibble[it] = c;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1: // seperator 1
|
|
|
|
case 2: // seperator 2
|
|
|
|
if(len - matched->base_len != matched->flag[m-1+SEP_1_INDEX]){
|
|
|
|
NODE_DBG("Smart: SEP-S not match\n");
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else { // in the pwd zone
|
|
|
|
uint16_t it = (seq_delta -1 -(SEP_NUM + 1)*(1+NIBBLE_PER_BYTE*matched->ssid_len) - 2 - SEP_NUM) / (SEP_NUM + 1); // the number of pwd byte
|
|
|
|
uint16_t m = (seq_delta -1 -(SEP_NUM + 1)*(1+NIBBLE_PER_BYTE*matched->ssid_len) - 2 - SEP_NUM) % (SEP_NUM + 1);
|
|
|
|
switch(m){
|
|
|
|
case 0: // the pwd hi/lo-nibble itself
|
|
|
|
c = (int16_t)(len - matched->base_len - C_FLAG);
|
|
|
|
if (c>255 || c<0){
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
NODE_DBG("Smart: wrong password nibble\n");
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
byte_num = it / 8; // 0~15 / 7
|
|
|
|
bit_num = it % 8; // 0~7
|
|
|
|
if( (got_password[byte_num] & (0x1 << bit_num)) == 0){
|
|
|
|
got_password[byte_num] |= 0x1 << bit_num; // set the bit
|
|
|
|
password_nibble[it] = c;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1: // seperator 1
|
|
|
|
case 2: // seperator 2
|
|
|
|
if(len - matched->base_len != matched->flag[m-1+SEP_1_INDEX]){
|
|
|
|
NODE_DBG("Smart: SEP-P not match\n");
|
|
|
|
matched->base_seq_valid = 0;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// check if all done
|
|
|
|
// NODE_DBG("Smart: ssid got %02x %02x\n", got_ssid[0], got_ssid[1]);
|
|
|
|
// NODE_DBG("Smart: password got %02x %02x %02x\n", got_password[0], got_password[1], got_password[2]);
|
|
|
|
int i,j;
|
|
|
|
for(i=0;i<NIBBLE_PER_BYTE*matched->ssid_len;i++){
|
|
|
|
byte_num = (i) / 8;
|
|
|
|
bit_num = (i) % 8;
|
|
|
|
if( (got_ssid[byte_num] & (0x1 << bit_num) ) != (0x1 << bit_num) ){ // check the bit == 1
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(j=0;j<NIBBLE_PER_BYTE*matched->pwd_len;j++){
|
|
|
|
byte_num = (j) / 8;
|
|
|
|
bit_num = (j) % 8;
|
|
|
|
if( (got_password[byte_num] & (0x1 << bit_num) ) != (0x1 << bit_num) ){ // check the 2 bit == 11
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(matched->ssid_len > 0 && matched->pwd_len > 0 && i==NIBBLE_PER_BYTE*matched->ssid_len && j==NIBBLE_PER_BYTE*matched->pwd_len){ // get everything, check it.
|
|
|
|
if( smart_check(ssid_nibble, NIBBLE_PER_BYTE*matched->ssid_len, sta_conf->ssid, got_ssid) && \
|
|
|
|
smart_check(password_nibble, NIBBLE_PER_BYTE*matched->pwd_len, sta_conf->password, got_password) ){
|
|
|
|
// all done
|
|
|
|
alldone = 1;
|
|
|
|
NODE_ERR(sta_conf->ssid);
|
|
|
|
NODE_ERR(" %d\n", matched->ssid_len);
|
|
|
|
NODE_ERR(sta_conf->password);
|
|
|
|
NODE_ERR(" %d\n", matched->pwd_len);
|
|
|
|
smart_end();
|
|
|
|
// if(succeed){
|
|
|
|
// succeed(smart_succeed_arg);
|
|
|
|
// succeed = NULL; // reset to NULL when succeed
|
|
|
|
// smart_succeed_arg = NULL;
|
|
|
|
// }
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
end:
|
|
|
|
#if 0
|
|
|
|
NODE_DBG("%d:\t0x%x 0x%x\t", len-BASE_LENGTH, buf[0],buf[1]);
|
|
|
|
NODE_DBG(MACSTR, MAC2STR(&(buf[BSSID_ADDR])));
|
|
|
|
NODE_DBG("\t");
|
|
|
|
NODE_DBG(MACSTR, MAC2STR(&(buf[SOURCE_ADDR])));
|
|
|
|
NODE_DBG("\t");
|
|
|
|
NODE_DBG(MACSTR, MAC2STR(&(buf[DEST_ADDR])));
|
|
|
|
uint16_t tseq = buf[SEQ_ADDR+1];
|
|
|
|
tseq = tseq<<4;
|
|
|
|
tseq += buf[SEQ_ADDR]>>4;
|
|
|
|
NODE_DBG("\t0x%04x\n", tseq);
|
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
void reset_map(smart_addr_map **am, size_t num){
|
2014-12-22 12:35:05 +01:00
|
|
|
int i;
|
|
|
|
for (i = 0; i < num; ++i)
|
|
|
|
{
|
|
|
|
am[i]->flag_match_num = 0;
|
|
|
|
am[i]->addr_len = ADDR_MATCH_LENGTH;
|
|
|
|
am[i]->base_len = BASE_LENGTH;
|
|
|
|
am[i]->cur_base_seq = -1;
|
|
|
|
am[i]->base_seq_valid = 0;
|
|
|
|
am[i]->ssid_len = 0;
|
|
|
|
am[i]->pwd_len = 0;
|
2016-05-26 10:36:20 +02:00
|
|
|
memset(am[i]->addr, 0, ADDR_MATCH_LENGTH);
|
2014-12-22 12:35:05 +01:00
|
|
|
if(SEP_1_INDEX==0){
|
|
|
|
am[i]->flag[0] = SEP_1;
|
|
|
|
am[i]->flag[1] = SEP_2;
|
|
|
|
am[i]->flag[2] = SSID_FLAG;
|
|
|
|
}
|
|
|
|
if(SEP_1_INDEX==2){
|
|
|
|
am[i]->flag[0] = SSID_FLAG;
|
|
|
|
am[i]->flag[1] = 0; // skip this flag
|
|
|
|
am[i]->flag[2] = SEP_1;
|
|
|
|
am[i]->flag[3] = SEP_2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
void smart_enable(void){
|
2014-12-22 12:35:05 +01:00
|
|
|
wifi_promiscuous_enable(1);
|
|
|
|
}
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
void smart_disable(void){
|
2014-12-22 12:35:05 +01:00
|
|
|
wifi_promiscuous_enable(0);
|
|
|
|
}
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
void smart_end(){
|
2014-12-22 12:35:05 +01:00
|
|
|
int i;
|
|
|
|
os_timer_disarm(&smart_timer);
|
|
|
|
smart_disable();
|
|
|
|
wifi_set_channel(cur_channel);
|
|
|
|
|
|
|
|
if(NULL_MODE != mode){
|
|
|
|
wifi_set_opmode(mode);
|
|
|
|
} else {
|
|
|
|
wifi_set_opmode(STATION_MODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
mode = wifi_get_opmode();
|
|
|
|
|
|
|
|
if(sta_conf && alldone){
|
|
|
|
if( (STATION_MODE == mode) || (mode == STATIONAP_MODE) ){
|
|
|
|
wifi_station_set_config(sta_conf);
|
|
|
|
wifi_station_set_auto_connect(true);
|
|
|
|
wifi_station_disconnect();
|
|
|
|
wifi_station_connect();
|
|
|
|
|
|
|
|
os_timer_disarm(&smart_timer);
|
2016-01-20 09:37:03 +01:00
|
|
|
os_timer_setfn(&smart_timer, (os_timer_func_t *)station_check_connect, (void *)1);
|
2014-12-22 12:35:05 +01:00
|
|
|
os_timer_arm(&smart_timer, STATION_CHECK_TIME, 0); // no repeat
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < ADDR_MAP_NUM; ++i)
|
|
|
|
{
|
|
|
|
if(am[i]){
|
2016-05-26 10:36:20 +02:00
|
|
|
free(am[i]);
|
2014-12-22 12:35:05 +01:00
|
|
|
am[i] = NULL;
|
|
|
|
}
|
|
|
|
matched = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sta_conf){
|
2016-05-26 10:36:20 +02:00
|
|
|
free(sta_conf);
|
2014-12-22 12:35:05 +01:00
|
|
|
sta_conf = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(got_password){
|
2016-05-26 10:36:20 +02:00
|
|
|
free(got_password);
|
2014-12-22 12:35:05 +01:00
|
|
|
got_password = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(got_ssid){
|
2016-05-26 10:36:20 +02:00
|
|
|
free(got_ssid);
|
2014-12-22 12:35:05 +01:00
|
|
|
got_ssid = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(password_nibble){
|
2016-05-26 10:36:20 +02:00
|
|
|
free(password_nibble);
|
2014-12-22 12:35:05 +01:00
|
|
|
password_nibble = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ssid_nibble){
|
2016-05-26 10:36:20 +02:00
|
|
|
free(ssid_nibble);
|
2014-12-22 12:35:05 +01:00
|
|
|
ssid_nibble = NULL;
|
|
|
|
}
|
|
|
|
// system_restart(); // restart to enable the mode
|
|
|
|
}
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
void smart_next_channel(){
|
2014-12-22 12:35:05 +01:00
|
|
|
smart_disable();
|
|
|
|
switch(cur_channel){
|
|
|
|
case 1:
|
|
|
|
cur_channel = MAX_CHANNEL;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
cur_channel++;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
cur_channel = 7;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
cur_channel = 1;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
case 8:
|
|
|
|
case 9:
|
|
|
|
case 10:
|
|
|
|
case 11:
|
|
|
|
case 12:
|
|
|
|
cur_channel++;
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
cur_channel = 6;
|
|
|
|
break;
|
|
|
|
case MAX_CHANNEL:
|
|
|
|
cur_channel = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cur_channel = 6;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
NODE_ERR("switch to channel %d\n", cur_channel);
|
|
|
|
wifi_set_channel(cur_channel);
|
|
|
|
reset_map(am, ADDR_MAP_NUM);
|
2016-05-26 10:36:20 +02:00
|
|
|
memset(sta_conf->ssid, 0, sizeof(sta_conf->ssid));
|
|
|
|
memset(sta_conf->password, 0, sizeof(sta_conf->password));
|
2014-12-22 12:35:05 +01:00
|
|
|
|
2016-05-26 10:36:20 +02:00
|
|
|
memset(got_ssid, 0, SSID_BIT_MAX);
|
|
|
|
memset(got_password, 0, PWD_BIT_MAX);
|
2014-12-22 12:35:05 +01:00
|
|
|
|
2016-05-26 10:36:20 +02:00
|
|
|
memset(ssid_nibble, 0, SSID_NIBBLE_MAX);
|
|
|
|
memset(password_nibble, 0, PWD_NIBBLE_MAX);
|
2014-12-22 12:35:05 +01:00
|
|
|
|
|
|
|
os_timer_disarm(&smart_timer);
|
|
|
|
os_timer_arm(&smart_timer, TIME_OUT_PER_CHANNEL, 0); // no repeat
|
|
|
|
|
|
|
|
smart_enable();
|
|
|
|
}
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
void smart_begin(int chnl, smart_succeed s, void *arg){
|
2014-12-22 12:35:05 +01:00
|
|
|
int i;
|
|
|
|
alldone = 0;
|
|
|
|
for (i = 0; i < ADDR_MAP_NUM; ++i)
|
|
|
|
{
|
|
|
|
if(!am[i]){
|
2016-05-26 10:36:20 +02:00
|
|
|
am[i] = (smart_addr_map*)zalloc(sizeof(smart_addr_map));
|
2014-12-22 12:35:05 +01:00
|
|
|
if(!am[i]){
|
|
|
|
NODE_DBG("smart_begin map no memory\n");
|
|
|
|
smart_end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!sta_conf){
|
2016-05-26 10:36:20 +02:00
|
|
|
sta_conf = (struct station_config *)zalloc(sizeof(struct station_config));
|
2014-12-22 12:35:05 +01:00
|
|
|
if(!sta_conf){
|
|
|
|
NODE_DBG("smart_begin sta_conf no memory\n");
|
|
|
|
smart_end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!ssid_nibble){
|
2016-05-26 10:36:20 +02:00
|
|
|
ssid_nibble = (uint8_t *)zalloc(SSID_NIBBLE_MAX);
|
2014-12-22 12:35:05 +01:00
|
|
|
if(!ssid_nibble){
|
|
|
|
NODE_DBG("smart_begin sta_conf no memory\n");
|
|
|
|
smart_end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!password_nibble){
|
2016-05-26 10:36:20 +02:00
|
|
|
password_nibble = (uint8_t *)zalloc(PWD_NIBBLE_MAX);
|
2014-12-22 12:35:05 +01:00
|
|
|
if(!password_nibble){
|
|
|
|
NODE_DBG("smart_begin sta_conf no memory\n");
|
|
|
|
smart_end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!got_ssid){
|
2016-05-26 10:36:20 +02:00
|
|
|
got_ssid = (uint8_t *)zalloc(SSID_BIT_MAX);
|
2014-12-22 12:35:05 +01:00
|
|
|
if(!got_ssid){
|
|
|
|
NODE_DBG("smart_begin sta_conf no memory\n");
|
|
|
|
smart_end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!got_password){
|
2016-05-26 10:36:20 +02:00
|
|
|
got_password = (uint8_t *)zalloc(PWD_BIT_MAX);
|
2014-12-22 12:35:05 +01:00
|
|
|
if(!got_password){
|
|
|
|
NODE_DBG("smart_begin sta_conf no memory\n");
|
|
|
|
smart_end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reset_map(am, ADDR_MAP_NUM);
|
2016-05-26 10:36:20 +02:00
|
|
|
// memset(sta_conf->ssid, 0, sizeof(sta_conf->ssid));
|
|
|
|
// memset(sta_conf->password, 0, sizeof(sta_conf->password));
|
2014-12-22 12:35:05 +01:00
|
|
|
|
2016-05-26 10:36:20 +02:00
|
|
|
// memset(got_ssid, 0, SSID_BIT_MAX);
|
|
|
|
// memset(got_password, 0, PWD_BIT_MAX);
|
2014-12-22 12:35:05 +01:00
|
|
|
|
2016-05-26 10:36:20 +02:00
|
|
|
// memset(ssid_nibble, 0, SSID_NIBBLE_MAX);
|
|
|
|
// memset(password_nibble, 0, PWD_NIBBLE_MAX);
|
2014-12-22 12:35:05 +01:00
|
|
|
mode = wifi_get_opmode();
|
|
|
|
if( (STATION_MODE == mode) || (mode == STATIONAP_MODE) ){
|
|
|
|
wifi_station_set_auto_connect(false);
|
|
|
|
wifi_station_disconnect();
|
|
|
|
}
|
|
|
|
cur_channel = chnl;
|
|
|
|
NODE_ERR("set channel to %d\n", cur_channel);
|
|
|
|
wifi_set_channel(cur_channel);
|
|
|
|
wifi_set_promiscuous_rx_cb(detect);
|
|
|
|
os_timer_disarm(&smart_timer);
|
|
|
|
os_timer_setfn(&smart_timer, (os_timer_func_t *)smart_next_channel, NULL);
|
|
|
|
os_timer_arm(&smart_timer, TIME_OUT_PER_CHANNEL, 0); // no repeat
|
|
|
|
|
|
|
|
if(s){
|
|
|
|
succeed = s; // init the succeed call back
|
|
|
|
smart_succeed_arg = arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
smart_enable();
|
|
|
|
}
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
void station_check_connect(bool smart){
|
2014-12-22 12:35:05 +01:00
|
|
|
mode = wifi_get_opmode();
|
|
|
|
if( (STATION_MODE != mode) && (mode != STATIONAP_MODE) ){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint8_t status = wifi_station_get_connect_status();
|
|
|
|
switch(status){
|
|
|
|
case STATION_GOT_IP:
|
|
|
|
NODE_DBG("station_check_connect is called with status: GOT_IP\n");
|
|
|
|
if(succeed){
|
|
|
|
succeed(smart_succeed_arg);
|
|
|
|
succeed = NULL; // reset to NULL when succeed
|
|
|
|
smart_succeed_arg = NULL;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case STATION_CONNECTING:
|
|
|
|
NODE_DBG("station_check_connect is called with status: CONNECTING\n");
|
|
|
|
break;
|
|
|
|
case STATION_IDLE:
|
|
|
|
wifi_station_set_auto_connect(true);
|
|
|
|
case STATION_CONNECT_FAIL:
|
|
|
|
case STATION_NO_AP_FOUND:
|
|
|
|
wifi_station_disconnect();
|
|
|
|
wifi_station_connect();
|
|
|
|
NODE_DBG("station_check_connect is called with smart: %d\n", smart);
|
|
|
|
break;
|
|
|
|
case STATION_WRONG_PASSWORD:
|
|
|
|
if(smart)
|
|
|
|
smart_begin(cur_channel, succeed, smart_succeed_arg);
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
os_timer_disarm(&smart_timer);
|
2016-01-20 09:37:03 +01:00
|
|
|
os_timer_setfn(&smart_timer, (os_timer_func_t *)station_check_connect, (void *)(int)smart);
|
2014-12-22 12:35:05 +01:00
|
|
|
os_timer_arm(&smart_timer, STATION_CHECK_TIME, 0); // no repeat
|
|
|
|
}
|