| #include <stdio.h> |
| #include <stdlib.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 { |
| mbtk_sock_session sock_fd; |
| char ser_addr[256]; |
| int ser_port; |
| char local_addr[256]; |
| int local_port; |
| bool ack_support; |
| bool ssl_support; |
| bool ignore_cert; |
| uint32 heartbeat_time; |
| uint32 delay_time; |
| |
| mbtk_tcpip_read_callback_func read_cb; |
| |
| uint32 data_traffic_send; |
| uint32 data_traffic_recv; |
| |
| } mbtk_tcpip_cli_info_t; |
| |
| typedef struct { |
| mbtk_sock_session sock_fd; |
| char ser_addr[256]; |
| int ser_port; |
| |
| int cli_num; |
| mbtk_tcpip_cli_info_t *cli_list; |
| } mbtk_tcpip_ser_info_t; |
| |
| typedef struct { |
| int link_id; |
| int link_cid; |
| bool link_connected; |
| mbtk_sock_type prot_type; // TCP/UDP |
| |
| mbtk_tcpip_type_enum type; |
| union |
| { |
| mbtk_tcpip_cli_info_t cli_info; |
| mbtk_tcpip_ser_info_t ser_info; |
| } tcpip_info; |
| |
| } 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; |
| |
| /* |
| struct tcp_info |
| { |
| 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, mbtk_sock_cb_info_s *sock_info) |
| { |
| if(tcpip_inited && tcpip_handle == handle/* && http_fd == fd*/) { |
| if(sock_info->event & (EPOLLIN | EPOLLOUT)) { // Cand read or write. |
| int sock_error = 0; |
| socklen_t socklen = sizeof(sock_error); |
| if(getsockopt(sock_info->sock_fd, SOL_SOCKET, SO_ERROR, &sock_error, (socklen_t*)&socklen) == 0) { |
| LOGV("Socket error:%d", sock_error); |
| } |
| |
| if(sock_error) { |
| LOGW("errno = %d", errno); |
| if(sock_error == ECONNRESET|| errno == EAGAIN) |
| { |
| // |
| } |
| else |
| { |
| return; |
| } |
| } |
| |
| if(sock_info->sock_type == MBTK_SOCK_TCP) { |
| struct tcp_info info; |
| int len = sizeof(info); |
| if(getsockopt(sock_info->sock_fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t*)&len) == 0) { |
| LOGV("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(sock_info->sock_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(sock_info->event & EPOLLIN) { // READ |
| LOGV("fd[%d] can read.", sock_info->sock_fd); |
| int link_id = tcpip_fd_2_link(sock_info->sock_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, sock_info->sock_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, sock_info->sock_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(sock_info->event & EPOLLRDHUP) { // Close |
| LOGD("fd[%d] Closed?", sock_info->sock_fd); |
| } else { |
| LOGW("Unknown event:%x",sock_info->event); |
| } |
| } |
| } |
| |
| static void tcpip_net_cb_func(mbtk_sock_handle handle, mbtk_net_cb_info_s *info) |
| { |
| if(tcpip_inited && tcpip_handle == handle) { |
| LOGD("Net state : %d, %s, %s", info->state, info->if_name, info->addr); |
| if(info->state == 0) { |
| mbtk_tcpip_net_close(); |
| } |
| |
| if(tcpip_net_cb) { |
| tcpip_net_cb(info->state, info->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() |
| { |
| 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) |
| { |
| 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) |
| { |
| 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 len = mbtk_sock_read_async(tcpip_handle, tcpip_link[link_id].tcpip_info.cli_info.sock_fd, |
| buff, buff_size); |
| 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. Return -1 if fail. |
| */ |
| int mbtk_tcpip_data_traffic_get(int link_id) |
| { |
| 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; |
| } |
| } |
| |
| /* |
| * Reset the data traffic of the specified link. |
| */ |
| mbtk_tcpip_err_enum mbtk_tcpip_data_traffic_reset(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[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, 1 for connected, other for fail. |
| */ |
| int mbtk_tcpip_link_state_get(int link_id) |
| { |
| if(!tcpip_link_check(link_id)) { |
| LOGE("Link error."); |
| return -1; |
| } |
| |
| return tcpip_link[link_id].link_connected ? 1 : 0; |
| } |
| |
| /* |
| * Get TCP state informations. |
| */ |
| int mbtk_tcpip_info_get(int link_id, mbtk_tcpip_tcp_state_info_s *state_info) |
| { |
| if(!tcpip_link_check(link_id)) { |
| LOGE("Link error."); |
| return -1; |
| } |
| |
| if(state_info == NULL) { |
| LOGE("ARG error."); |
| return -1; |
| } |
| |
| memset(state_info, 0x0, sizeof(mbtk_tcpip_tcp_state_info_s)); |
| |
| struct tcp_info info; |
| memset(&info, 0x0, sizeof(struct tcp_info)); |
| int len = sizeof(info); |
| if(tcpip_link[link_id].prot_type == MBTK_SOCK_TCP) { |
| if(getsockopt(tcpip_link[link_id].tcpip_info.cli_info.sock_fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t*)&len)) { |
| LOGE("Get TCP_INFO fail:%d", errno); |
| return -1; |
| } |
| |
| #if TCPIP_DEBUG |
| tcp_info_print(&info); |
| #endif |
| state_info->state = info.tcpi_state; |
| } else { |
| state_info->state = 0; |
| } |
| |
| #if TCPIP_DEBUG |
| int rcvbuf_size; |
| len = sizeof(rcvbuf_size); |
| if(getsockopt(tcpip_link[link_id].tcpip_info.cli_info.sock_fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf_size, (socklen_t*)&len)) { |
| LOGE("Get SO_RCVBUF fail:%d", errno); |
| return -1; |
| } |
| LOGD("SO_RCVBUF = %d", rcvbuf_size); |
| |
| int sndbuf_size; |
| len = sizeof(sndbuf_size); |
| if(getsockopt(tcpip_link[link_id].tcpip_info.cli_info.sock_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf_size, (socklen_t*)&len)) { |
| LOGE("Get SO_SNDBUF fail:%d", errno); |
| return -1; |
| } |
| LOGD("SO_SNDBUF = %d", sndbuf_size); |
| |
| int rcvlowat_size; |
| len = sizeof(rcvlowat_size); |
| if(getsockopt(tcpip_link[link_id].tcpip_info.cli_info.sock_fd, SOL_SOCKET, SO_RCVLOWAT, &rcvlowat_size, (socklen_t*)&len)) { |
| LOGE("Get SO_RCVLOWAT fail:%d", errno); |
| return -1; |
| } |
| LOGD("SO_RCVLOWAT = %d", rcvlowat_size); |
| |
| int sndlowat_size; |
| len = sizeof(sndlowat_size); |
| if(getsockopt(tcpip_link[link_id].tcpip_info.cli_info.sock_fd, SOL_SOCKET, SO_SNDLOWAT, &sndlowat_size, (socklen_t*)&len)) { |
| LOGE("Get SO_SNDLOWAT fail:%d", errno); |
| return -1; |
| } |
| LOGD("SO_SNDLOWAT = %d", sndlowat_size); |
| #endif |
| |
| state_info->link_id = link_id; |
| state_info->sock_fd = tcpip_link[link_id].tcpip_info.cli_info.sock_fd; |
| state_info->recv_data_len = mbtk_sock_tcp_recv_len_get(tcpip_handle, tcpip_link[link_id].tcpip_info.cli_info.sock_fd); |
| |
| return 0; |
| } |
| |
| /* |
| * Set socket auto read callback function,NULL for close auto read. |
| */ |
| void mbtk_tcpip_set_read_cb(int link_id, mbtk_tcpip_read_callback_func read_cb) |
| { |
| if(!tcpip_link_check(link_id)) { |
| LOGE("Link error."); |
| return; |
| } |
| |
| tcpip_link[link_id].tcpip_info.cli_info.read_cb = read_cb; |
| } |
| |
| void mbtk_tcpip_lib_info_print() |
| { |
| MBTK_SOURCE_INFO_PRINT("mbtk_tcpip_lib"); |
| } |
| |