From 9e649dd24799cd8d64058eab3782d1af9f7fed4c Mon Sep 17 00:00:00 2001 From: Guo Wenxue <guowenxue@gmail.com> Date: Wed, 24 Oct 2018 19:56:21 +0800 Subject: [PATCH] Add 2.Socket folder, which implement send temperature report in 1 second by TLV protocal to server --- apue/2.Socket/tlv.h | 41 ++++ apue/2.Socket/ds18b20.h | 20 ++ apue/2.Socket/socket_server.c | 119 +++++++++++++ apue/2.Socket/socket_client.c | 120 +++++++++++++ apue/2.Socket/makefile | 17 + apue/2.Socket/ds18b20.c | 102 +++++++++++ apue/2.Socket/tlv.c | 67 +++++++ 7 files changed, 486 insertions(+), 0 deletions(-) diff --git a/apue/2.Socket/ds18b20.c b/apue/2.Socket/ds18b20.c new file mode 100644 index 0000000..9a7b54e --- /dev/null +++ b/apue/2.Socket/ds18b20.c @@ -0,0 +1,102 @@ +/********************************************************************************* + * Copyright: (C) 2018 LingYun IoT System Studio + * All rights reserved. + * + * Filename: ds18b20.c + * Description: This file is temperature sensor DS18B20 code + * + * Version: 1.0.0(2018/10/14) + * Author: Guo Wenxue <guowenxue@gmail.com> + * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26" + * + ********************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <dirent.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +/* File Content: + pi@raspberrypi:~/guowenxue $ cat /sys/bus/w1/devices/28-041731f7c0ff/w1_slave + 3a 01 4b 46 7f ff 0c 10 a5 : crc=a5 YES + 3a 01 4b 46 7f ff 0c 10 a5 t=19625 + */ + +int ds18b20_get_temperature(float *temp) +{ + char w1_path[50] = "/sys/bus/w1/devices/"; + char chip[20]; + char buf[128]; + DIR *dirp; + struct dirent *direntp; + int fd =-1; + char *ptr; + float value; + int found = 0; + + if( !temp ) + { + return -1; + } + + /*+-------------------------------------------------------------------+ + *| open dierectory /sys/bus/w1/devices to get chipset Serial Number | + *+-------------------------------------------------------------------+*/ + if((dirp = opendir(w1_path)) == NULL) + { + printf("opendir error: %s\n", strerror(errno)); + return -2; + } + + while((direntp = readdir(dirp)) != NULL) + { + if(strstr(direntp->d_name,"28-")) + { + /* find and get the chipset SN filename */ + strcpy(chip,direntp->d_name); + found = 1; + } + } + closedir(dirp); + + if( !found ) + { + printf("Can not find ds18b20 in %s\n", w1_path); + return -3; + } + + /* get DS18B20 sample file full path: /sys/bus/w1/devices/28-xxxx/w1_slave */ + strncat(w1_path, chip, sizeof(w1_path)-strlen(w1_path)); + strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path)); + + /* open file /sys/bus/w1/devices/28-xxxx/w1_slave to get temperature */ + if( (fd=open(w1_path, O_RDONLY)) < 0 ) + { + printf("open %s error: %s\n", w1_path, strerror(errno)); + return -4; + } + + if(read(fd, buf, sizeof(buf)) < 0) + { + printf("read %s error: %s\n", w1_path, strerror(errno)); + return -5; + } + + ptr = strstr(buf, "t="); + if( !ptr ) + { + printf("ERROR: Can not get temperature\n"); + return -6; + } + + ptr+=2; + + /* convert string value to float value */ + *temp = atof(ptr)/1000; + + return 0; +} diff --git a/apue/2.Socket/ds18b20.h b/apue/2.Socket/ds18b20.h new file mode 100644 index 0000000..6e1ff74 --- /dev/null +++ b/apue/2.Socket/ds18b20.h @@ -0,0 +1,20 @@ +/********************************************************************************* + * Copyright: (C) 2018 LingYun IoT System Studio + * All rights reserved. + * + * Filename: ds18b20.h + * Description: This file is temperature sensor DS18B20 code + * + * Version: 1.0.0(2018/10/14) + * Author: Guo Wenxue <guowenxue@gmail.com> + * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26" + * + ********************************************************************************/ +#ifndef __DS18B20_H_ +#define __DS18B20_H_ + + +int ds18b20_get_temperature(float *temp); + +#endif + diff --git a/apue/2.Socket/makefile b/apue/2.Socket/makefile new file mode 100644 index 0000000..be238e3 --- /dev/null +++ b/apue/2.Socket/makefile @@ -0,0 +1,17 @@ +INST_PATH=/usr/bin + +BIN_FILES=socket_client socket_server + +all: clean ${BIN_FILES} + +socket_client: + gcc socket_client.c ds18b20.c tlv.c -o socket_client + +socket_server: + gcc socket_server.c tlv.c -o socket_server + +clean: + rm -f ${BIN_FILES} + +install: + @cp ${BIN_FILES} ${INST_PATH} diff --git a/apue/2.Socket/socket_client.c b/apue/2.Socket/socket_client.c new file mode 100644 index 0000000..0d292c2 --- /dev/null +++ b/apue/2.Socket/socket_client.c @@ -0,0 +1,120 @@ +/********************************************************************************* + * Copyright: (C) 2018 LingYun IoT Studio + * All rights reserved. + * + * Filename: socket_client.c + * Description: This file is socket client sample source code, it will connect + * socket server and send to/receive from it. + * + * Version: 1.0.0(10/23/2018) + * Author: Guo Wenxue <guowenxue@gmail.com> + * ChangeLog: 1, Release initial version on "2018-10-23 01:38:08 PM" + * + ********************************************************************************/ +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <math.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "ds18b20.h" +#include "tlv.h" + +#define SERVER_IP "127.0.0.1" +#define SERVER_PORT 8889 + + +int main(int argc, char **argv) +{ + int conn_fd = -1; + int rv = -1; + char buf[1024]; + struct sockaddr_in serv_addr; + float temp; + + conn_fd = socket(AF_INET, SOCK_STREAM, 0); + if(conn_fd < 0) + { + printf("create socket failure: %s\n", strerror(errno)); + return -1; + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(SERVER_PORT); + inet_aton( SERVER_IP, &serv_addr.sin_addr ); + + if( connect(conn_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) + { + printf("connect to server [%s:%d] failure: %s\n", SERVER_IP, SERVER_PORT, strerror(errno)); + return 0; + } + + while(1) + { + if( ds18b20_get_temperature(&temp) < 0 ) + { + printf("DS18B20 get temperature failure\n"); + continue; + } + printf("Current temperature: %f\n", temp); + + /*+-----------------------------------------------+ + *| TLV Format: Tag(1B) Length(1B) Value(2B) | + *+-----------------------------------------------+*/ + memset(buf, 0, sizeof(buf)); + buf[0] = TAG_TEMP; + buf[1] = 2; /*Length segement*/ + + /*Value: 1st Bytes is integer part and 2nd bytes is fractional part */ + buf[2] = (int)temp & 0xFF; + buf[3] = ( ((int)(temp*100))%100 ) & 0xFF ; + + //tlv_dump_buf("Temperature buff: ", buf, 4); + + if( write(conn_fd, buf, 4) < 0 ) + { + printf("Write data to server [%s:%d] failure: %s\n", SERVER_IP, SERVER_PORT, strerror(errno)); + goto cleanup; + } + + memset(buf, 0, sizeof(buf)); + rv = read(conn_fd, buf, sizeof(buf)); + if(rv < 0) + { + printf("Read data from server failure: %s\n", strerror(errno)); + goto cleanup; + } + else if( 0 == rv ) + { + printf("Client connect to server get disconnected\n"); + goto cleanup; + } + + tlv_dump_buf("Receive data from server: ", buf, rv); + if( rv >= 2) + { + if( TAG_NAK == buf[0] ) + { + printf("Parser TLV packet and get NOT Acknowledge reply from server!\n"); + } + else if( TAG_ACK == buf[0] ) + { + printf("Parser TLV packet and get Acknowledge reply from server!\n"); + + } + } + + //printf("Read %d bytes data from server: '%s'\n", rv, buf); + } + + +cleanup: + close(conn_fd); +} + + diff --git a/apue/2.Socket/socket_server.c b/apue/2.Socket/socket_server.c new file mode 100644 index 0000000..53f7ea4 --- /dev/null +++ b/apue/2.Socket/socket_server.c @@ -0,0 +1,119 @@ +/********************************************************************************* + * Copyright: (C) 2018 LingYun IoT Studio + * All rights reserved. + * + * Filename: socket_server.c + * Description: This file is socket server sample source code, it will echo back + * the receive data from client. + * + * Version: 1.0.0(10/23/2018) + * Author: Guo Wenxue <guowenxue@gmail.com> + * ChangeLog: 1, Release initial version on "2017-10-23 01:41:05 PM" + * + ********************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "tlv.h" + +#define LISTEN_PORT 8889 +#define BACKLOG 13 + + +int main(int argc, char **argv) +{ + int rv = -1; + int listen_fd, client_fd = -1; + struct sockaddr_in serv_addr; + struct sockaddr_in cli_addr; + socklen_t cliaddr_len; + char buf[1024]; + int reuse = 1; + + listen_fd = socket(AF_INET, SOCK_STREAM, 0); + if(listen_fd < 0 ) + { + printf("create socket failure: %s\n", strerror(errno)); + return -1; + } + printf("socket create fd[%d]\n", listen_fd); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(LISTEN_PORT); + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + if( bind(listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 ) + { + printf("create socket failure: %s\n", strerror(errno)); + return -2; + } + printf("socket[%d] bind on port[%d] for all IP address ok\n", listen_fd, LISTEN_PORT); + + /* Fix port can not be used when stop server program and run it again immediately.*/ + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); + + listen(listen_fd, BACKLOG); + + while(1) + { + printf("\nStart waiting and accept new client connect...\n", listen_fd); + client_fd = accept(listen_fd, (struct sockaddr*)&cli_addr, &cliaddr_len); + if(client_fd < 0) + { + printf("accept new socket failure: %s\n", strerror(errno)); + return -2; + } + printf("Accept new client[%s:%d] with fd [%d]\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), client_fd); + + while(1) + { + memset(buf, 0, sizeof(buf)); + if( (rv=read(client_fd, buf, sizeof(buf))) < 0) + { + printf("Read data from client socket[%d] failure: %s\n", client_fd, strerror(errno)); + close(client_fd); + break; + } + else if( rv == 0 ) + { + printf("client socket[%d] disconnected\n", client_fd); + close(client_fd); + break; + } + + //tlv_dump_buf("Read TLV data from client: ", buf, rv); + + if(buf[0] == TAG_TEMP ) + { + /* Tag+Length is 2 bytes, buf[1] is the data length, */ + if(2+buf[1]>rv) + { + printf("Receive TLV packet is not integrated\n"); + rv=tlv_pack_nak(buf, sizeof(buf)); + } + else + { + printf("Parser TLV packet and get temperature: %d.%d\n", buf[2], buf[3]); + rv=tlv_pack_ack(buf, sizeof(buf)); + } + } + + if( write(client_fd, buf, rv) < 0 ) + { + printf("Write %d bytes data back to client[%d] failure: %s\n", rv, client_fd, strerror(errno)); + close(client_fd); + } + } + + close(client_fd); + } + close(listen_fd); +} + diff --git a/apue/2.Socket/tlv.c b/apue/2.Socket/tlv.c new file mode 100644 index 0000000..5d19479 --- /dev/null +++ b/apue/2.Socket/tlv.c @@ -0,0 +1,67 @@ +/********************************************************************************* + * Copyright: (C) 2018 LingYun IoT System Studio + * All rights reserved. + * + * Filename: tlv.c + * Description: This file is TLV(Tag Length Value) protocal head file + * + * Version: 1.0.0(2018/10/14) + * Author: Guo Wenxue <guowenxue@gmail.com> + * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26" + * + ********************************************************************************/ + +#include <stdio.h> +#include "tlv.h" + +void tlv_dump_buf(const char *prompt, char *buf, int size) +{ + int i; + + if(!buf) + return ; + + if(prompt) + printf("%s", prompt); + + for(i=0; i<size; i++ ) + { + printf("0x%02x ", buf[i]); + } + + printf("\n"); +} + +int tlv_pack_ack(char *buf, int size) +{ + if( !buf ) + return 0; + + if(size < 2) + return 0; + + buf[0]=TAG_ACK; /* tag */ + buf[1]=0; /*length*/ + + /*No data here*/ + + return 2; +} + +int tlv_pack_nak(char *buf, int size) +{ + if( !buf ) + return 0; + + if(size < 2) + return 0; + + buf[0]=TAG_NAK; /* tag */ + buf[1]=0; /* length*/ + + /*No data here*/ + + return 2; +} + + diff --git a/apue/2.Socket/tlv.h b/apue/2.Socket/tlv.h new file mode 100644 index 0000000..a91fcb5 --- /dev/null +++ b/apue/2.Socket/tlv.h @@ -0,0 +1,41 @@ +/********************************************************************************* + * Copyright: (C) 2018 LingYun IoT System Studio + * All rights reserved. + * + * Filename: tlv.h + * Description: This file is TLV(Tag Length Value) protocal head file + * + * Version: 1.0.0(2018/10/14) + * Author: Guo Wenxue <guowenxue@gmail.com> + * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26" + * + ********************************************************************************/ + +#ifndef __TLV_H_ +#define __TLV_H_ + + +/*+-----------------------------------------------+ + *| TLV Format: Tag(1B) Length(1B) Value(2B) | + *+-----------------------------------------------+*/ + + +/*TLV Format Tag definition */ +enum +{ + TAG_TEMP = 1, /* Temperature */ + TAG_HUMI, /* Relative Humidity */ + TAG_DOOR, /* Door open status */ + + TAG_NAK=0xFD, /* NAK packet */ + TAG_ACK=0xFE, /* ACK packet */ +}; + +void tlv_dump_buf(const char *prompt, char *buf, int size); + +int tlv_pack_ack(char *buf, int size); + +int tlv_pack_nak(char *buf, int size); + + +#endif -- Gitblit v1.9.1