无线网络隔离设计和开发

文章讲述了如何通过设备型号实现无线通信设备的快速认证,利用自定义的二进制文件存储设备信息,包括型号、制造商等,并介绍了如何读取和调试这些信息。同时提到了在软件设计中的交互和线程使用问题。
摘要由CSDN通过智能技术生成


前言

该软件用于将不同型号的无线通信设备隔离开,由于目前的无线 WIFI 都是通过 SSID 和 KEY 来连接的。虽然有黑名单系统,但是黑名单系统从底层看是禁止了特定 MAC 地址的设备连接。这样就有一个问题,不可能每次生产一批设备,都要去改变之前卖给客户的设备的黑名单吧???
所以需要在连接时进行快速认证,认证结果将保存在进程中,掉电后会重新认证。这是考虑到我们的设备用于远距离基站互联,一般不会掉电,并且约定了后续会不断提供升级版本,并且特殊的机制可以预防一切客户的奇葩操作。

一、主线交互设计

在这里插入图片描述
需要注意的是黑名单是自写的双链接结构,因为 WIFI 移植时标配的 wpa_supplicant 工具的黑名单是写进硬盘的,掉电不可重置。
由于每个设备的 SSID 是客户设定的,所以通过 80211cfg 接口获取设备的 MAC 地址。

而对于设备的型号,每个厂商都有提供写号工具,我所见过的就有例如:高通、MTK、瑞芯微。
写号工具一般是将一段信息写进一个二进制文件中,这个二进制文件在系统中是不可改的类型。
各种应用程序会通过读取这个型号,完成不同的初始化,例如:webui ,这个就可以直观的让客户以为是差异性非常大的设备。我的这个无线网络隔离软件,也是通过型号来完成不同的功能的。
总之,型号可以做到一份源码兼容很多不同设备。

不过我们也可以自己写。

二、设备型号实现

我们可以将想好一段标志集,然后设计成结构体,后面有用。

typedef struct
{
	char model[32];         //项目型号
	char mfr[32];           //生产厂商
	char sn[32];            //出厂写入SN号
	char smt_sn[32];        //SMT写入SN号
	char mac[32];           //MAC地址,通常是有线网口的MAC
	char ssid[32];      	//Wireless SSID
	char password[32];  	//Wireless 密码
	char user_mode;         //1 : 为用户模式。0:工厂模式(默认为0)   
	char rail_mode          //可扩展设备类型 0: 普通类别(默认值)。1:XXX类别。2.3.4...
	char reserve[1694];     //预留字段,device_info.bin总文件大小2KB
}T_DeviceInfo

然后用任意可以编辑二进制文件(.bin)的编辑器新建一个 .bin 文件,以 UltraEdit 为例子。
在这里插入图片描述
每一行即是32个字节,通过编辑右边的内容,bin 文件中的十六进制内容会做出相应的改动。
改完保存,编译系统镜像时,顺便把文件打包进系统一个安全的目录。

接下来就是如何读取这段信息了。
为了方便调试,系统中可以制作一个小工具,用于快速读取型号文件中的任何内容:

#define DEVICE_INFO_BIN "/userdata/data/config/device_info.bin"    //二进制文件的路径

T_DeviceInfo *DeviceInfo = NULL;                        //用于承接数据

T_JwDeviceInfo *Get_DeviceInfo(void)
{
    if (!DeviceInfo)
    {
        FILE *fp = fopen(DEVICE_INFO_BIN, "r");
        if (fp)
        {
            char buff[2048] = {};
            /* 假如该二进制文件读取出来的数据有头部,那么应该移动到头部的内存之后
            fseek(fp, 1048576, SEEK_SET);
            */
            fread(buff, 2048, 1, fp);
            fclose(fp);
            if (buff[0] && buff[0] != 0xff)
            {
                DeviceInfo = malloc(2048);
                if (DeviceInfo)
                    memcpy(DeviceInfo, buff, 2048);
                }
            }
        }
    return JwDeviceInfo;
}

int Main_Devinf(int32_t argc, cint8_t **argv)
{
    if (argc < 2) { LOG_PRINT("Need key string!\n"); return 1; }
    if (!Get_DeviceInfo()) { LOG_PRINT("\n"); return 1; }
    if (!strcmp(argv[1], "model")) LOG_PRINT("%s\n", Get_DeviceInfo()->model);
    else if (!strcmp(argv[1], "mfr")) LOG_PRINT("%s\n", Get_DeviceInfo()->mfr);
    else if (!strcmp(argv[1], "sn")) LOG_PRINT("%s\n", Get_DeviceInfo()->sn);
    else if (!strcmp(argv[1], "smt_sn")) LOG_PRINT("%s\n", Get_DeviceInfo()->smt_sn);
    else if (!strcmp(argv[1], "mac")) LOG_PRINT("%s\n", Get_DeviceInfo()->mac);
    else if (!strcmp(argv[1], "ssid_60g")) LOG_PRINT("%s\n", Get_DeviceInfo()->ssid);
    else if (!strcmp(argv[1], "password_60g")) LOG_PRINT("%s\n", Get_DeviceInfo()->password);
    else if (!strcmp(argv[1], "user_mode")) LOG_PRINT("%c\n", Get_DeviceInfo()->user_mode);
    else if (!strcmp(argv[1], "rail_mode")) LOG_PRINT("%c\n", Get_DeviceInfo()->rail_mode);
    else { LOG_PRINT("\n"); return 1; }
    return 0;
}

框架内部的具体实现

在这里插入图片描述
首先,本人并不是特别喜欢这个框架,因为这个框架有些离散,回调没有直接传递给任务需要信息,需要任务自己获取信息处理。
但是这个框架也确实在工作中制作出了一个小工具软件,并且十分稳定好用。
针对上面的传递信息的缺点,如果在一种情况:回调偏偏暂时无法获取足够的信息可以传递给任务呢?
那么只能告诉工作线程该干活了和干多少个活。

还有就是本人特别讨厌线程,凡是可以减少使用线程并且效果只要达到相近的,我都不想用线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值