/*
 * simco_b.c
 *
 * Copyright (C) 2005, Ranch Networks, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * Author : Srivatsa Chivukula <srivatsa@ranchnetworks.com>
 *
 */

#include "simco_core.h"
#include "simco_client.h"
#include "simco_b.h"

/**
 * Builds a packet for simco session establish request, sends the
 * packet over TCP/IP and parses response to check error code.
 * @param con a pointer to MCAgenCon structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPSessionEstablish(MCAgentCon *con)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;
  simcoPacket_t sp;

  req_len = makeSessionEstablishRequest(request);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(&sp, response, res_len);
  free(response);
  return sp.status;
}

/**
 * Builds a packet for simco session authenticate request, sends the
 * packet over TCP/IP and parses response to check error code.
 * @param con a pointer to MCAgenCon structure.
 * @param username agent's username.
 * @param password agent's password.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPSessionAuthenticate(MCAgentCon *con, char *username, char *password)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;
  simcoPacket_t sp;
  char str[512];

  strcpy(str, username);
  strcat(str, ":");
  strcat(str, password);

  req_len = makeSessionAuthenticateRequest(request, str);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(&sp, response, res_len);
  free(response);
  return sp.status;
}

/**
 * Builds a packet for simco ping request, sends the
 * packet over TCP/IP and parses response to check error code.
 * @param con a pointer to MCAgenCon structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPPing(MCAgentCon *con)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;
  simcoPacket_t sp;
  int ret = -1;
  req_len = makePingRequest(request);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if ((ret = rnMCAgentComm(con, request, req_len, &response, &res_len)) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(&sp, response, res_len);
  free(response);
  return sp.status;
}

/**
 * Builds a packet for simco session terminate request, sends the
 * packet over TCP/IP and parses response to check error code.
 * @param con a pointer to MCAgenCon structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPSessionTerminate(MCAgentCon *con)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;
  simcoPacket_t sp;

  req_len = makeSessionTerminateRequest(request);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(&sp, response, res_len);
  free(response);
  return sp.status;
}

/**
 * Builds a packet for simco policy reserve rule request, sends the
 * packet over TCP/IP and parses response to fill corresponding fields in \a sp.
 * @param con a pointer to MCAgenCon structure.
 * @param sp a pointer to simcoPacket_t structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPPolicyReserveRule(MCAgentCon *con, simcoPacket_t *sp)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;

  req_len = makePolicyReserveRuleRequest(request, sp);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(sp, response, res_len);
  free(response);
  return sp->status;
}

/**
 * Builds a packet for simco policy enable rule request, sends the
 * packet over TCP/IP and parses response to fill corresponding fields in \a sp.
 * @param con a pointer to MCAgenCon structure.
 * @param sp a pointer to simcoPacket_t structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPPolicyEnableRule(MCAgentCon *con, simcoPacket_t *sp)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;

  req_len = makePolicyEnableRuleRequest(request, sp);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(sp, response, res_len);
  free(response);
  return sp->status;
}

/**
 * Builds a packet for simco PER after reservation request, sends the
 * packet over TCP/IP and parses response to fill corresponding fields in \a sp.
 * @param con a pointer to MCAgenCon structure.
 * @param sp a pointer to simcoPacket_t structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPPERAfterReservation(MCAgentCon *con, simcoPacket_t *sp)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;

  req_len = makePERAfterReservationRequest(request, sp);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(sp, response, res_len);
  free(response);
  return sp->status;
}

/**
 * Builds a packet for simco PBR after reservation request, sends the
 * packet over TCP/IP and parses response to fill corresponding fields in \a sp.
 * @param con a pointer to MCAgenCon structure.
 * @param sp a pointer to simcoPacket_t structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPPBRAfterReservation(MCAgentCon *con, simcoPacket_t *sp)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;

  req_len = makePBRAfterReservationRequest(request, sp);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(sp, response, res_len);
  free(response);
  return sp->status;
}

/**
 * Builds a packet for simco policy rule lifetime change request, sends the
 * packet over TCP/IP and parses response to fill corresponding fields in \a sp.
 * @param con a pointer to MCAgenCon structure.
 * @param sp a pointer to simcoPacket_t structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPPolicyRuleLifetimeChange(MCAgentCon *con, simcoPacket_t *sp)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;

  req_len = makePolicyRuleLifetimeChangeRequest(request, sp);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(sp, response, res_len);
  free(response);
  return sp->status;
}

/**
 * Builds a packet for simco policy rule status request, sends the
 * packet over TCP/IP and parses response to fill corresponding fields in \a sp.
 * @param con a pointer to MCAgenCon structure.
 * @param sp a pointer to simcoPacket_t structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPPolicyRuleStatus(MCAgentCon *con, simcoPacket_t *sp)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;

  req_len = makePolicyRuleStatusRequest(request, sp);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  parseSIMCOPdu(sp, response, res_len);
  free(response);
  return sp->status;
}

/**
 * Builds a packet for simco policy rule list request, sends the
 * packet over TCP/IP and parses response to get an array of rules.
 * @param con a pointer to MCAgenCon structure.
 * @param rules a pointer to an integer array.
 * @param numrules contains the number of elements in the integer array \a rules.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPPolicyRuleList(MCAgentCon *con, int **rules, int *numrules)
{
  char request[SET_REQUEST_SIZE];
  char *response;
  int req_len = 0;
  int res_len = 0;
  int ret;

  req_len = makePolicyRuleListRequest(request);
  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, request, req_len, &response, &res_len) <= 0)
    {
      return -1;
    }
  ret = parseSIMCORuleList(response, res_len, rules, numrules);
  free(response);
  return ret;
}

/**
 * Reads for data on the notification channel and parses it
 * to fill corresponding fields in \a np.
 * @param con a pointer to MCAgenCon structure.
 * @param np a pointer to simcoPacket_t structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int b_mcAgentTCPNotificationRead(MCAgentCon *con, simcoPacket_t *np)
{
  char *response;
  int res_len = 0;

  res_len = MAX_READ_SIZE;
  response = (char*)malloc(MAX_READ_SIZE);
  if (rnMCAgentComm(con, NULL, 0, &response, &res_len) <= 0)
    {
      return -1;
    }
  if (res_len != 0)
    parseSIMCOPdu(np, response, res_len);
  free(response);
  return np->status;
}
