Fix TCP/IP API
Change-Id: I302bf1ff97d2560e6f68402e0fae609e1435e257
diff --git a/mbtk/mbtk_lib/Makefile b/mbtk/mbtk_lib/Makefile
index 0e51728..77502d5 100755
--- a/mbtk/mbtk_lib/Makefile
+++ b/mbtk/mbtk_lib/Makefile
@@ -19,10 +19,10 @@
-lswscale \
-lcutils \
-laudio-apu
-
+
CFLAGS += -shared -Wl,-shared,-Bsymbolic
-DEFINE +=
+DEFINE += -DMBTK_NET_MONITOR_SUPPORT
MY_FILES_PATH:=$(LOCAL_PATH)/src
#ifeq ($(CONFIG_MBTK_QL_SUPPORT),y)
diff --git a/mbtk/mbtk_lib/src/mbtk_http_base.c b/mbtk/mbtk_lib/src/mbtk_http_base.c
index 40a6742..657b838 100755
--- a/mbtk/mbtk_lib/src/mbtk_http_base.c
+++ b/mbtk/mbtk_lib/src/mbtk_http_base.c
@@ -6,12 +6,6 @@
static void http_sock_cb_func(int handle, int fd, int event);
-static mbtk_init_info http_init_info =
-{
- MBTK_NET_LINUX,
- NULL,
- http_sock_cb_func
-};
static bool http_sock_inited = FALSE;
static int http_handle = -1;
static int http_fd = -1;
@@ -36,7 +30,11 @@
return -1;
}
- http_handle = mbtk_sock_init(&http_init_info);
+ mbtk_init_info init_info;
+ memset(&init_info, 0x0, sizeof(mbtk_init_info));
+ init_info.net_type = MBTK_NET_LINUX;
+ init_info.sock_cb = http_sock_cb_func;
+ http_handle = mbtk_sock_init(&init_info);
if(http_handle < 0) {
LOGE("mbtk_sock_init() fail.");
return -1;
@@ -174,7 +172,7 @@
char read_buf[1];
int read_len = 0;
while(TRUE) {
- if(mbtk_sock_read_async(http_handle, sock_fd, read_buf, 1) == 1) {
+ if(mbtk_sock_read_sync(http_handle, sock_fd, read_buf, 1) == 1) {
*buf_ptr++ = read_buf[0];
read_len++;
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;
+}
+
+
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);
diff --git a/mbtk/mbtk_lib/src/mbtk_tcpip_at.c b/mbtk/mbtk_lib/src/mbtk_tcpip_at.c
index 8f90bed..76dc526 100755
--- a/mbtk/mbtk_lib/src/mbtk_tcpip_at.c
+++ b/mbtk/mbtk_lib/src/mbtk_tcpip_at.c
@@ -1,13 +1,27 @@
#include <stdio.h>
#include <stdlib.h>
-#include <errno.h>
#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sys/epoll.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <netinet/tcp.h>
#include "mbtk_log.h"
#include "mbtk_tcpip.h"
+#include "mbtk_net_control.h"
+
+#define MBTK_TCPIP_CID_DEFAULT 0
+#define MBTK_TCPIP_READ_BUFF_SIZE 2048
+#define TCPIP_DEBUG 0
typedef struct {
- int fd;
+ mbtk_sock_session sock_fd;
char ser_addr[256];
int ser_port;
char local_addr[256];
@@ -26,7 +40,7 @@
} mbtk_tcpip_cli_info_t;
typedef struct {
- int fd;
+ mbtk_sock_session sock_fd;
char ser_addr[256];
int ser_port;
@@ -37,8 +51,8 @@
typedef struct {
int link_id;
int link_cid;
- bool link_active;
- mbtk_tcpip_prot_type_enum prot_type; // TCP/UDP
+ bool link_connected;
+ mbtk_sock_type prot_type; // TCP/UDP
mbtk_tcpip_type_enum type;
union
@@ -50,44 +64,467 @@
} mbtk_tcpip_link_t;
static mbtk_tcpip_link_t tcpip_link[MBTK_TCPIP_LINK_MAX];
+static bool tcpip_inited = FALSE;
+static mbtk_sock_handle tcpip_handle;
+static mbtk_tcpip_net_callback_func tcpip_net_cb = NULL;
+static mbtk_tcpip_sock_callback_func tcpip_sock_cb = NULL;
-mbtk_tcpip_err_enum mbtk_tcpip_net_open()
+/*
+struct tcp_info
{
- return MBTK_TCPIP_ERR_SUCCESS;
+ u_int8_t tcpi_state;
+ u_int8_t tcpi_ca_state;
+ u_int8_t tcpi_retransmits;
+ u_int8_t tcpi_probes;
+ u_int8_t tcpi_backoff;
+ u_int8_t tcpi_options;
+ u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+
+ u_int32_t tcpi_rto;
+ u_int32_t tcpi_ato;
+ u_int32_t tcpi_snd_mss;
+ u_int32_t tcpi_rcv_mss;
+
+ u_int32_t tcpi_unacked;
+ u_int32_t tcpi_sacked;
+ u_int32_t tcpi_lost;
+ u_int32_t tcpi_retrans;
+ u_int32_t tcpi_fackets;
+
+ u_int32_t tcpi_last_data_sent;
+ u_int32_t tcpi_last_ack_sent;
+ u_int32_t tcpi_last_data_recv;
+ u_int32_t tcpi_last_ack_recv;
+
+ u_int32_t tcpi_pmtu;
+ u_int32_t tcpi_rcv_ssthresh;
+ u_int32_t tcpi_rtt;
+ u_int32_t tcpi_rttvar;
+ u_int32_t tcpi_snd_ssthresh;
+ u_int32_t tcpi_snd_cwnd;
+ u_int32_t tcpi_advmss;
+ u_int32_t tcpi_reordering;
+
+ u_int32_t tcpi_rcv_rtt;
+ u_int32_t tcpi_rcv_space;
+
+ u_int32_t tcpi_total_retrans;
+};
+
+*/
+void tcp_info_print(struct tcp_info *tcp)
+{
+ if(tcp) {
+ LOGD("tcpi_state = %d", tcp->tcpi_state);
+ LOGD("tcpi_ca_state = %d", tcp->tcpi_ca_state);
+ LOGD("tcpi_retransmits = %d", tcp->tcpi_retransmits);
+ LOGD("tcpi_probes = %d", tcp->tcpi_probes);
+ LOGD("tcpi_backoff = %d", tcp->tcpi_backoff);
+ LOGD("tcpi_options = %d", tcp->tcpi_options);
+ LOGD("tcpi_snd_wscale = %d", 0x0F & tcp->tcpi_snd_wscale);
+ LOGD("tcpi_rcv_wscale = %d", 0xF0 & tcp->tcpi_rcv_wscale);
+ LOGD("tcpi_rto = %d", tcp->tcpi_rto);
+ LOGD("tcpi_ato = %d", tcp->tcpi_ato);
+ LOGD("tcpi_snd_mss = %d", tcp->tcpi_snd_mss);
+ LOGD("tcpi_rcv_mss = %d", tcp->tcpi_rcv_mss);
+ LOGD("tcpi_unacked = %d", tcp->tcpi_unacked);
+ LOGD("tcpi_sacked = %d", tcp->tcpi_sacked);
+ LOGD("tcpi_lost = %d", tcp->tcpi_lost);
+ LOGD("tcpi_retrans = %d", tcp->tcpi_retrans);
+ LOGD("tcpi_fackets = %d", tcp->tcpi_fackets);
+ LOGD("tcpi_last_data_sent = %d", tcp->tcpi_last_data_sent);
+ LOGD("tcpi_last_ack_sent = %d", tcp->tcpi_last_ack_sent);
+ LOGD("tcpi_last_data_recv = %d", tcp->tcpi_last_data_recv);
+ LOGD("tcpi_last_ack_recv = %d", tcp->tcpi_last_ack_recv);
+ LOGD("tcpi_pmtu = %d", tcp->tcpi_pmtu);
+ LOGD("tcpi_rcv_ssthresh = %d", tcp->tcpi_rcv_ssthresh);
+ LOGD("tcpi_rtt = %d", tcp->tcpi_rtt);
+ LOGD("tcpi_rttvar = %d", tcp->tcpi_rttvar);
+ LOGD("tcpi_snd_ssthresh = %d", tcp->tcpi_snd_ssthresh);
+ LOGD("tcpi_snd_cwnd = %d", tcp->tcpi_snd_cwnd);
+ LOGD("tcpi_advmss = %d", tcp->tcpi_advmss);
+ LOGD("tcpi_reordering = %d", tcp->tcpi_reordering);
+ LOGD("tcpi_rcv_rtt = %d", tcp->tcpi_rcv_rtt);
+ LOGD("tcpi_rcv_space = %d", tcp->tcpi_rcv_space);
+ LOGD("tcpi_total_retrans = %d", tcp->tcpi_total_retrans);
+ }
+}
+
+static int tcpip_fd_2_link(int fd)
+{
+ int link_id = 0;
+ mbtk_tcpip_link_t *link = NULL;
+ for(; link_id < MBTK_TCPIP_LINK_MAX; link_id++) {
+ link = tcpip_link + link_id;
+ if(link->link_connected) {
+ if(link->type == MBTK_TCPIP_TYPE_CLIENT) {
+ if(link->tcpip_info.cli_info.sock_fd > 0 && link->tcpip_info.cli_info.sock_fd == fd) {
+ break;
+ }
+ } else {
+ // Not support.
+
+ }
+ }
+ }
+
+ if(link_id == MBTK_TCPIP_LINK_MAX) {
+ return -1;
+ } else {
+ return link_id;
+ }
+}
+
+static void tcpip_sock_cb_func(int handle, int fd, int event)
+{
+ if(tcpip_inited && tcpip_handle == handle/* && http_fd == fd*/) {
+ if(event & (EPOLLIN | EPOLLOUT)) { // Cand read or write.
+ int sock_error = 0;
+ socklen_t socklen = sizeof(sock_error);
+ if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &sock_error, (socklen_t*)&socklen) == 0) {
+ LOGD("Socket error:%d", sock_error);
+ }
+
+ if(sock_error) {
+ LOGW("errno = %d", errno);
+ return;
+ }
+
+ struct tcp_info info;
+ int len = sizeof(info);
+ if(getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t*)&len) == 0) {
+ LOGD("State : %d", info.tcpi_state);
+#if TCPIP_DEBUG
+ tcp_info_print(&info);
+#endif
+ }
+
+ if(TCP_ESTABLISHED != info.tcpi_state) {
+ LOGW("errno = %d", errno);
+ int link_id = tcpip_fd_2_link(fd);
+ if(link_id >= 0) {
+ // Socket disconnected?
+ mbtk_tcpip_sock_close(link_id);
+
+ if(tcpip_sock_cb) {
+ tcpip_sock_cb(link_id, 0);
+ }
+ }
+ return;
+ }
+ }
+
+ if(event & EPOLLIN) { // READ
+ LOGD("fd[%d] can read.", fd);
+ int link_id = tcpip_fd_2_link(fd);
+ if(link_id >= 0) {
+ if(tcpip_link[link_id].type == MBTK_TCPIP_TYPE_CLIENT) {
+ if(tcpip_link[link_id].tcpip_info.cli_info.read_cb) {
+ char buff[MBTK_TCPIP_READ_BUFF_SIZE];
+ memset(buff, 0x0, MBTK_TCPIP_READ_BUFF_SIZE);
+ int read_len = mbtk_sock_read_async(tcpip_handle, fd, buff, MBTK_TCPIP_READ_BUFF_SIZE);
+ if(read_len > 0) {
+ tcpip_link[link_id].tcpip_info.cli_info.data_traffic_recv += read_len;
+ tcpip_link[link_id].tcpip_info.cli_info.read_cb(link_id, (const char*)buff, read_len);
+ }
+#if 0
+ else { // Socket error(Such as server disconnected.).
+ LOGW("errno = %d", errno);
+ // Socket disconnected?
+ mbtk_tcpip_sock_close(link_id);
+
+ if(tcpip_sock_cb) {
+ tcpip_sock_cb(link_id, 0);
+ }
+ }
+#endif
+ while(read_len > 0) {
+ memset(buff, 0x0, MBTK_TCPIP_READ_BUFF_SIZE);
+ read_len = mbtk_sock_read_async(tcpip_handle, fd, buff, MBTK_TCPIP_READ_BUFF_SIZE);
+ // LOGD("read_len = %d", read_len);
+ if(read_len > 0) {
+ tcpip_link[link_id].tcpip_info.cli_info.data_traffic_recv += read_len;
+ tcpip_link[link_id].tcpip_info.cli_info.read_cb(link_id, (const char*)buff, read_len);
+ }
+ }
+ }
+ } else {
+ // Not support.
+
+ }
+ }
+ } else if(event & EPOLLRDHUP) { // Close
+ LOGD("fd[%d] Closed?", fd);
+ } else {
+ LOGW("Unknown event:%x",event);
+ }
+ }
+}
+
+static void tcpip_net_cb_func(mbtk_sock_handle handle, int state, const char* addr, const char* if_name)
+{
+ if(tcpip_inited && tcpip_handle == handle) {
+ LOGD("Net state : %d, %s, %s", state, if_name, addr);
+ if(state == 0) {
+ mbtk_tcpip_net_close();
+ }
+
+ if(tcpip_net_cb) {
+ tcpip_net_cb(state, addr);
+ }
+ }
+}
+
+static bool tcpip_link_check(int link_id)
+{
+ if(tcpip_inited && link_id >= 0 && link_id < MBTK_TCPIP_LINK_MAX) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool tcpip_link_connected(int link_id)
+{
+ if(!tcpip_link_check(link_id)) {
+ return FALSE;
+ }
+
+ if(!tcpip_link[link_id].link_connected) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int tcpip_link_reset(mbtk_tcpip_link_t *link, int link_id)
+{
+ if(link) {
+ // Close socket if necessary.
+ if(link->link_connected) {
+ if(link->type == MBTK_TCPIP_TYPE_CLIENT) {
+ if(link->tcpip_info.cli_info.sock_fd > 0) {
+ int err;
+ if(mbtk_sock_close(tcpip_handle, link->tcpip_info.cli_info.sock_fd, 3000, &err) == 0
+ && err == MBTK_SOCK_SUCCESS) {
+ LOGD("Close socket[%d] success.", link->tcpip_info.cli_info.sock_fd);
+ } else {
+ LOGE("Close socket[%d] fail.", link->tcpip_info.cli_info.sock_fd);
+ return -1;
+ }
+ }
+ } else {
+ // Not support.
+
+ return -1;
+ }
+ }
+
+ memset(link, 0x0, sizeof(mbtk_tcpip_link_t));
+ link->link_id = link_id;
+ link->link_cid = MBTK_TCPIP_CID_DEFAULT;
+ return 0;
+ }
+
+ return -1;
+}
+
+mbtk_tcpip_err_enum mbtk_tcpip_net_open(mbtk_tcpip_net_callback_func net_cb, mbtk_tcpip_sock_callback_func sock_cb)
+{
+ if(tcpip_inited) {
+ LOGW("TCP/IP has inited.");
+ return MBTK_TCPIP_ERR_SUCCESS;
+ } else {
+ //mbtk_log_init("radio", "MBTK_TCPIP");
+ mbtk_net_state_t net_state = mbtk_net_state_get();
+ if(net_state == MBTK_NET_STATE_OFF) {
+ LOGE("Network unavailable.");
+ return MBTK_TCPIP_ERR_NET_UNAVAILABLE;
+ }
+
+ memset(&tcpip_link, 0x0, sizeof(mbtk_tcpip_link_t) * MBTK_TCPIP_LINK_MAX);
+ int i = 0;
+ for(; i < MBTK_TCPIP_LINK_MAX; i++) {
+ tcpip_link_reset(tcpip_link + i, i);
+ }
+
+ mbtk_init_info init_info;
+ init_info.net_type = MBTK_NET_LINUX;
+ init_info.net_cb = tcpip_net_cb_func;
+ init_info.sock_cb = tcpip_sock_cb_func;
+ sprintf(init_info.if_name, "ccinet%d", MBTK_TCPIP_CID_DEFAULT);
+ tcpip_handle = mbtk_sock_init(&init_info);
+ if(tcpip_handle < 0) {
+ LOGE("mbtk_sock_init() fail.");
+ return MBTK_TCPIP_ERR_NET_HANDLE;
+ }
+
+ tcpip_net_cb = net_cb;
+ tcpip_sock_cb = sock_cb;
+ tcpip_inited = TRUE;
+ return MBTK_TCPIP_ERR_SUCCESS;
+ }
}
mbtk_tcpip_err_enum mbtk_tcpip_net_close()
{
- return MBTK_TCPIP_ERR_SUCCESS;
+ if(tcpip_inited) {
+ int i = 0;
+ mbtk_tcpip_err_enum tcpip_err = MBTK_TCPIP_ERR_SUCCESS;
+
+ // Close all socket.
+ for(; i < MBTK_TCPIP_LINK_MAX; i++) {
+ if(tcpip_link_reset(tcpip_link + i, i)) {
+ tcpip_err = MBTK_TCPIP_ERR_UNKNOWN;
+ }
+ }
+
+ if(tcpip_err == MBTK_TCPIP_ERR_SUCCESS) {
+ tcpip_inited = FALSE;
+ }
+ return tcpip_err;
+ } else {
+ LOGW("TCP/IP not inited.");
+ return MBTK_TCPIP_ERR_SUCCESS;
+ }
}
mbtk_tcpip_err_enum mbtk_tcpip_sock_open(const mbtk_tcpip_info_t *tcpip_info)
{
- return MBTK_TCPIP_ERR_SUCCESS;
+ if(tcpip_info == NULL || strlen(tcpip_info->ser_addr) == 0 || tcpip_info->ser_port <= 0) {
+ LOGE("ARG error.");
+ return MBTK_TCPIP_ERR_ARG;
+ }
+
+ if(!tcpip_link_check(tcpip_info->link_id)) {
+ LOGE("Link[%d] error.", tcpip_info->link_id);
+ return MBTK_TCPIP_ERR_LINK_UNAVAILABLE;
+ }
+
+ if(tcpip_link_connected(tcpip_info->link_id)) {
+ LOGE("Link[%d] has connected.", tcpip_info->link_id);
+ return MBTK_TCPIP_ERR_LINK_UNAVAILABLE;
+ }
+
+ if(tcpip_info->tcpip_type == MBTK_TCPIP_TYPE_CLIENT) {
+ mbtk_tcpip_link_t *link = tcpip_link + tcpip_info->link_id;
+
+ int err;
+ mbtk_sock_info sock_info;
+ memset(&sock_info, 0x0, sizeof(mbtk_sock_info));
+ sock_info.type = tcpip_info->prot_type;
+ sock_info.is_support_ssl = tcpip_info->ssl_support;
+ sock_info.ingnore_cert = tcpip_info->ignore_cert;
+ memcpy(sock_info.address, tcpip_info->ser_addr, strlen(tcpip_info->ser_addr));
+ sock_info.port = tcpip_info->ser_port;
+ sock_info.local_port = tcpip_info->local_port;
+
+ link->tcpip_info.cli_info.sock_fd = mbtk_sock_open(tcpip_handle, &sock_info, 3000, &err);
+ if(link->tcpip_info.cli_info.sock_fd > 0) {
+ link->prot_type = tcpip_info->prot_type;
+ link->type = MBTK_TCPIP_TYPE_CLIENT;
+ memcpy(link->tcpip_info.cli_info.ser_addr, tcpip_info->ser_addr, strlen(tcpip_info->ser_addr));
+ link->tcpip_info.cli_info.ser_port = tcpip_info->ser_port;
+ link->tcpip_info.cli_info.local_port = tcpip_info->local_port;
+ link->tcpip_info.cli_info.ack_support = tcpip_info->ack_support;
+ link->tcpip_info.cli_info.ssl_support = tcpip_info->ssl_support;
+ link->tcpip_info.cli_info.ignore_cert = tcpip_info->ignore_cert;
+ link->tcpip_info.cli_info.heartbeat_time = tcpip_info->heartbeat_time;
+ link->tcpip_info.cli_info.delay_time = tcpip_info->delay_time;
+ link->tcpip_info.cli_info.read_cb = tcpip_info->read_cb;
+ link->link_connected = TRUE;
+ LOGD("Open socket[%d] success.");
+ return MBTK_TCPIP_ERR_SUCCESS;
+ } else {
+ LOGE("Open socket[%d] fail.");
+ return MBTK_TCPIP_ERR_UNKNOWN;
+ }
+ } else {
+ LOGE("Only support CLIENT now!");
+ return MBTK_TCPIP_ERR_UNKNOWN;
+ }
}
mbtk_tcpip_err_enum mbtk_tcpip_sock_close(int link_id)
{
+ if(!tcpip_link_connected(link_id)) {
+ LOGE("Link[%d] not connected.", link_id);
+ return MBTK_TCPIP_ERR_LINK_NOT_CONNECT;
+ }
+
+ if(tcpip_link_reset(tcpip_link + link_id, link_id)) {
+ LOGE("Close link[%d] fail.", link_id);
+ return MBTK_TCPIP_ERR_UNKNOWN;
+ }
+
return MBTK_TCPIP_ERR_SUCCESS;
}
int mbtk_tcpip_send(int link_id, const char* data, int data_len, const char* ser_addr, int ser_port)
{
+ if(!tcpip_link_connected(link_id)) {
+ LOGE("Link[%d] not connected.", link_id);
+ return -1;
+ }
+
+ if(tcpip_link[link_id].type == MBTK_TCPIP_TYPE_CLIENT) {
+ int err;
+ int len = mbtk_sock_write(tcpip_handle, tcpip_link[link_id].tcpip_info.cli_info.sock_fd,
+ data, data_len, 3000, &err);
+ if(len > 0) {
+ tcpip_link[link_id].tcpip_info.cli_info.data_traffic_send += len;
+ }
+ return len;
+ } else {
+ // Not support.
+ return -1;
+ }
return 0;
}
int mbtk_tcpip_read(int link_id, char* buff, int buff_size)
{
- return 0;
+ if(!tcpip_link_connected(link_id)) {
+ LOGE("Link[%d] not connected.", link_id);
+ return -1;
+ }
+
+ if(tcpip_link[link_id].type == MBTK_TCPIP_TYPE_CLIENT) {
+ if(tcpip_handle, tcpip_link[link_id].tcpip_info.cli_info.read_cb) {
+ LOGE("Set read_cb function,can not manual read.");
+ return -1;
+ }
+ int err;
+ int len = mbtk_sock_read(tcpip_handle, tcpip_link[link_id].tcpip_info.cli_info.sock_fd,
+ buff, buff_size, 3000, &err);
+ if(len > 0) {
+ tcpip_link[link_id].tcpip_info.cli_info.data_traffic_recv += len;
+ }
+ return len;
+ } else {
+ // Not support.
+ return -1;
+ }
}
/*
-* Get the data traffic of the specified link.
+* Get the data traffic of the specified link. Return -1 if fail.
*/
int mbtk_tcpip_data_traffic_get(int link_id)
{
- return 0;
+ if(!tcpip_link_connected(link_id)) {
+ LOGE("Link[%d] not connected.", link_id);
+ return -1;
+ }
+
+ if(tcpip_link[link_id].type == MBTK_TCPIP_TYPE_CLIENT) {
+ return tcpip_link[link_id].tcpip_info.cli_info.data_traffic_recv
+ + tcpip_link[link_id].tcpip_info.cli_info.data_traffic_send;
+ } else {
+ // Not support.
+ return -1;
+ }
}
/*
@@ -95,14 +532,33 @@
*/
mbtk_tcpip_err_enum mbtk_tcpip_data_traffic_reset(int link_id)
{
- return MBTK_TCPIP_ERR_SUCCESS;
+ if(!tcpip_link_connected(link_id)) {
+ LOGE("Link[%d] not connected.", link_id);
+ return MBTK_TCPIP_ERR_LINK_NOT_CONNECT;
+ }
+
+ if(tcpip_link[link_id].type == MBTK_TCPIP_TYPE_CLIENT) {
+ tcpip_link[link_id].tcpip_info.cli_info.data_traffic_recv = 0;
+ tcpip_link[link_id].tcpip_info.cli_info.data_traffic_send = 0;
+ return MBTK_TCPIP_ERR_SUCCESS;
+ } else {
+ // Not support.
+
+ }
+
+ return MBTK_TCPIP_ERR_UNKNOWN;
}
/*
-* Return 0 if disconnected, other for connected.
+* Return 0 if disconnected, 1 for connected, other for fail.
*/
int mbtk_tcpip_link_state_get(int link_id)
{
- return 0;
+ if(!tcpip_link_check(link_id)) {
+ LOGE("Link error.");
+ return -1;
+ }
+
+ return tcpip_link[link_id].link_connected ? 1 : 0;
}