Fix TCP/IP API

Change-Id: I302bf1ff97d2560e6f68402e0fae609e1435e257
diff --git a/mbtk/mbtk_lib/src/mbtk_sock2.c b/mbtk/mbtk_lib/src/mbtk_sock2.c
index 461c68c..f9f6b6b 100755
--- a/mbtk/mbtk_lib/src/mbtk_sock2.c
+++ b/mbtk/mbtk_lib/src/mbtk_sock2.c
@@ -200,6 +200,24 @@
     return 0;
 }
 
+void net_state_callback_func(mbtk_net_change_type_t type, const void *data)
+{
+    if(type == MBTK_NET_CHANGE_ADDR && data != NULL) {
+        int handle = 0;
+        const mbtk_net_addr_change_info_t *addr_info = (const mbtk_net_addr_change_info_t *)data;
+        while(handle < MBTK_HANDLE_MAX_NUM) {
+            if(mbtk_sock[handle] != NULL) {
+                if(mbtk_sock[handle]->init_info.net_cb != NULL) {
+                    mbtk_sock[handle]->init_info.net_cb(handle, (addr_info->type == MBTK_NET_ADDR_CHANGE_TYPE_ADD) ? 1 : 0,
+                        addr_info->addr, addr_info->if_name);
+                }
+            }
+
+            handle++;
+        }
+    }
+}
+
 extern mbtk_sock_handle mbtk_sock_init(mbtk_init_info *info)
 {
     mbtk_sock_handle handle = 0;
@@ -221,6 +239,9 @@
         mbtk_sock[handle]->init_info.net_type = info->net_type;
         mbtk_sock[handle]->init_info.net_cb = info->net_cb;
         mbtk_sock[handle]->init_info.sock_cb = info->sock_cb;
+        if(!str_empty(info->if_name)) {
+            memcpy(mbtk_sock[handle]->init_info.if_name, info->if_name, strlen(info->if_name));
+        }
     } else {
         mbtk_sock[handle]->init_info.net_type = MBTK_NET_LINUX;
         mbtk_sock[handle]->init_info.net_cb = NULL;
@@ -235,6 +256,11 @@
         }
     }
 
+    if(mbtk_net_monitor_reg(str_empty(info->if_name) ? NULL : info->if_name, net_state_callback_func)) {
+        LOGE("mbtk_net_monitor_reg() fail.");
+        return -1;
+    }
+
     return handle;
 }
 
@@ -527,6 +553,34 @@
     // Connect
     LOGD("Start conn:%s:%d",info->address,info->port);
     if(strlen(info->address) > 0 && info->port > 0) {
+        if(strlen(info->local_address) > 0 || info->local_port > 0) {
+            // 指定本地IP和端口,不指定内核会自动指定(一般不指定)
+            struct sockaddr_in loc_addr;
+            memset(&loc_addr, 0, sizeof(struct sockaddr_in));
+            loc_addr.sin_family = AF_INET;
+
+            // 指定IP
+            if(strlen(info->local_address) > 0) {
+                if(inet_pton(AF_INET, info->local_address, &loc_addr.sin_addr) < 0) {
+                    LOGE("inet_pton() error:%d", errno);
+                    goto result_fail_with_close;
+                }
+            }
+
+            if(info->local_port > 0) {
+                loc_addr.sin_port = htons(info->local_port);
+            }
+            if(bind(mbtk_sock[handle]->inter_infos[index_free].fd, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) {
+                LOGE("bind() error:%d", errno);
+                if(errno == EADDRINUSE) { // 地址已在使用
+                    LOGE("EADDRINUSE : Local port already occupied.");
+                }
+                goto result_fail_with_close;
+            } else {
+                LOGD("Bind ip/port success.");
+            }
+        }
+
         struct sockaddr_in servaddr;
         bzero(&servaddr, sizeof(servaddr));
         servaddr.sin_family = AF_INET;
@@ -633,7 +687,7 @@
                         60000,
                         &err_rw);
                 printf("\nmbtk_sock_read:\n%s\n",mbtk_ftp_ssl_read_buf_s);
-                
+
             mbtk_sock[handle]->infos[index_free].is_support_ssl=1;
         }else{
             mbtk_sock[handle]->infos[index_free].is_support_ssl=1;
@@ -662,7 +716,7 @@
     return -1;
 }
 extern int mbtk_ssl_init_func(mbtk_sock_handle handle ,bool ingnore_cert,mbtk_sock_session fd)
-{   
+{
     int i=0;
     int index_free=0;
 
@@ -677,7 +731,7 @@
     return mbtk_ssl_init(mbtk_sock[handle]->inter_infos[index_free].fd,ingnore_cert,&mbtk_sock[handle]->inter_infos[index_free]);
 }
 extern int mbtk_ssl_close_func(mbtk_sock_handle handle ,bool ingnore_cert,mbtk_sock_session fd)
-{   
+{
     int i=0;
     int index_free=0;
 
@@ -1050,7 +1104,7 @@
                         LOGE("read error.[%d]",errno);
                         if(count <= 0)
                             count = -1;
-                        else { 
+                        else {
                             *read_line_count = count;
                         }
                         break;
@@ -1182,6 +1236,85 @@
         return -1;
     }
 
+    int len = 0;
+    int read_count = 0;
+    if(mbtk_sock[handle]->infos[index].type == MBTK_SOCK_TCP) {
+        memset(buffer,0x0,buf_len);
+        while(read_count < buf_len) {
+            if(mbtk_sock[handle]->infos[index].is_support_ssl)
+                len = ssl_read(inter_info->ssl,(char*)buffer + read_count,buf_len - read_count);
+            else
+                len = read(inter_info->fd,(char*)buffer  + read_count,buf_len - read_count);
+
+            if(len > 0) {
+                read_count += len;
+            } else {
+                break;
+            }
+        }
+    } else if(mbtk_sock[handle]->infos[index].type == MBTK_SOCK_UDP) {
+        // Start recv data
+        struct sockaddr_in seraddr;
+        socklen_t seraddr_len;
+        memset(buffer,0x0,buf_len);
+        seraddr_len = sizeof(struct sockaddr_in);
+        memset(buffer,0x0,buf_len);
+
+        while(read_count < buf_len) {
+            len = recvfrom(inter_info->fd,buffer + read_count,buf_len - read_count,0,&seraddr,&seraddr_len);
+
+            if(len > 0) {
+                read_count += len;
+            } else {
+                break;
+            }
+        }
+    } else {
+        LOGE("Socket type error.");
+        return -1;
+    }
+
+    LOGV("Read data[%d/%d].",len,buf_len);
+
+    return read_count;
+}
+
+extern int mbtk_sock_read_sync(mbtk_sock_handle handle,mbtk_sock_session session,
+            void *buffer,
+            unsigned int buf_len)
+{
+    if(handle < 0 || handle >= MBTK_HANDLE_MAX_NUM
+        || session < 0 || mbtk_sock[handle] == NULL) {
+        LOGE("Socket not inited.");
+        return -1;
+    }
+
+    if(buffer == NULL) {
+        LOGE("mbtk_sock_write() args error.");
+        return -1;
+    }
+
+    mbtk_sock_inter_info_s *inter_info = NULL;
+    int index = 0;
+    while(index < MBTK_SOCK_MAX_NUM) {
+        if(session ==
+            mbtk_sock[handle]->inter_infos[index].fd) {
+            inter_info = &(mbtk_sock[handle]->inter_infos[index]);
+            break;
+        }
+        index++;
+    }
+    if(!sock_info_check(handle,inter_info)) {
+        LOGE("sock_info_check() fail.");
+        return -1;
+    }
+
+    index = sock_info_find_by_fd(handle,inter_info->fd);
+    if(index < 0) {
+        LOGE("No such socket in session list.");
+        return -1;
+    }
+
     int len;
     if(mbtk_sock[handle]->infos[index].type == MBTK_SOCK_TCP) {
 TCP_READ_AGAIN:
@@ -1193,6 +1326,7 @@
         if(len < 0){
             if(errno == EWOULDBLOCK){
                 usleep(100000);
+                LOGW("Read retry...");
                 goto TCP_READ_AGAIN;
             } else {
                 LOGE("read error.[%d]",errno);