[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/zte_comm/zte_hotplug/hotplug.c b/ap/app/zte_comm/zte_hotplug/hotplug.c
new file mode 100755
index 0000000..8c1893b
--- /dev/null
+++ b/ap/app/zte_comm/zte_hotplug/hotplug.c
@@ -0,0 +1,227 @@
+#include "hotplug.h"
+
+
+static hotplug_parse_func hotplug_parse_ptr[DEVICE_TYPE_MAX] = {NULL};
+static hotplug_proc_func hotplug_proc_ptr[DEVICE_TYPE_MAX] = {NULL};
+
+#define RTC_ALARM_TIMEOUT_MSG  "PMIC RTC ALARM IRQ COME"
+#define RTC_TIMER_TIMEOUT_MSG  "PMIC RTC TIMER IRQ COME"
+
+static const char *hotplug_action_str[] = {
+	[KOBJ_ADD]     =    "add",
+	[KOBJ_REMOVE]  =    "remove",
+	[KOBJ_CHANGE]  =    "change",
+	[KOBJ_MOVE]    =    "move",
+	[KOBJ_ONLINE]  =    "online",
+	[KOBJ_OFFLINE] =	"offline",
+};
+
+static int get_action_type(const char *buf, int count)
+{
+	int action;
+
+	if (count && (buf[count - 1] == '\n' || buf[count - 1] == '\0'))
+		count--;
+
+	if (!count)
+		goto err_out;
+
+	for (action = 0; action < KOBJ_MAX; action++) {
+		if (0 == strncmp(hotplug_action_str[action], buf, count)) {
+			return action;
+		}
+	}
+
+err_out:
+	return -1;
+}
+
+
+/*½«UEVENTÖеÄ'\0' Ìæ»»³É'\n'£¬·ÀÖ¹»ñÈ¡²»µ½'\0'ºóÃæµÄÄÚÈÝ*/
+void char_replace(char*buf, int count, char orig_char, char replace_char)
+{
+	int index = 0;
+
+	if (!buf || count <= 0) {
+		slog(NET_PRINT, SLOG_ERR,"[%s][%d]\n", __func__, __LINE__);
+		return;
+	}
+
+	for (index = 0; index < count; ++index) {
+		if (buf[index] == orig_char) {
+			buf[index] = replace_char;
+		}
+	}
+}
+
+/*×¢²ádeviceµÄueventÏûÏ¢½âÎöº¯Êý*/
+int hotplug_parse_register(int device_type, hotplug_parse_func func)
+{
+	if (device_type < DEVICE_TYPE_MAX && device_type >= 0) {
+		hotplug_parse_ptr[device_type] = func;
+	}
+
+	return 0;
+}
+
+/*×¢²ádeviceµÄueventÏûÏ¢½âÎöº¯Êý*/
+int hotplug_proc_register(int device_type, hotplug_proc_func func)
+{
+	if (device_type < DEVICE_TYPE_MAX && device_type >= 0) {
+		hotplug_proc_ptr[device_type] = func;
+	}
+
+    return 0;
+}
+
+
+/*ÈȰβåÏûÏ¢½âÎö*/
+static int hotplug_msg_parse(const char *msg, int msglen, struct hotplug_event *event)
+{
+	int i = 0;
+	int ret = 0;
+	int act_type = 0;
+	char *act_ptr = NULL;
+	char *p = NULL;
+
+	if (NULL == msg || NULL == event) {
+		slog(NET_PRINT, SLOG_ERR,"[%s][%d]\n", __func__, __LINE__);
+		return -1;
+	}
+
+	memset(event, 0, sizeof(struct hotplug_event));
+
+	slog(NET_PRINT, SLOG_ERR, "[%s][%d]uevent message = %s, %d, %d\n", __func__, __LINE__, msg, msglen, strlen(msg));
+
+    
+	//´¦ÀíÇý¶¯ÈȲå°ÎÉϱ¨ÏûÏ¢
+	act_ptr = strchr(msg, '@');
+	if (NULL == act_ptr) {
+		slog(NET_PRINT, SLOG_ERR, "hotplug msg parse failed!\n");
+		return -1;
+	}
+
+	act_type = get_action_type(msg, act_ptr - msg);
+
+	if (act_type < 0) {
+		slog(NET_PRINT, SLOG_ERR, "hotplug get action type failed!\n");
+		return -1;
+	}
+	event->action = act_type;
+
+	slog(NET_PRINT, SLOG_NORMAL, "[%s][%d]action = %s\n", __func__, __LINE__, hotplug_action_str[act_type]);
+
+	for (i = 0; i < DEVICE_TYPE_MAX; i++) {
+		if (hotplug_parse_ptr[i]) {
+			ret = hotplug_parse_ptr[i](msg, msglen, event);
+			if (0 == ret){				
+				if (hotplug_proc_ptr[event->type])
+					hotplug_proc_ptr[event->type](event);
+			}
+		}
+	}
+
+	return -1;
+}
+
+
+/*ÈȰβåÌ×½Ó×Ö³õʼ»¯*/
+int hotplug_sock_init()
+{
+	int sockfd = 0;
+	int ret;
+	struct sockaddr_nl snl;
+
+	bzero(&snl, sizeof(struct sockaddr_nl));
+	snl.nl_family = AF_NETLINK;
+	snl.nl_pid = getpid();
+	snl.nl_groups = 1;
+
+	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
+		perror("signal");
+
+	sockfd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+	if (sockfd < 0) {
+		slog(NET_PRINT, SLOG_ERR, "create hotplug socket failed!\n");
+		return -1;
+	}
+//  setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
+
+	ret = bind(sockfd, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
+	if (ret < 0) {
+		slog(NET_PRINT, SLOG_ERR, "hotplug socket bind fail!\n");
+		close(sockfd);
+		return -1;
+	}
+
+	return sockfd;
+}
+
+
+void hotplug_init()
+{
+	/*ÍøÂçÉ豸³õʼ»¯*/
+	netdev_hotplug_init();
+	/*Çý¶¯É豸³õʼ»¯*/
+	drv_hotplug_init();
+}
+
+
+int zte_hotplug_main(int argc, char * argv[])
+{
+	int hotplug_fd = 0;
+	fd_set readfds;
+	int maxfd = 0;
+	char buf[UEVENT_BUFFER_SIZE] = {0};
+	int len = 0;
+	int ret = 0;
+	struct hotplug_event hot_event;
+	prctl(PR_SET_NAME, "hotplug", 0, 0, 0);
+	//¸ù¾ÝNV³õʼ»¯´òÓ¡¼¶±ð£¬²¢×¢²á¶¯Ì¬µ÷Õû´òÓ¡¼¶±ðÐźÅÁ¿
+	loglevel_init();
+	
+	hotplug_fd = hotplug_sock_init();
+	if (hotplug_fd < 0) {
+		slog(NET_PRINT, SLOG_ERR, "hotplug socket init fail!\n");
+		return -1;
+	}
+
+	/*ÈȰβåÉ豸µÄ³õʼ»¯*/
+	hotplug_init();
+
+	maxfd = hotplug_fd;
+	while (1) {
+		FD_ZERO(&readfds);
+		FD_SET(hotplug_fd, &readfds);
+
+		ret = select(maxfd + 1, &readfds, NULL, NULL, NULL);
+		if (ret == -1 && errno == EINTR)
+			continue;
+
+		if (FD_ISSET(hotplug_fd, &readfds)) {
+			memset(buf, 0, sizeof(buf));
+			len = recv(hotplug_fd, &buf, sizeof(buf), 0);
+			if (len <= 0) {
+				slog(NET_PRINT, SLOG_ERR, "hotplug recv msg fail!\n");
+				continue;
+			}
+
+			/*½øÐÐueventÏûÏ¢½âÎö£¬·µ»Ø½âÎö½á¹û*/
+			ret = hotplug_msg_parse(buf, len, &hot_event);
+#if 0 //klocwork
+			if (ret < 0)
+				continue;
+
+			if (hot_event.type >= DEVICE_TYPE_MAX || hot_event.type < 0)
+				continue;
+#endif
+			/*É豸ueventʼþ´¦Àí
+			if (hotplug_proc_ptr[hot_event.type])
+				hotplug_proc_ptr[hot_event.type](&hot_event);*/
+		}
+	}
+
+	return 0;
+}
+
+