/* 
** PACS-WLL 2000 project, Prepaid System.
** 
** The module Copyright (C) 2000-2001 interWAVE Inc.
** Written completely by Zhang Shuzhong at iCRD January, 2001
**
** file name: iptrans.c
** CVS: $Id: iptrans.c,v 1.9 2001/02/09 08:53:43 zhangsz Exp $
**
** Description: IP transceiver common module of PACS-WLL Project.     
**
*/

#include     "./include/iptrans.h"

#define     PROG_NAME     "iptrans"

extern int          debug;            /* defined in errorlog.c */
extern int          under_develop;   /* defined in errorlog.c */            
static int          iptrans_shm_id;
static int          iptrans_sem_id;
static struct termio prev_termio;
static iptrans_shm         *iptrans_shm_ptr;

int  GetMessage(message_list *msgGet,int port);
void PutMessage(message_list  msgPut);

/*@ignore@*/
/* Set debug flag to control debug message print or not */
void SetDebugFlag(void)
{
    debug = DEBUG;                    /* DEBUG defined in debug.h */
    under_develop = UNDER_DEVELOP;     /* UNDER_DEVELOP defined in debug.h */
}

/* 
** Handler of terminatation,
** process while received a signal from user.
*/
static void Terminate(int sig)
{
    int retval;

    usleep(100000);
    retval = (int) shmdt(0);
    if (retval == -1) log_ret("%s: %s: shmdt", PROG_NAME, FUNCTION_MACRO);
    retval = shmctl(iptrans_shm_id, IPC_RMID, NULL);
    if (retval == -1) log_ret("%s: %s: shmctl", PROG_NAME, FUNCTION_MACRO);
    retval = semctl(iptrans_sem_id, PORT_NUM, IPC_RMID, NULL);
    if (retval == -1) log_ret("%s: %s: semctl", PROG_NAME, FUNCTION_MACRO);
    exit(sig);
}    

int GetMessage(struct message_list *msgGet,int port)
{
   message_list msgSend;
   if(iptrans_shm_ptr->msgPortIn[port].msgReadSub != iptrans_shm_ptr->msgPortIn[port].msgWriteSub)
   {
     memcpy(msgGet,
            &iptrans_shm_ptr->msgPortIn[port].msgList[iptrans_shm_ptr->msgPortIn[port].msgReadSub],
            sizeof(struct message_list));
     memcpy(&msgSend,msgGet,sizeof(struct message_list));
     PutMessage(msgSend);
    fprintf(stderr,"Recv msg %d.\n",port+4951);
     iptrans_shm_ptr->msgPortIn[port].msgReadSub ++;
     if(iptrans_shm_ptr->msgPortIn[port].msgReadSub==IN_LIST_NUM)
       iptrans_shm_ptr->msgPortIn[port].msgReadSub =0;             
        /*
fprintf(stderr,"iptrans state:\n  port=%d\n   packet in=%ld  out=%ld errors=%ld %ld\n",
                port, 
                iptrans_shm_ptr->msgPortStat[port].inPackets, 
                iptrans_shm_ptr->msgPortStat[port].outPackets,
                iptrans_shm_ptr->msgPortStat[port].errorInPackets,
                iptrans_shm_ptr->msgPortStat[port].errorOutPackets);
*/
    return 1;
   }   
   else
   {
    return 0;
   }
}

void PutMessage(struct message_list msgPut)
{
  memcpy(&iptrans_shm_ptr->msgPortOut.msgList[iptrans_shm_ptr->msgPortOut.msgWriteSub],
         &msgPut,sizeof(struct message_list));

  iptrans_shm_ptr->msgPortOut.msgWriteSub ++;
  if(iptrans_shm_ptr->msgPortOut.msgWriteSub==OUT_LIST_NUM)
     iptrans_shm_ptr->msgPortOut.msgWriteSub=0;
  
}

void timer_IRQ()
{
   int i;
   struct message_list msgList;
   for(i=0;i<13;i++)
   {    
        GetMessage(&msgList,i);
    //    PutMessage(msgList);
   }

}


void init_timer_interrupt(void)
{
  struct sigaction newact;
  newact.sa_handler =timer_IRQ;
  newact.sa_flags =0;
  sigemptyset(&newact.sa_mask);
  sigaction(SIGALRM,&newact,NULL);
}

void setup_interval_timer(void)
{
  struct itimerval value;
  value.it_interval.tv_sec =0;
  value.it_interval.tv_usec =5*1000;
  value.it_value =value.it_interval;
  setitimer(ITIMER_REAL,&value,NULL);
}

void init_timer()
{
  init_timer_interrupt();
  setup_interval_timer();
}

extern void DaemonInit(const char *pname, int facility);
extern void *ShmInit(int shm_id, char *prog_name, key_t key, int size, int shmflg);
extern void SetTermSignal(struct termio *ptermio, void (*handler)(int));
int main(int argc, char *argv[])
{
    int                 err_flag = FALSE;
    int                 test_mode = FALSE;
    int 			ret;
    SetDebugFlag();

    /* 
    ** Get option from command line.
    ** option 'd' is enable to run program with daemon mode.
    */
    while ((ret = getopt(argc, argv, "dt")) != -1)
        switch (ret)
        {
        case 'd':
            /* Set daemon mode and open a syslog */
            DaemonInit(PROG_NAME, LOG_USER);
            break;
        case 't':
            test_mode = TRUE;   /* test mode: bind port 4950 to recvfrom */
            break;
        case '?':
            err_flag = TRUE;
        }
    if (err_flag) {
        log_msg("Usage: %s -d -t \n", argv[0]);
        log_msg("    -d  with daemon mode");
        log_msg("    -t  with test mode");
        exit(1);
    }
    
    /*
    ** Get shared memory block,
    ** IPTRANS_SHM_KEY to be defined in iptrans.h. 
    */
    iptrans_shm_ptr = (iptrans_shm *) ShmInit(iptrans_shm_id, PROG_NAME,
            IPTRANS_SHM_KEY, sizeof(iptrans_shm), IPTRANS_SHM_PERM|IPC_CREAT);
    memset(iptrans_shm_ptr, 0, sizeof(iptrans_shm));

    /* 
    ** Get semaphores ID used by shared memory block,
    ** IPTRANS_SEM_KEY to be defined in iptrans.h.
    */

    SetTermSignal(&prev_termio, Terminate);
    /* 
    ** Open socket handler for IP transceiver.
    ** maxinum number is PORT_NUM.
    */
    init_timer();
    while(1){
     usleep(1);
    }
    exit(0);
}
/*@end@*/
