| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263 |
- /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2019-05-16 heyuanjie87 first version
- */
- #include "airkiss.h"
- #include <string.h>
- #include <stdint.h>
- #ifdef AIRKISS_LOG_ENABLE
- #define AKLOG_D \
- if (lc->cfg && lc->cfg->printf) \
- lc->cfg->printf
- #else
- #define AKLOG_D(...)
- #endif
- #define AKSTATE_WFG 0
- #define AKSTATE_WFM 1
- #define AKSTATE_WFP 2
- #define AKSTATE_WFD 4
- #define AKSTATE_CMP 5
- typedef uint16_t akwire_seq_t;
- typedef struct
- {
- uint16_t val[6];
- uint8_t pos;
- uint8_t scnt; /* 成功计数 */
- uint8_t err;
- uint8_t rcnt; /* 接收计数 */
- } akcode_t;
- typedef struct
- {
- akwire_seq_t ws;
- uint8_t crc;
- uint8_t ind;
- }akdatf_seq_t;
- typedef struct
- {
- uint8_t crc;
- uint8_t ind;
- }akdatf_header_t;
- typedef struct
- {
- uint8_t id[4];
- }akaddr_t;
- typedef struct
- {
- akwire_seq_t ws;
- uint8_t val[4];
- uint8_t pos : 4;
- uint8_t scnt : 4;
- uint8_t err;
- uint8_t wval;
- uint8_t seqcnt;
- akaddr_t sa;
- } akcode_guide_t;
- typedef struct
- {
- char data[16]; /* 保留后4个 */
- uint8_t pos[16];
- }akdatf_conflict_t;
- typedef struct
- {
- union {
- akcode_guide_t code1[3];
- akcode_t code2[1];
- } uc;
- akdatf_conflict_t dcfl; /* 记录有冲突的数据 */
- akwire_seq_t prews;
- akdatf_seq_t preseq;
- akdatf_seq_t curseq;
- akdatf_header_t pendseq[10]; /* 未完成的序列 */
- akaddr_t locked;
- uint8_t seqstep;/* 序列增量 */
- uint8_t reclen;
- uint8_t state;
- uint8_t nossid;
- uint8_t seq[16]; /* 标记已完成的序列 */
- char data[66];
- uint8_t random;
- uint8_t baselen;
- uint8_t prslen;
- uint8_t ssidcrc;
- uint8_t pwdlen;
- const airkiss_config_t *cfg;
- } akloc_context_t;
- #define AKLOC_CODE1(x, i) ((x)->uc.code1[i])
- #define AKLOC_CODE2(x) (&(x)->uc.code2[0])
- #define AKLOC_DFSEQ_PREV(lc) ((lc)->preseq)
- #define AKLOC_DFSEQ_CUR(lc) ((lc)->curseq)
- unsigned char airkiss_crc8(unsigned char *message, unsigned char len)
- {
- uint8_t crc = 0;
- uint8_t i;
- while (len--)
- {
- crc ^= *message++;
- for (i = 0; i < 8; i++)
- {
- if (crc & 0x01)
- crc = (crc >> 1) ^ 0x8c;
- else
- crc >>= 1;
- }
- }
- return crc;
- }
- static akwire_seq_t akwseq_make(uint8_t seq[2])
- {
- akwire_seq_t ws = 0;
- ws = (seq[1] << 4) | (seq[0] >> 4);
- return ws;
- }
- static void akloc_reset(akloc_context_t *lc)
- {
- const airkiss_config_t *cfg;
- cfg = lc->cfg;
- memset(lc, 0, sizeof(*lc));
- lc->cfg = cfg;
- }
- static uint8_t akinfo_getu8(uint16_t v[2])
- {
- uint8_t ret = 0;
- ret = ((v[0] & 0xF) << 4) | (v[1] & 0xF);
- return ret;
- }
- static uint16_t aklen_udp(akloc_context_t *lc, uint16_t len)
- {
- return (len - lc->baselen);
- }
- static int ak_get_magicfield(akloc_context_t *lc, akcode_t *ac)
- {
- int ret = 1;
- if (ac->val[0] == 8)
- ac->val[0] = 0;
- lc->prslen = akinfo_getu8(&ac->val[0]);
- lc->ssidcrc = akinfo_getu8(&ac->val[2]);
- if (lc->prslen > (sizeof(lc->data) - 1))
- {
- ret = 0;
- AKLOG_D("prslen(%d) large than(%d)", lc->prslen, (sizeof(lc->data) - 1));
- }
- return ret;
- }
- static int ak_magicfield_input(akcode_t *ac, uint16_t len)
- {
- int mc;
- mc = len >> 4;
- if (mc == 0)
- {
- ac->val[0] = len;
- ac->pos = 1;
- }
- else if (mc == ac->pos)
- {
- ac->val[ac->pos] = len;
- ac->pos ++;
- }
- else
- {
- ac->pos = 0;
- }
- return (ac->pos == 4);
- }
- static int ak_get_prefixfield(akloc_context_t *lc, akcode_t *ac)
- {
- int ret;
- uint8_t crc;
- lc->pwdlen = akinfo_getu8(&ac->val[0]);
- crc = akinfo_getu8(&ac->val[2]);
- if (airkiss_crc8(&lc->pwdlen, 1) != crc)
- ret = 0;
- return ret;
- }
- static int ak_prefixfield_input(akcode_t *ac, uint16_t len)
- {
- int mc;
- mc = len >> 4;
- if (mc == 4)
- {
- ac->val[0] = len;
- ac->pos = 1;
- }
- else if (mc == (ac->pos + 4))
- {
- ac->val[ac->pos] = len;
- ac->pos ++;
- }
- else
- {
- ac->pos = 0;
- }
- return (ac->pos == 4);
- }
- static int ak_get_datafield(akloc_context_t *lc, akcode_t *ac)
- {
- uint8_t tmp[6];
- int n;
- int ret = 0;
- int pos;
- int seqi;
- seqi = ac->val[1] & 0x7f;
- if (seqi > (lc->prslen/4))
- {
- return 0;
- }
- if (lc->seq[seqi])
- return 0;
- pos = seqi * 4;
- n = lc->prslen - pos;
- if (n > 4)
- n = 4;
- tmp[0] = ac->val[0] & 0x7F;
- tmp[1] = ac->val[1] & 0x7F;
- tmp[2] = ac->val[2] & 0xFF;
- tmp[3] = ac->val[3] & 0xFF;
- tmp[4] = ac->val[4] & 0xFF;
- tmp[5] = ac->val[5] & 0xFF;
- ret = ((airkiss_crc8(&tmp[1], n + 1) & 0x7F) == tmp[0]);
- if (ret)
- {
- memcpy(&lc->data[pos], &tmp[2], n);
- lc->reclen += n;
- lc->seq[seqi] = 1;
- #ifdef AIRKISS_LOG_GDO_ENABLE
- AKLOG_D("getdata(%d, %d)\n", seqi, n);
- #endif
- }
- return ret;
- }
- static void akaddr_fromframe(akaddr_t *a, uint8_t *f)
- {
- f += 10;
- a->id[0] = f[4];
- a->id[1] = f[5];
- a->id[2] = f[10];
- a->id[3] = f[11];
- }
- static akcode_guide_t *ak_guide_getcode(akloc_context_t *lc, unsigned char *f)
- {
- akcode_guide_t *ac;
- if (f == NULL) /* 是模拟测试 */
- {
- ac = &AKLOC_CODE1(lc, 2);
- }
- else
- {
- akaddr_t sa;
- unsigned i;
- int found = 0;
- akcode_guide_t *imin;
- akaddr_fromframe(&sa, f);
- imin = &AKLOC_CODE1(lc, 0);
- ac = imin;
- for (i = 0; i < sizeof(lc->uc.code1) / sizeof(lc->uc.code1[0]); i++)
- {
- /* 匹配地址 */
- found = !memcmp(&sa, &ac->sa, sizeof(ac->sa));
- if (found)
- break;
- /* 记录权值最小的 */
- if (ac->wval < imin->wval)
- imin = ac;
- ac++;
- }
- if (!found)
- {
- /* 淘汰输入最少的 */
- ac = imin;
- ac->pos = 0;
- ac->err = 0;
- ac->scnt = 0;
- ac->wval = 0;
- ac->sa = sa;
- }
- }
- return ac;
- }
- static int ak_guidefield_input(akcode_guide_t *ac, uint8_t *f, uint16_t len)
- {
- akwire_seq_t ws = 0;
- if (f)
- ws = akwseq_make(f + 22);
- if (ac->pos < 4)
- {
- if ((ac->pos != 0) && ((len - ac->val[ac->pos - 1]) != 1))
- {
- ac->pos = 0;
- if (ac->wval > 0)
- ac->wval--;
- }
- if (ac->pos == 0)
- {
- ac->ws = ws;
- ac->seqcnt = 0;
- }
- ac->seqcnt += (ws - ac->ws);
- ac->val[ac->pos] = len;
- ac->pos++;
- ac->wval += ac->pos;
- }
- return (ac->pos == 4);
- }
- static int ak_waitfor_guidefield(akloc_context_t *lc, uint8_t *f, uint16_t len)
- {
- int ret = AIRKISS_STATUS_CONTINUE;
- akcode_guide_t *ac;
- ac = ak_guide_getcode(lc, f);
- if (ak_guidefield_input(ac, f, len))
- {
- ac->pos = 0;
- ac->scnt++;
- /* 至少两次相同的guide code才算获取成功 */
- if ((ac->scnt >= 2) && ac->wval >= 20)
- {
- lc->state = AKSTATE_WFM;
- lc->baselen = ac->val[0] - 1;
- lc->seqstep = ac->seqcnt/6;
- AKLOG_D("guide baselen(%d) seqstep(%d)\n", lc->baselen, lc->seqstep);
- }
- if (lc->state == AKSTATE_WFM)
- {
- lc->locked = ac->sa;
- memset(&lc->uc, 0, sizeof(lc->uc));
- ret = AIRKISS_STATUS_CHANNEL_LOCKED;
- }
- }
- return ret;
- }
- static int ak_waitfor_magicfield(akloc_context_t *lc, uint16_t len)
- {
- int ret = AIRKISS_STATUS_CONTINUE;
- akcode_t *ac = AKLOC_CODE2(lc);
- int udplen;
- udplen = aklen_udp(lc, len);
- if (ak_magicfield_input(ac, udplen))
- {
- ac->pos = 0;
- if (ak_get_magicfield(lc, ac))
- {
- lc->state = AKSTATE_WFP;
- AKLOG_D("magic: prslen(%d) ssidcrc(%X)\n", lc->prslen, lc->ssidcrc);
- }
- }
- if (ac->rcnt++ > 250)
- {
- akloc_reset(lc);
- AKLOG_D("reset from magic\n");
- }
- return ret;
- }
- static int ak_waitfor_prefixfield(akloc_context_t *lc, uint16_t len)
- {
- int ret = AIRKISS_STATUS_CONTINUE;
- akcode_t *ac = AKLOC_CODE2(lc);
- int udplen;
- udplen = aklen_udp(lc, len);
- if (ak_prefixfield_input(ac, udplen))
- {
- ac->pos = 0;
- if (ak_get_prefixfield(lc, ac))
- {
- lc->state = AKSTATE_WFD;
- AKLOG_D("prefix: pwdlen(%d)\n", lc->pwdlen);
- }
- }
- return ret;
- }
- #ifdef AIRKISS_LOG_DFDUMP_ENABLE
- static void akdata_dump(akloc_context_t *lc, uint8_t *f, uint16_t len)
- {
- uint8_t seq[2];
- uint16_t dseq;
- seq[0] = f[22];
- seq[1] = f[23];
- dseq = (seq[1] << 4) | (seq[0]>> 4);
- if (len & 0x100)
- {
- AKLOG_D("(%d) %X %c", dseq, len, len & 0xff);
- }
- else
- {
- AKLOG_D("(%d) %X", dseq, len);
- }
- }
- #endif
- /*
- 只判断密码和random是否收完
- */
- static int ak_is_pwdrand_complete(akloc_context_t *lc)
- {
- int ret = 0;
- unsigned i;
- int n = 0;
- for (i = 0; i < (sizeof(lc->seq) / sizeof(lc->seq[0])); i++)
- {
- if (lc->seq[i] == 0)
- break;
- n += 4;
- if (n >= (lc->pwdlen + 1))
- {
- ret = 1;
- break;
- }
- }
- return ret;
- }
- static int ak_datainput_onlylength(akloc_context_t *lc, akcode_t *ac, uint16_t len)
- {
- int n = 6;
- if (len & 0x100)
- {
- if (ac->pos > 1)
- {
- int size;
- ac->val[ac->pos] = len;
- ac->pos ++;
- size = (ac->val[1] & 0x7f) * 4;
- if (size < lc->prslen)
- {
- size = lc->prslen - size;
- if (size < 4) /* 最后一个包不足4 */
- {
- n = size + 2;
- }
- }
- }
- else
- {
- ac->pos = 0;
- }
- }
- else
- {
- if (ac->pos < 2)
- {
- ac->val[ac->pos] = len;
- ac->pos ++;
- }
- else
- {
- ac->val[0] = len;
- ac->pos = 1;
- }
- }
- return (ac->pos == n);
- }
- static akdatf_header_t* akseq_getpend(akloc_context_t *lc, uint8_t ind)
- {
- akdatf_header_t* ret = 0;
- unsigned i;
- for (i = 0; i < sizeof(lc->pendseq)/sizeof(lc->pendseq[0]); i ++)
- {
- akdatf_header_t *p = &lc->pendseq[i];
- if (p->ind == ind)
- {
- ret = p;
- break;
- }
- }
- return ret;
- }
- static int ak_pendinput_mark(akloc_context_t *lc, uint8_t ind)
- {
- int ret = 0;
- akdatf_header_t* pd;
- pd = akseq_getpend(lc, ind);
- if (pd)
- {
- int size, pos, i;
- char d[6] = {0};
- uint8_t crc;
- ind = ind & 0x7f;
- pos = ind * 4;
- size = lc->prslen - pos;
- if (size > 4)
- size = 4;
- for (i = 0; i < size; i ++)
- {
- if (lc->data[pos + i] == 0)
- return 0;
- }
- d[0] = ind;
- memcpy(&d[1], &lc->data[pos], size);
- crc = airkiss_crc8((uint8_t*)d, size + 1) & 0x7f;
- if (crc == (pd->crc & 0x7f))
- {
- memset(pd, 0, sizeof(*pd));
- lc->seq[ind] = 1;
- lc->reclen += size;
- ret = 1;
- #ifdef AIRKISS_LOG_GDO_ENABLE
- AKLOG_D("getdata-p(%d, %d)[%s]", ind, size, &d[1]);
- #endif
- }
- }
- return ret;
- }
- static int ak_penddata_getpos(akloc_context_t *lc, akdatf_seq_t *ref, akwire_seq_t ws)
- {
- int ret = -1;
- uint8_t refind, ind;
- int offs;
- if (ws < ref->ws)
- {//todo
- AKLOG_D("ws-d overflow(%d, %d)", ws, ref->ws);
- }
- else
- {
- int maxoffs;
- int fmpos;
- offs = (ws - ref->ws)/lc->seqstep;
- if ((offs % 6) < 2)
- return -1;
- maxoffs = lc->prslen + ((lc->prslen + 3)/4) * 2;
- if (offs > maxoffs) /* 相差太大出错几率增大 */
- return ret;
- refind = ref->ind & 0x7f;
- fmpos = refind * 6 + offs;
- fmpos = fmpos % maxoffs; /* 指向下一轮 */
- ind = fmpos/6;
- ret = ind * 4 + (fmpos % 6) - 2;
- }
- return ret;
- }
- static int ak_pendcrc_getpos(akloc_context_t *lc, akdatf_seq_t *ref, akwire_seq_t ws)
- {
- int offs;
- int pos = -1;
- int maxoffs;
- maxoffs = lc->prslen + ((lc->prslen + 3)/4) * 2;
- if (ws < ref->ws)
- {//todo
- AKLOG_D("ws-c overflow(%d, %d)", ws, ref->ws);
- }
- else
- {
- offs = (ws - ref->ws)/lc->seqstep;
- if (offs > maxoffs)
- return -1;
- offs = offs + (ref->ind & 0x7f) * 6;
- offs = offs % maxoffs;
- pos = (offs/6) | 0x80;
- }
- return pos;
- }
- static void ak_dataconflict_add(akloc_context_t *lc, uint8_t pos, uint8_t d, int mode)
- {
- unsigned i;
- int zi = -1;
- int s, e;
- pos ++;
- if (mode == 0)
- {
- s = 0;
- e = sizeof(lc->dcfl.pos) - 4;
- }
- else
- {
- s = sizeof(lc->dcfl.pos) - 4;
- e = sizeof(lc->dcfl.pos);
- }
- for (i = s; i < e; i ++)
- {
- if ((lc->dcfl.pos[i] == pos) && (lc->dcfl.data[i] == d))
- return;
- if (lc->dcfl.pos[i] == 0)
- zi = i;
- }
- if (zi >= 0)
- {
- lc->dcfl.data[zi] = d;
- lc->dcfl.pos[zi] = pos;
- }
- }
- static int ak_dataconflict_getchar(akloc_context_t *lc, uint8_t pos, uint8_t *cpos)
- {
- int ch = -1;
- uint8_t i;
- if (*cpos >= sizeof(lc->dcfl.pos))
- return -1;
- pos ++;
- for (i = *cpos; i < sizeof(lc->dcfl.pos); i ++)
- {
- if (lc->dcfl.pos[i] == pos)
- {
- ch = lc->dcfl.data[i];
- i ++;
- break;
- }
- }
- *cpos = i;
- return ch;
- }
- static void ak_dataconflict_clear(akloc_context_t *lc, int pos)
- {
- unsigned i;
- if (pos < 0)
- {
- i = sizeof(lc->dcfl.pos) - 4;
- for (; i < sizeof(lc->dcfl.pos); i ++)
- {
- lc->dcfl.pos[i] = 0;
- lc->dcfl.data[i] = 0;
- }
- }
- else
- {
- pos ++;
- for (i = 0; i < sizeof(lc->dcfl.pos) - 4; i ++)
- {
- if (lc->dcfl.pos[i] == pos)
- {
- lc->dcfl.pos[i] = 0;
- lc->dcfl.data[i] = 0;
- }
- }
- }
- }
- static int _dataconflict_crccheck(akloc_context_t *lc, akdatf_header_t* pd, uint8_t dpos, char *d, int size)
- {
- int ret = 0;
- uint8_t crc;
- crc = airkiss_crc8((uint8_t*)d, size + 1) & 0x7f;
- if (crc == (pd->crc & 0x7f))
- {
- int pos;
- pos = (pd->ind & 0x7f) * 4;
- memcpy(&lc->data[pos], &d[1], size);
- memset(pd, 0, sizeof(*pd));
- lc->seq[(uint8_t)d[0]] = 1;
- lc->reclen += size;
- ak_dataconflict_clear(lc, dpos);
- ret = 1;
- #ifdef AIRKISS_LOG_GDO_ENABLE
- AKLOG_D("getdata-c(%d, %d)[%s]", d[0], size, &d[1]);
- #endif
- }
- return ret;
- }
- static int ak_dataconflict_crccheck(akloc_context_t *lc, akdatf_header_t* pd, int size)
- {
- char d[6] = {0};
- uint8_t spos;
- uint8_t cflpos0 = 0, cflpos1 = 0, cflpos2 = 0, cflpos3 = 0;
- int i;
- d[0] = pd->ind & 0x7f;
- spos = d[0] * 4;
- /* 把所有冲突的数据都校验一遍 */
- for (i = 0; i < size; i ++)
- {
- ak_dataconflict_add(lc, spos + i, lc->data[spos + i], 1);
- }
- while (size > 0)
- {
- int ch;
- ch = ak_dataconflict_getchar(lc, spos + 0, &cflpos0);
- if (ch < 0)
- break;
- d[1] = ch;
- cflpos1 = 0;
- while (size > 1)
- {
- int ch;
- ch = ak_dataconflict_getchar(lc, spos + 1, &cflpos1);
- if (ch < 0)
- break;
- d[2] = ch;
- cflpos2 = 0;
- while (size > 2)
- {
- int ch;
- ch = ak_dataconflict_getchar(lc, spos + 2, &cflpos2);
- if (ch < 0)
- break;
- d[3] = ch;
- cflpos3 = 0;
- while (size > 3)
- {
- int ch;
- ch = ak_dataconflict_getchar(lc, spos + 3, &cflpos3);
- if (ch < 0)
- break;
- d[4] = ch;
- if (_dataconflict_crccheck(lc, pd, spos + 3, d, size))
- {
- goto _out;
- }
- }
- }
- }
- }
- _out:
- ak_dataconflict_clear(lc, -1);
- return 0;
- }
- static int ak_dataconflict_input(akloc_context_t *lc, uint8_t ind, uint8_t pos, uint8_t data)
- {
- int ret = 0;
- int i;
- int size;
- int spos;
- akdatf_header_t* pd;
- spos = ind * 4;
- size = lc->prslen - spos;
- if (size > 4)
- size = 4;
- ak_dataconflict_add(lc, pos, data, 0);
- /* 检查接收是否足够 */
- for (i = 0; i < size; i ++)
- {
- if (lc->data[spos + i] == 0)
- {
- return 0;
- }
- }
- /* 查找包头 */
- pd = akseq_getpend(lc, ind | 0x80);
- if (!pd)
- return 0;
- ret = ak_dataconflict_crccheck(lc, pd, size);
- return ret;
- }
- static int ak_databody_input(akloc_context_t *lc, akdatf_seq_t *ref, akwire_seq_t ws, uint8_t data)
- {
- int pos;
- uint8_t ind;
- uint8_t dif;
- /* 与上一个帧相差太大则不接受 */
- dif = (ws - lc->prews)/lc->seqstep;
- if (dif > 5)
- return 0;
- pos = ak_penddata_getpos(lc, ref, ws);
- if (pos < 0)
- {
- return 0;
- }
- ind = pos / 4;
- if (lc->seq[ind])
- {
- return 0;
- }
- #if AIRKISS_LOG_RIO_ENABLE
- AKLOG_D("ref(%d %X) input(%d) %c", ref->ws, ref->ind, pos, data);
- #endif
- if (lc->data[pos] == 0)
- {
- lc->data[pos] = data;
- ak_pendinput_mark(lc, ind | 0x80);
- }
- else if (lc->data[pos] != data)
- {
- /* 出现数据冲突 */
- ak_dataconflict_input(lc, ind, (uint8_t)pos, data);
- }
- return 1;
- }
- static void akseq_allocpend(akloc_context_t *lc, uint8_t crc, uint8_t ind)
- {
- akdatf_header_t *found = 0, *idle = 0;
- unsigned i;
- if (lc->seq[ind & 0x7f])
- return;
- AKLOG_D("{%X %X}", crc, ind);
- idle = &lc->pendseq[0];
- for (i = 0; i < sizeof(lc->pendseq)/sizeof(lc->pendseq[0]); i ++)
- {
- akdatf_header_t *p = &lc->pendseq[i];
- if (p->ind == ind)
- {
- found = p;
- p->crc = crc;
- break;
- }
- if (p->crc == 0)
- idle = p;
- }
- if (found == NULL)
- {
- found = idle;
- found->crc = crc;
- found->ind = ind;
- }
- }
- static void ak_datahead_input(akloc_context_t *lc, akdatf_seq_t *cur, akwire_seq_t ws, uint8_t head)
- {
- int seqmax;
- uint8_t dif;
- seqmax = (lc->prslen/4) | 0x80;
- if (cur->crc != 0)
- {
- dif = (ws - cur->ws)/lc->seqstep;
- if (head <= seqmax)
- {
- cur->ind = head;
- cur->ws = ws - lc->seqstep;
- AKLOC_DFSEQ_PREV(lc) = *cur;
- if (dif < 3)
- {
- /* 暂存包头 */
- akseq_allocpend(lc, cur->crc, cur->ind);
- }
- }
- if (head > seqmax)
- {
- cur->crc = head;
- cur->ind = 0;
- cur->ws = ws;
- }
- }
- else
- {
- if (head > seqmax) //很大几率是crc
- {
- cur->crc = head;
- cur->ws = ws;
- cur->ind = 0;
- }
- else if (ak_pendcrc_getpos(lc, cur, ws) == head)
- {
- /* 没收到crc */
- cur->ind = head;
- cur->ws = ws - lc->seqstep; /* 设置crc的帧序号 */
- }
- }
- }
- static int ak_datainput_withwireseq(akloc_context_t *lc, uint8_t *f, uint16_t len)
- {
- akwire_seq_t ws;
- akdatf_seq_t *cur;
- ws = akwseq_make(f + 22);
- cur = &AKLOC_DFSEQ_CUR(lc);
- if (len & 0x100) /* 输入数据 */
- {
- akdatf_seq_t *ref;
- ref = &AKLOC_DFSEQ_PREV(lc);
- if ((cur->ind == 0) && (cur->crc != 0))
- {
- int pos;
- /* 如果只收到了crc就根据前一个包推测一个序号 */
- pos = ak_pendcrc_getpos(lc, ref, ws);
- if (pos > 0)
- {
- cur->ind = (uint8_t)pos;
- akseq_allocpend(lc, cur->crc, cur->ind);
- }
- }
- if (cur->ind)
- {
- if (!ak_databody_input(lc, cur, ws, len))
- {
- memset(&AKLOC_DFSEQ_CUR(lc), 0 , sizeof(*cur));
- }
- if (lc->reclen == lc->prslen)
- {
- lc->state = AKSTATE_CMP;
- }
- }
- AKLOC_DFSEQ_CUR(lc).crc = 0;/* 标记已收到数据 */
- }
- else
- {
- /* 输入包头 */
- ak_datahead_input(lc, cur, ws, len);
- }
- lc->prews = ws;
- return 0;
- }
- static int ak_waitfor_datafield(akloc_context_t *lc, uint8_t *f, uint16_t len, int nossid)
- {
- int ret = AIRKISS_STATUS_CONTINUE;
- akcode_t *ac = AKLOC_CODE2(lc);
- uint16_t udplen;
- udplen = aklen_udp(lc, len);
- if (udplen < 0x80)
- {
- return ret;
- }
- #ifdef AIRKISS_LOG_DFDUMP_ENABLE
- if (f)
- {
- akdata_dump(lc, f, udplen);
- }
- #endif
- if (ak_datainput_onlylength(lc, ac, udplen))
- {
- ac->pos = 0;
- ak_get_datafield(lc, ac);
- if (lc->reclen == lc->prslen)
- {
- lc->state = AKSTATE_CMP;
- goto _out;
- }
- }
- if (f)
- {
- ak_datainput_withwireseq(lc, f, udplen);
- }
- if (nossid && ak_is_pwdrand_complete(lc))
- {
- lc->state = AKSTATE_CMP;
- AKLOG_D("data complete nossid\n");
- }
- _out:
- if (lc->state == AKSTATE_CMP)
- {
- lc->nossid = nossid;
- ret = AIRKISS_STATUS_COMPLETE;
- }
- return ret;
- }
- static int ak_sa_filter(akloc_context_t *lc, uint8_t *f)
- {
- int ret = 0;
- if (lc->state != AKSTATE_WFG)
- {
- akaddr_t sa;
- akaddr_fromframe(&sa, f);
- ret = memcmp(&lc->locked, &sa, sizeof(sa));
- }
- return ret;
- }
- int airkiss_filter(const void *f, int len)
- {
- int ret = 0;
- unsigned char *da, *p;
- int i;
- p = (unsigned char *)f;
- if ((len < 25) || (p[0] != 0x08))
- return 1;
- da = p + 4;
- for (i = 0; i < 6; i++)
- {
- if (da[i] != 0xFF)
- {
- ret = 1;
- break;
- }
- }
- return ret;
- }
- static int _ak_recv(airkiss_context_t *c, const void *frame, uint16_t length, int nossid)
- {
- int ret = AIRKISS_STATUS_CONTINUE;
- akloc_context_t *lc = (akloc_context_t *)c;
- unsigned char *f = (unsigned char *)frame;
- if (frame != NULL) /* 模拟测试时可只传length */
- {
- if (airkiss_filter(frame, length))
- return ret;
- if (ak_sa_filter(lc, f))
- return ret;
- }
- switch (lc->state)
- {
- case AKSTATE_WFG:
- {
- ret = ak_waitfor_guidefield(lc, f, length);
- }
- break;
- case AKSTATE_WFM:
- {
- ret = ak_waitfor_magicfield(lc, length);
- }
- break;
- case AKSTATE_WFP:
- {
- ret = ak_waitfor_prefixfield(lc, length);
- }
- break;
- case AKSTATE_WFD:
- {
- ret = ak_waitfor_datafield(lc, f, length, nossid);
- }
- break;
- case AKSTATE_CMP:
- {
- ret = AIRKISS_STATUS_COMPLETE;
- }
- break;
- }
- return ret;
- }
- const char *airkiss_version(void)
- {
- return "airkiss-1.0.0-open";
- }
- int airkiss_init(airkiss_context_t *c, const airkiss_config_t *config)
- {
- akloc_context_t *lc = (akloc_context_t *)c;
- lc->cfg = config;
- akloc_reset(lc);
- return 0;
- }
- int airkiss_recv(airkiss_context_t *c, const void *frame, unsigned short length)
- {
- return _ak_recv(c, frame, length, 0);
- }
- int airkiss_get_result(airkiss_context_t *c, airkiss_result_t *res)
- {
- akloc_context_t *lc = (akloc_context_t *)c;
- if (lc->state != AKSTATE_CMP)
- return -1;
- res->pwd = (char *)&lc->data[0];
- res->pwd_length = lc->pwdlen;
- if (lc->data[lc->pwdlen] == 0)
- {
- res->random = lc->random;
- }
- else
- {
- res->random = lc->data[lc->pwdlen];
- lc->random = lc->data[lc->pwdlen];
- lc->data[lc->pwdlen] = 0;
- }
- res->ssid_crc = lc->ssidcrc;
- if (lc->nossid)
- {
- res->ssid = "";
- res->ssid_length = 0;
- }
- else
- {
- res->ssid = (char *)&lc->data[lc->pwdlen + 1];
- res->ssid_length = lc->prslen - lc->pwdlen - 1;
- }
- lc->data[lc->prslen] = 0;
- return 0;
- }
- int airkiss_recv_nossid(airkiss_context_t *c, const void *frame, unsigned short length)
- {
- return _ak_recv(c, frame, length, 1);
- }
- int airkiss_change_channel(airkiss_context_t *c)
- {
- akloc_context_t *lc = (akloc_context_t *)c;
- akloc_reset(lc);
- return 0;
- }
|