selfcare init
This commit is contained in:
98
proxy_c/tcp/Makefile
Normal file
98
proxy_c/tcp/Makefile
Normal file
@@ -0,0 +1,98 @@
|
||||
|
||||
##----------------------------------------------------------##
|
||||
## ##
|
||||
## Universal Makefile for module template : V1.6.3 ##
|
||||
## ##
|
||||
## Created : Wei Liu 07/04/11 ##
|
||||
## Revision: [Last]Wei Liu 07/07/07 ##
|
||||
## ##
|
||||
##----------------------------------------------------------##
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
##--------------------------------------
|
||||
##
|
||||
## Project correlation(Customer define)
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
## MODULE= [Module Name]
|
||||
## TYPE = app/plat => Module Type
|
||||
|
||||
## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ]
|
||||
## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release]
|
||||
|
||||
## BUILD = lib/exef => Output file format
|
||||
## CFG = debug/release => Build Configuration
|
||||
|
||||
## SRC_PATH = [Source file path]
|
||||
## INC_PATH = [Include file path]
|
||||
## APP_PATH = [App Module path]
|
||||
## PLT_PATH = [Plat Module path]
|
||||
|
||||
## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main
|
||||
## APP_LIB = [Needed app lib for Link] => just for test or wxc2main
|
||||
## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main
|
||||
|
||||
## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \
|
||||
## 8ecp bicc smpp xapp tcap mtp3 m2ua \
|
||||
## snmp iptrans debug sccp public
|
||||
##
|
||||
## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas
|
||||
## LIB_ADD e.g. = -liba3a8 -lm
|
||||
|
||||
## OBJ_ADD = [Extend third party object files needed]
|
||||
## TEST_OBJ_PATH = [module object files Path for test ] => just for test
|
||||
##---------------------------------------------------------------------##
|
||||
|
||||
MODULE = tcp
|
||||
TYPE = plat
|
||||
|
||||
DBUG_FLAGS_ADD = -DDEBUG
|
||||
RELS_FLAGS_ADD =
|
||||
|
||||
##Default commonly as below
|
||||
|
||||
BUILD = lib
|
||||
CFG = debug
|
||||
|
||||
|
||||
PLT_LIB =
|
||||
|
||||
APP_LIB =
|
||||
LIB_ADD =
|
||||
|
||||
SRC_PATH = ./src
|
||||
INC_PATH = ./src/include
|
||||
PLT_PATH = ../../plat
|
||||
APP_PATH = ../../mss
|
||||
|
||||
OBJ_ADD =
|
||||
TEST_OBJ_PATH =
|
||||
|
||||
PREPROC_CMD =
|
||||
POSTPROC_CMD =
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make configuration(Customer define)
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
## CCFLAG_SWITCH = on/off => gcc flag show on/off
|
||||
## COVER_NEED = yes/no => PTF cover report needed
|
||||
## COVER_REPORT_PATH = [path ] => PTF cover report path
|
||||
|
||||
CCFLAG_SWITCH = off
|
||||
COVER_NEED = no
|
||||
COVER_REPORT_PATH = ./output
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## include makefile.rules (Do not change)
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.rules
|
||||
32
proxy_c/tcp/src/include/tcp_if.h
Normal file
32
proxy_c/tcp/src/include/tcp_if.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef _TCP_IF_H_
|
||||
#define _TCP_IF_H_
|
||||
|
||||
#include "tcp_inc.h"
|
||||
#include "tcp_port.h"
|
||||
#define TCP_MAX_NUM_OF_SAP 4
|
||||
#define TCP_MAX_USER_NAME_LEN 16
|
||||
|
||||
typedef int (*tcp_recv_callback)(WORD usr_port, BYTE *pdata, WORD datalen);
|
||||
|
||||
typedef struct _tcp_sap_t
|
||||
{
|
||||
BYTE id;
|
||||
char name[TCP_MAX_USER_NAME_LEN];
|
||||
tcp_recv_callback recv_cb;
|
||||
}tcp_sap_t;
|
||||
|
||||
extern void tcp_init(void);
|
||||
extern void tcp_timer(void);
|
||||
extern int tcp_bind(tcp_sap_t *ptr_sap);
|
||||
extern int tcp_unbind(tcp_sap_t *ptr_sap, BYTE index);
|
||||
extern tcp_sap_t *tcp_sap_get_by_index(int index);
|
||||
|
||||
|
||||
//rtp_port.c
|
||||
extern int tcp_port_alloc_port(int sap_id, WORD usr_port, tcp_session_t *pSess);
|
||||
extern int tcp_port_release_port(int sap_id, WORD usr_port, WORD pid);
|
||||
extern int tcp_send(int sap_id, WORD usr_port, WORD pid, BYTE *payload, WORD len);
|
||||
extern tcp_session_t *tcp_port_update_sess(int sap_id, WORD usr_port, WORD pid, tcp_session_t *ptr_sess);
|
||||
|
||||
#endif
|
||||
|
||||
129
proxy_c/tcp/src/include/tcp_inc.h
Normal file
129
proxy_c/tcp/src/include/tcp_inc.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#ifndef _TCP_INC_H_
|
||||
#define _TCP_INC_H_
|
||||
|
||||
//#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <netdb.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <termio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/io.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#ifndef _T_BYTE
|
||||
#define _T_BYTE
|
||||
typedef unsigned char BYTE;
|
||||
#endif
|
||||
|
||||
#ifndef _T_WORD
|
||||
#define _T_WORD
|
||||
typedef unsigned short WORD;
|
||||
#endif
|
||||
|
||||
#ifndef _T_DWORD
|
||||
#define _T_DWORD
|
||||
typedef unsigned long DWORD;
|
||||
#endif
|
||||
|
||||
#ifndef _T_ULL
|
||||
#define _T_ULL
|
||||
typedef unsigned long long ull;
|
||||
#endif
|
||||
|
||||
#ifndef _T_U8
|
||||
#define _T_U8
|
||||
typedef unsigned char u8;
|
||||
#endif
|
||||
|
||||
#ifndef _T_U16
|
||||
#define _T_U16
|
||||
typedef unsigned short u16;
|
||||
#endif
|
||||
|
||||
#ifndef _T_U32
|
||||
#define _T_U32
|
||||
typedef unsigned long u32;
|
||||
#endif
|
||||
|
||||
#ifndef _T_U64
|
||||
#define _T_U64
|
||||
typedef unsigned long long u64;
|
||||
#endif
|
||||
|
||||
#ifndef _T_BOOL
|
||||
#define _T_BOOL
|
||||
typedef int BOOL;
|
||||
#endif
|
||||
|
||||
#ifndef SUCCESS
|
||||
#define SUCCESS (0)
|
||||
#endif
|
||||
|
||||
#ifndef FAILURE
|
||||
#define FAILURE (-1)
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1)
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#endif
|
||||
|
||||
#ifndef YES
|
||||
#define YES (1)
|
||||
#endif
|
||||
|
||||
#ifndef NO
|
||||
#define NO (0)
|
||||
#endif
|
||||
|
||||
#ifndef ERROR
|
||||
#define ERROR (-1)
|
||||
#endif
|
||||
|
||||
#ifndef EMPTY
|
||||
#define EMPTY (0)
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define BUFSIZE 8192
|
||||
#define MAXBUFLEN 8192
|
||||
#define MAXLINE 8192
|
||||
|
||||
#endif
|
||||
|
||||
59
proxy_c/tcp/src/include/tcp_port.h
Normal file
59
proxy_c/tcp/src/include/tcp_port.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef _TCP_PORT_H_
|
||||
#define _TCP_PORT_H_
|
||||
|
||||
#include "tcp_inc.h"
|
||||
|
||||
#define TCP_MAX_NUM_OF_PORT 16
|
||||
#define TCP_MAX_RECV_MSG_LEN 1500
|
||||
#define TCP_MAX_SEND_MSG_LEN 1500
|
||||
#define TCP_MAX_PAYLOAD_SIZE 1350
|
||||
#define TCP_MAX_RECV_BUF_LEN 8192
|
||||
#define TCP_MAX_RECV_COUNT 4
|
||||
|
||||
typedef struct _tcp_header_t
|
||||
{
|
||||
BYTE ver; // version
|
||||
BYTE pt; // payload type
|
||||
WORD sn; // sequence number
|
||||
DWORD timestamp;
|
||||
DWORD ssrc; //synchronization src
|
||||
}tcp_header_t;
|
||||
|
||||
typedef struct _tcp_session_t
|
||||
{
|
||||
DWORD src_ip;
|
||||
WORD src_port;
|
||||
DWORD dst_ip;
|
||||
WORD dst_port;
|
||||
BYTE bServer; // tcp client: 0; server: 1;
|
||||
}tcp_session_t;
|
||||
|
||||
typedef struct _tcp_port_t
|
||||
{
|
||||
BYTE flag;
|
||||
int index;
|
||||
BYTE status;
|
||||
int timer;
|
||||
int retry_num;
|
||||
WORD usr_port;
|
||||
int fd;
|
||||
int cli_fd;
|
||||
|
||||
BYTE rv_buf[TCP_MAX_RECV_BUF_LEN];
|
||||
int buf_len;
|
||||
|
||||
int connected_num;
|
||||
int disconnect_num;
|
||||
int sent_fail_num;
|
||||
tcp_session_t sess;
|
||||
struct _tcp_sap_t *ptr_sap;
|
||||
}tcp_port_t;
|
||||
|
||||
extern void tcp_port_init(WORD id);
|
||||
extern void tcp_port_recv_msg(void);
|
||||
extern int tcp_link_fsm();
|
||||
|
||||
int get_tcp_sess(WORD hdlPort, tcp_session_t *sess);
|
||||
|
||||
#endif
|
||||
|
||||
95
proxy_c/tcp/src/tcp_if.c
Normal file
95
proxy_c/tcp/src/tcp_if.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
#include "./include/tcp_if.h"
|
||||
#include "./include/tcp_port.h"
|
||||
|
||||
static tcp_sap_t tcp_sap[TCP_MAX_NUM_OF_SAP];
|
||||
|
||||
static void tcp_sap_init(tcp_sap_t *ptr_sap, BYTE index)
|
||||
{
|
||||
if((ptr_sap == NULL) || (index >= TCP_MAX_NUM_OF_SAP))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ptr_sap->id = index;
|
||||
strcpy(ptr_sap->name, "\0");
|
||||
ptr_sap->recv_cb = NULL;
|
||||
}
|
||||
|
||||
tcp_sap_t *tcp_sap_get_by_index(int index)
|
||||
{
|
||||
if(index < 0 || index >= TCP_MAX_NUM_OF_SAP)
|
||||
return NULL;
|
||||
return &tcp_sap[index];
|
||||
}
|
||||
|
||||
void tcp_init(void)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
for(i = 0; i < TCP_MAX_NUM_OF_SAP; i++)
|
||||
{
|
||||
tcp_sap_init(&tcp_sap[i], (BYTE)i);
|
||||
}
|
||||
|
||||
for(i = 0; i < TCP_MAX_NUM_OF_PORT; i++)
|
||||
{
|
||||
tcp_port_init(i);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void tcp_timer(void)
|
||||
{
|
||||
tcp_link_fsm();
|
||||
tcp_port_recv_msg();
|
||||
}
|
||||
|
||||
int tcp_bind(tcp_sap_t *ptr_sap)
|
||||
{
|
||||
BYTE i;
|
||||
tcp_sap_t *ptr_tmp = NULL;
|
||||
|
||||
if((ptr_sap == NULL) || (ptr_sap->recv_cb == NULL))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < TCP_MAX_NUM_OF_SAP; i++)
|
||||
{
|
||||
ptr_tmp = &tcp_sap[i];
|
||||
if(ptr_tmp->recv_cb != NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy((BYTE*)ptr_tmp, ptr_sap, sizeof(tcp_sap_t));
|
||||
ptr_tmp->id = i;
|
||||
ptr_tmp->name[TCP_MAX_USER_NAME_LEN-1] = '\0';
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tcp_unbind(tcp_sap_t *ptr_sap, BYTE index)
|
||||
{
|
||||
if((ptr_sap == NULL) || (index >= TCP_MAX_NUM_OF_SAP))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ptr_sap->id != index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcp_sap_init(ptr_sap, index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
867
proxy_c/tcp/src/tcp_port.c
Normal file
867
proxy_c/tcp/src/tcp_port.c
Normal file
@@ -0,0 +1,867 @@
|
||||
/*
|
||||
* tcp port
|
||||
*/
|
||||
#include "./include/tcp_port.h"
|
||||
#include "./include/tcp_if.h"
|
||||
|
||||
#define TCP_F_BB1 0x7E // Begin: The first byte
|
||||
#define TCP_F_BB2 0xA5 // Begin: The second byte
|
||||
#define TCP_F_EB1 0x7E // End: The first byte
|
||||
#define TCP_F_EB2 0x0D // End: The second byte
|
||||
|
||||
#define TCP_F_INF_BEGIN_FLAG_LEN 2 // length of begin flag
|
||||
#define TCP_F_INF_MSG_LEN_LEN 2 // length of msg length field
|
||||
//#define TCP_F_INF_MSG_TYPE_LEN 2 // length of msg type
|
||||
#define TCP_F_INF_END_FLAG_LEN 2 // length of end flag
|
||||
#define TCP_F_INF_HEAD_LEN 4 // length of format begin+lengthField
|
||||
#define TCP_F_INF_ALL_LEN 6 // total length of format
|
||||
|
||||
#define TCP_IsfBegin(f1,f2) ((f1==TCP_F_BB1) && (f2==TCP_F_BB2))// Begin flag of msg
|
||||
#define TCP_IsfEnd(f1,f2) ((f1==TCP_F_EB1) && (f2==TCP_F_EB2))// End flag of msg
|
||||
|
||||
#define TCP_MSG_DATA 1 // Data
|
||||
#define TCP_MSG_HB 2 // HB
|
||||
#define TCP_MSG_HB_ACK 3 // HB_ACK
|
||||
|
||||
#define TCP_TIMER_1_SEC (100) // 10ms * 100
|
||||
#define TCP_TIMER_WAIT_CONNECT (5) // 50ms
|
||||
#define TCP_TIMER_REINIT (3*TCP_TIMER_1_SEC) // 3 Sec
|
||||
#define TCP_TIMER_RECONNECT (3*TCP_TIMER_1_SEC) // 3 Sec
|
||||
#define TCP_TIMER_HB (3*TCP_TIMER_1_SEC) // 3 Sec
|
||||
|
||||
#define TCP_MAX_RETRY_NUM (3)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TCP_STATUS_NULL,
|
||||
TCP_STATUS_INITING,
|
||||
TCP_STATUS_INITED,
|
||||
TCP_STATUS_CONNECTING,
|
||||
TCP_STATUS_TESTING,
|
||||
TCP_STATUS_CONNECTED,
|
||||
TCP_STATUS_MAX,
|
||||
}e_tcp_status;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD usMsgId; // Tcp internal message Id, 1: Data; 2: HB; 3: HB_ACK
|
||||
WORD usPlLen; // Payload length
|
||||
DWORD param1; // App param1, optional
|
||||
DWORD param2; // App param2, optional
|
||||
DWORD param3; // App param3, optional
|
||||
} tcp_head_t;
|
||||
|
||||
static char tcp_status_str[TCP_STATUS_MAX][64] = {\
|
||||
"null", \
|
||||
"initing", \
|
||||
"inited", \
|
||||
"connecting", \
|
||||
"testing", \
|
||||
"connected"
|
||||
};
|
||||
|
||||
static tcp_port_t tcp_port[TCP_MAX_NUM_OF_PORT];
|
||||
|
||||
void tcp_port_init(WORD id)
|
||||
{
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if(id >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[id];
|
||||
memset((BYTE*)ptr_port, 0, sizeof(tcp_port_t));
|
||||
ptr_port->fd = -1;
|
||||
ptr_port->cli_fd = -1;
|
||||
ptr_port->ptr_sap = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
long tcp_str_to_uip(char *src_ip)
|
||||
{
|
||||
return inet_addr(src_ip);
|
||||
}
|
||||
|
||||
static tcp_port_t *tcp_port_get_by_index(WORD index)
|
||||
{
|
||||
if (index >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &tcp_port[index];
|
||||
}
|
||||
|
||||
|
||||
static int tcp_port_get_unused_pid(void)
|
||||
{
|
||||
static WORD index = 0;
|
||||
WORD id, i;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
i = index;
|
||||
do
|
||||
{
|
||||
id = i;
|
||||
ptr_port = &tcp_port[id];
|
||||
if(++i >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if(ptr_port->flag != FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
index = i;
|
||||
return id;
|
||||
}while(i != index);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_init_socket(tcp_session_t *pSess)
|
||||
{
|
||||
int sock = -1, on = 1, timeout = 20;
|
||||
struct sockaddr_in srcaddr;
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||
{
|
||||
close(sock);
|
||||
return -2;
|
||||
}
|
||||
|
||||
//if (bServer)
|
||||
{
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &timeout, sizeof(timeout)) != 0)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
{
|
||||
close(sock);
|
||||
return -4;
|
||||
}
|
||||
|
||||
memset( (void *)&srcaddr, 0, sizeof(srcaddr) );
|
||||
srcaddr.sin_family = AF_INET;
|
||||
srcaddr.sin_addr.s_addr = pSess->src_ip;//htonl( INADDR_ANY );
|
||||
srcaddr.sin_port = htons(pSess->src_port);
|
||||
if (bind(sock, (struct sockaddr *)&srcaddr, sizeof(srcaddr)) < 0)
|
||||
{
|
||||
close(sock);
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (pSess->bServer)
|
||||
{
|
||||
// change to passive socket
|
||||
if (listen(sock, 5))
|
||||
{
|
||||
close(sock);
|
||||
return -6;
|
||||
}
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_set_status(tcp_port_t *ptr_port, WORD new_status)
|
||||
{
|
||||
if ((ptr_port == NULL) || (ptr_port->status == new_status) || (new_status >= TCP_STATUS_MAX))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (ptr_port->status == TCP_STATUS_CONNECTED)
|
||||
{
|
||||
ptr_port->disconnect_num++;
|
||||
}
|
||||
|
||||
ptr_port->status = new_status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_connect(tcp_port_t *ptr_port)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
if (ptr_port == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set family to internet */
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = ptr_port->sess.dst_ip;
|
||||
serv_addr.sin_port = htons(ptr_port->sess.dst_port);
|
||||
ret = connect(ptr_port->fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr));
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == EINPROGRESS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*if((106 == errno)//Transport endpoint is already connected
|
||||
||(89 == errno))//Destination address required
|
||||
{
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int tcp_check_conn(tcp_port_t *ptr_port)
|
||||
{
|
||||
int client_sock;
|
||||
int timeout = 20;
|
||||
struct sockaddr_in remote;
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
tcp_session_t *pSess = NULL;
|
||||
|
||||
if (ptr_port == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
pSess = &ptr_port->sess;
|
||||
|
||||
// fill with zero terms
|
||||
memset(&remote, 0, sizeof( remote));
|
||||
|
||||
// wait for connetion
|
||||
client_sock = accept(ptr_port->fd, (struct sockaddr *)&(remote), &len);
|
||||
if ( client_sock < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((remote.sin_port != htons(pSess->dst_port)) || (remote.sin_addr.s_addr != pSess->dst_ip))
|
||||
{
|
||||
close(client_sock);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, &timeout, sizeof(timeout)) != 0)
|
||||
{
|
||||
//return -3;
|
||||
}
|
||||
|
||||
if (fcntl(client_sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
{
|
||||
//return -4;
|
||||
}
|
||||
|
||||
ptr_port->cli_fd = client_sock;
|
||||
return client_sock;
|
||||
}
|
||||
|
||||
|
||||
int tcp_port_alloc_port(int sap_id, WORD usr_port, tcp_session_t *pSess)
|
||||
{
|
||||
int pid;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
|
||||
if(pSess == NULL || pSess->src_ip == 0 || pSess->src_port == 0 \
|
||||
|| pSess->dst_ip == 0 || pSess->dst_port == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((pid = tcp_port_get_unused_pid()) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[pid];
|
||||
if((ptr_port->fd = tcp_init_socket(pSess)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_port->flag = TRUE;
|
||||
ptr_port->index = pid;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITED);
|
||||
ptr_port->timer = 5;
|
||||
ptr_port->retry_num = 0;
|
||||
ptr_port->ptr_sap = ptr_sap;
|
||||
ptr_port->usr_port = usr_port;
|
||||
ptr_port->cli_fd = -1;
|
||||
ptr_port->buf_len = 0;
|
||||
|
||||
ptr_port->connected_num = 0;
|
||||
ptr_port->disconnect_num = 0;
|
||||
ptr_port->sent_fail_num = 0;
|
||||
|
||||
memcpy(&ptr_port->sess, pSess, sizeof(tcp_session_t));
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
int tcp_port_release_port(int sap_id, WORD usr_port, WORD pid)
|
||||
{
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_port = tcp_port_get_by_index(pid)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ptr_port->fd >= 0)
|
||||
{
|
||||
close(ptr_port->fd);
|
||||
}
|
||||
|
||||
tcp_port_init(pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
tcp_session_t *tcp_port_update_sess(int sap_id, WORD usr_port, WORD pid, tcp_session_t *ptr_sess)
|
||||
{
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if(ptr_sess == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ptr_port = tcp_port_get_by_index(pid)) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy((BYTE*)&ptr_port->sess, (BYTE*)ptr_sess, sizeof(tcp_session_t));
|
||||
|
||||
return &ptr_port->sess;
|
||||
}
|
||||
|
||||
|
||||
int get_tcp_sess(WORD pid, tcp_session_t *sess)
|
||||
{
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if (pid >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(sess == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_port = tcp_port_get_by_index(pid)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(sess, &ptr_port->sess, sizeof(tcp_session_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_send_msg(tcp_port_t *ptr_port, BYTE *msg, WORD len)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if((ptr_port == NULL) || (len > TCP_MAX_SEND_MSG_LEN))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ptr_port->sess.bServer)
|
||||
{
|
||||
fd = ptr_port->cli_fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = ptr_port->fd;
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (send(fd, msg, len, MSG_NOSIGNAL) < 0)// add MSG_NOSIGNAL, to avoid Broken pipe, while sending data after received FIN and sent FIN_ACK
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_send_hb(tcp_port_t *ptr_port, WORD msg_id)
|
||||
{
|
||||
int ret = -1;
|
||||
BYTE msg_buf[TCP_MAX_SEND_MSG_LEN];
|
||||
WORD msg_len;
|
||||
DWORD pos = 0;
|
||||
BYTE *pDst = NULL;
|
||||
tcp_head_t *pHead = NULL;
|
||||
|
||||
if(ptr_port == NULL || ptr_port->flag == FALSE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
pDst = msg_buf;
|
||||
|
||||
// Begin flag
|
||||
pDst[pos++] = TCP_F_BB1;
|
||||
pDst[pos++] = TCP_F_BB2;
|
||||
//
|
||||
|
||||
// len, 2 Bytes
|
||||
msg_len = htons(sizeof(tcp_head_t));
|
||||
memcpy(&pDst[pos], (BYTE *)&msg_len, sizeof(msg_len));
|
||||
pos += sizeof(msg_len);
|
||||
//
|
||||
|
||||
// Head
|
||||
pHead = (tcp_head_t *)&pDst[pos];
|
||||
pHead->usMsgId = htons(msg_id);
|
||||
pHead->usPlLen = 0;
|
||||
pHead->param1 = 0;
|
||||
pHead->param2 = 0;
|
||||
pHead->param3 = 0;
|
||||
memcpy(&pDst[pos], (BYTE *)pHead, sizeof(tcp_head_t));
|
||||
pos += sizeof(tcp_head_t);
|
||||
//
|
||||
|
||||
// flagEnd
|
||||
pDst[pos++] = TCP_F_EB1;
|
||||
pDst[pos++] = TCP_F_EB2;
|
||||
//
|
||||
|
||||
msg_len = pos;
|
||||
|
||||
ret = tcp_send_msg(ptr_port, msg_buf, msg_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_handle_hb(tcp_port_t *ptr_port, tcp_head_t *pTcpHead)
|
||||
{
|
||||
WORD usMsgId = 0;
|
||||
if (ptr_port == NULL || pTcpHead == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pTcpHead->usPlLen != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
usMsgId = ntohs(pTcpHead->usMsgId);
|
||||
if (usMsgId == TCP_MSG_HB)
|
||||
{
|
||||
tcp_send_hb(ptr_port, TCP_MSG_HB_ACK);
|
||||
}
|
||||
else if (usMsgId == TCP_MSG_HB_ACK)
|
||||
{
|
||||
if (ptr_port->status == TCP_STATUS_TESTING)
|
||||
{
|
||||
tcp_set_status(ptr_port, TCP_STATUS_CONNECTED);
|
||||
ptr_port->connected_num++;
|
||||
ptr_port->retry_num = 0;
|
||||
}
|
||||
else if (ptr_port->status == TCP_STATUS_CONNECTED)
|
||||
{
|
||||
ptr_port->retry_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//static int tcp_port_handle_recv_msg(WORD pid, BYTE *buf, WORD len)
|
||||
static int tcp_port_handle_recv_msg(tcp_port_t *ptr_port)
|
||||
{
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
|
||||
if(ptr_port == NULL || ptr_port->ptr_sap == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_sap = ptr_port->ptr_sap;
|
||||
if(ptr_sap->recv_cb == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_sap->recv_cb(ptr_port->usr_port, ptr_port->rv_buf, ptr_port->buf_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tcp_port_recv_msg(void)
|
||||
{
|
||||
int index, i, len, addr_len, fd, pos;
|
||||
BYTE msg_buf[TCP_MAX_RECV_MSG_LEN];
|
||||
//struct timeval tv;
|
||||
|
||||
struct sockaddr_in sin_addr;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
addr_len = sizeof(struct sockaddr);
|
||||
memset(&sin_addr, 0, addr_len);
|
||||
|
||||
for(index = 0; index < TCP_MAX_NUM_OF_PORT; index++)
|
||||
{
|
||||
ptr_port = &tcp_port[index];
|
||||
if(ptr_port->flag == FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(((ptr_port->sess.bServer) && (ptr_port->fd < 0 || ptr_port->cli_fd < 0)) \
|
||||
|| ((!ptr_port->sess.bServer) && (ptr_port->fd < 0)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ptr_port->sess.bServer)
|
||||
{
|
||||
fd = ptr_port->cli_fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = ptr_port->fd;
|
||||
}
|
||||
|
||||
for(i = 0; i < TCP_MAX_RECV_COUNT; i++)
|
||||
{
|
||||
pos = ptr_port->buf_len;
|
||||
len = recv(fd, msg_buf, TCP_MAX_RECV_MSG_LEN, 0);
|
||||
if(len <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if((pos + len) >= TCP_MAX_RECV_BUF_LEN)
|
||||
{
|
||||
ptr_port->buf_len = 0;
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(&ptr_port->rv_buf[pos], msg_buf, len);
|
||||
ptr_port->buf_len += len;
|
||||
tcp_port_handle_recv_msg(ptr_port);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int tcp_send(int sap_id, WORD usr_port, WORD pid, BYTE *payload, WORD len)
|
||||
{
|
||||
int ret = -1;
|
||||
BYTE msg_buf[TCP_MAX_SEND_MSG_LEN];
|
||||
WORD msg_len;
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
WORD pos = 0;
|
||||
BYTE *pDst = NULL;
|
||||
|
||||
if((payload == NULL) || (len > TCP_MAX_PAYLOAD_SIZE))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(pid >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[pid];
|
||||
if((ptr_port->flag == FALSE) || (ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
if (ptr_port->status != TCP_STATUS_CONNECTED)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
pDst = msg_buf;
|
||||
|
||||
memcpy(&pDst[pos], payload, len);
|
||||
pos += len;
|
||||
|
||||
msg_len = pos;
|
||||
|
||||
ret = tcp_send_msg(ptr_port, msg_buf, msg_len);
|
||||
if(ret < 0)
|
||||
{
|
||||
ptr_port->sent_fail_num++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int tcp_link_fsm()
|
||||
{
|
||||
int i;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
tcp_session_t *pSess = NULL;
|
||||
|
||||
for (i=0; i<TCP_MAX_NUM_OF_PORT; i++)
|
||||
{
|
||||
ptr_port = &tcp_port[i];
|
||||
|
||||
if (!ptr_port->flag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//if (ptr_port->fd < 0)
|
||||
//{
|
||||
// tcp_port_init(i);
|
||||
// continue;
|
||||
//}
|
||||
|
||||
pSess = &ptr_port->sess;
|
||||
switch (ptr_port->status)
|
||||
{
|
||||
case TCP_STATUS_INITING:
|
||||
if (--ptr_port->timer > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr_port->fd = tcp_init_socket(pSess);
|
||||
if (ptr_port->fd < 0)
|
||||
{
|
||||
ptr_port->timer = TCP_TIMER_REINIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITED);
|
||||
}
|
||||
break;
|
||||
case TCP_STATUS_INITED:
|
||||
if (--ptr_port->timer > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pSess->bServer)
|
||||
{
|
||||
if (tcp_check_conn(ptr_port) < 0)
|
||||
{
|
||||
ptr_port->timer = TCP_TIMER_WAIT_CONNECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_port->timer = 0;
|
||||
ptr_port->retry_num = 0;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_TESTING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tcp_connect(ptr_port) < 0)
|
||||
{
|
||||
close(ptr_port->fd);
|
||||
ptr_port->fd = -1;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITING);
|
||||
ptr_port->timer = TCP_TIMER_REINIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_port->timer = TCP_TIMER_WAIT_CONNECT;
|
||||
ptr_port->retry_num = 0;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_TESTING);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TCP_STATUS_TESTING:// sending HB
|
||||
case TCP_STATUS_CONNECTED:
|
||||
break;
|
||||
if (--ptr_port->timer > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ptr_port->retry_num++ >= TCP_MAX_RETRY_NUM)
|
||||
{
|
||||
if (ptr_port->sess.bServer)
|
||||
{
|
||||
close(ptr_port->cli_fd);
|
||||
ptr_port->cli_fd = -1;
|
||||
ptr_port->timer = 0;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITED);
|
||||
}
|
||||
else
|
||||
{
|
||||
close(ptr_port->fd);
|
||||
ptr_port->fd = -1;
|
||||
ptr_port->timer = 0;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//tcp_send_hb(ptr_port, TCP_MSG_HB);
|
||||
ptr_port->timer = TCP_TIMER_HB;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL tcp_print_all_port(void)
|
||||
{
|
||||
int j = 0, i;
|
||||
char buf[516], tmp_buf[8];
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
strcpy(buf, "\0");
|
||||
for(i = 0; i < TCP_MAX_NUM_OF_PORT; i++)
|
||||
{
|
||||
ptr_port = &tcp_port[i];
|
||||
if(ptr_port->flag == TRUE)
|
||||
{
|
||||
if(j % 20 == 0 && j != 0)
|
||||
{
|
||||
strcpy(buf, "\0");
|
||||
}
|
||||
sprintf(tmp_buf, "%d ", i);
|
||||
strcat(buf, tmp_buf);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if(j % 20)
|
||||
{
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL tcp_print_port(int pid)
|
||||
{
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if((pid < 0) || (pid >= TCP_MAX_NUM_OF_PORT))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[pid];
|
||||
if(ptr_port->flag == FALSE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (ptr_port->status < TCP_STATUS_MAX)
|
||||
{
|
||||
}
|
||||
if (ptr_port->sess.bServer)
|
||||
{
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL tcp_clear_stat(int pid)
|
||||
{
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if((pid < 0) || (pid >= TCP_MAX_NUM_OF_PORT))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[pid];
|
||||
if(ptr_port->flag == FALSE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ptr_port->connected_num = 0;
|
||||
ptr_port->disconnect_num = 0;
|
||||
ptr_port->sent_fail_num = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user