AI-WB2-动态密码锁

说明
用AI-WB2实现一个动态密码锁。原理很简单,用随机数发生器生成一组密码,借助定时器每十分钟更新一次密码,开启一个http服务器,同步显示动态密码,借助内网穿透就可以在外面随时访问获取密码,应用在密码锁上就是一个随机动态密码锁。提供给访客临时用。
启动流程
- 启动
- 连接wifi
- 开启定时器每10分钟定时器中断一次
- 在中断回调函数中更新密码
- 开启http服务器,显示密码界面,以及一个倒计时更新进度条
- 访问静态页面获取密码,当进度条归零后,会自动更新页面保证获取密码的实时性
- 输入密码,解锁
代码示例
static void wifi_sta_connect(char *ssid, char *password) {
wifi_interface_t wifi_interface;
wifi_interface = wifi_mgmr_sta_enable();
wifi_mgmr_sta_connect(wifi_interface, ssid, password, NULL, NULL, 0, 0);
}
void flush_password(void *arg) {
count--;
if (count <= 0) {
if (Generate_password(lockpass) != SUCCESS) {
printf("[password]:error\r\n");
return;
}
printf("[password]:\t");
for (int i = 0; i < 6; i++) {
printf("%d\t", lockpass[i]);
}
printf("\r\n");
count = UPDATE_CYCLE;
}
}
// 更新锁任务
void updatelock_task(void *pvParameters) {
// 初始化锁
if (Generate_password(lockpass) != SUCCESS) {
printf("[LOCK]:init error");
return;
};
timer_init(timer, flush_password);
printf("[timer]:start\r\n");
hosal_timer_start(&timer);
while (1) {
//
}
}
int hosal_random_num_get(int range_min, int range_max) {
int status;
uint32_t buf; // 确保是 32 位整数
status = hosal_random_num_read(&buf, sizeof(buf));
if (!status) {
buf = abs(buf) % (range_max - range_min + 1) + range_min;
return buf;
}
return -1;
}
int Generate_password(char *passwd) {
for (int i = 0; i < 6; i++) {
LOCK_PASSWORD[i] = hosal_random_num_get(0, 9);
// printf("LOCK_PASSWORD[%d]= %d\n", i, LOCK_PASSWORD[i]);
}
memcpy(passwd, LOCK_PASSWORD, 6);
return 0;
}
LockState Authentication(char *passwd) {
for (int i = 0; i < 6; i++) {
if (passwd[i] != LOCK_PASSWORD[i]) {
return lock;
}
}
return unlock;
}
static void web_httpserver(struct netconn *conn) {
struct netbuf *inputbuf;
char *buf;
uint16_t buflen;
err_t err;
err = netconn_recv(conn, &inputbuf);
if (err != ERR_OK) {
return;
}
netbuf_data(inputbuf, (void **)&buf, &buflen);
// 处理 HTTP 请求
if (strstr(buf, "GET / ")) {
// netconn_write(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n",
// 44, NETCONN_NOCOPY);
netconn_write(conn, html_page, strlen(html_page), NETCONN_NOCOPY);
} else if (strstr(buf, "GET /cgi-bin/get_password")) {
char json_response[128];
snprintf(json_response, sizeof(json_response),
"HTTP/1.1 200 OK\r\n"
"Content-Type: application/json\r\n"
"Connection: close\r\n"
"\r\n"
"{\"password\":\"%d%d%d%d%d%d\",\"remainingTime\":%d}",
lockpass[0], lockpass[1], lockpass[2], lockpass[3], lockpass[4],
lockpass[5], count);
netconn_write(conn, json_response, strlen(json_response), NETCONN_NOCOPY);
}
netconn_close(conn);
netbuf_delete(inputbuf);
}
void server_task(void *pvParameters) {
struct netconn *conn, *newconn;
err_t err;
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn, NULL, SERVER_PORT);
netconn_listen(conn);
while (1) {
err = netconn_accept(conn, &newconn);
if (err != ERR_OK) {
netconn_close(conn);
netconn_delete(conn);
break;
}
web_httpserver(newconn);
netconn_delete(newconn);
}
}
演示效果
这里为了快速演示用的是每50s自动更新一次
