#include "../os/linux/osal.h"
#include "../lib/sccb.h"
#include "msc.h"
#include "../lib/plat.h"
#include "rtmp_comm.h"
#include "rt_os_util.h"
#include "rt_os_net.h"
#include "rt_config.h"
static unsigned char msc_listen_chls[] = {1, 6, 11, 2, 5, 7, 1, 6, 11, 10, 12, 3, 1, 6, 11, 8, 13, 4, 9};
#if 0
struct chan_info msc_listen_chls[] = {
{1, MSC_CHAN_WIDTH_40_PLUS, 0},
{6, MSC_CHAN_WIDTH_40_PLUS, 0},
{6, MSC_CHAN_WIDTH_40_MINUS, 0},
{11, MSC_CHAN_WIDTH_40_MINUS, 0},
{2, MSC_CHAN_WIDTH_40_PLUS, 0},
{5, MSC_CHAN_WIDTH_40_PLUS, 0},
{5, MSC_CHAN_WIDTH_40_MINUS, 0},
{7, MSC_CHAN_WIDTH_40_PLUS, 0},
{7, MSC_CHAN_WIDTH_40_MINUS, 0},
{1, MSC_CHAN_WIDTH_40_PLUS, 0},
{6, MSC_CHAN_WIDTH_40_PLUS, 0},
{6, MSC_CHAN_WIDTH_40_MINUS, 0},
{11, MSC_CHAN_WIDTH_40_MINUS, 0},
{10, MSC_CHAN_WIDTH_40_MINUS, 0},
{12, MSC_CHAN_WIDTH_40_MINUS, 0},
{3, MSC_CHAN_WIDTH_40_PLUS, 0},
{1, MSC_CHAN_WIDTH_40_PLUS, 0},
{6, MSC_CHAN_WIDTH_40_PLUS, 0},
{6, MSC_CHAN_WIDTH_40_MINUS, 0},
{11, MSC_CHAN_WIDTH_40_MINUS, 0},
{8, MSC_CHAN_WIDTH_40_MINUS, 0},
{13, MSC_CHAN_WIDTH_40_MINUS, 0},
{4, MSC_CHAN_WIDTH_40_PLUS, 0},
{9, MSC_CHAN_WIDTH_40_MINUS, 0},
};
#endif
#define MSC_CHANNEL_DWELL_TIME 800 //ms in unit
/* On linux OS, timer handler is running in INTR context.
It can't call any function which may cause sleep. we have
to handle this case carefully.
*/
//TODO: thread or timer? which one is better.
#define MSC_CHANNEL_SWITCH_USE_THREAD 1
struct msc_contex {
/* event call back, when received ssid&pwd,
this function will be call with parameter
struct msc_param. */
msc_evt_cb evt_cb;
#if MSC_CHANNEL_SWITCH_USE_THREAD
osal_thread chl_thread;
int chl_thread_running;
bool chl_thread_switch_stop;
bool is_thread_run_to_end;
#else
osal_timer timer;
#endif
unsigned int chl_num;
unsigned char *channel;
struct monitor_info m_info;
spinlock_t lock;
int cur_chl;
#define MSC_STATE_STARTED 1
#define MSC_STATE_STOPED 0
int state;
void *priv;
} msc_ctx;
static void msc_core_evt_cbk(enum eevent_id eid);
#if MSC_CHANNEL_SWITCH_USE_THREAD
static int chl_switch_thread(void *data);
#else
static void timeout_handler(unsigned long data);
#endif
static int msc_init(struct msc_param *param, void *priv);
inline int msc_msleep(unsigned int ms)
{
//msleep(ms);
OS_WAIT(ms);
return 0;
}
int msc_get_current_channel_info(void)
{
int cur_chl = 0;
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(msc_ctx.priv);
cur_chl = pAd->CommonCfg.Channel;
MSC_PRINT(MSC_DEBUG_INFO,("[MSC] current channel = %d\n",cur_chl));
return cur_chl;
}
static void msc_core_evt_cbk(enum eevent_id eid)
{
// struct msc_param para = {0};
// int ret = 0;
switch(eid) {
case EVT_ID_SYNCSUC:
osal_lock(&msc_ctx.lock);
if (msc_ctx.chl_num > 1) {
#if MSC_CHANNEL_SWITCH_USE_THREAD
/*We don't used osal_thread_stop because this function
may cause sleep on linux(kthread_stop), and we this runtine
may be called from intr context.*/
msc_ctx.cur_chl = msc_get_current_channel_info();
msc_ctx.chl_thread_running = 0;
msc_ctx.chl_thread_switch_stop = 1;
MSC_PRINT(MSC_DEBUG_OFF,("[MSC]stop chl_switch thread.\n"));
//osal_thread_stop(&msc_ctx.chl_thread);
#else
osal_timer_stop(&msc_ctx.timer);
#endif
}
osal_unlock(&msc_ctx.lock);
break;
case EVT_ID_INFOGET:
osal_lock(&msc_ctx.lock);
sccb_disable_input();
if (msc_ctx.evt_cb)
msc_ctx.evt_cb(eid);
osal_unlock(&msc_ctx.lock);
break;
case EVT_ID_TIMEOUT:
msc_ctx.chl_thread_switch_stop = 0;
break;
default:
break;
}
return;
}
#if MSC_CHANNEL_SWITCH_USE_THREAD
static int chl_switch_thread(void *data)
{
int idx = 0;
struct chan_info chl_info;
chl_info.chan_id = 0;
chl_info.flags = 0x0;
chl_info.width = MSC_CHAN_WIDTH_40_PLUS;
//while(!osal_thread_should_stop(&msc_ctx.chl_thread)) {
while(1) {//msc_ctx.chl_thread_running) {
msc_msleep(MSC_CHANNEL_DWELL_TIME);
if(msc_ctx.chl_thread_switch_stop == 0)
{
osal_lock(&msc_ctx.lock);
if(!msc_ctx.chl_thread_running)
{
osal_unlock(&msc_ctx.lock);
break;
}
msc_ctx.is_thread_run_to_end = 0;
chl_info.chan_id = msc_ctx.channel[(idx++)%msc_ctx.chl_num];
if (chl_info.chan_id >= 8 && chl_info.chan_id <= 14) {
chl_info.width = MSC_CHAN_WIDTH_40_MINUS;
} else {
chl_info.width = MSC_CHAN_WIDTH_40_PLUS;
}
chl_info.flags = 0x0;
sccb_set_monitor_chan(&chl_info, msc_ctx.priv);
msc_ctx.is_thread_run_to_end = 1;
osal_unlock(&msc_ctx.lock);
}
else
{
idx = 0;
}
};
if ((msc_ctx.cur_chl != chl_info.chan_id) && (chl_info.chan_id != 0) && (msc_ctx.cur_chl != 0))
{
msc_msleep(100);
chl_info.chan_id = msc_ctx.cur_chl;
if (chl_info.chan_id >= 8 && chl_info.chan_id <= 14) {
chl_info.width = MSC_CHAN_WIDTH_40_MINUS;
} else {
chl_info.width = MSC_CHAN_WIDTH_40_PLUS;
}
chl_info.flags = 0x0;
sccb_set_monitor_chan(&chl_info, msc_ctx.priv);
MSC_PRINT(MSC_DEBUG_OFF,("[MSC] chl_info.chan_id = %d\n",chl_info.chan_id));
}
return 0;
}
#else
static void timeout_handler(unsigned long data)
{
static int idx = 0;
struct chan_info chl_info;
osal_lock(&msc_ctx.lock);
chl_info.chan_id = msc_ctx.channel[(idx++)%msc_ctx.chl_id];
if (chl_info.chan_id >= 8 && chl_info.chan_id <= 14) {
chl_info.width = MSC_CHAN_WIDTH_40_MINUS;
} else {
chl_info.width = MSC_CHAN_WIDTH_40_PLUS;
}
chl_info.flags = 0x0;
sccb_set_monitor_chan(&chl_info, msc_ctx.priv);
osal_timer_modify(&msc_ctx.timer, 1000);
osal_unlock(&msc_ctx.lock);
return;
}
#endif
struct efunc_table f_tbl = {
.report_evt = msc_core_evt_cbk,
.start_timer = sc_plt_add_timer,
.stop_timer = sc_plt_del_timer,
.aes128_decrypt = sc_plt_aes128_decrypt,
};
static int msc_init(struct msc_param *param, void *priv)
{
int ret = 0;
osal_memset(&msc_ctx, 0, sizeof(msc_ctx));
osal_lock_init(&msc_ctx.lock);
msc_ctx.evt_cb = param->evt_cb;
MSC_PRINT(MSC_DEBUG_OFF,("[MSC] Driver v 1.0.0\n"));
if (param->chl_num == 0) {
msc_ctx.channel = msc_listen_chls;
msc_ctx.chl_num = sizeof(msc_listen_chls);
} else {
msc_ctx.channel = param->chls;
msc_ctx.chl_num = param->chl_num;
}
ret = elian_init(sc_plt_get_la(priv), &f_tbl, param->key);
if (ret) {
MSC_PRINT(MSC_DEBUG_OFF,("[MSC] Get sc fsm init failed.\n"));
//Add error handler.
}
#if MSC_CHANNEL_SWITCH_USE_THREAD
msc_ctx.chl_thread.thread_func = chl_switch_thread;
msc_ctx.chl_thread.data = NULL;
strcpy(msc_ctx.chl_thread.name, "chl_switch");
osal_thread_create(&msc_ctx.chl_thread);
#else
msc_ctx.timer.timeoutHandler = timeout_handler;
osal_timer_create(&msc_ctx.timer);
#endif
return ret;
}
int msc_start(struct msc_param *param, void *priv)
{
int ret = 0;
if(msc_ctx.state == MSC_STATE_STARTED)
return 0;
msc_init(param, priv);
sccb_init(elian_input, NULL);
msc_ctx.m_info.filter = 0x00000000;
msc_ctx.m_info.priv = NULL;
msc_ctx.m_info.chl_info.chan_id = msc_ctx.channel[0];
if (msc_ctx.m_info.chl_info.chan_id >= 8 && msc_ctx.m_info.chl_info.chan_id <= 14) {
msc_ctx.m_info.chl_info.width = MSC_CHAN_WIDTH_40_MINUS;
} else {
msc_ctx.m_info.chl_info.width = MSC_CHAN_WIDTH_40_PLUS;
}
msc_ctx.m_info.chl_info.flags = 0x0;
msc_ctx.chl_thread_running = 1;
msc_ctx.chl_thread_switch_stop = 0;
msc_ctx.is_thread_run_to_end = 1;
msc_ctx.cur_chl = 0;
msc_ctx.priv = priv;
//msc_ctx.cur_chl = pAd->CommonCfg.Channel;
//MSC_WARN("[MSC] Current channel is [%d].\n", msc_ctx.cur_chl);
sccb_enable_input();
/* Config to monitor mode. */
//sccb_enter_monitor_mode(&msc_ctx.m_info, priv);
if (msc_ctx.chl_num > 1) {
#if MSC_CHANNEL_SWITCH_USE_THREAD
osal_thread_run(&msc_ctx.chl_thread);
#else
osal_timer_start(&msc_ctx.timer, 1000);
#endif
}
msc_ctx.state = MSC_STATE_STARTED;
return ret;
}
void msc_stop(void *priv)
{
unsigned int count=0;
bool timeout = 0;
if (msc_ctx.state == MSC_STATE_STOPED)
return;
osal_lock(&msc_ctx.lock);
if (msc_ctx.chl_num > 1) {
#if MSC_CHANNEL_SWITCH_USE_THREAD
/* Avoid INTR cont
MTK elian 一键配网 有详细操作流程
1星 需积分: 39 48 浏览量
2018-07-14
09:10:59
上传
评论
收藏 89KB RAR 举报
Raigorfeacher
- 粉丝: 4
- 资源: 2
最新资源
- 80632180.jpg
- 李旭国体注入追踪[5.0](1).zip
- semantic.c
- C语言基础-C语言编程基础之Leetcode编程题解之第39题组合总和.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第38题外观数列.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第37题解数独.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第36题有效的数独.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第35题搜索插入位置.zip
- index.wxml
- C语言基础-C语言编程基础之Leetcode编程题解之第33题搜索旋转排序数组.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈