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