概述
引言
人们出行旅游住宿的话,住酒店是躲不过的,那么酒店的安全管理则愈发重要。本项目旨在打造一款模拟智能门锁产品,针对酒店服务。
需求分析
前期构思:
1、密码锁,动态生成密码
2、触摸屏输入密码,6位数密码
3、手机app填入手机号用短信接收密码
4、屏幕触碰显示,长不用息屏
5、密码可设置到期时间
6、门锁连WiFi
后期更改:
1、密码锁,前台发送设置动态密码
2、手机输入密码,6位数密码
3、手机web网页填入IP和短信接收到的随机密码
4、密码可设置到期时间
5、门锁连WiFi,开机自启程序
项目分工
同学A,查找相关资料,找到linux下与短信服务商的C接口,用作密码服务器,并发送给短信服务商发送短信。
同学B,在安卓手机上弄一个app,与云端linux服务器通信,进行用户信息传送。(后期改成了web)
我,处理数据,针对来自密码服务器的密码以及来自用户开锁的密码还有驱动程序进行处理和调试。
虚拟场景
设备及器材
ARM S5PV210开发板(装载linux系统)、linux虚拟机、阿里云linux、PC机、继电器、灯泡(前代替门锁)、手机
我的详细部分
接收来自服务端的字符串,判断其长度,若长度为9则将字符串分割成密码和天数(前六位为密码,后三位为天数)。密码和天数字符串传给等待开锁比对模块,并将天数与系统时间计算出有效期,过期则清空密码。板子服务端模块只需接收客户端给的字符串,如果为设置密码,则需要9个字符;如果为清空密码,则只需3个字符。(其中9个字符是“六位数密码加三位数时间”,例如"123456002";其中3个字符是“门牌号”,例如"001"。)
等待开锁比对模块则是控制驱动操控板子上的IO口(被人说过不安全), 也是,就一个IO口确实是有点简单了。
大致架构
本项目由两个服务器(1号密码短信服务器和2号用户服务器),门锁上一个“主进程”(main),两个“辅助进程”(c1, c2),用户手里一个app,前台一个app。后来发现我们弄的app只能在虚拟机上能连通云端,一放到手机上就没反应,找了很多资料也无法解决,有说是sdk等级太低,也有说手机系统等级过高。后来我决定采用web服务器的形式,将2号用户服务器用http实现,这样做的好处是甭管你是什么系统的什么端,手机也好电脑也罢,都可以实现和服务器的通信,做到了跨平台的效果。
通信过程最复杂的在于“门锁”上,由于会被随时更换密码的状况发生,那么有一个客户端程序必须一致待命接收1号服务器的信息,传给主程序,即用c1代替;2号服务器则是用户填入的密码,传给“门锁”上的c2接收,也传给主程序。它们之间用fifo通信,因此我把一个处理程序叫做“主程序”, 另外两个叫做“辅助程序”。
其实还有一个驱动程序,等待主程序中的模块来写入字符从而驱动开锁。
遇到的问题
在我负责的这一部分里遇到了许多问题。例如,如果只有一个进程的话,那么当客户端函数接收到服务器发来的消息后客户端函数就结束了,也就是说一运行程序只能收到一次消息,如果是每次执行完开锁后或者是密码输入错误后才跳转到客户端函数的话,这样就违背了即时性,因为服务器随时都可能给客户端发送消息。所以这里我需要把客户端函数分离出来,当成一个独立的进程,确切的说不能叫做独立的进程,因为进程本来就是独立的。
那么,有了客户端进程后,就可以随时接收服务器的讯息了。可是这样又衍生出一个新的问题,就是需要进行进程间通信,进程间通信有信号、管道、共享内存等方式,这里选择了命名管道fifo里来通信,因为fifo可以让两个没有半点关系的进程进行通信。好了,知道了用fifo之后更多的问题接踵而至,例如write是阻塞的,有一个注意事项就是要先开启write端的进程,也就是先开启客户端的进程,它会阻塞在write,如果read的进程没开的话。而一开始我就是纯粹用的read函数,没有加非阻塞,这我才意识到会出问题,必须让它非阻塞的读管道里的内容。
后续在读管道内容时,一旦更改密码多次之后会出现数据偏移情况,一直未能解决,所以这个fifo管道很让人捉摸不透。
代码详情
头文件:
/**
******************************************************************************
* @file Func.h
* @author 邓子康
* @version V1.0
* @date 2018-05-02
* @brief 门锁头文件
******************************************************************************
**/
#ifndef __FUNC_H
#define __FUNC_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
int fdsocket;
void mybzero(char *str)
{
bzero(str, sizeof(str));
str[sizeof(str) - 1] = '