/*      XAPP coding test function c file        */
/*      created by Liu Wei  2006-01-13          */
/*      Version 1.0                             */
/*      -------------------------------------   */

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <termio.h>
#include <sys/stat.h>
#include <sys/io.h>

#include "xapp_coding_test.h"
#include "xapp_main.h"

static int sys_timer10ms = 0;

static char test_sync_cmd[6][32] = {
     "XAPP_TEST",
     "XAPP_RSP",
     "XAPP_OK",
     "XAPP_FAIL",
     "XAPP_OK,NEXT",
     "XAPP_FAIL,NEXT",
};

static char udp_contents = 0;

#define  	SYS_IT_INTERVAL_SEC 0
#define  	SYS_IT_INTERVAL_USEC  (10*1000)
int  remote_ip;
int  test_port = 6999;
u8   time_count;

int get_socket(u_int32_t ip, int port)
{
     int  sock;
     int  on = 1;
     u_long cmdarg = 1;
     struct sockaddr_in sin_addr;

     sin_addr.sin_family = AF_INET;
     sin_addr.sin_port = htons(port);
     sin_addr.sin_addr.s_addr = htonl(INADDR_ANY);

     if(!(sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
          perror("Get socket");
     setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
     if(bind(sock, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr_in)) != 0)
     {
          perror("bind");
          return 0;
     }
     ioctl(sock, FIONBIO, &cmdarg);
     return (sock);
}

int Get_Peer_IP()
{
     char s[16];
     FILE *fp = NULL;
     int  i = 0;
     char c;

     fp = fopen("./conf/sccp_test.conf", "r");
     if(fp != NULL)
     {
          while((c = fgetc(fp)) != EOF && c != ' ' && c != '\n' && c != '\t')
          {
               s[i++] = c;
               if(i >= 16)
                    break;
          }
          s[i] = '\0';
          printf("Remote ip :%s\r\n", s);
          remote_ip = inet_addr(s);
          i = 0;
          while((c = fgetc(fp)) != EOF && c != ' ' && c != '\n' && c != '\t')
          {
               s[i++] = c;
               if(i >= 5)
                    break;

          }
          s[i] = '\0';
          test_xapp.wait_time = strtol(s, NULL, 10);
          printf("Waiting start test time :%ld\r\n", test_xapp.wait_time);
          return 1;
     }
     return 0;
}

void MS_mode_test()
{
     memset(&test_xapp, 0, sizeof(struct test_xapp_struct));
     //test_cmd=0;
     //test_xapp.ms_mode = 0;
     if(Get_Peer_IP())
     {
          test_xapp.sock = get_socket(remote_ip, test_port);
     }
     else
     {
          printf("Get Peer IP Fail!\r\n");
     }
}

void next_case()
{
     test_cmd++;
	 
     test_xapp.test_result = 0;
     test_xapp.peer_state = 0;
     printf("\r\n ------------------------>> Next Case %d<<------------------ \r\n",(int )test_cmd);
     if(test_cmd == XAPP_TEST_LAST_IDLE)
     {
          printf("\r\n\r\nTest over !\r\n\r\n");
          test_cmd = 0;
          test_xapp.test_result = 7;
     }
}

void MS_test_timer()
{
     char msg[256];
     struct sockaddr_in sin_addr;
     int  addr_len;
     u8   isdn[ISDN_LEN];
     u8   i;
     char str[32];

     sin_addr.sin_port = htons(test_port);
     sin_addr.sin_addr.s_addr = remote_ip;
     addr_len = sizeof(struct sockaddr_in);
     udp_contents = 0;
     memset(msg, 0, 256);
     recvfrom(test_xapp.sock, (char *)msg, 256, 0, (struct sockaddr *)&sin_addr, &addr_len);
     if(msg[0])
     {
		  //printf("Recv Test sycn msg :%s \r\n",msg); 
          for(i = 0; i <= 6; i++)
          {
               sprintf(str, "%s", test_sync_cmd[i]);
               if(i >= 2)
                    sprintf(str, "%s:%d", test_sync_cmd[i], test_cmd);
               if(strcmp(msg, str) == 0)
               {
                    udp_contents = i + 1;
                    break;
               }
          }

     }
     if(test_xapp.ms_mode == 0)
     {
          if(udp_contents == 0)
          {
               strcpy(msg, "XAPP_TEST");
               sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
          }
          if(udp_contents == 2)
          {
               test_xapp.local_ssn = 7;
               test_xapp.peer_ssn = 6;
               imap_reg_ssn(test_xapp.local_ssn);
               AsciiToBcd(isdn, "918675557122001F", 16);
               xapp_set_sccpadd(test_xapp.local_ssn, isdn, &test_xapp.local_add);
               AsciiToBcd(isdn, "918675557122002F", 16);
               xapp_set_sccpadd(test_xapp.peer_ssn, isdn, &test_xapp.peer_add);
               printf(" XAPP Test Slave Started :%s\r\n", msg);
               test_xapp.ms_mode = 2;
               return;
          }
          else if(udp_contents == 1)
          {
               test_xapp.local_ssn = 6;
               test_xapp.peer_ssn = 7;
               imap_reg_ssn(test_xapp.local_ssn);
               AsciiToBcd(isdn, "918675557122002F", 16);
               xapp_set_sccpadd(test_xapp.local_ssn, isdn, &test_xapp.local_add);
               AsciiToBcd(isdn, "918675557122001F", 16);
               xapp_set_sccpadd(test_xapp.peer_ssn, isdn, &test_xapp.peer_add);
               printf(" XAPP Test Master Started :%s\r\n", msg);
               strcpy(msg, "XAPP_RSP");
               sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
               test_xapp.ms_mode = 1;
               return;
          }

     }
     if(test_xapp.ms_mode)
     {
          switch (test_xapp.test_result)
          {
          case 0:
               
               if(udp_contents == 4)
               {
                    sprintf(msg, "XAPP_FAIL:%d,Next", test_cmd);
                    sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
                    printf("[Test]:Fail!\r\n\r\n");
                    next_case();
                    return;
               }
               else if(udp_contents == 3)
               {
                    printf("Peer Test OK  !\r\n");
                    test_xapp.peer_state = 1;
               }
               break;
          case 1:              //OK
               printf("Local Test OK  !\r\n");
               if(test_xapp.peer_state == 1)
               {
                    sprintf(msg, "XAPP_OK,NEXT:%d", test_cmd);
                    sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
                    printf("[Test]: OK!\r\n\r\n");
                    next_case();
                    return;
               }
               sprintf(msg, "XAPP_OK:%d", test_cmd);
               sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
			         printf("Send sycn msg : %s\r\n ",msg);
               test_xapp.test_result = 3;
               break;
          case 2:
               printf("Local Test Fail !\r\n");
               if(test_xapp.peer_state == 1)
               {
                    sprintf(msg, "XAPP_FAIL,NEXT:%d", test_cmd);
                    sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
                    printf("[Test]:Fail!\r\n\r\n");
                    next_case();
                    return;
               }
               sprintf(msg, "XAPP_FAIL:%d", test_cmd);
               sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
               printf("Send sycn msg : %s\r\n ",msg);
			   test_xapp.test_result = 4;
               break;
          case 3:
          case 4:
			  if( msg[0] )
					printf("udp recv pos 3:%s\r\n", msg); 
               if(udp_contents == 5 || udp_contents == 6)
               {
                    (test_xapp.test_result == 3) ? printf("Peer Test OK  !\r\n") : printf("Peer Test Fail  !\r\n");
                    (test_xapp.test_result == 3) ? printf("[Test]: OK!\r\n\r\n") : printf("[Test]: Fail!\r\n\r\n");
                    next_case();
                    return;
               }
               else if(udp_contents == 3)
               {
                    sprintf(msg, "XAPP_OK,NEXT:%d", test_cmd);
                    sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
                    printf("Peer Test OK  !\r\n");
                    printf("[Test]: OK!\r\n\r\n");
                    next_case();
                    return;
               }
               else if(udp_contents == 4)
               {
                    sprintf(msg, "XAPP_FAIL,NEXT:%d", test_cmd);
                    sendto(test_xapp.sock, (char *)msg, 32, 0, (struct sockaddr *)&sin_addr, sizeof(struct sockaddr));
                    printf("Peer Test Fail  !\r\n");
                    printf("[Test]:Fail!\r\n\r\n");
                    next_case();
                    return;
               }
               break;
          default:
               break;

          }

     }
}




void moduleInit()
{
     //ioperm(0x27A,3,1);
     MS_mode_test();            //master and slaver mode
     debug_init();
     //#ifdef NEW_PLATFORM
     iptrMainInit();
     /*#else
        iptrans_init();
        #endif */
     mtp_shm_init(); 
     snmp_init(4957);
     sccp_init();
     tcap_init(1024);
	 printf("MAP OP data size : %d\r\n,MAP OP Str size : %d\r\n",sizeof(MapOprData_struct),sizeof(MapOprSrv_struct));
	 //printf("send para res size : %d \r\nProvid_SSInfo_struct : %d \r\nOdbData_struct :%d \r\n" ,sizeof(MapSP_Res),
	 //sizeof(Provid_SSInfo_struct),sizeof(struct OdbData_struct));
	 printf("Sub_data_struct :%d ExtSsInfo_struct:%d \r\n",sizeof(Sub_data_struct),sizeof(ExtSsInfo_struct));
	 printf("MapISD_Arg :%d \r\n",sizeof(MapISD_Arg));    
	 xap_init(1204);
	 extract_sri();
     printf("\r\nWating Peer test message ... \r\n");
}

void sysTimer_IRQ()
{
     sys_timer10ms = 1;
}

static void SigactionSystem()
{
     struct sigaction action;

     action.sa_handler = sysTimer_IRQ;
     sigemptyset(&action.sa_mask);
     action.sa_flags = 0;
     if(sigaction(SIGALRM, &action, NULL) < 0)
     {
          printf("sigactin sigalarm failed\n");
     }
}

void SetFSMTimer()
{
     struct itimerval *ptv, tv;

     ptv = (struct itimerval *)&tv;
     ptv->it_interval.tv_sec = 0;
     ptv->it_interval.tv_usec = 10 * 1000;
     ptv->it_value = ptv->it_interval;
     setitimer(ITIMER_REAL, ptv, NULL);
}

void moduleProc()
{
     iptrans_timer();
     snmp_timer();
     heartbeat_timer();
     mtp3_proc();
     sccp_timer();
     debug_rt();
     tcap_fsm();
     xap_fsm();
     Test_func();
     MS_test_timer();
}

int main()
{
     moduleInit();
     SigactionSystem();
     SetFSMTimer();

     sys_timer10ms = 1;
     while(1)
     {
          if(sys_timer10ms)
          {
               sys_timer10ms = 0;
               moduleProc();
          }
          if(sys_timer10ms == 0)
               usleep(1);
     }
     return 1;
}
