//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
//
// Description:
//      Implementation of UDP handler of RSVC Server
//
// Author:  Jie Chen
//
// Revision History:
//   rsvcUdpHandler.cc,v
// Revision 1.1  1998/01/22  17:08:26  akers
// Addition of new NameServer
//
//
//
#include <rsvcNetData.h>
#include <rsvcDataStore.h>
#include "rsvcUdpHandler.h"

rsvcUdpHandler::rsvcUdpHandler (char* name,
				cdevReactor& r, rsvcDataStoreTable& table)
:cdevEventHandler (), reactor_ (r), listener_ (), storeTable_ (table)
{
#ifdef _TRACE_OBJECTS
  printf ("    Create rsvcUdpHandler Class Object\n");
#endif
  dbasename_ = new char[strlen (name) + 1];
  strcpy (dbasename_, name);
}

rsvcUdpHandler::~rsvcUdpHandler (void)
{
#ifdef _TRACE_OBJECTS
  printf ("    Delete rsvcUdpHandler Class Object\n");
#endif

  handleClose ();
  delete []dbasename_;
}

int
rsvcUdpHandler::open (unsigned short port, int async)
{
  cdevInetAddr addr (port);

  if (listener_.open (addr) == -1)
    return -1;
#ifndef _WIN32
  else if (async && listener_.setFlags (SIGIO) == -1)
    return -1;
#endif
  else
    return 0;
}

unsigned short
rsvcUdpHandler::port_number (void)
{
  cdevInetAddr addr;

  listener_.getLocalAddress (addr);

  // host byte order
  return addr.getPortNum ();
}

int
rsvcUdpHandler::handleClose (void)
{
  return listener_.close ();
}

int
rsvcUdpHandler::getHandle (void) const
{
  return listener_.getHandle ();
}

int
rsvcUdpHandler::handleInput (void)
{
  cdevInetAddr sa;
  rsvcNetData   ndata;
  int           n;
  int           i = 0;

  if ((n = listener_.recv (ibuffer_, sizeof (ibuffer_), sa) < 0)) {
#ifdef _RSVC_DEBUG
    printf ("rsvcUdpHandler: recv messge error with error number %d\n", errno);
#endif
    return -1;
  }

  size_t datasize;
  i = 0;

  if (rsvcNetData::readHeader (ibuffer_, rsvcNetData::headerLen (), 
			       &datasize) !=	RSVC_SUCCESS) {
#ifdef _RSVC_DEBUG
    printf ("rsvcUdpHandler: This is not header\n");
#endif
    return -1;
  }
  if (datasize > sizeof (ibuffer_) - rsvcNetData::headerLen ()) {
#ifdef _RSVC_DEBUG
    printf ("rsvcUdpHandler: incoming rsvcNetData is too big\n");
#endif
    return -1;
  }
    
  // increase i by header len
  i += rsvcNetData::headerLen ();

  if (ndata.streamIn (&(ibuffer_[i]), datasize) != RSVC_SUCCESS) {
#ifdef _RSVC_DEBUG
    printf ("rsvcUdpHandler: rsvcNetData stream in error\n");
#endif
    return -1;
  }

  // now we can call process function
  rsvcDataStore* store = storeTable_.find (dbasename_);
  if (store) {
    rsvcNetData* backdata[1];
    size_t numdata = 0;
    // put zero numdata to denote we do not want anything back
    if (store->setValue (ndata, backdata, &numdata) == RSVC_SUCCESS) {
#ifdef _RSVC_DEBUG
      printf ("rsvcUdpHandler: update server success\n");
#endif
    }
    else 
      printf ("rsvcUdpHandler: update server failed\n");
  }
  return 0;
}


  
