智能家居中的物联网网关的可信计算平台模块(TPM)设计
版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/BlueCloudMatrix/article/details/24184461
摘要:
随着智能家居的普及。安全性问题的研究已成当务之急。针对物联网网关自身的易受攻击性和网络传输过程中的信息窃听,我们分别採用SHA-1和AES算法对网关中的操作系统和节点採集的信息进行验证和加密,在一定程度上实现可信。我们创造性地将可信模块与网关平台进行解耦,利于可信模块的升级和维护。
简单介绍:
智能家居通过物联网技术将家中的各种设备(如照明系统、空调控制、安防系统)连接到一起。智能家居最初的发展主要以灯光遥控、电器远程控制和电动窗帘控制为主,后来延伸到家庭安防报警、背景音乐、可视对讲、门禁指纹控制等领域。
可见智能家居中的中央控制系统已经担当起大管家的职责,然而随之而来的安全性问题日益突出,须要我们对大管家进行特殊的防护。
物联网网关,作为一个新的名词。在未来的物联网时代将会扮演很重要的角色。它将成为连接感知网络与传统通信网络的纽带。作为网关设备,物联网网关能够实现感知网络与通信网络。以及不同类型感知网络之间的协议转换。既能够实现广域互联.也能够实现局域互联。物联网网关在智能家居中处于核心地位,在我们的设计中网关便担当了大管家的职责,因此我们将重点针对物联网网关进行防护。
可信计算是在计算和通信系统中广泛使用基于硬件安全模块支持下的计算平台。以提高系统总体的安全性与可靠性。
可信计算包含5个完整的可信系统所必须的关键技术概念:签注密钥、安全输入输出、储存器屏蔽、密封储存、以及远程认证。因此将可信计算用于物联网网关,实现一套完毕的物联网网关可信平台模块。而眼下国内还暂无技术较成熟的基于可信计算的物联网网关平台,项目较为新颖。
系统设计:
将可信平台模块(TPM)用于对嵌入式物联网网关设备的安全管理。实现网关的安全信息处理及通信。我们设计并在Devkit8500平台上实现了TPM模块的主要基本功能,并搭配基于ARM9的TQ2440平台的嵌入式物联网网关以及基于Zigbee通信协议的无线传感器网络。通过TPM模块对网关启动时(包含Boot Loader以及OS Kernel)的完整性验证,能够在启动前保证网关的核心系统程序的安全性。同一时候。网关应用程序(传感器数据收集、Web Service等)对数据的处理以及同外部设备通信也将通过TPM模块进行加解密处理,以保证数据的安全性。
功能模块设计:
1、TPM模块:
1)通过RS232与网关进行通信。
2)上面运行SHA-1验证算法,当网关启动时,网关会先后将其操作系统的bootloader和kernel通过RS232串口传送到TPM。届时SHA-1算法利用传来的信息生成信息摘要并与正确摘要匹配达到开机可信验证的目的,这是针对对物联网网关系统级的攻击的防护,一旦系统发生修改,SHA-1验证算法便会检測到异常。提醒用户。
3)AES加密算法。主要针对传感网节点传来的信息,若以明文存在网关数据库中。相同面临被窃取的风险。我们借鉴https的加密策略。在TPM上集成AES加密算法,节点传来的信息经由TPM进行加密,以密文的信息存在网关上的sqlite数据库中。
2、网关模块:
1)搭载GoAhead webserver。并编写CGI程序作为逻辑与界面控制。
2)通过RS232与TPM通信,并与温湿度传感器节点组成的Zigbee网络中协调器
进行RS232通讯。
3)自己定义通信协议,实现网关与TPM通信的有序性。
当两路或多路节点信息同一时候经由TPM进行加密处理时。它们是在争用一条串口线。这时就须要定义规则,对多路信息进行惟一标识和排队等候。
3、用户端:
通过訪问网关上的CGI页面,用户先进行身份验证,然后可选择是否将请求信息进行AES加密处理。防止用户指令遭窃听。大规模用户訪问对可信模块的计算能力提出了严峻的挑战。而实现的TPM和网关的解耦。却不利于大规模用户訪问,也造成了性能瓶颈。
4、传感节点:
温湿度传感器配备Zigbee通信模块,组建传感网。协调器节点负责发起并维护一个无线网络。识别网络中的设备增加网络;路由器节点支撑网络链路结构,完毕数据包的转发。终端节点是网络的感知者和运行者,负责数据採集和可运行的网络动作。
总结:
针对智能家居。我们搭建了一个模拟环境,建立起TPM负责可信验证,实现节点信息的安全存储、用户訪问信息的加密传输以及系统级的可信验证,并对大规模訪问有所探究。同一时候涉及Zigbee网络的组建,而解耦设计能够对TPM进行单独维护和升级。我们所构建的原始模型。不仅能够用于开发智能家居,并且我们曾将这一模型用于火车站自己主动检票机的设计。这也是我们大胆的将可信计算平台应用于物联网网关设计的一次尝试。
附:
AESListen.c
/*********************************************************
*TPM AES jiemi
*
**********************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<errno.h>
#include<sys/time.h>
#include <time.h>
#include "aes.h"
#define FALSE -1
#define TRUE 1
int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {115200,38400, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300, };
void set_speed(int fd, int speed);
int set_Parity(int fd,int databits,int stopbits,int parity);
void Print(BYTE a[])
{
int i;
for(i=0; i<4*Nb; i++)
{
printf("%02X ", a[i]);
}
printf("\n\n");
}
int main(void)
{
char *serialport="/dev/ttyUSB0";
int fd;
int nread;
int count;
char buffer[16]={'\0'};
char buffer_all[16]={'\0'};
fd=open(serialport,O_RDWR|O_NOCTTY|O_NDELAY);
if(fd==-1)
{
printf("%s open error!\n",serialport);
return -1;
}
printf("open %s successfully !",serialport);
fflush(stdout);
set_speed(fd,115200);
if (set_Parity(fd,8,1,'N')==FALSE)
{
printf("Set Parity Error\n");
exit(1);
}
DWORD e_key[Nb*(MaxNr+1)];
BYTE key[4*MaxNk]={ //miyao
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17};
BYTE decrypted_msg[4*Nb];
int filelen;
int times=0;
SetKey(192);
KeyExpansion(key, e_key);
tcflush(fd,TCIOFLUSH);
count=0;
while(1)
{
nread=read(fd,buffer,16);
if(nread>0)
{
memcpy(buffer_all+count,buffer,nread);
count +=nread;
}
if(count==16)
{
printf("total_size : %d\n",count);
break;
}
sleep(1);
printf("loop one second\n");
}
printf("encrypted message:\n");
Print(buffer_all);
AesDecrypt(buffer_all, decrypted_msg, e_key); //jiemi
printf("decrypted message:\n");
Print(decrypted_msg);
write(fd,decrypted_msg,16);
return 0;
}
void set_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]); /* */
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt); /* */
if (status != 0)
{
perror("tcsetattr fd1");
return;
}
}
tcflush(fd,TCIOFLUSH); /* */
}
}
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if (tcgetattr( fd,&options) != 0)
{
printf("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE; /* */
switch (databits) /**/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* */
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* */
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/**/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 150; // 15 seconds
options.c_cc[VMIN] = 0;
options.c_lflag &= ~(ICANON |ISIG);
options.c_iflag &= ~(ICRNL|IGNCR);
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
printf("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
Listenarm.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
#include "sha1.h"
#include "stdint.h"
#define MAX 1024
#define FALSE -1
#define TRUE 1
#define BUFFER_SIZE 1024
typedef unsigned char TPM_TAG ;
typedef unsigned int UINT32;
typedef unsigned char TPM_COMMAND_CODE;
int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {115200,38400, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300, };
void set_speed(int fd, int speed);
int set_Parity(int fd,int databits,int stopbits,int parity);
void itoa ( unsigned int val, char *buf, int radix );
unsigned char buffer_all_bootloader[1024*1024];
int buffer_len_bootloader;
unsigned char buffer_all_kernel[1024*1024];
int buffer_len_kernel;
unsigned char Message_Digest_bootloader[SHA1HashSize];
unsigned char Message_Digest_kernel[SHA1HashSize];
typedef struct
{
TPM_TAG tag;
UINT32 paramSize;
TPM_COMMAND_CODE ordinal;
}TPM_COMMAND;
//unsigned char bootloader_sha1_checksum[20]={31,79,191,25,22,207,68,233,254,242,171,148,233,85,122,172,52,150,227,121};
unsigned char bootloader_sha1_checksum[20]={0x77,0xCA,0x04,0xD2,0x41,0xA7,0xF7,0xCD,0x9F,0x69,0x11,0x06,0x68,0x28,0x95,0xE3,0x71,0x7F,0x24,0xEC};
//unsigned char kernel_sha1_checksum[20]={161,76,7,206,132,245,247,137,244,45,3,48,49,98,232,213,32,219,62,17};
unsigned char kernel_sha1_checksum[20]={0x70,0xD0,0x0C,0x51,0x7C,0x10,0xFB,0xCB,0x93,0x81,0x2C,0x0C,0x5C,0x8C,0xBF,0x35,0x23,0xB8,0xE5,0x99};
int main(void)
{
char *serialport = "/dev/ttyUSB0";
int fd=open(serialport,O_RDWR,O_NOCTTY);
if(fd == -1)
{
printf("%s Open Error!\n",serialport);
return -1;
}
printf("open %s successfully !\n",serialport);
fflush(stdout);
set_speed(fd,115200);
if (set_Parity(fd,8,1,'N')== FALSE)
{
printf("Set Parity Error\n");
exit(1);
}
/*******************************************************************************/
struct timeval tpstart,tpend;
float timeuse;
gettimeofday(&tpstart,NULL);
write(fd,"s",1);
/*TPM帧格式*/
TPM_COMMAND request_bootloader={'t',6,'s'};
unsigned char d[5];
itoa(request_bootloader.paramSize,d,10);
unsigned char dest[strlen(d)+5];
sprintf(dest,"%c%d%c",request_bootloader.tag,request_bootloader.paramSize,request_bootloader.ordinal);
dest[3]='a';
dest[4]='b';
dest[5]='c';
write(fd,dest,strlen(d)+5);
/*******************************************************************************/
//监听bootloader
int nread = 1,nwrite = 0;
int total_size = 0;
unsigned char buffer[BUFFER_SIZE] = {'\0'};
int i;
buffer_len_bootloader = 0;
while(1)
{
nread=read(fd,buffer,1024);
if(nread>0)
{
total_size+=nread;
memcpy(buffer_all_bootloader+buffer_len_bootloader,buffer,nread);
buffer_len_bootloader+=nread;
#if 0
for(i = 0;i<nread;i++)
{
if(i%8==0)
{
printf("\n");
}
printf("0x%x,",buffer[i]);
}
#endif
}
if(total_size==29700)
{
printf("total_size:%d\n",total_size);
break;
}
}
//生成bootloader摘要值
sha1_test(buffer_all_bootloader,buffer_len_bootloader,Message_Digest_bootloader);
/* sha-1 */
sleep(1);
int count;
for(count=0;count<20;count++)
{
if(bootloader_sha1_checksum[count]==Message_Digest_bootloader[count])
continue;
else
goto close;
}
write(fd,"s",1);
write(fd,"abcdef",6);
gettimeofday(&tpend,NULL);
timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;
timeuse/=1000000;
printf("Used Time:%f\n",timeuse);
/*******************************************************************************/
//监听kernel0
struct timeval tpstart2,tpend2;
float timeuse2;
gettimeofday(&tpstart2,NULL);
nread = 1,nwrite = 0;
total_size = 0;
unsigned char buffer2[BUFFER_SIZE] = {'\0'};
buffer_len_kernel = 0;
while(1)
{
nread=read(fd,buffer2,1024);
if(nread>0)
{
total_size+=nread;
memcpy(buffer_all_kernel+buffer_len_kernel,buffer2,nread);
buffer_len_kernel+=nread;
#if 0
for(i = 0;i<nread;i++)
{
if(i%8==0)
{
printf("\n");
}
//printf("0x%x,",buffer2[i]);
}
#endif
}
if(total_size==29386)
{
printf("total_size:%d\n",total_size);
break;
}
}
//生成kernel摘要值
sha1_test(buffer_all_kernel,buffer_len_kernel,Message_Digest_kernel);
sleep(1);
for(count=0;count<20;count++)
{
if(kernel_sha1_checksum[count]==Message_Digest_kernel[count])
continue;
else
goto close;
}
write(fd,"s",1);
write(fd,"abcdef",6);
gettimeofday(&tpend2,NULL);
timeuse2=1000000*(tpend2.tv_sec-tpstart2.tv_sec)+tpend2.tv_usec-tpstart2.tv_usec;
timeuse2/=1000000;
printf("Used Time:%f\n",timeuse2);
close:
close(fd);
return 0;
}
void set_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]); /* 指定输入波特率 */
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt); /* 将修改后的termios数据设置到串口中 */
if (status != 0)
{
perror("tcsetattr fd1");
return;
}
}
tcflush(fd,TCIOFLUSH); /* */
}
}
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
/*if (tcgetattr( fd,&options) != 0)
{
printf("SetupSerial 1");
return(FALSE);
} */
options.c_cflag &= ~CSIZE; /* 设置数据位前必须先使用CSIZE做位屏蔽 */
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 150; // 15 seconds
options.c_cc[VMIN] = 0;
options.c_lflag &= ~(ICANON |ISIG);
options.c_iflag &= ~(ICRNL|IGNCR);
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
printf("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
void itoa ( unsigned int val, char *buf, int radix )
{
char *p; /* pointer to traverse string */
char *firstdig; /* pointer to first digit */
char temp; /* temp char */
unsigned int digval; /* value of digit */
p = buf;
firstdig = p; /* save pointer to first digit */
do {
digval = (unsigned int) (val % radix);
val /= radix; /* get next digit */
/* convert to ascii and store */
if (digval > 9)
*p++ = (char)(digval - 10 + 'a'); /* a letter */ ///////////////////////////////
else
*p++ = (char ) (digval + '0'); /* a digit */ ////////////////////////////////
} while (val > 0);
/* We now have the digit of the number in the buffer, but in reverse
order. Thus we reverse them now. */
*p-- = '\0'; /* terminate string; p points to last digit */ /////////////////////
do {
temp = *p;
*p = *firstdig;
*firstdig = temp; /* swap *p and *firstdig */
--p;
++firstdig; /* advance to next two digits */
} while (firstdig < p); /* repeat until halfway */
}
CGI.c
/*****************
* CGI
*
*
******************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
#define MAX 1024
#define FALSE -1
#define TRUE 1
#define BUFFER_SIZE 1024
typedef unsigned char BYTE;
int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {115200,38400, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300, };
void set_speed(int fd, int speed);
int set_Parity(int fd,int databits,int stopbits,int parity);
void Print(BYTE a[])
{
int i;
for(i=0; i<4*4; i++)
{
printf("%02X ", a[i]);
}
printf("\n\n");
}
int main()
{
char *method;
char *data;
int count;
int i;
int j;
char *serialport = "/dev/tq2440_serial1" ; //
int fd;
int nread;
char buffer[16] = {'\0'};
char buffer_all[16]={'\0'};
FILE *fp;
time_t rawtime;
struct tm *timeinfo;
int end=5;
printf("Content-type:text/html\n\n");
printf("<p>this is a cgi");
if((method=getenv("REQUEST_METHOD"))==NULL) //
return 1;
printf("<p>method: %s",method);
if((data=getenv("QUERY_STRING"))==NULL) //
return 1;
printf("<p>%s",data);
/*if((i=sscanf(data,"command=%s",command))==0)
return 1;
printf("%s",command);*/
/**************************
*
*
*
**************************/
fd=open(serialport,O_RDWR|O_NOCTTY|O_NDELAY);
if(fd == -1)
{
printf("%s Open Error!\n",serialport);
return -1;
}
printf("<p>open %s successfully !",serialport);
set_speed(fd,115200);
if (set_Parity(fd,8,1,'N')== FALSE)
{
printf("Set Parity Error\n");
exit(1);
}
tcflush(fd,TCIOFLUSH);
write(fd,data,16);
count=0;
while(end)
{
end--;
nread=read(fd,buffer,16);
if(nread>0)
{
memcpy(buffer_all+count,buffer,nread);
count += nread;
}
if(count==16)
{
printf("<p>receive success !");
break;
}
sleep(1);
printf("<p>loop one time");
}
Print(buffer_all);
time(&rawtime);
timeinfo=localtime(&rawtime);
if((fp=fopen("/mnt/usrcommand.txt","ab+"))==NULL)
return 1;
fprintf(fp,"%4d-%02d-%02d %02d%02d%02d\n",1900+timeinfo->tm_year,1+timeinfo->tm_mon,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
//fwrite(data,sizeof(char),strlen(data),fp);
for(j=0; j<4*4; j++)
{
fprintf(fp,"%02X",buffer_all[j]);
}
//fwrite(buffer_all,sizeof(char),16,fp);
fclose(fp);
return 0;
}
void set_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]); /* */
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt); /* */
if (status != 0)
{
perror("tcsetattr fd1");
return;
}
}
tcflush(fd,TCIOFLUSH); /* */
}
}
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if (tcgetattr( fd,&options) != 0)
{
printf("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE; /* */
switch (databits) /**/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* */
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/**/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 150; // 15 seconds
options.c_cc[VMIN] = 0;
options.c_lflag &= ~(ICANON |ISIG);
options.c_iflag &= ~(ICRNL|IGNCR);
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
printf("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
智能家居中的物联网网关的可信计算平台模块(TPM)设计的更多相关文章
- 迅为4412开发平台Zigbee模块在物联网智能家居中的应用
物联网智能家居的发展物联网随着互联网的发展,可以通过互联网实现物和物的互联,就有了物联网的概念.传统家居电器 有了物联网之后,在家居电器范围中,就是通过物联网技术将家中的各种设备连接到一起,家居中 ...
- 一款新型的智能家居WiFi选择方案——SimpleWiFi在无线智能家居中的应用
一款新型的智能家居WiFi选择方案——SimpleWiFi在无线智能家居中的应用 先上图: 随着科学技术的不断发展,局域网也正逐渐向无线化,多网合一的方向发展,在这个多网合一快速发展过程中,带 ...
- 【智能家居篇】wifi在智能家居中的应用
转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 在设计智能家居系统方案时,一个很关键的point就是组网方式.组网方式关系到整个智能家居系统的稳定性.可扩展性.实时 ...
- 基于能量收集的智能家居-2013国家级大学生创业实践项目申报_商业计划书_V0.2
SmartHome项目商业计划 基于能量收集的 免电池无线智能家居系统 IA-SmartHome团队 2012.12 l 基于无线的智能家居解决方案,节省施工成本: l 基于能 ...
- DIY智能家居——零基础入门篇
概要 本文主要根据笔者从零开始接触硬件,以小白视角开启IoT探索,根据相关资料DIY一个温湿度传感器.后经过探索发现新大陆--Home Assistant&Homebridge,最终实现了一个 ...
- 物联网网关开发:基于MQTT消息总线的设计过程(上)
道哥的第 021 篇原创 目录 一.前言 二.网关的作用 2.1 指令转发 2.2 外网通信 2.3 协议转换 2.4 设备管理 2.5 边沿计算(自动化控制) 三.网关内部进程之间的通信 3.1 网 ...
- 利用Socket与硬件通信(智能家居)
前几天做一个智能家居APP,硬件段使用的是ESP8266WIFI模块,其实不管是WIFI模块还是蓝牙,通信都是同样一个道理,获取IP和端口来进行通信. 我是通过XCOM v2.0 发送信息,移动端接收 ...
- 入门智能家居,从 IFTTT 到 HomeKit 自动化(二)
入门智能家居,从 IFTTT 到 HomeKit 自动化(二) 目录 0. HomeKit.HomeBridge.HomeAssistant 分别是什么?关系是什么? 1. 开始前的准备 2. 整 ...
- Android利用Socket与硬件通信之智能家居APP
前几天做一个智能家居APP,硬件段使用的是ESP8266WIFI模块,其实不管是WIFI模块还是蓝牙,通信都是同样一个道理,获取IP和端口来进行通信. 我是通过XCOM v2.0 发送信息,移动端接收 ...
随机推荐
- cef3加载flash闪烁问题非easyhook的另外一种解决方法
1.现象 cef3加载flash,会出现弹出命令行窗口,显示not sandboxed,影响使用体验. 网上的解决方法,参考此文. http://blog.csdn.NET/zx2356/articl ...
- ios app真正的相互!!调用
1.需求:A应用打开B.B回跳到A 2.问题: 看到网络上的文档讲的大多数都是app单向跳转的例子,而我们在跳转到第二个app的时候往往需要返回到原来的app,虽然支付宝微信等第三方等应用会有回调 ...
- java自学-基本数据类型
java中也有对数据的运算处理,java中数据分为常量和变量,常量就是直接固定不变的数据,变量是数据可能发生改变的数据,如下: int a=0; a=1+1; 上边代码,a就是变量,初始为0,接下来 ...
- zookeeper 选举
选举概述: 1.启动时期的选举 所有的服务器状态为 LOOKING. 1.1.每个Server 会投出一票(投票规则为:SID.ZXID ,即 服务器ID 和 最大事务ID). 1.2.处理选票 (A ...
- 【PyQt5 学习记录】009:批量创建组件并查找
这里需要在创建组件时使用 setObjectName() 为其添加 objectName 属性,再通过 findChild() 或者 findChildren() 函数来查找. 举个栗子,批量创建10 ...
- git push 提示 Everything up-to-date
第一次在 Google Code 上弄项目,注册完毕后,尝试增加一个新文件用以测试 Git 是否好好工作.结果在 Push 时却显示 Every up-to-date,检查文件时却发现实际上一个都没更 ...
- mkdir failed for img Read-only file system
最简单的方法就是打开模拟起,然后 windows-->show view-->file explorer-->mnt-->sdcard (最好在该目录下重新创建个文件夹)选中文 ...
- Gson基本操作,JsonObject,JsonArray,String,JavaBean,List互转
(转自)https://www.cnblogs.com/robbinluobo/p/7217387.html String.JsonObject.JavaBean 互相转换 User user = n ...
- linux yum list、search、-y、install、update、remove、grouplist、groupinstall、groupremove
redhat使用yum需要付费yum安装的也是rpm包 centos的网络yum源默认已经配置好了,连接的是centos官方yum源,在国外,网速慢 yum源配置在/etc/yum.repos.d下 ...
- Linux 系统下 centOS 7 ipconfig 提示没有安装
首先更正一下,在Linux系统下,查看IP地址,指令是ifconfig 没有root权限情况下,安装指令为 sudo yum -y install net-tool 有root权限的话,直接执行 yu ...