Add 2.Socket folder, which implement send temperature report in 1 second by TLV protocal to server
New file |
| | |
| | | /********************************************************************************* |
| | | * 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; |
| | | } |
New file |
| | |
| | | /********************************************************************************* |
| | | * 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 |
| | | |
New file |
| | |
| | | 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} |
New file |
| | |
| | | /********************************************************************************* |
| | | * 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); |
| | | } |
| | | |
| | | |
New file |
| | |
| | | /********************************************************************************* |
| | | * 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); |
| | | } |
| | | |
New file |
| | |
| | | /********************************************************************************* |
| | | * 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; |
| | | } |
| | | |
| | | |
New file |
| | |
| | | /********************************************************************************* |
| | | * 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 |