/*
 * simco_client.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"
#include "simco_nb.h"

/**
 * Connect to the simco service running on the middlebox.
 * The simco session and policy requests can be sent on this channel.
 * @param host IP address (dotted decimal notation) of the middlebox.
 * @return index to connection structure, or -1 on error.
 */
int mc_comm_connect(char *host)
{
  return midcomAgentConnect(host, COMM_PORT);
}

/**
 * Connect to the simco notification service running on the middlebox.
 * Only simco session requests can be sent on this channel.
 * @param host IP address (dotted decimal notation) of the middlebox.
 * @return index to connection structure, or -1 on error.
 */
int mc_notif_connect(char *host)
{
  return midcomAgentConnect(host, NOTF_PORT);
}

/**
 * Disconnect the connection corresponding to the index \a i.
 * @param i connection index.
 */
void mc_comm_disconnect(int i)
{
  midcomAgentDisconnect(&conn[i]);
}

/**
 * Disconnect the connection corresponding to the index \a i.
 * @param i connection index.
 */
void mc_notif_disconnect(int i)
{
  midcomAgentDisconnect(&conn[i]);
}



/**
 * Send session establish request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_se_b(int i)
{
  return b_mcAgentTCPSessionEstablish(&conn[i]);
}

/**
 * Send session establish request and get response on the
 * notification connection corresponding to the index \a i.
 * @param i notification connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_ne_b(int i)
{

  return b_mcAgentTCPSessionEstablish(&conn[i]);
}

/**
 * Send session authenticate request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @param username login name for the agent
 * @param password password for the agent
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_sa_b(int i, char *username, char *password)
{
  assert(username);
  assert(password);
  return b_mcAgentTCPSessionAuthenticate(&conn[i], username, password);
}

/**
 * Send session authenticate request and get response on the
 * notification connection corresponding to the index \a i.
 * @param i notification connection index.
 * @param username login name for the agent
 * @param password password for the agent
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_na_b(int i, char *username, char *password)
{
  assert(username);
  assert(password);
  return b_mcAgentTCPSessionAuthenticate(&conn[i], username, password);
}

/**
 * Send session terminate request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_st_b(int i)
{
  return b_mcAgentTCPSessionTerminate(&conn[i]);
}

/**
 * Send session terminate request and get response on the
 * notification connection corresponding to the index \a i.
 * @param i notification connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_nt_b(int i)
{
  return b_mcAgentTCPSessionTerminate(&conn[i]);
}

/**
 * Send simco ping request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_ping_b(int i)
{
  return b_mcAgentTCPPing(&conn[i]);
}

/**
 * Send policy reserve rule request and get response on the
 * connection corresponding to the index \a i.
 * \a sp->lifetime has to be passed in \a sp. \a sp->ruleid,
 * \a sp->groupid, \a sp->lifetime, \a sp->outside_ip, \a sp->outside_port
 * will be returned on success.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_prr_b(int i, simcoPacket_t *sp)
{
  return b_mcAgentTCPPolicyReserveRule(&conn[i], sp);
}

/**
 * Send policy enable rule request and get response on the
 * connection corresponding to the index \a i.
 * \a sp->internal_ip, \a sp->internal_port, \a sp->external_ip,
 * \a sp->external_port, \a sp->lifetime have to be passed in \a sp.
 * \a sp->ruleid, \a sp->groupid, \a sp->lifetime, \a sp->outside_ip,
 * \a sp->outside_port will be returned on success.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_per_b(int i, simcoPacket_t *sp)
{
  return b_mcAgentTCPPolicyEnableRule(&conn[i], sp);
}

/**
 * Send PER after reservation request and get response on the
 * connection corresponding to the index \a i.
 * \a sp->ruleid, \a sp->internal_ip, \a sp->internal_port, \a sp->external_ip,
 * \a sp->external_port, \a sp->lifetime have to be passed in \a sp.
 * \a sp->ruleid, \a sp->groupid, \a sp->lifetime, \a sp->outside_ip,
 * \a sp->outside_port will be returned on success.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_pea_b(int i, simcoPacket_t *sp)
{
  return b_mcAgentTCPPERAfterReservation(&conn[i], sp);
}

/**
 * Send PBR after reservation request and get response on the
 * connection corresponding to the index \a i.
 * \a sp->ruleid, \a sp->internal_ip, \a sp->internal_port, \a sp->external_ip,
 * \a sp->external_port, \a sp->lifetime have to be passed in \a sp.
 * \a sp->ruleid, \a sp->groupid, \a sp->lifetime, \a sp->outside_ip,
 * \a sp->outside_port will be returned on success.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_pba_b(int i, simcoPacket_t *sp)
{
  return b_mcAgentTCPPBRAfterReservation(&conn[i], sp);
}

/**
 * Send policy rule lifetime change request and get response on the
 * connection corresponding to the index \a i.
 * \a sp->ruleid, \a sp->internal_ip, \a sp->internal_port, \a sp->external_ip,
 * \a sp->external_port, \a sp->lifetime have to be passed in \a sp.
 * \a sp->ruleid, \a sp->groupid, \a sp->lifetime, \a sp->outside_ip,
 * \a sp->outside_port will be returned on success.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_plc_b(int i, simcoPacket_t *sp)
{
  return b_mcAgentTCPPolicyRuleLifetimeChange(&conn[i], sp);
}

/**
 * Send policy rule status request and get response on the
 * connection corresponding to the index \a i.
 * \a sp->ruleid has to be passed in \a sp.
 * \a sp->ruleid, \a sp->groupid, \a sp->internal_ip, \a sp->internal_port,
 * \a sp->outside_ip, \a sp->outside_port, \a sp->external_ip, \a sp->external_port,
 * \a sp->lifetime will be returned on success.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_prs_b(int i, simcoPacket_t *sp)
{
  return b_mcAgentTCPPolicyRuleStatus(&conn[i], sp);
}

/**
 * Send policy rule list request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @param rules pointer to the rules array returned.
 * @param numrules pointer ot the number of rules returned
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_prl_b(int i, int **rules, int *numrules)
{
  return b_mcAgentTCPPolicyRuleList(&conn[i], rules, numrules);
}

/**
 * Read the notification sent by the server on the connection corresponding
 * to the index \a i.
 * \a np->ruleid, and \a np->lifetime will be set in an ARE notification
 * (notification code = 3).
 * @param i notification connection index.
 * @param np pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success, or notification code set by server.
 */
int simco_notif_read(int i, simcoPacket_t *np)
{
  return b_mcAgentTCPNotificationRead(&conn[i], np);
}


/**
 * Add the connection index \a i to pool of connections
 * the client will be listening for responses.
 * Required only if sending non-blocking requests on 
 * connection index \a i.
 * @param i connection index.
 */
void mc_add_con_to_pool(int i)
{
  conn[i].inpool = 1;
}

/**
 * Return the status of the last operation receive operation
 * on the connection index \a i.
 * Required only if sending non-blocking requests on
 * connection index \a i.
 * @param i connection index.
 */
int simco_get_error(int i)
{
  return conn[i].error;
}

/**
 * Remove the connection index \a i from pool of connections
 * the client will be listening for responses.
 * @param i connection index.
 */
void mc_rem_con_from_pool(int i)
{
  conn[i].inpool = 0;
}

/**
 * Send session establish request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_se_nb(int i)
{
  return nb_mcAgentTCPSessionEstablish(&conn[i]);
}

/**
 * Send session establish request and get response on the
 * notification connection corresponding to the index \a i.
 * @param i notification connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_ne_nb(int i)
{
  return nb_mcAgentTCPSessionEstablish(&conn[i]);
}

/**
 * Send session authenticate request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @param username login name for the agent
 * @param password password for the agent
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_sa_nb(int i, char *username, char *password)
{
  return nb_mcAgentTCPSessionAuthenticate(&conn[i], username, password);
}

/**
 * Send session authenticate request and get response on the
 * notification connection corresponding to the index \a i.
 * @param i notification connection index.
 * @param username login name for the agent
 * @param password password for the agent
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_na_nb(int i, char *username, char *password)
{
  assert(username);
  assert(password);
  return nb_mcAgentTCPSessionAuthenticate(&conn[i], username, password);
}

/**
 * Send session terminate request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_st_nb(int i)
{
  return nb_mcAgentTCPSessionTerminate(&conn[i]);
}

/**
 * Send session terminate request and get response on the
 * notification connection corresponding to the index \a i.
 * @param i notification connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_nt_nb(int i)
{
  return nb_mcAgentTCPSessionTerminate(&conn[i]);
}

/**
 * Send simco ping request and get response on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @return -1 if communication failed, 0 on success, or error code set by server.
 */
int simco_ping_nb(int i)
{
  return nb_mcAgentTCPPing(&conn[i]);
}

/**
 * Send policy reserve rule request on the
 * connection corresponding to the index \a i.
 * \a sp->lifetime has to be passed in \a sp.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success.
 */
int simco_prr_nb(int i, simcoPacket_t *sp)
{
  return nb_mcAgentTCPPolicyReserveRule(&conn[i], sp);
}

/**
 * Send policy enable rule request on the
 * connection corresponding to the index \a i.
 * \a sp->internal_ip, \a sp->internal_port, \a sp->external_ip,
 * \a sp->external_port, \a sp->lifetime have to be passed in \a sp.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success.
 */
int simco_per_nb(int i, simcoPacket_t *sp)
{
  return nb_mcAgentTCPPolicyEnableRule(&conn[i], sp);
}

/**
 * Send PER after reservation request on the
 * connection corresponding to the index \a i.
 * \a sp->ruleid, \a sp->internal_ip, \a sp->internal_port, \a sp->external_ip,
 * \a sp->external_port, \a sp->lifetime have to be passed in \a sp.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success.
 */
int simco_pea_nb(int i, simcoPacket_t *sp)
{
  return nb_mcAgentTCPPERAfterReservation(&conn[i], sp);
}

/**
 * Send PBR after reservation request on the
 * connection corresponding to the index \a i.
 * \a sp->ruleid, \a sp->internal_ip, \a sp->internal_port, \a sp->external_ip,
 * \a sp->external_port, \a sp->lifetime have to be passed in \a sp.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success.
 */
int simco_pba_nb(int i, simcoPacket_t *sp)
{
  return nb_mcAgentTCPPBRAfterReservation(&conn[i], sp);
}

/**
 * Send policy rule lifetime change request on the
 * connection corresponding to the index \a i.
 * \a sp->ruleid, \a sp->internal_ip, \a sp->internal_port, \a sp->external_ip,
 * \a sp->external_port, \a sp->lifetime have to be passed in \a sp.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success.
 */
int simco_plc_nb(int i, simcoPacket_t *sp)
{
  return nb_mcAgentTCPPolicyRuleLifetimeChange(&conn[i], sp);
}

/**
 * Send policy rule status request on the
 * connection corresponding to the index \a i.
 * \a sp->ruleid has to be passed in \a sp.
 * @param i connection index.
 * @param sp pointer to the simco packet structure.
 * @return -1 if communication failed, 0 on success.
 */
int simco_prs_nb(int i, simcoPacket_t *sp)
{
  return nb_mcAgentTCPPolicyRuleStatus(&conn[i], sp);
}

/**
 * Send policy rule list request on the
 * connection corresponding to the index \a i.
 * @param i connection index.
 * @return -1 if communication failed, 0 on success.
 */
int simco_prl_nb(int i)
{
  return nb_mcAgentTCPPolicyRuleList(&conn[i]);
}

