792 lines
22 KiB
C
792 lines
22 KiB
C
/****************************************************/
|
|
/* MTP3LITE Implementation Program */
|
|
/* Version 10.0.1 */
|
|
/* Designed By Ying Min */
|
|
/* Last Update: 2005-04-7 */
|
|
/* Modify : Victor Luo, 2005-07-14 add TCP client for mtp3lite*/
|
|
/****************************************************/
|
|
#include <errno.h>
|
|
#include <netinet/tcp.h>
|
|
#include "./include/mtp3.h"
|
|
#include "./include/mtpstm.h"
|
|
#include "./include/mtp3lite.h"
|
|
#include "./include/mtpext.h"
|
|
#include "./include/mtpfunc.h"
|
|
|
|
BYTE mtp3lite_ka_msg[3];
|
|
mtp3lite_lk mtp3lite_link[1024];
|
|
int mtp3lite_listen_fd;
|
|
BYTE mtp3lite_msg_buf[1024][MTP3LITE_MSG_BUF_SIZE_PER_LINK];
|
|
BYTE mtp3lite_rem_len[1024];
|
|
BYTE mtp3lite_id_fg[1024];
|
|
|
|
extern u32 GetLocalIP();
|
|
/*@ignore@*/
|
|
void mtp3lite_print_msg(BYTE *ptr, WORD len)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
printf("%X ", ptr[i]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void mtp3lite_init_lk(WORD lk)
|
|
{
|
|
mtp3lite_link[lk].connfd = -1;
|
|
mtp3lite_link[lk].cliSockfd = -1;
|
|
mtp3lite_link[lk].remote_port = 0;
|
|
mtp3lite_link[lk].local_inactive = 2000; // 20 seconds
|
|
mtp3lite_link[lk].local_reconnect = 10; // 10 * 2.56 seconds
|
|
mtp3lite_link[lk].remote_inactive = mtp3_para->lk[lk].inactive * 100;
|
|
mtp3lite_link[lk].remote_inactive_timeouts = mtp3_para->lk[lk].inactive_tm;
|
|
mtp3lite_link[lk].init_guard_timer = 2000; // 20 seconds
|
|
mtp3lite_msg_buf[lk][0] = 0;
|
|
mtp3lite_rem_len[lk] = 0;
|
|
mtp3lite_id_fg[lk] = 0;
|
|
}
|
|
|
|
void mtp3lite_init_ka_msg(void)
|
|
{
|
|
mtp3lite_ka_msg[0] = 2;
|
|
mtp3lite_ka_msg[1] = 0x4B;
|
|
mtp3lite_ka_msg[2] = 0x41;
|
|
}
|
|
|
|
int mtp3lite_Init_TCPSocket(struct sockaddr_in saddr,int needBind)
|
|
{ //flag,0=client, 1=server
|
|
int sock;
|
|
long sockbuf = 40*1024;
|
|
int on = 1, timeout = 20;
|
|
|
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
if (sock < 0)
|
|
{
|
|
fprintf(stderr,"Socket() failed\n");
|
|
return -3;
|
|
}
|
|
|
|
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
|
|
&sockbuf, sizeof(sockbuf)) != 0)
|
|
{
|
|
fprintf(stderr,"set socket buffer failed\n");
|
|
return -4;
|
|
}
|
|
|
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
|
|
&on,sizeof(on)) != 0)
|
|
{
|
|
fprintf(stderr,"set addr reusable failed\n");
|
|
return -5;
|
|
}
|
|
|
|
if (setsockopt(sock,SOL_SOCKET, SO_KEEPALIVE,
|
|
&timeout, sizeof(timeout)) != 0)
|
|
{
|
|
fprintf(stderr,"set keepalive failed\n");
|
|
return -6;
|
|
}
|
|
|
|
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
|
|
{
|
|
fprintf(stderr,"set nonblock failed\n");
|
|
return -7;
|
|
}
|
|
|
|
if(needBind)
|
|
{
|
|
if (bind(sock, (struct sockaddr*)&saddr, sizeof(struct sockaddr)) < 0)
|
|
{
|
|
fprintf(stderr,"MTP3LITE bind failed,port:%d\n",htons(saddr.sin_port));
|
|
close(sock);
|
|
return -2;
|
|
}
|
|
}
|
|
return sock;
|
|
}
|
|
|
|
int mtp3lite_InitServerSocket()
|
|
{
|
|
struct sockaddr_in sin_addr;
|
|
|
|
memset(&sin_addr, 0, sizeof(struct sockaddr));
|
|
sin_addr.sin_family = AF_INET;
|
|
//sin_addr.sin_port = htons(mtp3lite_port);
|
|
sin_addr.sin_port = mtp3_para->mtp3lite_port;
|
|
sin_addr.sin_addr.s_addr = GetLocalIP();
|
|
bzero(&(sin_addr.sin_zero),8);
|
|
|
|
if ((mtp3lite_listen_fd = mtp3lite_Init_TCPSocket(sin_addr,1)) < 0)
|
|
{
|
|
printf("MTP3LITE TCP Socket(%X) Init Failed!\n", mtp3_para->mtp3lite_port);
|
|
exit(1);
|
|
}
|
|
else
|
|
listen(mtp3lite_listen_fd, 1);
|
|
|
|
printf("mtp3lite_listen_fd: %d\n", mtp3lite_listen_fd);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int isMtp3LiteClientLink(WORD lk)
|
|
{
|
|
//4bits:none sigtran, link enable, mtp3lite enable,client
|
|
if(mtp3_para->lk[lk].admin_state && mtp3_para->lk[lk].mtp3lite_apl_mode && mtp3_para->lk[lk].e1_lk_type==LKTYPE_MTP3_LITE&& mtp3_para->lk[lk].remote_ip>0)
|
|
{
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int checkIfOveridesocket(WORD lk)
|
|
{
|
|
int i;
|
|
for(i=0;i<lk;i++)
|
|
{
|
|
if(isMtp3LiteClientLink(i) && mtp3_para->lk[lk].remote_ip==mtp3_para->lk[i].remote_ip)
|
|
{
|
|
printf("mtp3lite client, lk %d is overide with %d \n",lk,i);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int mtp3lite_InitClientSocket(WORD lk)
|
|
{
|
|
struct sockaddr_in sin_addr;
|
|
int socketfd;
|
|
|
|
bzero(&sin_addr,sizeof(struct sockaddr));
|
|
sin_addr.sin_family = AF_INET;
|
|
//sin_addr.sin_port = htons(mtp3lite_port);
|
|
sin_addr.sin_addr.s_addr = GetLocalIP();
|
|
|
|
mtp3lite_link[lk].cliSockfd = -1;
|
|
if (isMtp3LiteClientLink(lk) && !checkIfOveridesocket(lk))
|
|
{
|
|
//sin_addr.sin_port = mtp3_para->mtp3lite_port; //server port,tmp
|
|
//sin_addr.sin_addr.s_addr = mtp3_para->lk[lk].remote_ip;
|
|
//bzero(&(sin_addr.sin_zero),8);
|
|
if ((socketfd = mtp3lite_Init_TCPSocket(sin_addr,1)) < 0)
|
|
{
|
|
printf("MTP3LITE TCP Client Socket(%d) Init Failed!\n",mtp3_para->mtp3lite_port);
|
|
//exit(1);
|
|
return 0;
|
|
}
|
|
mtp3lite_link[lk].cliSockfd = socketfd;
|
|
printf("mtp3lite: init client socket link=%d\n",lk);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int mtp3lite_CloseTcpConn(WORD link)
|
|
{
|
|
if(mtp3lite_link[link].connfd>=0)
|
|
close(mtp3lite_link[link].connfd);
|
|
if(mtp3lite_link[link].cliSockfd>=0)
|
|
close(mtp3lite_link[link].cliSockfd);
|
|
mtp3lite_init_lk(link);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int mtp3lite_get_lk_by_ip(struct sockaddr_in *client_addr)
|
|
{
|
|
int lk;
|
|
|
|
for (lk = 0; lk < MAX_LK; lk++)
|
|
{
|
|
if ((mtp3_para->lk[lk].remote_ip == client_addr->sin_addr.s_addr) &&
|
|
(mtp3_para->lk[lk].e1_to_mtp3 == mtp3_localip) &&
|
|
(mtp3_para->lk[lk].e1_lk_type ==LKTYPE_MTP3_LITE && mtp3_para->lk[lk].admin_state && mtp3_para->lk[lk].mtp3lite_apl_mode==0) && // Server & MTP3LITE & Enabled
|
|
(mtp3ObjState.lk_command[lk]!=0)) //Command enabled
|
|
{
|
|
if (mtp3lite_link[lk].connfd > 0)
|
|
{
|
|
mtp3lite_CloseTcpConn(lk);
|
|
mtp3lite_updateStatus(lk, MTP2_STATE_STOP, MTP3LITE_INACTIVITY_TIMEOUT);
|
|
}
|
|
else if (mtp3lite_link[lk].init_guard_timer == 0)
|
|
return lk;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int mtp3lite_DirectSendMsg(WORD link, int len, BYTE *msg_ptr)
|
|
{
|
|
struct sockaddr_in sin;
|
|
|
|
if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE
|
|
!(mtp3_para->lk[link].admin_state & 0x01) || // Not Enabled
|
|
(mtp3ObjState.lk_command[link] == 0) || // Command Disabled
|
|
(mtp3lite_link[link].connfd <= 0)) // Link Not Established
|
|
return -1;
|
|
|
|
bzero(&sin.sin_zero, sizeof(sin.sin_zero));
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_addr.s_addr = mtp3_para->lk[link].remote_ip;
|
|
sin.sin_port = mtp3lite_link[link].remote_port;
|
|
|
|
return send(mtp3lite_link[link].connfd, msg_ptr, len, MSG_NOSIGNAL);
|
|
}
|
|
|
|
int mtp3liteTcpConnect(int sock,struct sockaddr_in *sin_addr)
|
|
{
|
|
if (connect(sock, (struct sockaddr *)sin_addr, sizeof(struct sockaddr)) < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
printf("tcpConnect success, ip=%s\n",inet_ntoa(sin_addr->sin_addr));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int mtp3lite_TcpConnectCheck()
|
|
{
|
|
int keepAlive = 1,
|
|
keepIdle = 15,
|
|
keepInterval = 3,
|
|
keepCount = 3;
|
|
int connfdtmp = 0;
|
|
socklen_t clilen;
|
|
struct sockaddr_in cliaddr;
|
|
int link;
|
|
static BYTE cliLk=0;
|
|
|
|
bzero(&cliaddr,(clilen = sizeof(struct sockaddr)));
|
|
|
|
connfdtmp = accept(mtp3lite_listen_fd,(struct sockaddr *)&cliaddr,&clilen);
|
|
if (connfdtmp <= 0)//no connect request , check client socket
|
|
{
|
|
link = cliLk++;
|
|
if (!isMtp3LiteClientLink(link))
|
|
return 0;
|
|
if (mtp3lite_link[link].connfd > 0)
|
|
return 0;
|
|
else if (mtp3lite_link[link].local_reconnect > 0)
|
|
{
|
|
mtp3lite_link[link].local_reconnect--;
|
|
return 0;
|
|
}
|
|
|
|
if (mtp3lite_link[link].cliSockfd <= 0)
|
|
{
|
|
if (!mtp3lite_InitClientSocket(link))
|
|
mtp3lite_init_lk(link);
|
|
}
|
|
cliaddr.sin_family = AF_INET;
|
|
cliaddr.sin_port = mtp3_para->mtp3lite_port;
|
|
cliaddr.sin_addr.s_addr = mtp3_para->lk[link].remote_ip;
|
|
bzero(&(cliaddr.sin_zero),8);
|
|
connfdtmp = mtp3lite_link[link].cliSockfd;
|
|
if (!mtp3liteTcpConnect(connfdtmp, &cliaddr))
|
|
{
|
|
if ((errno != EINPROGRESS) && (errno != EALREADY))
|
|
mtp3lite_CloseTcpConn(link);
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
mtp3lite_link[link].connfd = connfdtmp;
|
|
mtp3lite_updateStatus(link, MTP2_STATE_WORKING, 0);
|
|
}
|
|
return 0;
|
|
}
|
|
else if ((link = mtp3lite_get_lk_by_ip(&cliaddr)) < 0)
|
|
{
|
|
close(connfdtmp);
|
|
return 0;
|
|
}
|
|
|
|
mtp3lite_init_lk(link);
|
|
mtp3lite_link[link].init_guard_timer = 0;
|
|
mtp3lite_link[link].connfd = connfdtmp;
|
|
mtp3lite_link[link].cliSockfd = connfdtmp;
|
|
mtp3lite_link[link].remote_port = cliaddr.sin_port;
|
|
mtp3_debug(MTP3DB_EVENT,"link[%d] connfd: %d, rem_port: %d\n", link, connfdtmp, ntohs(mtp3lite_link[link].remote_port));
|
|
|
|
fcntl(mtp3lite_link[link].connfd,F_SETFL,O_NONBLOCK);
|
|
if (setsockopt(mtp3lite_link[link].connfd,SOL_SOCKET,SO_KEEPALIVE, &keepAlive,sizeof(keepAlive)) != 0)
|
|
fprintf(stderr,"set keepalive failed\n");
|
|
|
|
setsockopt(mtp3lite_link[link].connfd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
|
|
setsockopt(mtp3lite_link[link].connfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
|
|
setsockopt(mtp3lite_link[link].connfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
|
|
|
|
|
|
mtp3lite_updateStatus(link, MTP2_STATE_WORKING, 0);
|
|
// mtp3lite_DirectSendMsg(link, 3, mtp3lite_ka_msg);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int send_mtp3lite_id_ack(WORD link)
|
|
{
|
|
BYTE id_ack_msg[4]={0,0x1,0xfe, 0x6};
|
|
|
|
mtp3lite_DirectSendMsg(link, 4, id_ack_msg);
|
|
mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d send Inditify ACK",link);
|
|
return 1;
|
|
}
|
|
|
|
int send_mtp3lite_ping(WORD link)
|
|
{
|
|
BYTE id_ack_msg[4]={0x00,0x01,0xfe, 0x00};
|
|
|
|
mtp3lite_DirectSendMsg(link, 4, id_ack_msg);
|
|
mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d send PING",link);
|
|
return 1;
|
|
}
|
|
|
|
int mtp3lite_DirectRecvMsg(WORD link)
|
|
{
|
|
struct sockaddr_in sin;
|
|
int nbytes;
|
|
BYTE len1;
|
|
|
|
socklen_t len = sizeof(struct sockaddr);
|
|
// if ((len1 = mtp3lite_rem_len[link])>0)
|
|
// printf("len1: %d\n", len1);
|
|
len1 = mtp3lite_rem_len[link];
|
|
|
|
if(len >= MTP3LITE_MSG_BUF_SIZE_PER_LINK)
|
|
{
|
|
mtp3_debug(MTP3DB_EVENT, "mtp3lite link[%d] buffer is full!\n", link);
|
|
return 0;
|
|
}
|
|
|
|
nbytes = recvfrom(mtp3lite_link[link].connfd, mtp3lite_msg_buf[link] + len1,
|
|
MTP3LITE_MSG_BUF_SIZE_PER_LINK - len1, 0, (struct sockaddr *) &sin, &len);
|
|
|
|
if (nbytes == 0 && errno != 11)
|
|
{
|
|
mtp3_debug(MTP3DB_EVENT, "mtp3lite tcp link[%d] error : %d\n", link, errno);
|
|
mtp3lite_CloseTcpConn(link);
|
|
mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_TCP_FAILURE);
|
|
mtp3lite_rem_len[link] = 0;
|
|
}
|
|
if(nbytes < 0 && errno == ETIMEDOUT)
|
|
{
|
|
mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_INACTIVITY_TIMEOUT);
|
|
mtp3lite_CloseTcpConn(link);
|
|
mtp3lite_rem_len[link] = 0;
|
|
}
|
|
|
|
if ((len1 > 0) && (nbytes > 0))
|
|
nbytes += len1;
|
|
|
|
return nbytes;
|
|
}
|
|
/*
|
|
int mtp3lite_decode_tcp_msg(WORD total_len, BYTE link)
|
|
{
|
|
BYTE lk_set, *buf_ptr;
|
|
WORD sub_len, rem_len, total_hdl_len = 0;
|
|
up_message up_msg;
|
|
up_message *up_msg_ptr = &up_msg;
|
|
BYTE nw;
|
|
|
|
if (total_len > MTP3LITE_MSG_BUF_SIZE_PER_LINK)
|
|
return -1;
|
|
|
|
while (total_hdl_len < total_len)
|
|
{
|
|
buf_ptr = mtp3lite_msg_buf[link] + total_hdl_len;
|
|
rem_len = total_len - total_hdl_len;
|
|
sub_len = buf_ptr[0];
|
|
|
|
if (rem_len < (sub_len + 1))
|
|
{
|
|
if (total_hdl_len > 0)
|
|
memcpy(mtp3lite_msg_buf[link], mtp3lite_msg_buf[link] + total_hdl_len, rem_len);
|
|
mtp3lite_rem_len[link] = rem_len;
|
|
//printf("Remain: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len);
|
|
return 1;
|
|
}
|
|
|
|
if (sub_len < 2)
|
|
return -1;
|
|
else if (sub_len == 2)
|
|
{
|
|
if ((buf_ptr[1] == 0x4B) && (buf_ptr[2] == 0x41))
|
|
{ // Receive Keep Alive Message
|
|
mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 100;
|
|
mtp3lite_link[link].remote_inactive_timeouts = 0;
|
|
//mtp3lite_print_msg(buf_ptr, 3);
|
|
total_hdl_len += (sub_len + 1);
|
|
//printf("KeepAlive: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len);
|
|
continue;
|
|
}
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
if ((buf_ptr[1] > 9) || (buf_ptr[1] == 0))
|
|
return -1;
|
|
|
|
mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 100;
|
|
mtp3lite_link[link].remote_inactive_timeouts = 0;
|
|
|
|
//mtp3lite_print_msg(buf_ptr, sub_len + 1);
|
|
|
|
up_msg_ptr->len = sub_len;
|
|
up_msg_ptr->link = link;
|
|
lk_set = mtp3_para->lk[link].e1_to_linkset;
|
|
if (lk_set >= 128)
|
|
return -1;
|
|
nw = mtp3_para->ls_pro[lk_set] & 3;
|
|
up_msg_ptr->sio = 0x03 | (nw << 6) | 0x10;//sccp lite always ansi message
|
|
up_msg_ptr->opc = mtp3_para->ls_op_pc[lk_set];
|
|
if (pc_length(up_msg_ptr->sio >> 6) == MTP3_24BIT_PC)
|
|
up_msg_ptr->dpc = mtp3_para->nw[nw].opc24;
|
|
else
|
|
up_msg_ptr->dpc = mtp3_para->nw[nw].opc14;
|
|
|
|
memcpy(up_msg_ptr->msgList, buf_ptr + 1, sub_len);
|
|
|
|
iptrans_msg_flow_2(up_msg_ptr);
|
|
send_to_sccp_lite(up_msg_ptr);
|
|
|
|
total_hdl_len += (sub_len + 1);
|
|
//printf("Data: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len);
|
|
}
|
|
|
|
mtp3lite_rem_len[link] = 0;
|
|
return 1;
|
|
}
|
|
*/
|
|
/******change to struct: 00, len, 0xfd*****/
|
|
int mtp3lite_decode_tcp_msg(WORD total_len, WORD link)
|
|
{
|
|
BYTE *buf_ptr;
|
|
WORD lk_set, sub_len, rem_len, total_hdl_len = 0;
|
|
up_message up_msg;
|
|
up_message *up_msg_ptr = &up_msg;
|
|
BYTE nw;
|
|
|
|
if (total_len > MTP3LITE_MSG_BUF_SIZE_PER_LINK)
|
|
return -1;
|
|
|
|
while (total_hdl_len < total_len)
|
|
{
|
|
buf_ptr = mtp3lite_msg_buf[link] + total_hdl_len;
|
|
rem_len = total_len - total_hdl_len;
|
|
sub_len = (buf_ptr[0]<<8) + buf_ptr[1];
|
|
|
|
if (rem_len < (sub_len + 1))
|
|
{
|
|
if (total_hdl_len > 0)
|
|
memcpy(mtp3lite_msg_buf[link], mtp3lite_msg_buf[link] + total_hdl_len, rem_len);
|
|
mtp3lite_rem_len[link] = rem_len;
|
|
//printf("Remain: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len);
|
|
return 1;
|
|
}
|
|
|
|
if (sub_len < 1)
|
|
return -1;
|
|
else if (sub_len == 1)
|
|
{
|
|
if(buf_ptr[1+2] == 0x6)
|
|
// if(buf_ptr[1+2] == 0x6 || buf_ptr[2] == 0x06)
|
|
{ // Receive Keep Alive Message
|
|
mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 200;
|
|
mtp3lite_link[link].remote_inactive_timeouts = 0;
|
|
//mtp3lite_print_msg(buf_ptr, 3);
|
|
total_hdl_len += (sub_len + 3);
|
|
mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d RECV Inditify ACK",link);
|
|
//printf("KeepAlive: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len);
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
//mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d RECV IPA Ping!",link);
|
|
//send_mtp3lite_ping(link);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// if ((buf_ptr[1+2] > 9) || (buf_ptr[1+2] == 0))
|
|
// return -1;
|
|
|
|
mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 200;
|
|
mtp3lite_link[link].remote_inactive_timeouts = 0;
|
|
|
|
//mtp3lite_print_msg(buf_ptr, sub_len + 1);
|
|
|
|
up_msg_ptr->len = sub_len;
|
|
up_msg_ptr->link = link;
|
|
lk_set = mtp3_para->lk[link].e1_to_linkset;
|
|
if (lk_set >= MAX_LS)
|
|
return -1;
|
|
//nw = mtp3_para->ls_pro[lk_set] & 3;
|
|
nw = mtp3_para->ls_pro[lk_set].nw_id ;
|
|
up_msg_ptr->sio = 0x03 | (nw << 6);//sccp lite always itu message
|
|
up_msg_ptr->sio |= (mtp3_para->nw[nw].pc_type & 1)<<4;//detect ansi or itu sccp, ansi=1,itu=0
|
|
up_msg_ptr->opc = mtp3_para->ls_pro[lk_set].ls_op_pc;
|
|
if (pc_length(up_msg_ptr->sio >> 6) == MTP3_24BIT_PC)
|
|
up_msg_ptr->dpc = mtp3_para->nw[nw].opc24;
|
|
else
|
|
up_msg_ptr->dpc = mtp3_para->nw[nw].opc14;
|
|
|
|
memcpy(up_msg_ptr->msgList, buf_ptr + 1 + 2, sub_len);
|
|
|
|
iptrans_msg_flow_2(up_msg_ptr);
|
|
send_to_sccp_lite(up_msg_ptr);
|
|
|
|
total_hdl_len += (sub_len + 1 + 2);
|
|
//printf("Data: total_len: %d, total_hld_len: %d, sub_len: %d, rem_len: %d\n", total_len, total_hdl_len, sub_len, rem_len);
|
|
}
|
|
|
|
mtp3lite_rem_len[link] = 0;
|
|
return 1;
|
|
}
|
|
|
|
|
|
int get_mtp3lite_msg(WORD link)
|
|
{
|
|
int nbytes;
|
|
|
|
if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE
|
|
!(mtp3_para->lk[link].admin_state& 0x01) || // Not Enabled
|
|
(mtp3ObjState.lk_command[link]==0) || // command disabled
|
|
(mtp3lite_link[link].connfd <= 0)) // Link Not Established
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if ((nbytes = mtp3lite_DirectRecvMsg(link)) <= 0)
|
|
return -1;
|
|
|
|
//mtp3lite_print_msg(mtp3lite_msg_buf[link], nbytes);
|
|
|
|
if (mtp3lite_decode_tcp_msg(nbytes, link) < 0)
|
|
{
|
|
mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d mtp3lite_decode_tcp_msg failed!",link);
|
|
/*
|
|
printf("tcp link[%d] decode error!\n", link);
|
|
mtp3lite_CloseTcpConn(link);
|
|
mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_TCP_FAILURE);
|
|
mtp3lite_rem_len[link] = 0;
|
|
*/
|
|
return -1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int put_mtp3lite_msg(BYTE *msg_ptr)
|
|
{
|
|
BYTE nw, pclen, offset;
|
|
WORD ls, len, link;
|
|
|
|
link = msg_ptr[1]*256+msg_ptr[0];//???
|
|
len = (msg_ptr[2]<<8) + msg_ptr[3];
|
|
|
|
if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE
|
|
!(mtp3_para->lk[link].admin_state& 0x01) || // Not Enabled
|
|
(mtp3ObjState.lk_command[link]==0) || // Command disabled
|
|
(mtp3lite_link[link].connfd <= 0)) // Link Not Established
|
|
return -1;
|
|
|
|
if ((ls = mtp3_para->lk[link].e1_to_linkset) >= MAX_LS)
|
|
return -1;
|
|
|
|
nw = mtp3_para->ls_pro[ls].nw_id; //& 0x03;
|
|
pclen = (mtp3_para->nw[nw].pc_len) & 0x01;
|
|
|
|
if (pclen)
|
|
{
|
|
if (len <= 8)
|
|
return -1;
|
|
offset = 9+1+1;//msg_ptr[offset+1] = sccp data
|
|
msg_ptr[offset-1] = (len - 8)%0xff;
|
|
msg_ptr[offset-2] = (len - 8)/0xff;
|
|
len = len - 7+2;
|
|
}
|
|
else
|
|
{
|
|
if (len <= 5)
|
|
return -1;
|
|
offset = 6+1+1;
|
|
msg_ptr[offset-1] = (len - 5)%0xff;
|
|
msg_ptr[offset-2] = (len - 5)/0xff;
|
|
len = len - 4+2;
|
|
}
|
|
/******change to struct: 00, len, 0xfd*****/
|
|
msg_ptr[offset] = 0xfd;
|
|
|
|
/******change to struct: 00, len, 0xfd*****/
|
|
mtp3lite_DirectSendMsg(link, len, msg_ptr + offset - 2);
|
|
//mtp3lite_link[link].local_inactive = 2000;
|
|
|
|
return 0;
|
|
}
|
|
/*
|
|
int put_mtp3lite_msg(BYTE *msg_ptr)
|
|
{
|
|
BYTE link, len, ls, nw, pclen, offset;
|
|
|
|
link = msg_ptr[0];
|
|
len = msg_ptr[1];
|
|
|
|
if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE
|
|
!(mtp3_para->lk[link].e1_lk_type & 0x01) || // Not Enabled
|
|
(mtp3ObjState.lk_command[link]==0) || // Command disabled
|
|
(mtp3lite_link[link].connfd <= 0)) // Link Not Established
|
|
return -1;
|
|
|
|
if ((ls = mtp3_para->lk[link].e1_to_linkset) >= 128)
|
|
return -1;
|
|
|
|
nw = mtp3_para->ls_pro[ls] & 0x03;
|
|
pclen = (mtp3_para->nw_pro >> nw) & 0x01;
|
|
|
|
if (pclen)
|
|
{
|
|
if (len <= 8)
|
|
return -1;
|
|
offset = 9;
|
|
msg_ptr[offset] = len - 8;
|
|
len = len - 7;
|
|
}
|
|
else
|
|
{
|
|
if (len <= 5)
|
|
return -1;
|
|
offset = 6;
|
|
msg_ptr[offset] = len - 5;
|
|
len = len - 4;
|
|
}
|
|
|
|
mtp3lite_DirectSendMsg(link, len, msg_ptr + offset);
|
|
//mtp3lite_link[link].local_inactive = 2000;
|
|
|
|
return 0;
|
|
}
|
|
*/
|
|
int mtp3lite_chk_lk(WORD link)
|
|
{
|
|
// char str[19]={7,0,0x11,0x83,0x71,0xab,0xdc,0x1a,0x06,0xf6, 0,0,0,1,5,1,3,2,9,4};
|
|
if ((MTP3_LINK_TYPE(link) != LKTYPE_MTP3_LITE) || // Not MTP3LITE
|
|
!(mtp3_para->lk[link].admin_state& 0x01) || // Not Enabled
|
|
(mtp3ObjState.lk_command[link] == 0)) // Command disabled
|
|
return 0;
|
|
|
|
if (mtp3lite_link[link].init_guard_timer > 0)
|
|
mtp3lite_link[link].init_guard_timer--;
|
|
|
|
if (mtp3lite_link[link].connfd <= 0) // Link Not Established
|
|
return 0;
|
|
|
|
if (mtp3lite_link[link].remote_inactive > 0)
|
|
{
|
|
if (--mtp3lite_link[link].remote_inactive == 0)
|
|
{
|
|
|
|
// if (++mtp3lite_link[link].remote_inactive_timeouts >= mtp3_para->lk[link].inactive_tm)
|
|
if(0)
|
|
{
|
|
printf("link[%d] remote inactivity %d seconds timeout %d times!\n", link, mtp3_para->lk[link].inactive, mtp3_para->lk[link].inactive_tm);
|
|
mtp3lite_CloseTcpConn(link);
|
|
mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_INACTIVITY_TIMEOUT);
|
|
}
|
|
else
|
|
{
|
|
mtp3lite_link[link].remote_inactive = mtp3_para->lk[link].inactive * 200;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mtp3lite_link[link].local_inactive > 0)
|
|
{
|
|
if(mtp3lite_id_fg[link]==0)
|
|
{
|
|
mtp3lite_id_fg[link] = 1;
|
|
send_mtp3lite_id_ack(link);
|
|
//send_mtp3lite_ping(link);
|
|
}
|
|
if (--mtp3lite_link[link].local_inactive == 0)
|
|
{
|
|
// mtp3lite_DirectSendMsg(link, 3, mtp3lite_ka_msg);
|
|
// put_mtp3lite_msg(&str);
|
|
mtp3lite_link[link].local_inactive = 2000;
|
|
send_mtp3lite_id_ack(link);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void deactive_mtp3lite_lk(WORD link)
|
|
{
|
|
if ((MTP3_LINK_TYPE(link) == LKTYPE_MTP3_LITE) && // MTP3LITE
|
|
(mtp3_para->lk[link].admin_state & 0x01) && // Enabled
|
|
(mtp3lite_link[link].connfd > 0))
|
|
{//sccp lite link
|
|
mtp3_debug(MTP3DB_EVENT,"mtp3-lite link %d Deactive by MNG",link);
|
|
mtp3lite_CloseTcpConn(link);
|
|
mtp3lite_updateStatus(link, MTP2_STATE_STOP, MTP3LITE_INACTIVITY_TIMEOUT);
|
|
}
|
|
}
|
|
|
|
void mtp3lite_init(void)
|
|
{
|
|
int i;
|
|
|
|
printf("MTP3LITE Init Start!\n");
|
|
|
|
for (i = 0; i < 1024; i++)
|
|
{
|
|
mtp3lite_init_lk(i);
|
|
mtp3lite_InitClientSocket(i);
|
|
}
|
|
|
|
mtp3lite_listen_fd = -1;
|
|
|
|
// mtp3lite_InitServerSocket();
|
|
|
|
mtp3lite_init_ka_msg();//keep alive message
|
|
|
|
printf("MTP3LITE Init Complete!\n");
|
|
}
|
|
|
|
void mtp3lite_reset(void)
|
|
{
|
|
int link;
|
|
|
|
for (link=0;link<MAX_LK;link++)
|
|
{
|
|
if (mtp3lite_link[link].connfd >=0)
|
|
{
|
|
mtp3lite_CloseTcpConn(link);
|
|
mtp3lite_rem_len[link] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void mtp3lite_timer(void)
|
|
{
|
|
int link;
|
|
|
|
mtp3lite_TcpConnectCheck();
|
|
|
|
for (link = 0; link < MAX_LK; link++)
|
|
{
|
|
get_mtp3lite_msg(link);
|
|
mtp3lite_chk_lk(link);
|
|
}
|
|
}
|
|
/*@end@*/
|