/*

This is demo Software to demonstrate the server and client mode
on the dbox2. using the gbox.

1. First the NET mode is INIT
   The dbox2 will not decode the ECM's any more. It will work in
   CLIENT mode, send every ECM to the NET, and waiting for a response

2. When a ECM is accepted, we will use the dbox2 SERVER mode to decode
   the CW's, and will send the back to the dbox2.

compile on cygwin: gcc net.c -o net.exe
run it on cygwin : ./net

*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/ioctl.h>

int s, sd, cliLen;
struct sockaddr_in cliAddr;

// ----------------------------------------------------------------------------

void print(unsigned char *str, unsigned char *buf) {
  int i;
  printf("%s\n",str);
  for(i=0;i<buf[2]+3;i++){
    printf("%02X ",buf[i]);
    if ((i==15)||(i==31)||(i==47)||(i==63)||(i==79)||(i==95)) printf("\n");
  }
  printf("\n");
}

// ----------------------------------------------------------------------------

void send_net(unsigned char *buff) {
  send(s,buff,buff[2]+3,0);
}

// ----------------------------------------------------------------------------

int receive_net(unsigned char *msg) {
   int n;
   memset(msg,0x0,256);
   cliLen = sizeof(cliAddr);
   n = recvfrom(sd, msg, 256, 0, (struct sockaddr *) &cliAddr, &cliLen);
   if(n<0) printf("cannot receive data \n");
   return(n);
}

// ----------------------------------------------------------------------------

int main () {
  int lens, code;
	struct sockaddr_in saddr;
  unsigned char buffer[255];
  int rc, n;
  struct sockaddr_in servAddr;
  unsigned char msg[512];
  char ipstring [100];
  char *sub_string;
  long iplong;
  long portlong;
  int i;
	int len;

// init UDP port --------------------------------------------------------------
  strcpy (ipstring, "192.168.1.51"); // change this to be the dbox2 IP
  iplong = 0;
  iplong =  atoi ( strtok(ipstring, "."));
  while ( (sub_string=strtok(NULL, ".")) != NULL)
  {
    iplong = iplong << 8;
    iplong = iplong | atoi (sub_string);
  }
   portlong = atol ("8017");
  s = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
	if (s < 0) {
    printf("Cannot open UDP socket\n");
		return 16;
	}
	fcntl(s,F_SETFL,O_NONBLOCK);
  bzero(&saddr,sizeof(saddr));
	saddr.sin_family = AF_INET;
  saddr.sin_port = htons(8017);
	saddr.sin_addr.s_addr = htonl(iplong);
	len = connect(s,(struct sockaddr *) &saddr,sizeof(saddr));
	if (len < 0) {
    printf("Cannot connect UDP socket\n");
		close(s);
		return 16;
	}
  sd=socket(AF_INET, SOCK_DGRAM, 0);
  if(sd<0) {
    printf("cannot open socket \n");
    exit(1);
  }
  servAddr.sin_family = AF_INET;
  servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servAddr.sin_port = htons(8017);
  rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
  if(rc<0) {
    printf("cannot bind port\n");
    exit(1);
  }
// end of init UDP port -------------------------------------------------------

//Init NET mode
  printf ("Output to IP:192.168.1.51 on port 1500\n");
  buffer[0]=0x42;
  buffer[1]=0x12;
  buffer[2]=0x00;
  send_net(buffer);
  n=receive_net(msg);
  print("-Init NET mode --------------------------------",msg);

// Main loop-------------------------------------------------------------------
nextecm:

  n=receive_net(msg); // wait for a message
  code=(msg[0]<<8)+msg[1];

  switch ( code ) {
    case 0x4E15: // it is a ECM, we will send it to the dbox2 SERVER for decode
      print("-Received ECM, requesting CW decode from dbox2-",msg);
      msg[0]=0x42;
      msg[1]=0x15;
      send_net(msg);
    break;
    case 0x4115: // it is a CW decode response from the dbox2 SERVER
      print("-Received decoded CW's, sending them to dbox2-",msg);
      if (msg[2]==0x10) { // cw decoded
        msg[0]=0x42;
        msg[1]=0x10;
        send_net(msg);    // send to dbox2 so they are written
      } else {
        msg[0]=0x42;      // cw decode failed
        msg[1]=0x10;
        msg[2]=0x00;
        send_net(msg);    // send to dbox2 in order to get a new ECM
      }
    break;
    case 0x4110:
      print("-CW's accepted---------------------------------",msg);
    break;
    default:
      print("-Received unexpected mesage from dbox2---------",msg);
    break;
  }

goto nextecm;

return 0;
}
