Fix TCP/IP API

Change-Id: I302bf1ff97d2560e6f68402e0fae609e1435e257
diff --git a/mbtk/mbtk_lib/src/mbtk_net_control.c b/mbtk/mbtk_lib/src/mbtk_net_control.c
index ff3af08..722efda 100755
--- a/mbtk/mbtk_lib/src/mbtk_net_control.c
+++ b/mbtk/mbtk_lib/src/mbtk_net_control.c
@@ -49,12 +49,14 @@
 *************************************************************/
 static char net_interface[20];
 static char net_ip[20];
+static bool net_if_inited = FALSE;
 static mbtk_net_state_t net_state = MBTK_NET_STATE_OFF;
 static bool net_control_thread_running = FALSE;
 
 #ifdef MBTK_NET_MONITOR_SUPPORT
 static pthread_t net_control_thread_id = -1;
 static int net_control_fd = -1;
+static char net_if_name[100] = {0};
 #endif
 
 /*************************************************************
@@ -65,7 +67,7 @@
 /*************************************************************
     Local Function Declaration
 *************************************************************/
-
+static mbtk_net_state_callback_func net_state_cb = NULL;
 
 /*************************************************************
     Local Function Definitions
@@ -164,8 +166,18 @@
     return 0;
 }
 
+static void parse_rtattr(struct rtattr **tb, int max, struct rtattr *attr, int len)
+{
+    for ( ; RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {
+        if (attr->rta_type <= max) {
+            tb[attr->rta_type] = attr;
+        }
+    }
+}
+
 static void net_control_if_change(struct nlmsghdr *nh)
 {
+    int msg_len;
     struct rtattr *tb[IFLA_MAX + 1];
     struct ifinfomsg *ifinfo;
     bzero(tb, sizeof(tb));
@@ -182,45 +194,94 @@
         return;
     }
 
-    LOGD("nlmsghdr:%d,%d,%d,%d,%d\n",nh->nlmsg_len,
-         nh->nlmsg_type,
-         nh->nlmsg_flags,
-         nh->nlmsg_seq,
-         nh->nlmsg_pid);
+    msg_len = nh->nlmsg_len - NLMSG_SPACE(sizeof(*ifinfo));
+    parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifinfo), msg_len); /* 8 */
 
-    LOGD("ifinfomsg:%d,%d,%d,%d,%d,%d\n",ifinfo->ifi_family,
-         ifinfo->__ifi_pad,
-         ifinfo->ifi_type,
-         ifinfo->ifi_index,
-         ifinfo->ifi_flags,
-         ifinfo->ifi_change);
+    LOGD("Interface changed:if_index=%d,if_name=%s,type=%s,state=%s",
+        ifinfo->ifi_index, (tb[IFLA_IFNAME] ? RTA_DATA(tb[IFLA_IFNAME]) : " "),
+        (nh->nlmsg_type == RTM_NEWLINK) ? "NEWLINK" : "DELLINK",
+        (ifinfo->ifi_flags & IFF_UP) ? "up" : "down");
 
-    if((ifinfo->ifi_flags & IFF_RUNNING)
-       && (ifinfo->ifi_flags & IFF_LOWER_UP))
-    {
-        LOGD("Wired inserted.");
-    }
-    else
-    {
-        LOGD("Wired not insert.");
+    if(net_state_cb) {
+        mbtk_net_if_change_info_t if_info;
+        memset(&if_info, 0x0, sizeof(mbtk_net_if_change_info_t));
+        if_info.if_index = ifinfo->ifi_index;
+        if(tb[IFLA_IFNAME]) {
+            memcpy(if_info.if_name, RTA_DATA(tb[IFLA_IFNAME]), strlen(RTA_DATA(tb[IFLA_IFNAME])));
+        }
+        if_info.type = (nh->nlmsg_type == RTM_NEWLINK) ? MBTK_NET_IF_CHANGE_TYPE_ADD : MBTK_NET_IF_CHANGE_TYPE_DEL;
+        if_info.state = (ifinfo->ifi_flags & IFF_UP) ? MBTK_NET_IF_CHANGE_STATE_UP : MBTK_NET_IF_CHANGE_STATE_DOWN;
+        if(str_empty(net_if_name)) { // No set if name, process all interface change.
+            net_state_cb(MBTK_NET_CHANGE_IF, &if_info);
+        } else {
+            // Only monitor specific interface.
+            if(strcmp(net_if_name, if_info.if_name) == 0) {
+                net_state_cb(MBTK_NET_CHANGE_IF, &if_info);
+            }
+        }
     }
 }
 
-static void net_control_addr_change(struct nlmsghdr *nh)
+static void net_control_addr_change(struct nlmsghdr *nlh)
 {
-    if(nh == NULL)
-    {
-        LOGE("mbtk_net_if_change() nh == NULL");
-        return;
-    }
+    int len;
+    struct rtattr *tb[IFA_MAX + 1];
+    struct ifaddrmsg *ifaddr;
 
-    if(nh->nlmsg_type==RTM_NEWADDR)
-    {
-        LOGD("New addr...");
-    }
-    else
-    {
-        LOGD("Del addr...");
+    bzero(tb, sizeof(tb));
+    ifaddr = NLMSG_DATA(nlh);
+    len =nlh->nlmsg_len - NLMSG_SPACE(sizeof(*ifaddr));
+    parse_rtattr(tb, IFA_MAX, IFA_RTA (ifaddr), len);
+
+    if (tb[IFA_ADDRESS] != NULL) {
+        char tmp[256] = {0};
+        inet_ntop(ifaddr->ifa_family, RTA_DATA(tb[IFA_ADDRESS]), tmp, sizeof(tmp));
+        LOGD("Address changed:index=%d,type=%s,if_name=%s,addr=%s", ifaddr->ifa_index,
+                (nlh->nlmsg_type == RTM_NEWADDR) ? "NEWADDR":"DELADDR",
+                tb[IFA_LABEL] ? RTA_DATA(tb[IFA_LABEL]) : "Unknown", tmp);
+
+        if(net_state_cb) {
+            mbtk_net_addr_change_info_t addr_info;
+            memset(&addr_info, 0x0, sizeof(mbtk_net_addr_change_info_t));
+            addr_info.if_index = ifaddr->ifa_index;
+            addr_info.type = (nlh->nlmsg_type == RTM_NEWADDR) ? MBTK_NET_ADDR_CHANGE_TYPE_ADD : MBTK_NET_ADDR_CHANGE_TYPE_DEL;
+            if(tb[IFA_LABEL] != NULL) {
+                memcpy(addr_info.if_name, RTA_DATA(tb[IFA_LABEL]), strlen(RTA_DATA(tb[IFA_LABEL])));
+            }
+            if (strlen(tmp) > 0) {
+                memcpy(addr_info.addr, tmp, strlen(tmp));
+            }
+            if(str_empty(net_if_name)) { // No set if name, process all address change.
+                net_state_cb(MBTK_NET_CHANGE_ADDR, &addr_info);
+            } else {
+                // Only monitor specific address.
+                if(strcmp(net_if_name, addr_info.if_name) == 0) {
+                    net_state_cb(MBTK_NET_CHANGE_ADDR, &addr_info);
+                }
+            }
+        }
+    } else {
+        LOGD("Address changed:type=%s,if_name=%s,addr=%s",
+            (nlh->nlmsg_type == RTM_NEWADDR) ? "NEWADDR":"DELADDR",
+            tb[IFA_LABEL] ? RTA_DATA(tb[IFA_LABEL]) : "Unknown", "Unknown");
+
+        if(net_state_cb) {
+            mbtk_net_addr_change_info_t addr_info;
+            memset(&addr_info, 0x0, sizeof(mbtk_net_addr_change_info_t));
+            addr_info.if_index = ifaddr->ifa_index;
+            addr_info.type = (nlh->nlmsg_type == RTM_NEWADDR) ? MBTK_NET_ADDR_CHANGE_TYPE_ADD : MBTK_NET_ADDR_CHANGE_TYPE_DEL;
+            if(tb[IFA_LABEL] != NULL) {
+                memcpy(addr_info.if_name, RTA_DATA(tb[IFA_LABEL]), strlen(RTA_DATA(tb[IFA_LABEL])));
+            }
+            if(str_empty(net_if_name)) { // No set if name, process all address change.
+                net_state_cb(MBTK_NET_CHANGE_ADDR, &addr_info);
+            } else {
+                // Only monitor specific address.
+                if(strcmp(net_if_name, addr_info.if_name) == 0) {
+                    net_state_cb(MBTK_NET_CHANGE_ADDR, &addr_info);
+                }
+            }
+        }
     }
 }
 
@@ -258,11 +319,11 @@
             {
                 read_r = read(net_control_fd, buff, NET_CONTROL_BUF_SIZE);
                 LOGI("Net change:read len:%d",read_r);
-
+#if 0
                 int i;
                 for(i = 0; i < 32 && i < read_r; i++)
                     LOGI("data:%x",buff[i]);
-
+#endif
                 for (nh = (struct nlmsghdr *) buff; NLMSG_OK(nh, read_r); nh = NLMSG_NEXT(nh, read_r))
                 {
                     LOGI("msg_type:%d",nh->nlmsg_type);
@@ -353,27 +414,18 @@
 
 static int net_control_init()
 {
-//    if(net_control_thread_running)
-//    {
-//        LOGD("Network control has inited.");
-//        return 0;
-//    }
+    if(net_if_inited)
+    {
+        LOGD("Network control has inited.");
+        return 0;
+    }
 
     memset(net_ip,0x0,20);
     memset(net_interface,0x0,20);
-    if( net_control_interface_init())
+    if(net_control_interface_init())
         return -1;
-    net_control_thread_running = TRUE;
 
-#ifdef MBTK_NET_MONITOR_SUPPORT
-    if(mbtk_task_start(&net_control_thread))
-    {
-        LOGE("Create thread fail.");
-        net_control_thread_id = -1;
-        net_control_thread_running = FALSE;
-        return -1;
-    }
-#endif
+    net_if_inited = TRUE;
     LOGI("net_control_init() success.");
     return 0;
 }
@@ -533,3 +585,31 @@
     return result;
 }
 
+int mbtk_net_monitor_reg(const char* if_name, mbtk_net_state_callback_func state_cb)
+{
+    if( net_control_init())
+        return -1;
+
+#ifdef MBTK_NET_MONITOR_SUPPORT
+    net_control_thread_running = TRUE;
+    if(mbtk_task_start(&net_control_thread))
+    {
+        LOGE("Create thread fail.");
+        net_control_thread_id = -1;
+        net_control_thread_running = FALSE;
+        return -1;
+    }
+#endif
+
+    net_state_cb = state_cb;
+    if(str_empty(if_name)) {
+        memset(net_if_name, 0x0, sizeof(net_if_name));
+    } else {
+        memset(net_if_name, 0x0, sizeof(net_if_name));
+        memcpy(net_if_name, if_name, strlen(if_name));
+    }
+
+    return 0;
+}
+
+