[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;
+}
+
+