/* arequipa.c - AREQUIPA support functions */
 
/* Written 1996,1997 by Jean-Michel Pittet and Werner Almesberger, EPFL-LRC */


#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/arequipa.h>
#include <linux/atm.h>
#include <linux/atmclip.h>

#include "atmsap.h"
#include "arequipa.h"


#include <stdio.h>
static int arequipa_attach(int upper,int lower)
{
    if (ioctl(lower,AREQUIPA_PRESET,upper) < 0) {
	(void) close(lower);
	return -1;
    }
    (void) close(lower);
    return 0;
}


static void adjust_qos(const struct atm_qos *in,struct atm_qos *out)
{
    *out = *in;
    if (!out->txtp.max_sdu) out->txtp.max_sdu = RFC1626_MTU+RFC1483LLC_LEN;
    if (!out->rxtp.max_sdu) out->rxtp.max_sdu = RFC1626_MTU+RFC1483LLC_LEN;
    out->aal = ATM_AAL5;
}


int arequipa_preset(int sd,const struct sockaddr_atmsvc *addr,
  const struct atm_qos *qos)
{
    struct sockaddr_atmsvc a;
    struct atm_qos q;
    int s;

    if ((s = socket(addr->sas_family,SOCK_DGRAM,0)) < 0) return -1;
    adjust_qos(qos,&q);
    if (setsockopt(s,SOL_ATM,SO_ATMQOS,&q,sizeof(q)) < 0) {
	(void) close(s);
	return -1;
    }
    a = *addr;
    if (a.sas_family == AF_ATMSVC) {
	struct atm_sap sap;

	sap.bhli.hl_type = ATM_HL_VENDOR;
	sap.bhli.hl_length = 7;
	memcpy(sap.bhli.hl_info,AREQUIPA_HLT_VS_ID,7);
	sap.blli[0].l2_proto = ATM_L2_ISO8802;
	sap.blli[0].l3_proto = ATM_L3_NONE;
	if (setsockopt(s,SOL_ATM,SO_ATMSAP,&sap,sizeof(sap)) < 0) {
	    (void) close(s);
	    return -1;
	}
    }
    if (connect(s,(struct sockaddr *) &a,a.sas_family == AF_ATMSVC ? sizeof(a)
      : sizeof(struct sockaddr_atmpvc)) < 0) {
	(void) close (s);
	return -1;
    }
    return arequipa_attach(sd,s);
}


int arequipa_expect(int sd,int on)
{
    return ioctl(sd,AREQUIPA_EXPECT,on);
}


#ifdef AREQUIPA_RENEGOTIATE

int arequipa_renegotiate(int sd,const struct atm_qos *qos)
{
    struct atm_qos q;

    adjust_qos(qos,&q);
    return ioctl(sd,AREQUIPA_RENEGOTIATE,&q);
}

#endif


int arequipa_close(int sd)
{
    if (ioctl(sd,AREQUIPA_CLOSE,0) < 0) return -1;
    return ioctl(sd,AREQUIPA_SYNCREQ,0);
    
}
