[Feature] add GA346 baseline version

Change-Id: Ic62933698569507dcf98240cdf5d9931ae34348f
diff --git a/src/apps/atom-base/progs/property/libprop/request.c b/src/apps/atom-base/progs/property/libprop/request.c
new file mode 100644
index 0000000..d72531d
--- /dev/null
+++ b/src/apps/atom-base/progs/property/libprop/request.c
@@ -0,0 +1,264 @@
+/* Copyright Statement:
+
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+
+ * MediaTek Inc. (C) 2015. All rights reserved.
+
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <syslog.h>
+#include "utility.h"
+#include "request.h"
+
+/*******************************************************************************/
+/* REQUEST local definitions                                                   */
+/*******************************************************************************/
+
+/*******************************************************************************/
+/* REQUEST local prototypes                                                    */
+/*******************************************************************************/
+
+/*******************************************************************************/
+/* REQUEST local variables                                                     */
+/*******************************************************************************/
+
+/*******************************************************************************/
+/* REQUEST local functions                                                     */
+/*******************************************************************************/
+static int pack_request_string(char **p, char **next, const char *roof)
+{
+	if (*p == NULL) {
+		return 0;
+	} else {
+		size_t len = strlen(*p) + 1;
+
+		if ((roof - *next) < (ptrdiff_t)len) {
+			return -1;
+		} else {
+			strcpy(*next, *p);
+			*next += len;
+			*p = (char *)0x12345678;
+			return 0;
+		}
+	}	
+}
+
+static int unpack_request_string(char **p, char **next, const char *roof)
+{
+	if (*p == NULL) {
+		return 0;
+	} else if (*p == (char *)0x12345678) {
+		char *end = memchr(*next, '\0', roof - *next);
+		
+		if (end == NULL) {
+			return -1;
+		} else {
+			*p = *next;
+			*next = end + 1;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+/*******************************************************************************/
+/* REQUEST functions                                                           */
+/*******************************************************************************/
+int pack_request(struct sncfg_request *request)
+{
+	int size;
+	char *next, *roof;
+	
+    next = request->string + request->reservedLen;
+    roof = next + sizeof(request->string);
+    
+	if (request->magic != SNCFG_REQUEST_MAGIC) {
+		return -1;
+	}
+
+	if (request->type >= SNCFG_REQUEST_TYPE_RESERVED) {
+		return -1;
+	}
+					
+	if (pack_request_string(&request->key, &next, roof) < 0 ||
+		pack_request_string(&request->value, &next, roof) < 0) {
+		return -1;
+	}
+
+	size = next - (char *)request;
+	return size;
+}
+
+int unpack_request(struct sncfg_request *request, int size)
+{
+	char *next, *roof;
+	
+	next = request->string + request->reservedLen;
+	roof = (char *)request + size;
+
+	if (roof < next) {
+		return -1;
+	}
+	
+	if (request->magic != SNCFG_REQUEST_MAGIC) {
+		return -1;
+	}
+
+	if (request->type >= SNCFG_REQUEST_TYPE_RESERVED) {
+		return -1;
+	}
+
+	if (unpack_request_string(&request->key, &next, roof) < 0 ||
+		unpack_request_string(&request->value, &next, roof) < 0) {
+		return -1;
+	}
+
+	return 0;
+}
+
+int connect_request(void)
+{
+	int sock;
+	struct sockaddr_un addr = { AF_UNIX, SNCFG_REQUEST_UNIX_SOCKET };
+
+	if (access(addr.sun_path, R_OK | W_OK) < 0) {
+		return -1;
+	}
+
+	sock = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (sock == -1) {
+		return -1;
+	}
+					
+	struct timeval tm;
+	tm.tv_sec = 8;  /* 8 Secs Timeout */
+	tm.tv_usec = 0;
+		
+	if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const void *)&tm, sizeof(tm)) < 0) {
+		fprintf(stderr, "[LIBSNCFG][%d] Can't setsockopt SO_SNDTIMEO 8 seconds for connect ... %s !!\r\n", getpid(), strerror(errno));
+		syslog(LOG_WARNING, "[LIBSNCFG][%d] Can't setsockopt SO_SNDTIMEO 8 seconds for connect ... %s !!", getpid(), strerror(errno));
+		close(sock);
+		return -1;
+	}
+	if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const void *)&tm, sizeof(tm)) < 0) {
+		fprintf(stderr, "[LIBSNCFG][%d] Can't setsockopt SO_RCVTIMEO 8 seconds for connect ... %s !!\r\n", getpid(), strerror(errno));
+		syslog(LOG_WARNING, "[LIBSNCFG][%d] Can't setsockopt SO_RCVTIMEO 8 seconds for connect ... %s !!", getpid(), strerror(errno));
+		close(sock);
+		return -1;
+	}
+					
+	if (connect(sock, (struct sockaddr *)&addr, 
+				offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path)) < 0) {
+		close(sock);
+		return -1;
+	}
+			
+	return sock;
+}
+
+int accept_request(int sockfd)
+{
+	int sock;
+	socklen_t addrlen;
+	struct sockaddr_un addr;
+
+	addrlen = sizeof(addr);
+	sock = accept(sockfd, (struct sockaddr *)&addr, &addrlen);
+	if (sock == -1) {
+		return -1;
+	}
+
+	if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
+		close(sock);
+		return -1;
+    }	
+
+	struct timeval tm;
+	tm.tv_sec = 8;  /* 8 Secs Timeout */
+	tm.tv_usec = 0;
+		
+	if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const void *)&tm, sizeof(tm)) < 0) {
+		fprintf(stderr, "[LIBSNCFG][%d] Can't setsockopt SO_SNDTIMEO 8 seconds for accept ... %s !!\r\n", getpid(), strerror(errno));
+		syslog(LOG_WARNING, "[LIBSNCFG][%d] Can't setsockopt SO_SNDTIMEO 8 seconds for accept ... %s !!", getpid(), strerror(errno));
+		close(sock);
+		return -1;
+	}
+	if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const void *)&tm, sizeof(tm)) < 0) {
+		fprintf(stderr, "[LIBSNCFG][%d] Can't setsockopt SO_RCVTIMEO 8 seconds for accept ... %s !!\r\n", getpid(), strerror(errno));
+		syslog(LOG_WARNING, "[LIBSNCFG][%d] Can't setsockopt SO_RCVTIMEO 8 seconds for accept ... %s !!", getpid(), strerror(errno));
+		close(sock);
+		return -1;
+	}
+
+	return sock;
+}
+
+int request_for_sncfg(struct sncfg_request *request)
+{
+	int sock, size;
+
+	size = pack_request(request);
+	if (size < 0) {
+		return -1;
+	}
+	
+	sock = connect_request();
+	if (sock < 0) {
+		return -1;
+	}
+	
+	if (safe_write(sock, request, size) != size) {
+		close(sock);
+		return -1;
+	}
+
+	size = safe_read(sock, request, sizeof(struct sncfg_request));
+
+	if (size < 0 ||
+		unpack_request(request, size) < 0 ||
+		request->status < 0) {
+		/* request processing failed */
+		close(sock);
+		return -1;
+	}
+	
+	close(sock);
+	return 0;
+}