#include <stdio.h>

#include <qmsgbox.h>
#include <qstring.h>

#include <kconfig.h>
#include <kprocess.h>

#include "kISDNdata.h"
#include "connection.h"


Connection::Connection(QWidget *parent, const char *name):QWidget(parent, name)
{
  char     ipneg[48], user[NAMESIZE+1], device[16], ipppd[PATHSIZE+1];
  char     kdebug[16] = "";
    
  GenData *gen    = ISDNData.General;
  AdvData *adv    = &(gen->Advanced);
  AccData *acc    = ISDNData.Current;
  DevData *master = &(acc->MasterDevice);
  QString encaps;
  
  createInterface();
  
  sprintf(user, "%s", acc->username.data()); 

  encaps = (master->Encaps == PROTSYNC) ? "ppp" : "sdn";
  sprintf(device, "/dev/i%s%i", encaps.data(), acc->device);
  sprintf(ipppd, "%s", gen->ipppdpath.data());
  
  if (acc->ipdynamic) sprintf(ipneg, "noipdefault");
  else sprintf(ipneg, "%s:%s", acc->iplocaddress.data(), acc->ipremaddress.data());
  
  IPPPD = new KProcess();
 
  *IPPPD << ipppd
         << ipneg
         << "user"
         << user;
	 
  if (adv->bsdcomp)  *IPPPD << "-bsdcomp";
  if (adv->incdebug) *IPPPD << "debug";

  if (adv->dbglevel != 0)
  {
    sprintf(kdebug, "kdebug %i", adv->dbglevel);
    *IPPPD << kdebug;
  }
  
  *IPPPD << "-detach"
         << "lock"
         << "defaultroute"
         << device;
         
  if (!IPPPD->start()) QMessageBox::warning(this, "Fatal Error",
                       "ipppd could not be\n"
                       "started !\n\n", "OK", 0);
}


Connection::~Connection(void)
{
  if (!IPPPD->kill(SIGKILL)) QMessageBox::warning(this, "Fatal Error",
                             "ipppd could not be\n"
                             "killed !\n\n", "OK", 0);
  else deleteInterface();
}


void Connection::createInterface(void)
{
  char  buffer[64], ctrl[PATHSIZE+1];
  char  enc[6][16] = {"rawip", "ip", "cisco_h", "ethernet", "syncppp", "uihdlc"};  
  char  la2[4][8]  = {"x75i", "x75ui", "x75bui", "hdlc"};
    
  GenData   *gen    = ISDNData.General;
  AccData   *acc    = ISDNData.Current;
  DevData   *master = &(acc->MasterDevice);
  PhoneData *phone  = master->FirstPhone;
  
  fprintf(stderr, "Configuring master device...\n");
  
  sprintf(ctrl, "%s", gen->ctrlpath.data());
  
  sprintf(buffer, "%s addif ippp0", ctrl);
  system(buffer);
  sprintf(buffer, "%s eaz ippp0 %s%s", ctrl, (gen->prefix).data(), (gen->msn).data());
  system(buffer);
  
  if (phone == (PhoneData *) 0L) QMessageBox::warning(this, "Fatal Error",
                                   "No phone number for master\n"
                                   "device supplied !\n\n", "OK", 0);

  else
  {
    while (phone != (PhoneData *) 0L)
    {
      sprintf(buffer, "%s addphone ippp0 out %s", ctrl, phone->number.data());
      system(buffer);
      phone = phone->next;
    }
    sprintf(buffer, "%s dialmax ippp0 %i", ctrl, master->DialAttempts);
    system(buffer);
    sprintf(buffer, "%s huptimeout ippp0 %i", ctrl, master->HupTimeout);
    system(buffer);
    sprintf(buffer, "%s encap ippp0 %s", ctrl, enc[master->Encaps]);
    system(buffer);
    sprintf(buffer, "%s l2_prot ippp0 %s", ctrl, la2[master->Layer2]);
    system(buffer);
    sprintf(buffer, "%s l3_prot ippp0 trans", ctrl);
    system(buffer);   
    
    if (acc->bundle)			// Wanna try some channel bundling ?
    {
      fprintf(stderr, "Configuring the slave device...\n");
      sprintf(buffer, "%s addslave ippp0 slave", ctrl);
      system(buffer);
      sprintf(buffer, "%s eaz slave %s%s", ctrl, (gen->prefix).data(), (gen->msn).data());
      system(buffer);
      
      phone  = master->FirstPhone;
      while (phone != (PhoneData *) 0L)
      {
        sprintf(buffer, "%s addphone ippp0 out %s", ctrl, phone->number.data());
        system(buffer);
        phone = phone->next;
      }
      sprintf(buffer, "%s dialmax slave %i", ctrl, master->DialAttempts);
      system(buffer);
      sprintf(buffer, "%s huptimeout slave %i", ctrl, master->HupTimeout);
      system(buffer);
      sprintf(buffer, "%s encap slave %s", ctrl, enc[master->Encaps]);
      system(buffer);
      sprintf(buffer, "%s l2_prot slave %s", ctrl, la2[master->Layer2]);
      system(buffer);
      sprintf(buffer, "%s l3_prot slave trans", ctrl);
      system(buffer);      
      sprintf(buffer, "%s sdelay slave %i", ctrl, master->Delay);
      system(buffer);      
    } 
  } 
}


void Connection::deleteInterface(void)
{
  char  buffer[32];
  
  AccData  *acc = ISDNData.Current;
  GenData  *gen = ISDNData.General;

  if (acc->bundle)			
  {
    fprintf(stderr, "Deleting slave device...\n");
    sprintf(buffer, "%s delif slave", gen->ctrlpath.data());
    system(buffer);
  }  
  sprintf(buffer, "%s ippp0 down", gen->ifconpath.data());
  system(buffer);
  sprintf(buffer, "%s delif ippp0", gen->ctrlpath.data());
  system(buffer);
}


void Connection::dialOut(void)
{
  char     buffer[128];
  GenData  *gen = ISDNData.General;
  AccData  *acc = ISDNData.Current;
  
  sprintf(buffer, "%s dial ippp%i", gen->ctrlpath.data(), acc->device);
  system(buffer); 
}


void Connection::hangUp(void)
{
  char     buffer[128];
  GenData  *gen = ISDNData.General;
  AccData  *acc = ISDNData.Current;
  
  sprintf(buffer, "%s hangup ippp%i", gen->ctrlpath.data(), acc->device);
  system(buffer); 
}
