OpenSS7
SS7 for the
Common Man

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified:

Home Overview Status News Documentation Resources About
   
 Overview
 Status
 News
 Documentation
 Resources
 About

   
Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/daemons/isupmon/isupmon.cpp


File /code/strss7/daemons/isupmon/isupmon.cpp


#ident "@(#) $Id: isupmon.cpp,v 0.8 2003/07/24 20:38:38 brian Exp $"

static char const ident[] = "$Id: isupmon.cpp,v 0.8 2003/07/24 20:38:38 brian Exp $";

extern "C" {
#	include <unistd.h>
#	include <sys/types.h>
#	include <sys/stat.h>
#	include <fcntl.h>
#	include <sys/ioctl.h>
#	include <sys/poll.h>
#	include <errno.h>
#	include <string.h>
#	include <stdio.h>
#	include <signal.h>
#	include <sys/time.h>
#	include <ss7/lmi.h>
#	include <ss7/lmi_ioctl.h>
#	include <ss7/sdti.h>
#	include <ss7/sdti_ioctl.h>
};

#include <iostream>

#pragma implementation
#include "isupmon.hh"

#define complain(__error) \
	do { \
		UnixError e(__PRETTY_FUNCTION__, __error); \
		return; \
	} while (0)

#define throwerr(__error) \
	do { \
		throw UnixError(__PRETTY_FUNCTION__, __error); \
	} while (0)

//  --------------------------------------------------------------------------
//
//  UnixError
//
//  --------------------------------------------------------------------------

UnixError::UnixError(const char *function, int error)
{
	const char *errstr;
	// print to stderr or syslog on construction
	// don't need these attributes then
	if (error < 0) {
		errstr = strerror(-error);
	} else {
		switch (error) {
		case LMI_UNSPEC:
			errstr = "Unknown or unspecified";
			break;
		case LMI_BADADDRESS:
			errstr = "Address was invalid";
			break;
		case LMI_BADADDRTYPE:
			errstr = "Invalid address type";
			break;
		case LMI_BADDIAL:
			errstr = "(not used)";
			break;
		case LMI_BADDIALTYPE:
			errstr = "(not used)";
			break;
		case LMI_BADDISPOSAL:
			errstr = "Invalid disposal parameter";
			break;
		case LMI_BADFRAME:
			errstr = "Defective SDU received";
			break;
		case LMI_BADPPA:
			errstr = "Invalid PPA identifier";
			break;
		case LMI_BADPRIM:
			errstr = "Unregognized primitive";
			break;
		case LMI_DISC:
			errstr = "Disconnected";
			break;
		case LMI_EVENT:
			errstr = "Protocol-specific event ocurred";
			break;
		case LMI_FATALERR:
			errstr = "Device has become unusable";
			break;
		case LMI_INITFAILED:
			errstr = "Link initialization failed";
			break;
		case LMI_NOTSUPP:
			errstr = "Primitive not supported by this device";
			break;
		case LMI_OUTSTATE:
			errstr = "Primitive was issued from invalid state";
			break;
		case LMI_PROTOSHORT:
			errstr = "M_PROTO block too short";
			break;
		case LMI_SYSERR:
			errstr = "UNIX system error";
			break;
		case LMI_WRITEFAIL:
			errstr = "Unitdata request failed";
			break;
		case LMI_CRCERR:
			errstr = "CRC or FCS error";
			break;
		case LMI_DLE_EOT:
			errstr = "DLE EOT detected";
			break;
		case LMI_FORMAT:
			errstr = "Format error detected";
			break;
		case LMI_HDLC_ABORT:
			errstr = "Aborted frame detected";
			break;
		case LMI_OVERRUN:
			errstr = "Input overrun";
			break;
		case LMI_TOOSHORT:
			errstr = "Frame too short";
			break;
		case LMI_INCOMPLETE:
			errstr = "Partial frame received";
			break;
		case LMI_BUSY:
			errstr = "Telephone was busy";
			break;
		case LMI_NOANSWER:
			errstr = "Connection went unanswered";
			break;
		case LMI_CALLREJECT:
			errstr = "Connection rejected";
			break;
		case LMI_HDLC_IDLE:
			errstr = "HDLC line went idle";
			break;
		case LMI_HDLC_NOTIDLE:
			errstr = "HDLC link no longer idle";
			break;
		case LMI_QUIESCENT:
			errstr = "Line being reassigned";
			break;
		case LMI_RESUMED:
			errstr = "Line has been reassigned";
			break;
		case LMI_DSRTIMEOUT:
			errstr = "Did not see DSR in time";
			break;
		case LMI_LAN_COLLISIONS:
			errstr = "LAN excessive collisions";
			break;
		case LMI_LAN_REFUSED:
			errstr = "LAN message refused";
			break;
		case LMI_LAN_NOSTATION:
			errstr = "LAN no such station";
			break;
		case LMI_LOSTCTS:
			errstr = "Lost Clear to Send signal";
			break;
		case LMI_DEVERR:
			errstr = "Start of device-specific error codes";
			break;
		default:
			errstr = "(unknown)";
			break;
		}
	}
	cerr.form("%s: %s\n", function, errstr);
}

//  --------------------------------------------------------------------------
//
//  Pollable
//
//  --------------------------------------------------------------------------

static int Pollable::npfd = 0;
static struct pollfd Pollable::pfd[] = { {0, 0, 0}, };

static Pollable *Pollable::list = NULL;

static void Pollable::poll_recalc(Pollable * p)
{
	if (p) {
		int fd = p->pfdp->fd;
		int events = p->pfdp->events;
		int revents = p->pfd->revents;
		poll_recalc(p->next);
		p->pfdp = &pfd[npfd++];
		p->pfdp->fd = fd;
		p->pfdp->events = events;
		p->pfdp->revents = revents;
	} else {
		npfd = 0;
	}
}

Pollable::Pollable(const char *fname)
{
	int fd;
	pfdp = NULL;
	if (npfd >= MAXPOLL)
		throwerr(-ENFILE);
	fd = this->poll_open();	// throws UnixError on failure
	// add ourselves to end of list
	pfdp = &pfd[npfd++];
	pfdp->fd = ret;
	pfdp->events = POLLIN | POLLPRI;
	pfdp->revents = 0;
	// put ourselves on the master list
	if ((next = list))
		next->prev = &next;
	list = this;
	prev = &list;
}

Pollable::~Pollable(void)
{
	// remove from master list
	if ((*prev = next))
		next->prev = prev;
	next = NULL;
	prev = &next;
	if (pfdp) {
		// close fd
		this->poll_close(pfdp->fd);
		pfdp->fd = 0;
		pfdp->events = 0;
		pfdp->revents = 0;
		// collapse poll fd list
		poll_recalc(list);
	}
}

static void Pollable::poll_loop(int wait)
{
	int ret, i;
	// run the poll on all pollables
	while (npfd) {
		if (timer_timeout) {
			timer_timeout = 0;
			// process timeout
		}
		if ((ret = poll(pfd, npfd, wait)) >= 0) {
			for (i = 0; i < npfd && ret > 0; i++) {
				if (pfd[i].revents & pfd[i].events) {
					this->poll_event();	// process event
					ret--;
				}
			}
		} else {
			// should at least display error
		}
	}
}

//  --------------------------------------------------------------------------
//
//  Buffer
//
//  --------------------------------------------------------------------------

StreamBuffer::StreamBuffer(SignallingTerminal & st)
:  sigTerm(st)
{
	ctrl.buf = cbuf;
	ctrl.maxlen = BUFSIZE;
	ctrl.len = 0;
	data.buf = dbuf;
	data.maxlen = BUFSIZE;
	data.len = 0;
}
StreamBuffer::~StreamBuffer(void)
{
}

RxStreamBuffer::RxStreamBuffer(SignallingTerminal & st)
:  StreamBuffer(st)
{
	int type, ret, flags = 0;
	if ((ret = getmsg(st.pfdp->fd, &ctrl, &data, &flags)) < 0)
		throw UnixError(__PRETTY_FUNCTION__, -errno);
	if (ctrl.len > 0) {
		st.primitive(this);
		return;
	}
	if (data.len > 0) {
		st.message(this);
		return;
	}
	throw UnixError(__PRETTY_FUNCTION__, -EPROTO);
}

RxStreamBuffer::~RxStreamBuffer(void)
{
}

TxStreamBuffer::TxStreamBuffer(ulong csize = 0, ulong dsize = 0)
:StreamBuffer(st)
{
	if (csize > BUFSIZE || dsize > BUFSIZE)
		throw UnixError(__PRETTY_FUNCTION__, -EFAULT);
	ctrl.len = csize;
	data.len = dsize;
}
TxStreamBuffer::~TxStreamBuffer(void)
{
}
TxStreamBuffer::send(void)
{
	int ret;
	if ((ret = putmsg(st.pfdp->fd, ctrl.len ? &ctrl : NULL, data.len ? &data : NULL, flags)) < 0)
		throw UnixError(__PRETTY_FUNCTION__, -errno);
}

//  --------------------------------------------------------------------------
//
//  SignallingTerminal
//
//  --------------------------------------------------------------------------

SignallingTerminal::SignallingTerminal(const char *devname, ulong ppa, Collector * c)
:Pollable(devname), state(LMI_UNUSABLE), collector(c)
{
	int ret;
	union LMI_primitives *p = (typeof(p)) cbuf;
	union SDT_primitives *s = (typeof(s)) cbuf;
	// always place in master list
	if ((next = list))
		next->prev = &next;
	list = this;
	prev = &list;
	if (!pfdp)
		goto efault;
	if (!pfdp->fd)
		goto ebadf;
	ctrl.maxlen = BUFSIZE;
	ctrl.buf = cbuf;
	ctrl.len = sizeof(p->info_req);
	p->lmi_primitive = LMI_INFO_REQ;
	if ((ret = putmsg(pfdp->fd, &ctrl, NULL, RS_HIPRI)) < 0)
		goto error;
	state = LMI_UNUSABLE;
	this->poll_loop();
	if (state == LMI_UNUSABLE)
		goto eproto;
	if (style == LMI_STYLE1)
		goto enable;
	ctrl.len = sizeof(p->attach_req) + sizeof(ulong);
	p->lmi_primitive = LMI_ATTACH_REQ;
	*(ulong *) p->attach_req.lmi_ppa = ppa;
	if ((ret = putmsg(pfdp->fd, &ctrl, NULL, RS_HIPRI)) < 0)
		goto error;
	state = LMI_ATTACH_PENDING;
	this->poll_loop();
	if (state != LMI_DISABLED)
		goto eproto;
      enable:
	ctrl.len = sizeof(p->enable_req);
	p->lmi_primitive = LMI_ENABLE_REQ;
	if ((ret = putmsg(pfdp->fd, &ctrl, NULL, RS_HIPRI)) < 0)
		goto error;
	state = LMI_ENABLE_PENDING;
	this->poll_loop();
	if (state != LMI_ENABLED)
		goto eproto;
	ctrl.len = sizeof(s->daedr_start_req);
	s->sdt_primitive = SDT_DAEDR_START_REQ;
	if ((ret = putmsg(pfdp->fd, &ctrl, NULL, RS_HIPRI)) < 0)
		goto error;
	return;
      efault:
	errno = EFAULT;
	goto error;
      ebadf:
	errno = EBADF;
	goto error;
      eproto:
	errno = EPROTO;
	goto error;
      error:
	throwerr(-errno);
}

SignallingTerminal::~SignallingTerminal(void)
{
	int ret;
	union LMI_primitives *p = (typeof(p)) cbuf;
	// always remove from master list
	if ((*prev = next))
		next->prev = prev;
	next = NULL;
	prev = &next;
	if (!pfdp)
		goto efault;
	if (!pfdp->fd)
		goto ebadf;
	ctrl.maxlen = BUFSIZE;
	ctrl.buf = cbuf;
	switch (state) {
	case LMI_ENABLED:
	case LMI_ENABLE_PENDING:
		ctrl.len = sizeof(p->disable_req);
		p->lmi_primitive = LMI_DISABLE_REQ;
		if ((ret = putmsg(pfdp->fd, &ctrl, NULL, RS_HIPRI)) < 0)
			goto error;
		state = LMI_DISABLE_PENDING;
		this->poll_loop();
		if (state != LMI_DISABLED)
			goto eproto;
	case LMI_DISABLE_PENDING:
	case LMI_DISABLED:
	case LMI_ATTACH_PENDING:
		if (style == LMI_STYLE1)
			goto detached;
		ctrl.len = sizeof(p->detach_req);
		p->lmi_primitive = LMI_DETACH_REQ;
		if ((ret = putmsg(pfdp->fd, &ctrl, NULL, RS_HIPRI)) < 0)
			goto error;
		state = LMI_DETACH_PENDING;
		this->poll_loop();
		if (state != LMI_UNATTACHED)
			return;
	default:
	case LMI_DETACH_PENDING:
	case LMI_UNATTACHED:
	case LMI_UNUSABLE:
		break;
	}
	return;
      efault:
	errno = EFAULT;
	goto error;
      ebadf:
	errno = EBADF;
	goto error;
      eproto:
	errno = EPROTO;
	goto error;
      error:
	complain(-errno);
}

int SignallingTerminal::poll_open(void)
{
	int fd, ret;
	if ((ret = open(&name, O_NONBLOCK | O_RDWR)) < 0)
		goto error;
	fd = ret;
	if ((ret = ioctl(fd, I_SRDOPT, RMSGD)) < 0)
		goto error;
	if ((ret = ioctl(fd, I_SETCLTIME, 0)) < 0)
		goto error;
	state = LMI_UNATTACHED;
	return (fd);
      error:
	throwerr(-errno);
}

SignallingTerminal::poll_close(int fd)
{
	ret;
	if ((ret = close(fd)) < 0)
		goto error;
	return;
      error:
	complain(-errno);
	return;
}

SignallingTerminal::poll_event(void)
{
	try {
		if (!(new RxStreamBuffer(*this)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
		return;
	}
	catch(UnixError e) {
		return;
	}
	catch(DecodeError e) {
		return;
	}
}

SignallingTerminal::primitive(StreamBuffer * buf)
{
	switch (*(ulong *) buf->ctrl.buf) {
	case SDT_RC_SIGNAL_UNIT_IND:
		message(buf);
		return;
	case SDT_RC_CONGESTION_ACCEPT_IND:
	case SDT_RC_CONGESTION_DISCARD_IND:
	case SDT_RC_NO_CONGESTION_IND:
	case SDT_IAC_CORRECT_SU_IND:
	case SDT_IAC_ABORT_PROVING_IND:
	case SDT_LSC_LINK_FAILURE_IND:
	case SDT_TXC_TRANSMISSION_REQUEST_IND:
		break;
	case LMI_INFO_ACK:
		state = l->info_ack.lmi_state;
		style = l->info_ack.lmi_style;
		max_sdu = l->info_ack.lmi_max_sdu;
		min_sdu = l->info_ack.lmi_min_sdu;
		hdr_len = l->info_ack.lmi_header_len;
		break;
	case LMI_OK_ACK:
		state = l->ok_ack.lmi_state;
		break;
	case LMI_ERROR_ACK:
		state = l->error_ack.lmi_state;
		if (l->error_ack.lmi_errno == LMI_SYSERR)
			complain(-l->error_ack.lmi_reason);
		else
			complain(l->error_ack.lmi_errno);
		break;
	case LMI_ENABLE_CON:
		state = l->enable_con.lmi_state;
		break;
	case LMI_DISABLE_CON:
		state = l->disable_con.lmi_state;
		break;
	case LMI_ERROR_IND:
		state = l->error_ack.lmi_state;
		// we should try to reinitialize the SDT
		if (l->error_ack.lmi_errno == LMI_SYSERR)
			complain(-l->error_ack.lmi_reason);
		else
			complain(l->error_ack.lmi_errno);
		break;
	case LMI_OPTMGMT_ACK:
	case LMI_STATS_IND:
	case LMI_EVENT_IND:
	default:
		// discard
		break;
	}
	delete buf;
	return;
}

SignallingTerminal::message(StreamBuffer * buf)
{
	if (buf->data.len < hdr_len)
		throw UnixError(__PRETTY_FUNCTION__, -EPROTO);
	buf->data.buf += hdr_len;	// pull header
	buf->data.len -= hdr_len;
	if (!(new RoutingLabel(collector, buf)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
}

SignallingTerminal::buffer(StreamBuffer * buf)
{
	if (buf->ctrl.len > 0)
		return primitive(buf);
	if (buf->data.len > 0)
		return message(buf);
	delete buf;
	return;
}

//  -------------------------------------------------------------------------
//
//  Parameter
//
//  -------------------------------------------------------------------------

Parameter::Parameter(Message & m):
msg(m), next(NULL), prev(&next)
{
}

Parameter::Parameter(Message & m, Parameter * &list):
msg(m), next(NULL), prev(&next)
{
	link(list);
}

Parameter::~Parameter(void)
{
	// unlink it when we destroy
	unlink();
}
Parameter::unlink(void)
{
	if (prev && prev != &next) {
		if ((*prev = next))
			next->prev = prev;
		next = NULL;
		prev = &next;
	}
}

Parameter::link(Parameter * &list)
{
	if ((next = list))
		next->prev = &next;
	list = next;
	prev = &list;
}

Parameter::print(iostream & str)
{
	int i;
	for (i = 0; i < len; i++)
		str.form(" %02X", ptr[i]);
}

inline void Parameter::unpack_zero(char *&p, uchar *e)
{
	ptr = p;
	val = 0;
	len = 0;
}
inline void Parameter::unpack_one(uchar *&p, uchar *e)
{
	if (p + 1 <= e) {
		ulong b;
		ptr = p;
		b = *p++ & 0x00ff;
		val = b;
		len = 1;
		return;
	}
	throw DecodeError();
}
inline void Parameter::unpack_two(uchar *&p, uchar *e)
{
	if (p + 2 <= e) {
		ulong b;
		ptr = p;
		b = *p++ & 0x00ff;
		val = b;
		b = *p++ & 0x00ff;
		val |= (b << 8);
		len = 2;
		return;
	}
	throw DecodeError();
}
inline void Parameter::unpack_three(uchar *&p, uchar *e)
{
	if (p + 3 <= e) {
		ulong b;
		ptr = p;
		b = *p++ & 0x00ff;
		val = b;
		b = *p++ & 0x00ff;
		val |= (b << 8);
		b = *p++ & 0x00ff;
		val |= (b << 16);
		len = 3;
		return;
	}
	throw DecodeError();
}
inline void Parameter::unpack_four(uchar *&p, uchar *e)
{
	if (p + 4 <= e) {
		ulong b;
		ptr = p;
		b = *p++ & 0x00ff;
		val = b;
		b = *p++ & 0x00ff;
		val |= (b << 8);
		b = *p++ & 0x00ff;
		val |= (b << 16);
		b = *p++ & 0x00ff;
		val |= (b << 24);
		len = 4;
		return;
	}
	throw DecodeError();
}
inline void Parameter::unpack_many(uchar *&p, uchar *e)
{
	unpack_four(p, e);
	len += e - p;
	p = e;
}
inline void Parameter::unpack_val(uchar *&p, uchar *e)
{
	if (p <= e) {
		switch ((len = e - p)) {
		case 0:
			return unpack_zero(p, e)
		case 1:
			return unpack_one(p, e)
		case 2:
			return unpack_two(p, e)
		case 3:
			return unpack_three(p, e)
		case 4:
			return unpack_four(p, e)
		default:
			return unpack_many(p, e)
		}
	}
	throw DecodeError();
}

// mandatory variable parameters are LV not TLV
inline void Parameter::unpack_mvar(char *&p, uchar *e)
{
	uchar *pp, *ep;
	if ((pp = pp + *p++) < e)	// pointer and length byte inside message
		if ((ep = pp + *pp++ + 1) <= e)	// value inside message
			return unpack_val(pp, ep);
	throw DecodeError();
}
inline void Parameter::unpack_pc(uchar *&p, uchar *e)
{
	switch (msg.pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		unpack_three(p, e)
		    break;
	default:
		unpack_two(p, e)
		    break;
	}
}
inline void Parameter::unpack_eop(uchar *&p, uchar *e)
{
	if (p < e) {
		v.len = 0;
		v.ptr = p;
		v.val = 0;
		p += 1;
		return;
	}
	throw DecodeError();
}

ParameterZero::ParameterZero(Message & m)
:  Parameter(m)
{
	unpack_zero(m.p, m.e);
}

ParameterZero::print(iostream & str)
{
	str.form(" (empty)");
}

ParameterOne::ParameterOne(Message & m)
:  Parameter(m)
{
	unpack_one(m.p, m.e);
}

ParameterOne::print(iostream & str)
{
	str.form(" 0x%02x");
}

ParameterTwo::ParameterTwo(Message & m)
:  Parameter(m)
{
	unpack_two(m.p, m.e);
}

ParameterTwo::print(iostream & str)
{
	str.form(" 0x%04x");
}

ParameterThree::ParameterThree(Message & m)
:  Parameter(m)
{
	unpack_three(m.p, m.e);
}

ParameterThree::print(iostream & str)
{
	str.form(" 0x%06x");
}

ParameterFour::ParameterFour(Message & m)
:  Parameter(m)
{
	uppack_four(m.p, m.e);
}

ParameterThree::print(iostream & str)
{
	str.form(" 0x%08x");
}

ParameterPc::ParameterPc(Message & m)
:  Parameter(m)
{
	unpack_pc(m.p, m.e);
}

ParameterPc::print(iostream & str)
{
	switch (msg.pvar) {
	case SS7_PVAR_ANSI:	
	case SS7_PVAR_JTTC:
	case SS7_PVAR_CHIN:
		str.form(" %u.%u.%u", ((val >> 16) & 0x00ff), ((val >> 8) & 0x00ff), ((val >> 0) & 0x00ff));
		break;
	case SS7_PVAR_ITUT:	/* 14-bit point codes */
	case SS7_PVAR_ETSI:
	case SS7_PVAR_SING:
	case SS7_PVAR_SPAN:
		str.form(" %u.%u.%u", ((val >> 10) & 0x000f), ((val >> 4) & 0x003f), ((val >> 0) & 0x000f));
		break;
	default:
		str.form(" 0x%08x", val);
		break;
	}
}

ParameterVar::Parameter(Message & m)
:  Parameter(m)
{
	unpack_mvar(m.p, m.e);
}

ParameterVar::print(iostream & str)
{
	switch (len) {
	case 0:
		str.form(" (empty)");
		break;
	case 1:
		str.form(" 0x%02x", val & 0x00ff);
		break;
	case 2:
		str.form(" 0x%04x", val & 0x00ffff);
		break;
	case 3:
		str.form(" 0x%06x", val & 0x00ffffff);
		break;
	case 4:
		str.form(" 0x%08x", val);
		break;
	default:
	{
		int i;
		for (i = 0; i < len; i++)
			str.form(" %02X", ptr[i]);
	}
		break;
	}
}

// 0x00 - 0b00000000 - End of optional parameters
ParameterEOP::ParameterEOP(Message & m):
ParameterOne(m), tag(ISUP_PT_EOP)
{
}

ParameterEOP::print(iostream & str)
{
	str.form("\n\t\tParameter-End-Of-Optional-Parameters:");
	ParameterOne::print(str);
}

// 0x01 - 0b00000001 - Call reference @
ParameterCLRF::ParameterCLRF(Message & m):
ParameterVar(m), tag(ISUP_PT_CLRF)
{
}

ParameterCLRF::print(iostream & str)
{
	str.form("\n\t\tParameter-Call-Reference:");
	ParameterVar::print(str);
}

// 0x02 - 0b00000010 - Transmission medium requirement
ParameterTMR::ParameterTMR(Message & m):
ParameterOne(m), tag(ISUP_PT_TMR)
{
}

ParameterTMR::print(iostream & str)
{
	str.form("\n\t\tParameter-Transmission-Medium-Requirement:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x03 - 0b00000011 - Access transport
ParameterATP::ParameterATP(Message & m):
ParameterVar(m), tag(ISUP_PT_ATP)
{
}

ParameterATP::print(iostream & str)
{
	int i;
	str.form("\n\t\tParameter-Access-Transport:");
	// FIXME: break out this parameter
	for (i = 0; i < len; i++)
		str.form(" %02X", ptr[i]);
}

// 0x04 - 0b00000100 - Called party number
ParameterCDPN::ParameterCDPN(Message & m):
ParameterVar(m), tag(ISUP_PT_CDPN)
{
}

ParameterCDPN::print(iostream & str)
{
	str.form("\n\t\tParameter-Called-Party-Number:");
	ParameterVar::print(str);
}

// 0x05 - 0b00000101 - Subsequent number
ParameterSUBN::ParameterSUBN(Message & m):
ParameterVar(m), tag(ISUP_PT_SUBN)
{
}

ParameterSUBN::print(iostream & str)
{
	str.form("\n\t\tParameter-Subsequent-Number:");
	ParameterVar::print(str);
}

// 0x06 - 0b00000110 - Nature of connection indicators
ParameterNCI::ParameterNCI(Message & m):
ParameterOne(m), tag(ISUP_PT_NCI)
{
}

ParameterNCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Nature-of-Connection-Indicators:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x07 - 0b00000111 - Forward call indicators
ParameterFCI::ParameterFCI(Message & m):
ParameterTwo(m), tag(ISUP_PT_FCI)
{
}

ParameterFCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Forward-Call-Indicators:");
	switch (val) {
	default:
		ParameterTwo::print(str);
	}
}

// 0x08 - 0b00001000 - Optional forward call indicators
ParameterOFCI::ParameterOFCI(Message & m):
ParameterVar(m), tag(ISUP_PT_OFCI)
{
}

ParameterOFCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Optional-Forward-Call-Indicators:");
	ParameterVar::print(str);
}

// 0x09 - 0b00001001 - Calling party's category
ParameterCPC::ParameterCPC(Message & m):
ParameterOne(m), tag(ISUP_PT_CPC)
{
}

ParameterCPC::print(iostream & str)
{
	str.form("\n\t\tParameter-Calling-Party-Category:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x0a - 0b00001010 - Calling party number
ParameterCGPN::ParameterCGPN(Message & m):
ParameterVar(m), tag(ISUP_PT_CGPN)
{
}

ParameterCGPN::print(iostream & str)
{
	str.form("\n\t\tParameter-Calling-Party-Number:");
	ParameterVar::print(str);
}

// 0x0b - 0b00001011 - Redirecting number
ParameterRDGN::ParameterRDGN(Message & m):
ParameterVar(m), tag(ISUP_PT_RDGN)
{
}

ParameterRDGN::print(iostream & str)
{
	str.form("\n\t\tParameter-Redirecting-Number:");
	ParameterVar::print(str);
}

// 0x0c - 0b00001100 - Redirection number
ParameterRDNN::ParameterRDNN(Message & m):
ParameterVar(m), tag(ISUP_PT_RDNN)
{
}

ParameterRDNN::print(iostream & str)
{
	str.form("\n\t\tParameter-Redirection-Number:");
	ParameterVar::print(str);
}

// 0x0d - 0b00001101 - Connection request
ParameterCONR::ParameterCONR(Message & m):
ParameterVar(m), tag(ISUP_PT_CONR)
{
}

ParameterCONR::print(iostream & str)
{
	str.form("\n\t\tParameter-Connection-Request:");
	ParameterVar::print(str);
}

// 0x0e - 0b00001110 - Information request indicators
ParameterINRI::ParameterINRI(Message & m):
ParameterOne(m), tag(ISUP_PT_INRI)
{
}

ParameterINRI::print(iostream & str)
{
	str.form("\n\t\tParameter-Information-Request-Indicators:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x0f - 0b00001111 - Information indicators @
ParameterINFI::ParameterINFI(Message & m):
ParameterOne(m), tag(ISUP_PT_INFI)
{
}

ParameterINFI::print(iostream & str)
{
	str.form("\n\t\tParameter-Information-Indicators:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x10 - 0b00010000 - Continuity indicators
ParameterCOTI::ParameterCOTI(Message & m):
ParameterTwo(m), tag(ISUP_PT_COTI)
{
}

ParameterCOTI::print(iostream & str)
{
	str.form("\n\t\tParameter-Continuity-Indicators:");
	switch (val) {
	default:
		ParameterTwo::print(str);
	}
}

// 0x11 - 0b00010001 - Backward call indicators
ParameterBCI::ParameterBCI(Message & m):
ParameterTwo(m), tag(ISUP_PT_BCI)
{
}

ParameterBCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Backward-Call-Indicators:");
	switch (val) {
	default:
		ParameterTwo::print(str);
	}
}

// 0x12 - 0b00010010 - Cause indicators
ParameterCAUS::ParameterCAUS(Message & m):
ParameterVar(m), tag(ISUP_PT_CAUS)
{
}

ParameterCAUS::print(iostream & str)
{
	str.form("\n\t\tParameter-Cause-Indicators:");
	ParameterVar::print(str);
}

// 0x13 - 0b00010011 - Redirection information
ParameterRDI::ParameterRDI(Message & m):
ParameterTwo(m), tag(ISUP_PT_RDI)
{
}

ParameterRDI::print(iostream & str)
{
	str.form("\n\t\tParameter-Redirection-Information:");
	switch (val) {
	case 1:
		str.form(" (1) Unallocated (unassigned) number");
		break;
	case 2:
		str.form(" (2) No route to specified transit newtork");
		break;
	case 3:
		str.form(" (3) No route to destination");
		break;
	case 4:
		str.form(" (4) Send special information tone");
		break;
	case 5:
		str.form(" (5) Misdialled trunk prefix");
		break;
	case 8:
		str.form(" (8) Premption");
		break;
	case 9:
		str.form(" (9) Premption - circuit reserved for reuse");
		break;
	case 16:
		str.form(" (16) Normal call clearing");
		break;
	case 17:
		str.form(" (17) User busy");
		break;
	case 18:
		str.form(" (18) No user repsonding");
		break;
	case 19:
		str.form(" (19) No answer from user (user alerted)");
		break;
	case 20:
		str.form(" (20) Subscriber absent");
		break;
	case 21:
		str.form(" (21) Call rejected");
		break;
	case 22:
		str.form(" (22) Number changed");
		break;
	case 23:
		str.form(" (23) Redirect to new destination");
		break;
	case 27:
		str.form(" (27) Destination out of order");
		break;
	case 28:
		str.form(" (28) Invalid number format (address incomplete)");
		break;
	case 29:
		str.form(" (29) Facility rejected");
		break;
	case 31:
		str.form(" (31) Normal, unspecified");
		break;
	case 34:
		str.form(" (34) No circuit channel available");
		break;
	case 38:
		str.form(" (38) Network out of order");
		break;
	case 41:
		str.form(" (41) Temporary failure");
		break;
	case 42:
		str.form(" (42) Switching equipment congestion");
		break;
	case 43:
		str.form(" (43) Access information discarded");
		break;
	case 44:
		str.form(" (44) Requested circuit/channel no available");
		break;
	case 46:
		str.form(" (46) Precedence call blocked");
		break;
	case 47:
		str.form(" (47) Resource unavailable, unspecified");
		break;
	case 50:
		str.form(" (50) Requested facility not subscribed");
		break;
	case 53:
		str.form(" (53) Outgoing calls barred within CUG");
		break;
	case 55:
		str.form(" (55) Incoming calls barred within CUG");
		break;
	case 57:
		str.form(" (57) Bearer capability not authorized");
		break;
	case 58:
		str.form(" (58) Bearer capability not presently available");
		break;
	case 62:
		str.form(" (62) Inconsistency in designated outgoing access information and subscriber class");
		break;
	case 63:
		str.form(" (63) Service or option not available, unspecified");
		break;
	case 65:
		str.form(" (65) Bearer capability not implemented");
		break;
	case 69:
		str.form(" (69) Requested facility not implemented");
		break;
	case 70:
		str.form(" (70) Only restricted digital information bearer capability is available");
		break;
	case 79:
		str.form(" (79) Service or option not implemented, unspecified");
		break;
	case 87:
		str.form(" (87) User not member of CUG");
		break;
	case 88:
		str.form(" (88) Incompatible destination");
		break;
	case 90:
		str.form(" (90) Non-existent CUG");
		break;
	case 91:
		str.form(" (91) Invalid transit network selection");
		break;
	case 95:
		str.form(" (95) Invalid message, unspecified");
		break;
	case 97:
		str.form(" (97) Message type non-existent or not implemented");
		break;
	case 99:
		str.form(" (99) Information element/Parameter non-existent or not implemented");
		break;
	case 102:
		str.form(" (102) Recover on timer expiry");
		break;
	case 103:
		str.form(" (103) Parameter non-existent or not implemented");
		break;
	case 110:
		str.form(" (110) Message with unrecognized parameter discarded");
		break;
	case 111:
		str.form(" (111) Protoocol error, unspecified");
		break;
	case 127:
		str.form(" (127) Interworking, unspecified");
		break;
	case 23:
		str.form(" (23) Unallocated destination number");
		break;
	case 24:
		str.form(" (24) Unknown business group");
		break;
	case 25:
		str.form(" (25) Exchange routing error");
		break;
	case 26:
		str.form(" (26) Misrouted call to a ported number");
		break;
	case 27:
		str.form(" (27) Number portability Query on Release (QoR) number not found");
		break;
	case 45:
		str.form(" (45) Preemption");
		break;
	case 46:
		str.form(" (46) Precedence call blocked");
		break;
	case 51:
		str.form(" (51) Call type incompatible with service request");
		break;
	case 54:
		str.form(" (54) Call blocked due to group restrictions");
		break;
	default:
		ParameterTwo::print(str);
	}
}

// 0x15 - 0b00010101 - Circuit group supervision msg type ind
ParameterCGI::ParameterCGI(Message & m):
ParameterOne(m), tag(ISUP_PT_CGI)
{
}

ParameterCGI::print(iostream & str)
{
	str.form("\n\t\tParameter-Circuit-Group-Supervision-Message-Type-Indicator:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x16 - 0b00010110 - Range and status
ParameterRS::ParameterRS(Message & m):
ParameterVar(m), tag(ISUP_PT_RS)
{
}

ParameterRS::print(iostream & str)
{
	str.form("\n\t\tParameter-Range-and-Status:");
	ParameterVar::print(str);
}

// 0x17 - 0b00010111 - Call modification indicators (Blue Book)
ParameterCMI::ParameterCMI(Message & m):
ParameterOne(m), tag(ISUP_PT_CMI)
{
}

ParameterCMI::print(iostream & str)
{
	str.form("\n\t\tParameter-Call-Modification-Indicators:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x18 - 0b00011000 - Facility indicator
ParameterFACI::ParameterFACI(Message & m):
ParameterOne(m), tag(ISUP_PT_FACI)
{
}

ParameterFACI::print(iostream & str)
{
	str.form("\n\t\tParameter-Facility-Indicator:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x19 - 0b00011001 - Facility information indicators (Bcore)
ParameterFAII::ParameterFAII(Message & m):
ParameterOne(m), tag(ISUP_PT_FAII)
{
}

ParameterFAII::print(iostream & str)
{
	str.form("\n\t\tParameter-Facility-Information-Indicators:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x1a - 0b00011010 - Closed user group interlock code
ParameterCUGI::ParameterCUGI(Message & m):
ParameterVar(m), tag(ISUP_PT_CUGI)
{
}

ParameterCUGI::print(iostream & str)
{
	str.form("\n\t\tParameter-Closed-User-Group-Interlock-Code:");
	ParameterVar::print(str);
}

// 0x1b - 0b00011011 - Index (Bellcore)
ParameterINDEX::ParameterINDEX(Message & m):
ParameterFour(m), tag(ISUP_PT_INDEX)
{
}

ParameterINDEX::print(iostream & str)
{
	str.form("\n\t\tParameter-Index:");
	switch (val) {
	default:
		str.form(" 0x%08x", (uint32_t) val);
	}
}

// 0x1d - 0b00011101 - User service information
ParameterUSI::ParameterUSI(Message & m):
ParameterVar(m), tag(ISUP_PT_USI)
{
}

ParameterUSI::print(iostream & str)
{
	str.form("\n\t\tParameter-User-Service-Information:");
	ParameterVar::print(str);
}

// 0x1e - 0b00011110 - Signalling point code @ (Bellcore)
ParameterSPC::ParameterSPC(Message & m):
ParameterPc(m), tag(ISUP_PT_SPC)
{
}

ParameterSPC::print(iostream & str)
{
	str.form("\n\t\tParameter-Signalling-Point-Code:");
	ParameterPc::print(str);
}

// 0x20 - 0b00100000 - User to user information
ParameterUUI::ParameterUUI(Message & m):
ParameterVar(m), tag(ISUP_PT_UUI)
{
}

ParameterUUI::print(iostream & str)
{
	str.form("\n\t\tParameter-User-to-User-Information:");
	ParameterVar::print(str);
}

// 0x21 - 0b00100001 - Connected number
ParameterCONN::ParameterCONN(Message & m):
ParameterVar(m), tag(ISUP_PT_CONN)
{
}

ParameterCONN::print(iostream & str)
{
	str.form("\n\t\tParameter-Connected-Number:");
	ParameterVar::print(str);
}

// 0x22 - 0b00100010 - Suspend/resume indicators
ParameterSRIS::ParameterSRIS(Message & m):
ParameterOne(m), tag(ISUP_PT_SRIS)
{
}

ParameterSRIS::print(iostream & str)
{
	str.form("\n\t\tParameter-Suspend-Resume-Indicators:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x23 - 0b00100011 - Transit network selection @
ParameterTNS::ParameterTNS(Message & m):
ParameterVar(m), tag(ISUP_PT_INS)
{
}

ParameterTNS::print(iostream & str)
{
	str.form("\n\t\tParameter-Transit-Network-Selection:");
	ParameterVar::print(str);
}

// 0x24 - 0b00100100 - Event information
ParameterEVNT::ParameterEVNT(Message & m):
ParameterOne(m), tag(ISUP_PT_EVNT)
{
}

ParameterEVNT::print(iostream & str)
{
	str.form("\n\t\tParameter-Event-Information:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x26 - 0b00100110 - Circuit state indicator @
ParameterCSI::ParameterCSI(Message & m):
ParameterVar(m), tag(ISUP_PT_CSI)
{
}

ParameterCSI::print(iostream & str)
{
	str.form("\n\t\tParameter-Circuit-State-Indicator:");
	ParameterVar::print(str);
}

// 0x27 - 0b00100111 - Automatic congestion level
ParameterACL::ParameterACL(Message & m):
ParameterOne(m), tag(ISUP_PT_ACL)
{
}

ParameterACL::print(iostream & str)
{
	str.form("\n\t\tParameter-Automatic-Congestion-Level:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x28 - 0b00101000 - Original called number
ParameterOCDN::ParameterOCDN(Message & m):
ParameterVar(m), tag(ISUP_PT_OCON)
{
}

ParameterOCDN::print(iostream & str)
{
	str.form("\n\t\tParameter-Original-Called-Number:");
	ParameterVar::print(str);
}

// 0x29 - 0b00101001 - Optional backward call indicators
ParameterOBCI::ParameterOBCI(Message & m):
ParameterVar(m), tag(ISUP_PT_OBCI)
{
}

ParameterOBCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Optional-Backward-Call-Indicators:");
	ParameterVar::print(str);
}

// 0x2a - 0b00101010 - User to user indicators
ParameterUUIND::ParameterUUIND(Message & m):
ParameterOne(m), tag(ISUP_PT_UUIND)
{
}

ParameterUUIND::print(iostream & str)
{
	str.form("\n\t\tParameter-User-to-User-Indicators:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x2b - 0b00101011 - Origination ISC point code
ParameterISPC::ParameterISPC(Message & m):
ParameterPc(m), tag(ISUP_PT_ISPC)
{
}

ParameterISPC::print(iostream & str)
{
	str.form("\n\t\tParameter-Origination-ISC-Point-Code:");
	ParameterPc::print(str);
}

// 0x2c - 0b00101100 - Generic notification
ParameterGNOT::ParameterGNOT(Message & m):
ParameterOne(m), tag(ISUP_PT_GNOT)
{
}

ParameterGNOT::print(iostream & str)
{
	str.form("\n\t\tParameter-Generic-Notification:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x2d - 0b00101101 - Call history information
ParameterCHI::ParameterCMI(Message & m):
ParameterTwo(m), tag(ISUP_PT_CMI)
{
}

ParameterCHI::print(iostream & str)
{
	str.form("\n\t\tParameter-Call-History-Information:");
	switch (val) {
	default:
		ParameterTwo::print(str);
	}
}

// 0x2e - 0b00101110 - Access delivery information
ParameterADI::ParameterADI(Message & m):
ParameterOne(m), tag(ISUP_PT_ADI)
{
}

ParameterADI::print(iostream & str)
{
	str.form("\n\t\tParameter-Access-Delivery-Information:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x2f - 0b00101111 - Network specific facilities @
ParameterNSF::ParameterNSF(Message & m):
ParameterVar(m), tag(ISUP_PT_NSF)
{
}

ParameterNSF::print(iostream & str)
{
	str.form("\n\t\tParameter-Network-Specific-Facilities:");
	ParameterVar::print(str);
}

// 0x30 - 0b00110000 - User service information prime
ParameterUSIP::ParameterUSIP(Message & m):
ParameterVar(m), tag(ISUP_PT_USIP)
{
}

ParameterUSIP::print(iostream & str)
{
	str.form("\n\t\tParameter-User-Service-Information-Prime:");
	ParameterVar::print(str);
}

// 0x31 - 0b00110001 - Propagation delay counter
ParameterPROP::ParameterRPOP(Message & m):
ParameterTwo(m), tag(ISUP_PT_RPOP)
{
}

ParameterPROP::print(iostream & str)
{
	str.form("\n\t\tParameter-Propagation-Delay-Counter:");
	switch (val) {
	default:
		ParameterTwo::print(str);
	}
}

// 0x32 - 0b00110010 - Remote operations @
ParameterROPS::ParameterROPS(Message & m):
ParameterVar(m), tag(ISUP_PT_ROPS)
{
}

ParameterROPS::print(iostream & str)
{
	str.form("\n\t\tParameter-Remote-Operations:");
	ParameterVar::print(str);
}

// 0x33 - 0b00110011 - Service activation @
ParameterSA::ParameterSA(Message & m):
ParameterVar(m), tag(ISUP_PT_SA)
{
}

ParameterSA::print(iostream & str)
{
	str.form("\n\t\tParameter-Service-Activation:");
	ParameterVar::print(str);
}

// 0x34 - 0b00110100 - User teleservice information
ParameterUTI::ParameterUTI(Message & m):
ParameterVar(m), tag(ISUP_PT_UTI)
{
}

ParameterUTI::print(iostream & str)
{
	str.form("\n\t\tParameter-User-Teleservice-Information:");
	ParameterVar::print(str);
}

// 0x35 - 0b00110101 - Transmission medium used
ParameterTMU::ParameterTMU(Message & m):
ParameterOne(m), tag(ISUP_PT_TMU)
{
}

ParameterTMU::print(iostream & str)
{
	str.form("\n\t\tParameter-Transmission-Medium-Used:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x36 - 0b00110110 - Call diversion information
ParameterCDI::ParameterCDI(Message & m):
ParameterOne(m), tag(ISUP_PT_CDI)
{
}

ParameterCDI::print(iostream & str)
{
	str.form("\n\t\tParameter-Call-Diversion-Information:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x37 - 0b00110111 - Echo control information
ParameterECI::ParameterECI(Message & m):
ParameterOne(m), tag(ISUP_PT_ECI)
{
}

ParameterECI::print(iostream & str)
{
	str.form("\n\t\tParameter-Echo-Control-Information:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x38 - 0b00111000 - Message compatibility information
ParameterMCI::ParameterMCI(Message & m):
ParameterOne(m), tag(ISUP_PT_MCI)
{
}

ParameterMCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Message-Compatibility-Information:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x39 - 0b00111001 - Parameter compatibility information
ParameterPCI::ParameterPCI(Message & m):
ParameterOne(m), tag(ISUP_PT_PCI)
{
}

ParameterPCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Parameter-Compatibility-Information:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x3a - 0b00111010 - MLPP preference
ParameterMLPP::ParameterMLPP(Message & m):
ParameterOne(m), tag(ISUP_PT_MLPP)
{
}

ParameterMLPP::print(iostream & str)
{
	str.form("\n\t\tParameter-MLPP-Preference:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x3b - 0b00111011 - MCID request indicator
ParameterMCIQ::ParameterMCIQ(Message & m):
ParameterOne(m), tag(ISUP_PT_MCIQ)
{
}

ParameterMCIQ::print(iostream & str)
{
	str.form("\n\t\tParameter-Malicious-Call-Identification-Request-Indicator:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x3c - 0b00111100 - MCID response indicator
ParameterMCIR::ParameterMCIR(Message & m):
ParameterOne(m), tag(ISUP_PT_MCIR)
{
}

ParameterMCIR::print(iostream & str)
{
	str.form("\n\t\tParameter-Malicious-Call-Identification-Response-Indicator:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x3d - 0b00111101 - Hop counter (reserved)
ParameterHOPC::ParameterHOPC(Message & m):
ParameterOne(m), tag(ISUP_PT_HOPC)
{
}

ParameterHOPC::print(iostream & str)
{
	str.form("\n\t\tParameter-Hop-Counter:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x3e - 0b00111110 - Transmission medium requirement prime
ParameterTMRP::ParameterTMRP(Message & m):
ParameterOne(m), tag(ISUP_PT_TMRP)
{
}

ParameterTMRP::print(iostream & str)
{
	str.form("\n\t\tParameter-Transmission-Medium-Requirement-Prime:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x3f - 0b00111111 - Location number
ParameterLN::ParameterLN(Message & m):
ParameterVar(m), tag(ISUP_PT_LN)
{
}

ParameterLN::print(iostream & str)
{
	str.form("\n\t\tParameter-Location-Number:");
	ParameterVar::print(str);
}

// 0x40 - 0b01000000 - Redirection number restriction
ParameterRDNR::ParameterRDNR(Message & m):
ParameterOne(m), tag(ISUP_PT_RDNR)
{
}

ParameterRDNR::print(iostream & str)
{
	str.form("\n\t\tParameter-Redirection-Number-Restriction:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x41 - 0b01000001 - Freephone indicators (reserved)
ParameterFREEP::ParameterFREEP(Message & m):
ParameterOne(m), tag(ISUP_PT_FREEP)
{
}

ParameterFREEP::print(iostream & str)
{
	str.form("\n\t\tParameter-Freephone-Indicators:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0x42 - 0b01000010 - Generic reference (reserved)
ParameterGREF::ParameterGREF(Message & m):
ParameterVar(m), tag(ISUP_PT_GREF)
{
}

ParameterGREF::print(iostream & str)
{
	str.form("\n\t\tParameter-Generic-Reference:");
	ParameterVar::print(str);
}

// 0xc0 - 0b11000000 - Generic number (address Bellcore)
ParameterGNUM::ParameterGNUM(Message & m):
ParameterVar(m), tag(ISUP_PT_GNUM)
{
}

ParameterGNUM::print(iostream & str)
{
	str.form("\n\t\tParameter-Generic-Number:");
	ParameterVar::print(str);
}

// 0xc1 - 0b11000001 - Generic digits @
ParameterGDIG::ParameterGDIG(Message & m):
ParameterVar(m), tag(ISUP_PT_GDIG)
{
}

ParameterGDIG::print(iostream & str)
{
	str.form("\n\t\tParameter-Generic-Digits:");
	ParameterVar::print(str);
}

// 0xc3 - 0b11000011 - Egress (ANSI)
ParameterEGRESS::ParameterEGRESS(Message & m):
ParameterOne(m), tag(ISUP_PT_EGRESS)
{
}

ParameterEGRESS::print(iostream & str)
{
	str.form("\n\t\tParameter-Egress:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0xc4 - 0b11000100 - Jurisdiction (ANSI)
ParameterJUR::ParameterJUR(Message & m):
ParameterVar(m), tag(ISUP_PT_JUR)
{
}

ParameterJUR::print(iostream & str)
{
	str.form("\n\t\tParameter-Jurisdiction:");
	ParameterVar::print(str);
}

// 0xc5 - 0b11000101 - Carrier identification code (ANSI)
ParameterCIDC::ParameterCIDC(Message & m):
ParameterVar(m), tag(ISUP_PT_CIDC)
{
}

ParameterCIDC::print(iostream & str)
{
	str.form("\n\t\tParameter-Carrier-Identification-Code:");
	ParameterVar::print(str);
}

// 0xc6 - 0b11000110 - Business group (ANSI)
ParameterBGROUP::ParameterBGROUP(Message & m):
ParameterVar(m), tag(ISUP_PT_BGROUP)
{
}

ParameterBRGOUP::print(iostream & str)
{
	str.form("\n\t\tParameter-Business-Group:");
	ParameterVar::print(str);
}

// 0xe1 - 0b11100001 - Notification indicator (ANSI)
ParameterNOTI::ParameterNOTI(Message & m):
ParameterOne(m), tag(ISUP_PT_NOTI)
{
}

ParameterNOTI::print(iostream & str)
{
	str.form("\n\t\tParameter-Notification-Indicator:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0xe2 - 0b11100010 - Service activation (ANSI)
ParameterSVACT::ParameterSVACT(Message & m):
ParameterVar(m), tag(ISUP_PT_SVACT)
{
}

ParameterSVACT::print(iostream & str)
{
	str.form("\n\t\tParameter-Service-Activation:");
	ParameterVar::print(str);
}

// 0xe3 - 0b11100011 - Transaction request (ANSI,Bellcore)
ParameterTRNSRQ::ParameterTRNSRQ(Message & m):
ParameterVar(m), tag(ISUP_PT_TRNSRQ)
{
}

ParameterTRNSRQ::print(iostream & str)
{
	str.form("\n\t\tParameter-Transaction-Request:");
	ParameterVar::print(str);
}

// 0xe4 - 0b11100100 - Special processing request (Bellcore)
ParameterSPR::ParameterSPR(Message & m):
ParameterVar(m), tag(ISUP_PT_SPR)
{
}

ParameterSPR::print(iostream & str)
{
	str.form("\n\t\tParameter-Special-Processing-Request:");
	ParameterVar::print(str);
}

// 0xe5 - 0b11100101 - Cc't group char ind (ANSI,Bellcore)
ParameterCGCI::ParameterCGCI(Message & m):
ParameterOne(m), tag(ISUP_PT_CGCI)
{
}

ParameterCGCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Circuit-Group-Char-Indication:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0xe6 - 0b11100110 - Cc't validation resp ind (ANSI,Bellcore)
ParameterCVRI::ParameterCVRI(Message & m):
ParameterOne(m), tag(ISUP_PT_CVRI)
{
}

ParameterCVRI::print(iostream & str)
{
	str.form("\n\t\tParameter-Circuit-Validation-Response-Indicator:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0xe7 - 0b11100111 - Outgoing trunk group numb (ANSI,Bellcore)
ParameterOTGN::ParameterOTGN(Message & m):
ParameterVar(m), tag(ISUP_PT_OTGN)
{
}

ParameterOTGN::print(iostream & str)
{
	str.form("\n\t\tParameter-Outgoing-Trunk-Group-Number:");
	ParameterVar::print(str);
}

// 0xe8 - 0b11101000 - Circuit ident name (ANSI,Bellcore)
ParameterCIN::ParameterCIN(Message & m):
ParameterVar(m), tag(ISUP_PT_CIN)
{
}

ParameterCIN::print(iostream & str)
{
	str.form("\n\t\tParameter-Circuit-Identification-Name:");
	ParameterVar::print(str);
}

// 0xe9 - 0b11101001 - Common language loc id (ANSI,Bellcore)
ParameterCLLI::ParameterCLLI(Message & m):
ParameterVar(m), tag(ISUP_PT_CLLI)
{
}

ParameterCLLI::print(iostream & str)
{
	str.form("\n\t\tParameter-Originating-Line-Information:");
	ParameterVar::print(str);
}

// 0xea - 0b11101010 - Originating line info (ANSI,Bellcore)
ParameterOLI::ParameterOLI(Message & m):
ParameterVar(m), tag(ISUP_PT_OLI)
{
}

ParameterOLI::print(iostream & str)
{
	str.form("\n\t\tParameter-Originating-Line-Information:");
	ParameterVar::print(str);
}

// 0xeb - 0b11101011 - Charge number (ANSI,Bellcore)
ParameterCHGN::ParameterCHGN(Message & m):
ParameterVar(m), tag(ISUP_PT_CHGN)
{
}

ParameterCHGN::print(iostream & str)
{
	str.form("\n\t\tParameter-Charge-Number:");
	ParameterVar::print(str);
}

// 0xec - 0b11101100 - Service code indicator (ANSI,Bellcore)
ParameterSVCD::ParameterSVCD(Message & m):
ParameterVar(m), tag(ISUP_PT_SVCD)
{
}

ParameterSVCD::print(iostream & str)
{
	str.form("\n\t\tParameter-Service-Code-Indicator:");
	ParameterVar::print(str);
}

// 0xee - 0b11101110 - Carrier selection info (ANSI,Bellcore)
ParameterCSEL::ParameterCSEL(Message & m):
ParameterVar(m), tag(ISUP_PT_CSEL)
{
}

ParameterCSEL::print(iostream & str)
{
	str.form("\n\t\tParameter-Carrier-Selection-Information:");
	ParameterVar::print(str);
}

// 0xf3 - 0b11110011 - Outgoing route identification (Spain)
ParameterORI::ParameterORI(Message & m):
ParameterVar(m), tag(ISUP_PT_ORI)
{
}

ParameterORI::print(iostream & str)
{
	str.form("\n\t\tParameter-Outgoing-Route-Identification:");
	ParameterVar::print(str);
}

// 0xf4 - 0b11110100 - Incoming route identification (Spain)
ParameterIRI::ParameterIRI(Message & m):
ParameterVar(m), tag(ISUP_PT_IRI)
{
}

ParameterIRI::print(iostream & str)
{
	str.form("\n\t\tParameter-Incoming-Route-Identification:");
	ParameterVar::print(str);
}

// 0xf8 - 0b11111000 - Rate (Spain)
ParameterRATE::ParameterRATE(Message & m):
ParameterVar(m), tag(ISUP_PT_RATE)
{
}

ParameterRATE::print(iostream & str)
{
	str.form("\n\t\tParameter-Rate:");
	ParameterVar::print(str);
}

// 0xf9 - 0b11111001 - Identifier of incoming circuit (Spain)
ParameterIIC::ParameterIIC(Message & m):
ParameterVar(m), tag(ISUP_PT_IIC)
{
}

ParameterIIC::print(iostream & str)
{
	str.form("\n\t\tParameter-Identifier-of-Incoming-Circuit:");
	ParameterVar::print(str);
}

// 0xfd - 0b11111101 - Trunk offering information (Singapore)
ParameterTOI::ParameterTOI(Message & m):
ParameterVar(m), tag(ISUP_PT_TOI)
{
}

ParameterTOI::print(iostream & str)
{
	str.form("\n\t\tParameter-Trunk-Offering-Information:");
	ParameterVar::print(str);
}

// 0xfd - 0b11111101 - Type of notification (Spain)
ParameterTON::ParameterTON(Message & m):
ParameterVar(m), tag(ISUP_PT_TON)
{
}

ParameterTON::print(iostream & str)
{
	str.form("\n\t\tParameter-Type-of-Notification:");
	ParameterVar::print(str);
}

// 0xfe - 0b11111110 - Charge rate information (Singapore)
ParameterCRI::ParameterCRI(Message & m):
ParameterOne(m), tag(ISUP_PT_CRI)
{
}

ParameterCRI::print(iostream & str)
{
	str.form("\n\t\tParameter-Charge-Rate-Information:");
	switch (val) {
	default:
		ParameterOne::print(str);
	}
}

// 0xff - 0b11111111 - Call charge information (Singapore)
ParameterICCI::ParameterICCI(Message & m):
ParameterVar(m), tag(ISUP_PT_ICCI)
{
}

ParameterICCI::print(iostream & str)
{
	str.form("\n\t\tParameter-Call-Charge-Information:");
	ParameterVar::print(str);
}

//  -------------------------------------------------------------------------
//
//  Message
//
//  -------------------------------------------------------------------------

/*
 *  Optional Parameters
 *  -------------------------------------------------------------------------
 */

//
//  Decoder loop for optional parameters.  Each optional parameter is decoded
//  in turn an placed on the optional parameters list for the message.
//
inline void Message::unpack_oparms(uchar *&p, uchar *e)
{
	uchar *pp = p, *ep = e;
	if (p >= e)
		throw DecodeError();
	for (pp = p + 2, ep = pp + pp[-1]; pp[-2] && pp < e && ep <= e; pp = ep + 2,, ep = pp + pp[-1]) {
		try {
			switch (pp[-2]) {
			case ISUP_PT_EOP:	/* 0 - End of optional parameters */
				new ParameterEOP(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CLRF:	/* 1 - Call reference @ */
				new ParameterCLRF(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_TMR:	/* 2 - Transmission medium requirement */
				new ParameterTMR(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_ATP:	/* 3 - Access transport */
				new ParameterATP(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CDPN:	/* 4 - Called party number */
				new ParameterCDPN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_SUBN:	/* 5 - Subsequent number */
				new ParameterSUBN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_NCI:	/* 6 - Nature of connection indicators */
				new ParameterNCI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_FCI:	/* 7 - Forward call indicators */
				new ParameterFCI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_OFCI:	/* 8 - Optional forward call indicators */
				new ParameterOFCI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CPC:	/* 9 - Calling party's category */
				new ParameterCPC(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CGPN:	/* 10 - Calling party number */
				new ParameterCGPN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_RDGN:	/* 11 - Redirecting number */
				new ParameterRDGN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_RDNN:	/* 12 - Redirection number */
				new ParameterRDNN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CONR:	/* 13 - Connection request */
				new ParameterCONR(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_INRI:	/* 14 - Information request indicators */
				new ParameterINRI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_INFI:	/* 15 - Information indicators @ */
				new ParameterINFI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_COTI:	/* 16 - Continuity indicators */
				new ParameterCOTI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_BCI:	/* 17 - Backward call indicators */
				new ParameterBCI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CAUS:	/* 18 - Cause indicators */
				new ParameterCAUS(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_RDI:	/* 19 - Redirection information */
				new ParameterRDI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CGI:	/* 21 - Circuit group supervision msg type indicator */
				new ParameterCGI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_RS:	/* 22 - Range and status */
				new ParameterRS(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CMI:	/* 23 - Call modification indicators (Blue Book) */
				new ParameterCMI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_FACI:	/* 24 - Facility indicator */
				new ParameterFACI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_FAII:	/* 25 - Facility information indicators (Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterFAII(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CUGI:	/* 26 - Closed user group interlock code */
				new ParameterCUGI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_INDEX:	/* 27 - Index (Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterINDEX(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_USI:	/* 29 - User service information */
				new ParameterUSI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_SPC:	/* 30 - Signalling point code @ (Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterSPC(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_UUI:	/* 32 - User to user information */
				new ParameterUUI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CONN:	/* 33 - Connected number */
				new ParameterCONN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_SRIS:	/* 34 - Suspend/resume indicators */
				new ParameterSRIS(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_TNS:	/* 35 - Transit network selection @ */
				new ParameterTNS(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_EVNT:	/* 36 - Event information */
				new ParameterEVNT(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CSI:	/* 38 - Circuit state indicator @ */
				new ParameterCSI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_ACL:	/* 39 - Automatic congestion level */
				new ParameterACL(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_OCDN:	/* 40 - Original called number */
				new ParameterOCDN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_OBCI:	/* 41 - Optional backward call indicators */
				new ParameterOBCI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_UUIND:	/* 42 - User to user indicators */
				new ParameterUUIND(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_ISPC:	/* 43 - Origination ISC point code */
				new ParameterISPC(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_GNOT:	/* 44 - Generic notification */
				new ParameterGNOT(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CHI:	/* 45 - Call history information */
				new ParameterCMI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_ADI:	/* 46 - Access delivery information */
				new ParameterADI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_NSF:	/* 47 - Network specific facilities @ */
				new ParameterNSF(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_USIP:	/* 48 - User service information prime */
				new ParameterUSIP(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_PROP:	/* 49 - Propagation delay counter */
				new ParameterPROP(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_ROPS:	/* 50 - Remote operations @ */
				new ParameterROPS(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_SA:	/* 51 - Service activation @ */
				new ParameterSA(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_UTI:	/* 52 - User teleservice information */
				new ParameterUTI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_TMU:	/* 53 - Transmission medium used */
				new ParameterTMU(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CDI:	/* 54 - Call diversion information */
				new ParameterCDI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_ECI:	/* 55 - Echo control information */
				new ParameterECI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_MCI:	/* 56 - Message compatibility information */
				new ParameterMCI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_PCI:	/* 57 - Parameter compatibility information */
				new ParameterPCI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_MLPP:	/* 58 - MLPP preference */
				new ParameterMLPP(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_MCIQ:	/* 59 - MCID request indicator */
				new ParameterMCIQ(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_MCIR:	/* 60 - MCID response indicator */
				new ParameterMCIR(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_HOPC:	/* 61 - Hop counter (reserved) */
				new ParameterHOPC(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_TMRP:	/* 62 - Transmission medium requirement prime */
				new ParameterTMRP(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_LN:	/* 63 - Location number */
				new ParameterLN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_RDNR:	/* 64 - Redirection number restriction */
				new ParameterRDNR(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_FREEP:	/* 65 - Freephone indicators (reserved) */
				new ParameterFREEP(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_GREF:	/* 66 - Generic reference (reserved) */
				new ParameterGREF(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_GNUM:	/* 192 - Generic number (address Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterGNUM(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_GDIG:	/* 193 - Generic digits @ */
				new ParameterGDIG(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_EGRESS:	/* 195 - Egress (ANSI) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterEGRESS(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_JUR:	/* 196 - Jurisdiction (ANSI) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterJUR(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CIDC:	/* 197 - Carrier identification code (ANSI) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterCIDC(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_BGROUP:	/* 198 - Business group (ANSI) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterBGROUP(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_NOTI:	/* 225 - Notification indicator (ANSI) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterNOTI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_SVACT:	/* 226 - Service activation (ANSI) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterSVACT(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_TRNSRQ:	/* 227 - Transaction request (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterTRNSRQ(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_SPR:	/* 228 - Special processing request (Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterSPR(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CGCI:	/* 229 - Circuit group char inds (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterCGCI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CVRI:	/* 230 - Circuit validation resp ind (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterCVRI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_OTGN:	/* 231 - Outgoing trunk group number (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterOTGN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CIN:	/* 232 - Circuit identification name (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterCIN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CLLI:	/* 233 - Common language loc id (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterCLLI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_OLI:	/* 234 - Originating line information (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterOLI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CHGN:	/* 235 - Charge number (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterCHGN(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_SVCD:	/* 236 - Service code indicator (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterSVCD(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_CSEL:	/* 238 - Carrier selection information (ANSI, Bellcore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
					goto unrecognized;
				new ParameterCSEL(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_ORI:	/* 243 - Outgoing route identification (Spain) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SPAN)
					goto unrecognized;
				new ParameterORI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_IRI:	/* 244 - Incoming route identification (Spain) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SPAN)
					goto unrecognized;
				new ParameterIRI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_RATE:	/* 248 - Rate (Spain) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SPAN)
					goto unrecognized;
				new ParameterRATE(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_IIC:	/* 249 - Identifier of incoming circuit (Spain) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SPAN)
					goto unrecognized;
				new ParameterIIC(*this, oparms, pp, ep);
				continue;
			case 253:
				// case ISUP_PT_TOI:
				// case ISUP_PT_TON:
				switch (pvar & SS7_PVAR_MASK) {
				case SS7_PVAR_SING:	/* 253 - Trunk offering information (Singapore) */
					new ParameterTOI(*this, oparms, pp, ep);
					continue;
				case SS7_PVAR_SPAN:	/* 253 - Type of notification (Spain) */
					new ParameterTON(*this, oparms, pp, ep);
					continue;
				default:
					goto unrecognized;
				}
			case ISUP_PT_CRI:	/* 254 - Charge rate information (Singapore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SING)
					goto unrecognized;
				new ParameterCRI(*this, oparms, pp, ep);
				continue;
			case ISUP_PT_ICCI:	/* 255 - Call charge information (Singapore) */
				if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SING)
					goto unrecognized;
				new ParameterICCI(*this, oparms, pp, ep);
				continue;
			default:
			      unrecognized:
				new ParameterUNREC(*this, oparms, pp, ep);
				continue;
			}
		}
		catch() {
			continue;
		}
	}
	return;
}

/*
 *  -------------------------------------------------------------------------
 *
 *  Decode message functions
 *
 *  -------------------------------------------------------------------------
 */

RoutingLabel::RoutingLabel(Collector & cl, StreamBuffer * buf)
:  pvar(cl.pvar), p(buf->data.buf), e(buf->data.buf + buf->data.len)
{
	int ret;
	ulong b;
	Call *call;
	if ((ret gettimeofday(&timestamp, NULL)) < 0)
		throw UnixError(__PRETTY_FUNCTION__, -errno);
	switch ((pvar & SS7_PVAR_MASK)) {
	case SS7_PVAR_ANSI:	/* 24-bit point codes */
	case SS7_PVAR_JTTC:
	case SS7_PVAR_CHIN:
		if (p + 11 >= e)
			throw DecodeError();
		si = mp = ni = *p++;
		si &= 0x0f;
		ni >>= 4;
		ni &= 0x03;
		mp >>= 6;
		mp &= 0x03;
		b = *p++ & 0x00ff;
		dpc = b;
		b = *p++ & 0x00ff;
		dpc |= b << 8;
		b = *p++ & 0x00ff;
		dpc |= b << 16;
		b = *p++ & 0x00ff;
		opc = b;
		b = *p++ & 0x00ff;
		opc |= b << 8;
		b = *p++ & 0x00ff;
		opc |= b << 16;
		b = *p++ & 0x00ff;
		sls = b;
		b = *p++ & 0x00ff;
		cic = b;
		b = *p++ & 0x00ff;
		cic |= b << 8;
		b = *p++ & 0x00ff;
		mt = b;
		break;
	default:
	case SS7_PVAR_ITUT:	/* 14-bit point codes */
	case SS7_PVAR_ETSI:
	case SS7_PVAR_SING:
	case SS7_PVAR_SPAN:
		if (p + 8 >= e)
			throw DecodeError();
		si = ni = mp = *p++;
		si &= 0x0f;
		ni >>= 4;
		ni &= 0x0f;
		mp = 0;
		b = *p++ & 0x00ff;
		dpc = b;
		b = *p++ & 0x00ff;
		dpc |= b << 8;
		dpc &= 0x3fff;
		opc = b >> 6;
		b = *p++ & 0x00ff;
		opc |= b << 2;
		b = *p++ & 0x00ff;
		opc |= b << 10;
		opc &= 0x3fff;
		sls = b >> 4;
		b = *p++ & 0x00ff;
		cic = b;
		b = *p++ & 0x00ff;
		cic |= b << 8;
		cic &= 0x0fff;
		b = *p++ & 0x00ff;
		mt = b;
		break;
	}
	// lookup the call by dpc, opc, cic n-tuple
	if (!(call = cl.lookup(rl)))
		throw UnixError(__PRETTY_FUNCTION, -ENOMEM);
	// decode specific message for call
	switch (mt) {
	case ISUP_MT_IAM:	// 0x01 - 0b00000001 - Initial address
		return call->message(new MessageIAM(rl));
	case ISUP_MT_SAM:	// 0x02 - 0b00000010 - Subsequent address
		return call->message(new MessageSAM(rl));
	case ISUP_MT_INR:	// 0x03 - 0b00000011 - Information request
		return call->message(new MessageINR(rl));
	case ISUP_MT_INF:	// 0x04 - 0b00000100 - Information
		return call->message(new MessageINF(rl));
	case ISUP_MT_COT:	// 0x05 - 0b00000101 - Continuity
		return call->message(new MessageCOT(rl));
	case ISUP_MT_ACM:	// 0x06 - 0b00000110 - Address complete
		return call->message(new MessageACM(rl));
	case ISUP_MT_CON:	// 0x07 - 0b00000111 - Connect (new ANSI)
		return call->message(new MessageCON(rl));
	case ISUP_MT_FOT:	// 0x08 - 0b00001000 - Forward transfer
		return call->message(new MessageFOT(rl));
	case ISUP_MT_ANM:	// 0x09 - 0b00001001 - Answer
		return call->message(new MessageANM(rl));
	case ISUP_MT_REL:	// 0x0c - 0b00001100 - Release
		return call->message(new MessageREL(rl));
	case ISUP_MT_SUS:	// 0x0d - 0b00001101 - Suspend
		return call->message(new MessageSUS(rl));
	case ISUP_MT_RES:	// 0x0e - 0b00001110 - Resume
		return call->message(new MessageRES(rl));
	case ISUP_MT_RLC:	// 0x10 - 0b00010000 - Release complete
		return call->message(new MessageRLC(rl));
	case ISUP_MT_CCR:	// 0x11 - 0b00010001 - Continuity check request
		return call->message(new MessageCCR(rl));
	case ISUP_MT_RSC:	// 0x12 - 0b00010010 - Reset circuit
		return call->message(new MessageRSC(rl));
	case ISUP_MT_BLO:	// 0x13 - 0b00010011 - Blocking
		return call->message(new MessageBLO(rl));
	case ISUP_MT_UBL:	// 0x14 - 0b00010100 - Unblcoking
		return call->message(new MessageUBL(rl));
	case ISUP_MT_BLA:	// 0x15 - 0b00010101 - Blocking acknowledgement
		return call->message(new MessageBLA(rl));
	case ISUP_MT_UBA:	// 0x16 - 0b00010110 - Unblocking acknowledgement
		return call->message(new MessageUBA(rl));
	case ISUP_MT_GRS:	// 0x17 - 0b00010111 - Circuit group reset
		return call->message(new MessageGRS(rl));
	case ISUP_MT_CGB:	// 0x18 - 0b00011000 - Circuit group blocking
		return call->message(new MessageCGB(rl));
	case ISUP_MT_CGU:	// 0x19 - 0b00011001 - Circuit group unblocking
		return call->message(new MessageCGU(rl));
	case ISUP_MT_CGBA:	// 0x1a - 0b00011010 - Circuit group blocking acknowledgement
		return call->message(new MessageCGBA(rl));
	case ISUP_MT_CGUA:	// 0x1b - 0b00011011 - Circuit group unblocking acknowledgement
		return call->message(new MessageCGUA(rl));
	case ISUP_MT_CMR:	// 0x1c - 0b00011100 - Call Modification Request (new ANSI)
		return call->message(new MessageCMR(rl));
	case ISUP_MT_CMC:	// 0x1d - 0b00011101 - Call Modification Completed (new ANSI)
		return call->message(new MessageCMC(rl));
	case ISUP_MT_CMRJ:	// 0x1e - 0b00011110 - Call Modification Reject (new ANSI)
		return call->message(new MessageCMRJ(rl));
	case ISUP_MT_FAR:	// 0x1f - 0b00011111 - Facility request
		return call->message(new MessageFAR(rl));
	case ISUP_MT_FAA:	// 0x20 - 0b00100000 - Facility accepted
		return call->message(new MessageFAA(rl));
	case ISUP_MT_FRJ:	// 0x21 - 0b00100001 - Facility reject
		return call->message(new MessageFRJ(rl));
	case ISUP_MT_FAD:	// 0x22 - 0b00100010 - Facility Deactivated (old Bellcore only)
		return call->message(new MessageFAD(rl));
	case ISUP_MT_FAI:	// 0x23 - 0b00100011 - Facility Information (old Bellcore only)
		return call->message(new MessageFAI(rl));
	case ISUP_MT_LPA:	// 0x24 - 0b00100100 - Loop back acknowledgement
		return call->message(new MessageLPA(rl));
	case ISUP_MT_DRS:	// 0x27 - 0b00100111 - Delayed release (new ANSI)
		return call->message(new MessageDRS(rl));
	case ISUP_MT_PAM:	// 0x28 - 0b00101000 - Pass along
		return call->message(new MessagePAM(rl));
	case ISUP_MT_GRA:	// 0x29 - 0b00101001 - Circuit group reset acknowledgement
		return call->message(new MessageGRA(rl));
	case ISUP_MT_CQM:	// 0x2a - 0b00101010 - Circuit group query
		return call->message(new MessageCQM(rl));
	case ISUP_MT_CQR:	// 0x2b - 0b00101011 - Circuit group query response
		return call->message(new MessageCQR(rl));
	case ISUP_MT_CPG:	// 0x2c - 0b00101100 - Call progress
		return call->message(new MessageCPG(rl));
	case ISUP_MT_USR:	// 0x2d - 0b00101101 - User-to-user information
		return call->message(new MessageUSR(rl));
	case ISUP_MT_UCIC:	// 0x2e - 0b00101110 - Unequipped circuit identification code
		return call->message(new MessageUCIC(rl));
	case ISUP_MT_CFN:	// 0x2f - 0b00101111 - Confusion
		return call->message(new MessageCFN(rl));
	case ISUP_MT_OLM:	// 0x30 - 0b00110000 - Overload
		return call->message(new MessageOLM(rl));
	case ISUP_MT_CRG:	// 0x31 - 0b00110001 - Charge information
		return call->message(new MessageCRG(rl));
	case ISUP_MT_NRM:	// 0x32 - 0b00110010 - Network resource management
		return call->message(new MessageNRM(rl));
	case ISUP_MT_FAC:	// 0x33 - 0b00110011 - Facility
		return call->message(new MessageFAC(rl));
	case ISUP_MT_UPT:	// 0x34 - 0b00110100 - User part test
		return call->message(new MessageUPT(rl));
	case ISUP_MT_UPA:	// 0x35 - 0b00110101 - User part available
		return call->message(new MessageUPA(rl));
	case ISUP_MT_IDR:	// 0x36 - 0b00110110 - Identification request
		return call->message(new MessageIDR(rl));
	case ISUP_MT_IRS:	// 0x37 - 0b00110111 - Identification response
		return call->message(new MessageIRS(rl));
	case ISUP_MT_SGM:	// 0x38 - 0b00111000 - Segmentation
		return call->message(new MessageSGM(rl));
	case ISUP_MT_CRA:	// 0xe9 - 0b11101001 - Circuit Reservation Ack (ANSI 2000)
		return call->message(new MessageCRA(rl));
	case ISUP_MT_CRM:	// 0xea - 0b11101010 - Circuit Reservation (ANSI 2000)
		return call->message(new MessageCRM(rl));
	case ISUP_MT_CVR:	// 0xeb - 0b11101011 - Circuit Validation Response (ANSI 2000)
		return call->message(new MessageCVR(rl));
	case ISUP_MT_CVT:	// 0xec - 0b11101100 - Circuit Validation Test (ANSI 2000)
		return call->message(new MessageCVT(rl));
	case ISUP_MT_EXM:	// 0xed - 0b11101101 - Exit (old Bellcore/ANSI 2000)
		return call->message(new MessageEXM(rl));
	case ISUP_MT_NON:	// 0xf8 - 0b11111000 - National Notification (Spain)
		return call->message(new MessageNON(rl));
	case ISUP_MT_LLM:	// 0xfc - 0b11111100 - National Malicious Call (Spain)
		return call->message(new MessageLLM(rl));
	case ISUP_MT_CAK:	// 0xfd - 0b11111101 - Charge Acknowledgement (Singapore)
		return call->message(new MessageCAK(rl));
	case ISUP_MT_TCM:	// 0xfe - 0b11111110 - Tariff Charge (Singapore)
		return call->message(new MessageTCM(rl));
	case ISUP_MT_MCP:	// 0xff - 0b11111111 - Malicious Call Print (Singapore)
		return call->message(new MessageMCP(rl));
	}
}

RoutingLabel::print(iostream & str)
{
	str.form("\n\t\tMessage-Timestamp: %lu.%06lu", timestamp.tv_sec, timestamp.tv_usec);
	str.form("\n\t\tSignalling-Link-Selection: %d", sls);
}

Message::Message(RoutingLabel & rl)
:  pvar(rl.pvar), p(rl.p), e(rl.e), routLabel(rl);
{
}

Message::~Message(void)
{
	while (oparms)
		delete oparms;
	delete & routLabel;
}

Message::print(iostream & str)
{
	routLabel.print(str);
}

/*
 *  ISUP_MT_???? - Unrecognized Message
 *  -------------------------------------------------------------------------
 *  ANSI: O(MCI PCI ...)
 *  ITUT: O(MCI PCI ...)
 *  SING: O(MCI PCI ...)
 *  SPAN: O(MCI PCI ...)
 */
MessageUNREC::MessageUNREC(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

/*
 *  ISUP_MT_IAM   0x01 - Initial address
 *  -------------------------------------------------------------------------
 *  ANSI: F(NCI FCI CPC) V(USI CDPN) O()
 *  ITUT: F(NCI FCI CPC TMR) V(CDPN) O()
 */
MessageIAM::MessageIAM(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterNCI(pvar, p, e, nci)))	/* NCI F */
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	if (!(new ParameterFCI(pvar, p, e, fci)))	/* FCI F */
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	if (!(new ParameterCPC(pvar, p, e, cpc)))	/* CPC F */
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	switch (pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		if (!(new ParameterUSI(pvar, p, e, usi)))	/* USI V */
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
		break;
	default:
		new ParaemterTMR(pvar, p, e, tmr);	/* TMR F */
		break;
	}
	ParameterCDPN(pvar, p, e, cdpn);	/* CDPN V */
	unpack_oparms(p + *p, e);
}
MessageIAM::~MessageIAM(void)
{
	if (nci)
		delete nci;
	if (fci)
		delete fci;
	if (cpc)
		delete cpc;
	if (usi)
		delete usi;
	if (tmr)
		delete tmr;
	if (cdpn)
		delete cdpn;
}

MessageIAM::print(iostream & str)
{
	str.form("Message-Initial-Address:");
	Message::print(str);
	if (nci)
		nci->print(str);
	if (fci)
		fci->print(str);
	if (cpc)
		cpc->print(str);
	if (usi)
		usi->print(str);
	if (tmr)
		tmr->print(str);
	if (cdpn)
		cdpn->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_SAM   0x02 - Subsequent address
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: V(SUBN) O()
 */
MessageSAM::MessageSAM(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
		if (!(new ParameterSUBN(pvar, p, e, subn)))	/* SUBN V */
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageSAM::~MessageSAM(void)
{
	if (subn)
		delete subn;
}

MessageSAM::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Subsequent-Address:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLable.mt);
	}
	Message::print(str);
	if (subn)
		subn->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_INR   0x03 - Information request
 *  -------------------------------------------------------------------------
 *  ANSI: F(INRI) O()
 *  ITUT: F(INRI) O()
 */
MessageINR::MessageINR(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterINRI(pvar, p, e, inri)))	/* INRI F */
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageINR::~MessageINR(void)
{
	if (inri)
		delete inri;
}

MessageINR::print(iostream & str)
{
	str.form("Message-Information-Request:");
	Message::print(str);
	if (inri)
		inri->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_INF   0x04 - Information
 *  -------------------------------------------------------------------------
 *  ANSI: F(INFI) O()
 *  ITUT: F(INFI) O()
 */
MessageINF::MessageINF(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterINFI(pvar, p, e, infi)))	/* INFI F */
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MesageINF::~MessageINF(void)
{
	if (infi)
		delete infi;
}

MessageINF::print(iostream & str)
{
	str.form("Message-Information:");
	Message::print(str);
	if (infi)
		infi->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_COT   0x05 - Continuity
 *  -------------------------------------------------------------------------
 *  ANSI: F(COTI)
 *  ITUT: F(COTI)
 */
MessageCOT::MessageCOT(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterCOTI(pvar, p, e, coti)))	/* COTI F */
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
}
MessageCOT::~MessageCOT(void)
{
	if (coti)
		delete coti;
}

MessageCOT::print(iostream & str)
{
	str.form("Message-Continuity:");
	Message::print(str);
	if (coti)
		coti->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_ACM   0x06 - Address complete
 *  -------------------------------------------------------------------------
 *  ANSI: F(BCI) O()
 *  ITUT: F(BCI) O()
 */
MessageACM::MessageACM(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterBCI(pvar, p, e, bci)))	/* BCI F */
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageACM::~MessageACM(void)
{
	if (coti)
		delete coti;
}

MessageACM::print(iostream & str)
{
	str.form("Message-Address-Complete:");
	Message::print(str);
	if (coti)
		coti->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CON   0x07 - Connect (not ANSI)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: F(BCI) O()
 */
MessageCON::MessageCON(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
		new ParemeterBCI(pvar, p, e, bci);	/* BCI F */
	unpack_oparms(p + *p, e);
}
MessageCON::~MessageCON(void)
{
	if (bci)
		delete bci;
}

MessageCON::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Connect:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLable.mt);
	}
	Message::print(str);
	if (bci)
		bci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_FOT   0x08 - Forward transfer
 *  -------------------------------------------------------------------------
 *  ANSI: O()
 *  ITUT: O()
 */
MessageFOT::MessageFOT(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageFOT::print(iostream & str)
{
	str.form("Message-Forward-Transfer:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_ANM   0x09 - Answer
 *  -------------------------------------------------------------------------
 *  ANSI: O()
 *  ITUT: O()
 */
MessageANM::MessageANM(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageANM::print(iostream & str)
{
	str.form("Message-Answer:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_REL   0x0c - Release
 *  -------------------------------------------------------------------------
 *  ANSI: V(CAUS) O()
 *  ITUT: V(CAUS) O()
 */
MessageREL::MessageREL(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterCAUS(pvar, p, e, caus)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageREL::~MessageREL(void)
{
	if (caus)
		delete caus;
}

MessageREL::print(iostream & str)
{
	str.form("Message-Release:");
	Message::print(str);
	if (caus)
	      caus->print(str):
		if (oparms)
			oparms->print(str);
}

/*
 *  ISUP_MT_SUS   0x0d - Suspend
 *  -------------------------------------------------------------------------
 *  ANSI: F(SRIS) O()
 *  ITUT: F(SRIS) O()
 */
MessageSUS::MessageSUS(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterSRIS(pvar, p, e, sris)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageSUS::~MessageSUS(void)
{
	if (sris)
		delete sris;
}

MessageSUS::print(iostream & str)
{
	str.form("Message-Suspend:");
	Message::print(str);
	if (sris)
		sris->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_RES   0x0e - Resume
 *  -------------------------------------------------------------------------
 *  ANSI: F(SRIS) O()
 *  ITUT: F(SRIS) O()
 */
MessageRES::MessageRES(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterSRIS(p, e, sris)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageRES::MessageRES(void)
{
	if (sris)
		delete sris;
}

MessageRES::print(iostream & str)
{
	str.form("Message-Resume:");
	Message::print(str);
	if (sris)
		sris->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_RLC   0x10 - Release complete
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: O()
 */
MessageRLC::MessageRLC(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageRLC::print(iostream & str)
{
	str.form("Message-Release-Complete:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CCR   0x11 - Continuity check request
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (none)
 */
MessageCCR::MessageCCR(RoutingLabel & rl)
:  Message(rl)
{
}

MessageCCR::print(iostream & str)
{
	str.form("Message-Continuity-Check-Request:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_RSC   0x12 - Reset circuit
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (none)
 */
MessageRSC::MessageRSC(RoutingLabel & rl)
:  Message(rl)
{
}

MessageRSC::print(iostream & str)
{
	str.form("Message-Reset-Circuit:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_BLO   0x13 - Blocking
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (none)
 */
MessageBLO::MessageBLO(RoutingLabel & rl)
:  Message(rl)
{
}

MessageBLO::print(iostream & str)
{
	str.form("Message-Blocking:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_UBL   0x14 - Unblcoking
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (none)
 */
MessageUBL::MessageUBL(RoutingLabel & rl)
:  Message(rl)
{
}

MessageUBL::print(iostream & str)
{
	str.form("Message-Unblocking:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_BLA   0x15 - Blocking acknowledgement
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (none)
 */
MessageBLA::MessageBLA(RoutingLabel & rl)
:  Message(rl)
{
}

MessageBLA::print(iostream & str)
{
	str.form("Message-Blocking-Acknowledgement:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_UBA   0x16 - Unblocking acknowledgement
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (none)
 */
MessageUBA::MessageUBA(RoutingLabel & rl)
:  Message(rl)
{
}

MessageUBA::print(iostream & str)
{
	str.form("Message-Unblocking-Acknowledgement:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_GRS   0x17 - Circuit group reset
 *  -------------------------------------------------------------------------
 *  ANSI: V(RS)
 *  ITUT: V(RS)
 */
MessageGRS::MessageGRS(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterRS(pvar, p, e, rs)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	switch (pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		/* ANSI allows range value of zero for pre-arranged circuit groups */
		if (rs->len == 1 && rs->ptr[0] == 0)
			break;
		/* fall through */
	default:
	case SS7_PVAR_ITUT:
		if (rs->len != 1 || rs->ptr[0] < 1 || rs->ptr[0] > 31)
			throw DecodeError();
	}
}
MessageGRS::~MessageGRS(void)
{
	if (rs)
		delete rs;
}

MessageGRS::print(iostream & str)
{
	str.form("Message-Circuit-Group-Reset:");
	Message::print(str);
	if (rs)
		rs->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CGB   0x18 - Circuit group blocking
 *  -------------------------------------------------------------------------
 *  ANSI: F(CGI) V(RS)
 *  ITUT: F(CGI) V(RS)
 */
MessageCGB::MessageCGB(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterCGI(pvar, p, e, cgi)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	if (!(new ParameterRS(pvar, p, e, rs)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	switch (pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		/* ANSI allows range value of zero for pre-arranged circuit groups */
		if (rs->len == 1) {
			if (rs->ptr[0] == 0)
				break;
			throw DecodeError();
		}
		/* fall through */
	default:
	case SS7_PVAR_ITUT:
	{
		int i, j, set;
		if (rs->len < 2 || rs->len > 33 || rs->ptr[0] < 1 || rs->ptr[0] > 31)
			throw DecodeError();
		for (set = 0, i = 1; i < rs->len; i++)
			for (j = 0; j < 7; j++)
				if (rs->ptr[i] & (0x1 << j))
					set++;
		if (set > 32)
			throw DecodeError();
	}
	}
}
MessageCGB::~MessageCGB(void)
{
	if (cgi)
		delete cgi;
	if (rs)
		delete rs;
}

MessageCGB::print(iostream & str)
{
	str.form("Message-Cirguit-Group-Blocking:");
	Message::print(str);
	if (cgi)
		cgi->print(str);
	if (rs)
		rs->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CGU   0x19 - Circuit group unblocking
 *  -------------------------------------------------------------------------
 *  ANSI: F(CGI) V(RS)
 *  ITUT: F(CGI) V(RS)
 */
MessageCGU::MessageCGU(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterCGI(pvar, p, e, cgi)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	if (!(new ParameterRS(pvar, p, e, rs)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	switch (pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		/* ANSI allows range value of zero for pre-arranged circuit groups */
		if (rs->len == 1) {
			if (rs->ptr[0] == 0)
				break;
			throw DecodeError();
		}
		/* fall through */
	default:
	{
		int i, j, set;
		if (rs->len < 2 || rs->len > 33 || rs->ptr[0] < 1 || rs->ptr[0] > 31)
			throw DecodeError();
		for (set = 0, i = 1; i < rs->len; i++)
			for (j = 0; j < 7; j++)
				if (rs->ptr[i] & (0x1 << j))
					set++;
		if (set > 32)
			throw DecodeError();
	}
	}
}
MessageCGU::~MessageCGU(void)
{
	if (cgi)
		delete cgi;
	if (rs)
		delete rs;
}

MessageCGU::print(iostream & str)
{
	str.form("Message-Circuit-Group-Unblocking:");
	Message::print(str);
	if (cgi)
		cgi->print(str);
	if (rs)
		rs->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CGBA   0x1a - Circuit group blocking acknowledgement
 *  -------------------------------------------------------------------------
 *  ANSI: F(CGI) V(RS)
 *  ITUT: F(CGI) V(RS)
 */
MessageCGBA::MessageCGBA(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterCGI(pvar, p, e, cgi)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	if (!(new ParameterRS(pvar, p, e, rs)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	switch (pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		/* ANSI allows range value of zero for pre-arranged circuit groups */
		if (rs->len == 1) {
			if (rs->ptr[0] == 0)
				break;
			throw DecodeError();
		}
		/* fall through */
	default:
	case SS7_PVAR_ITUT:
	{
		int i, j, set;
		if (rs->len < 2 || rs->len > 33 || rs->ptr[0] < 1 || rs->ptr[0] > 31)
			throw DecodeError();
		for (set = 0, i = 1; i < rs->len; i++)
			for (j = 0; j < 7; j++)
				if (rs->ptr[i] & (0x1 << j))
					set++;
		if (set > 32)
			throw DecodeError();
	}
	}
}
MessageCGBA::~MessageCGBA(void)
{
	if (cgi)
		delete cgi;
	if (rs)
		delete rs;
}

MessageCGBA::print(iostream & str)
{
	str.form("Message-Circuit-Group-Blocking-Acknowledgement:");
	Message::print(str);
	if (cgi)
		cgi->print(str);
	if (rs)
		rs->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CGUA   0x1b - Circuit group unblocking acknowledgement
 *  -------------------------------------------------------------------------
 *  ANSI: F(CGI) V(RS)
 *  ITUT: F(CGI) V(RS)
 */
MessageCGUA::MessageCGUA(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterCGI(pvar, p, e, cgi)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	if (!(new ParameterRS(pvar, p, e, rs)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	switch (pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		/* ANSI allows range value of zero for pre-arranged circuit groups */
		if (rs.len == 1) {
			if (rs.ptr[0] == 0)
				break;
			throw DecodeError();
		}
		/* fall through */
	default:
	case SS7_PVAR_ITUT:
	{
		int i, j, set;
		if (rs.len < 2 || rs.len > 33 || rs.ptr[0] < 1 || rs.ptr[0] > 31)
			throw DecodeError();
		for (set = 0, i = 1; i < rs.len; i++)
			for (j = 0; j < 7; j++)
				if (rs.ptr[i] & (0x1 << j))
					set++;
		if (set > 32)
			throw DecodeError();
	}
	}
}
MessageCGUA::~MessageCGUA(void)
{
	if (cgi)
		delete cgi;
	if (rs)
		delete rs;
}

MessageCGUA::print(iostream & str)
{
	str.form("Message-Circuit-Group-Unblocking-Acknowledgement:");
	Message::print(str);
	if (cgi)
		cgi->print(str);
	if (rs)
		rs->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CMR   0x1c - Call Modification Request (not ANSI)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: CMI O()
 */
MessageCMR::MessageCMR(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		if (!(new ParameterCMI(pvar, p, e, cmi)))	/* F(CMI) */
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	}
	unpack_oparms(p + *p, e);
}
MessageCMR::~MessageCMR(void)
{
	if (cmi)
		delete cmi;
}

MessageCMR::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Call-Modification-Request:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLable.mt);
	}
	Message::print(str);
	if (cmi)
		cmi->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CMC   0x1d - Call Modification Completed (not ANSI)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: CMI O()
 */
MessageCMC::MessageCMC(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		if (!(new ParameterCMI(pvar, p, e, cmi)))	/* F(CMI) */
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	}
	unpack_oparms(p + *p, e);
}
MessageCMC::~MessageCMC(void)
{
	if (cmi)
		delete cmi;
}

MessageCMC::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Call-Modification-Completed:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLable.mt);
	}
	Message::print(str);
	if (cmi)
		cmi->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CMRJ   0x1e - Call Modification Reject (not ANSI)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: CMI O()
 */
MessageCMRJ::MessageCMRJ(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		if (!(new ParameterCMI(pvar, p, e, cmi)))	/* F(CMI) */
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	}
	unpack_oparms(p + *p, e);
}
MessageCMRJ::~MessageCMRJ(void)
{
	if (cmi)
		delete cmi;
}

MessageCMRJ::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Call-Modification-Reject:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLable.mt);
	}
	Message::print(str);
	if (cmi)
		cmi->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_FAR   0x1f - Facility request
 *  -------------------------------------------------------------------------
 *  ANSI: F(FACI) O()
 *  ITUT: F(FACI) O()
 */
MessageFAR::MessageFAR(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterFACI(pvar, p, e, faci)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageFAR::~MessageFAR(void)
{
	if (faci)
		delete faci;
}

MessageFAR::print(iostream & str)
{
	str.form("Message-Facility-Request:");
	Message::print(str);
	if (faci)
		faci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_FAA   0x20 - Facility accepted
 *  -------------------------------------------------------------------------
 *  ANSI: F(FACI) O()
 *  ITUT: F(FACI) O()
 */
MessageFAA::MessageFAA(RoutingLabel & rl)
:  Message(rl)
{
	new ParmeterFACI(pvar, p, e, faci);
	unpack_oparms(p + *p, e);
}
MessageFAA::~MessageFAA(void)
{
	if (faci)
		delete faci;
}

MessageFAA::print(iostream & str)
{
	str.form("Message-Facility-Accepted:");
	Message::print(str);
	if (faci)
		faci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_FRJ   0x21 - Facility reject
 *  -------------------------------------------------------------------------
 *  ANSI: F(FACI) V(CAUS) O()
 *  ITUT: F(FACI) V(CAUS) O()
 */
MessageFRJ::MessageFRJ(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterFACI(pvar, p, e, faci)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	if (!(new ParameterCAUS(pvar, p, e, caus)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageFRJ::~MessageFRJ(void)
{
	if (faci)
		delete faci;
	if (caus)
		delete caus;
}

MessageFAR::print(iostream & str)
{
	str.form("Message-Facility-Reject:");
	Message::print(str);
	if (faci)
		faci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_FAD   0x22 - Facility Deactivated (Bellcore only)
 *  -------------------------------------------------------------------------
 *  ANSI: F(FACI) O()
 *  ITUT: (no such message)
 */
MessageFAD::MessageFAD(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		if (!(new ParameterFACI(pvar, p, e, faci)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	}
	unpack_oparms(p + *p, e);
}
MessageFAD::~MessageFAD(void)
{
	if (faci)
		delete faci;
}

MessageFAD::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		str.form("Message-Facility-Deactivated:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLable.mt);
	}
	Message::print(str);
	if (faci)
		faci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_FAI   0x23 - Facility Information (Bellcore only)
 *  -------------------------------------------------------------------------
 *  ANSI: F(FACI) FAII O()
 *  ITUT: (no such message)
 */
MessageFAI::MessageFAI(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		if (!(new ParameterFACI(pvar, p, e, faci)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
		new ParaemterFAII(pvar, p, e, faii);
	}
	unpack_oparms(p + *p, e);
}
MessageFAI::~MessageFAI(void)
{
	if (faci)
		delete faci;
	if (faii)
		delete faii;
}

MessageFAI::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		str.form("Message-Facility-Information:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLable.mt);
	}
	Message::print(str);
	if (faci)
		faci->print(str);
	if (fali)
		faci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_LPA   0x24 - Loop back acknowledgement
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (none)
 */
MessageLPA::MessageLPA(RoutingLabel & rl)
:  Message(rl)
{
}

MessageLPA::print(iostream & str)
{
	str.form("Message-Loop-Back-Acknowledgement:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_DRS   0x27 - Delayed release (not ANSI)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: O()
 */
MessageDRS::MessageDRS(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageDRS::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Delayed-Release:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLable.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_PAM   0x28 - Pass along
 *  -------------------------------------------------------------------------
 *  ANSI: (encapsultated ISUP message)
 *  ITUT: (encapsultated ISUP message)
 */
MessagePAM::MessagePAM(RoutingLabel & rl)
:  Message(rl)
{
	swerr();
	throw DecodeError();
}

MessagePAM::print(iostream & str)
{
	str.form("Message-Pass-Along:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_GRA   0x29 - Circuit group reset acknowledgement
 *  -------------------------------------------------------------------------
 *  ANSI: V(RS)
 *  ITUT: V(RS)
 */
MessageGRA::MessageGRA(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterRS(pvar, p, e, rs)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
}
MessageGRA::~MessageGRA(void)
{
	if (rs)
		delete rs;
}

MessageGRA::print(iostream & str)
{
	str.form("Message-Circuit-Group-Reset-Acknowledgement:");
	Message::print(str);
	if (rs)
		rs->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CQM   0x2a - Circuit group query
 *  -------------------------------------------------------------------------
 *  ANSI: V(RS)
 *  ITUT: V(RS)
 */
MessageCQM::MessageCQM(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterRS(pvar, p, e, rs)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	switch (pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		/* ANSI allows range value of zero for pre-arranged circuit groups */
		if (rs->len == 1 && rs->ptr[0] == 0)
			break;
		/* fall through */
	default:
	case SS7_PVAR_ITUT:
		if (rs->len != 1 || rs->ptr[0] < 1 || rs->ptr[0] > 31)
			throw DecodeError();
	}
}
MessageCQM::~MessageCQM(void)
{
	if (rs)
		delete rs;
}

MessageCQM::print(iostream & str)
{
	str.form("Message-Circuit-Group-Query:");
	Message::print(str);
	if (rs)
		rs->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CQR   0x2b - Circuit group query response
 *  -------------------------------------------------------------------------
 *  ANSI: V(RS) V(CSI)
 *  ITUT: V(RS) V(CSI)
 */
MessageCQR::MessageCQR(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterRS(pvar, p, e, rs)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	if (!(new ParameterCSI(pvar, p, e, csi)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
}
MessageCQR::~MessageCQR(void)
{
	if (rs)
		delete rs;
	if (csi)
		delete csi;
}

MessageCQR::print(iostream & s)
{
	str.form("Message-Cirguit-Group-Query-Response:");
	Message::print(str);
	if (rs)
		rs->print(str);
	if (csi)
		csi->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CPG   0x2c - Call progress
 *  -------------------------------------------------------------------------
 *  ANSI: F(EVNT) O()
 *  ITUT: F(EVNT) O()
 */
MessageCPG::MessageCPG(RoutingLabel & rl)
:  Message(rl)
{
	if (!(new ParameterEVNT(pvar, p, e, evnt)))
		throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	unpack_oparms(p + *p, e);
}
MessageCPG::~MessageCPG(void)
{
	if (evnt)
		delete evnt;
}

MessageCGP::print(iostream & str)
{
	str.form("Message-Call-Progress:");
	Message::print(str);
	if (evnt)
		evnt->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_USR   0x2d - User-to-user information
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: V(UUI) O()
 */
MessageUSR::MessageUSR(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		if (!(new ParameterUUI(pvar, p, e, uui)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	}
	unpack_oparms(p + *p, e);
}
MessageUSR::~MessageUSR(void)
{
	if (uui)
		delete uui;
}

MessageUSR::print(iostream & str)
{
	str.form("Message-User-to-User-Information:");
	Message::print(str);
	if (uui)
		uui->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_UCIC   0x2e - Unequipped circuit identification code
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (none)
 */
MessageUCIC::MessageUCIC(RoutingLabel & rl)
:  Message(rl)
{
}

MessageUCIC::print(iostream & str)
{
	str.form("Message-Unequipped-Circuit-Identification-Code:");
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CFN   0x2f - Confusion
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: V(CAUS) O()
 */
MessageCFM::MessageCFM(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		if (!(new ParameterCAUS(pvar, p, e, caus)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	}
	unpack_oparms(p + *p, e);
}
MessageCGM::~MessageCFM(void)
{
	if (caus)
		delete caus;
}

MessageCGM::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Confusion:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (caus)
		caus->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_OLM   0x30 - Overload
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: (none)
 */
MessageOLM::MessageOLM(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI)
		upack_oparms(p + *p, e);
}

Message::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Overload:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CRG   0x31 - Charge information
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: (none)
 *  SING: ICCI O()
 *  SPAN: O()
 */
MessageCRG::MessageCRG(RoutingLabel & rl)
:  Message(rl)
{
	switch (pvar & SS7_PVAR_MASK) {
	case SS7_PVAR_ANSI:
		break;
	default:
	case SS7_PVAR_ITUT:
		return;
	case SS7_PVAR_SPAN:
		break;
	case SS7_PVAR_SING:
		if (!(new ParameterICCI(pvar, p, e, icci)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
		break;
	}
	unpack_oparms(p + *p, e);
}
MessageCRG::~MessageCRG(void)
{
	if (icci)
		delete icci;
}

Message::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Charge-Information:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (icci)
		icci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_NRM   0x32 - Network resource management
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: O(MCI PCI ECI TMU)
 */
MessageNRM::MessageNRM(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageNRM::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Network-Resource-Management:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_FAC   0x33 - Facility
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: O(MCI PCI ROPS SA)
 */
MessageFAC::MessageFAC(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageFAC::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Facility:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_UPT   0x34 - User part test
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: O(PCI)
 */
MessageUPT::MessageUPT(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageUPT::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-User-Part-Test:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_UPA   0x35 - User part available
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: O(PCI)
 */
MessageUPA::MessageUPA(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageUPA::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-User-Part-Available:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_IDR   0x36 - Identification request
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: O(MCIQ MCI PCI)
 */
MessageIDR::MessageIDR(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageIDR::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Identification-Request:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_IRS   0x37 - Identification response
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: O(MCIR MCI PCI CGPN ATP GNUM*)
 */
MessageIRS::MessageIRS(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageIRS::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Identification-Response:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_SGM   0x38 - Segmentation
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: O(ATP UUI MCI GDIG* GNOT* GNUM*)
 */
MessageSGM::MessageSGM(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageSGM::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI) {
		str.form("Message-Segmentation:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CRA   0xe9 - Circuit Reservation Acknowledgement (Bellcore)
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (no such message)
 */
MessageCRA::MessageCRA(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
		unpack_oparms(p + *p, e);
}

MessageCRA::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		str.form("Message-Circuit-Reservation-Acknowledgement:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CRM   0xea - Circuit Reservation (Bellcore)
 *  -------------------------------------------------------------------------
 *  ANSI: NCI
 *  ITUT: (no such message)
 */
MessageCRM::MessageCRM(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		if (!(new ParameterNCI(pvar, p, e, nci)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	} else {
		unpack_oparms(p + *p, e);
	}
}
MessageCRM::~MessageCRM(void)
{
	if (nci)
		delete nci;
}

MessageCRM::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		str.form("Message-Circuit-Reservation:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (nci)
		nci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CVR   0xeb - Circuit Validation Response (Bellcore)
 *  -------------------------------------------------------------------------
 *  ANSI: CVRI CGCI O()
 *  ITUT: (no such message)
 */
MessageCVR::MessageCVR(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		if (!(new ParameterCVRI(pvar, p, e, cvri)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
		if (!(new ParameterCGCI(pvar, p, e, cgci)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	}
	unpack_oparms(p + *p, e);
}
MessageCVR::~MessageCVR(void)
{
	if (cvri)
		delete cvri;
	if (cgci)
		delete cgci;
}

MessageCVR::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		str.form("Message-Circuit-Validation-Response:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (cvri)
		cvri->print(str);
	if (cgci)
		cgci->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CVT   0xec - Circuit Validation Test (Bellcore)
 *  -------------------------------------------------------------------------
 *  ANSI: (none)
 *  ITUT: (no such message)
 */
MessageCVT::MessageCVT(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_ANSI)
		unpack_oparms(p + *p, e);
}

MessageCVT::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		str.form("Message-Circuit-Validation-Test:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_EXM   0xed - Exit (Bellcore)
 *  -------------------------------------------------------------------------
 *  ANSI: O()
 *  ITUT: (no such message)
 */
MessageEXM::MessageEXM(RoutingLabel & rl)
:  Message(rl)
{
	unpack_oparms(p + *p, e);
}

MessageEXM::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_ANSI) {
		str.form("Message-Exit:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_NON   0xf8 - National Notification (Spain)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: (no such message)
 *  SPAN: TON
 */
MessageNON::MessageNON(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_SPAN) {
		if (!(new ParameterTON(pvar, p, e, ton)))
			throw UnixError(__PRETTY_FUNCTION__, -ENOMEM);
	} else {
		unpack_oparms(p + *p, e);
	}
}
MessageNON::~MessageNON(void)
{
	if (ton)
		delete ton;
}

MessageNON::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_SPAN) {
		str.form("Message-National-Notification:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (ton)
		ton->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_LLM   0xfc - National Malicious Call (Spain)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: (no such message)
 *  SPAN: (none)
 */
MessageLLM::MessageLLM(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SPAN) {
		unpack_oparms(p + *p, e);
	}
}

MessageLLM::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_SPAN) {
		str.form("Message-National-Malicious-Call:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_CAK   0xfd - Charge Acknowledgement (Singapore)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: (no such message)
 *  SING: (none)
 */
MessageCAK::MessageCAK(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SING) {
		unpack_oparms(p + *p, e);
	}
}

MessageCAK::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_SING) {
		str.form("Message-Charge-Acknowledgement:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_TCM   0xfe - Tariff Charge (Singapore)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: (no such message)
 *  SING: CRI
 */
MessageTCM::MessageTCM(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_SING) {
		unpack_one(p, e, cri);
	} else {
		unpack_oparms(p + *p, e);
	}
}

MessageTCM::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_SING) {
		str.form("Message-Tariff-Charge:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (cri)
		cri->print(str);
	if (oparms)
		oparms->print(str);
}

/*
 *  ISUP_MT_MCP   0xff - Malicious Call Print (Singapore)
 *  -------------------------------------------------------------------------
 *  ANSI: (no such message)
 *  ITUT: (no such message)
 *  SING: (none)
 */
MessageMCP::MessageMCP(RoutingLabel & rl)
:  Message(rl)
{
	if ((pvar & SS7_PVAR_MASK) != SS7_PVAR_SING) {
		unpack_oparms(p + *p, e);
	}
}

MessageMCP::print(iostream & str)
{
	if ((pvar & SS7_PVAR_MASK) == SS7_PVAR_SING) {
		str.form("Message-Malicious-Call-Print:");
	} else {
		str.form("Message-Unrecognized-Message-%d:", routLabel.mt);
	}
	Message::print(str);
	if (oparms)
		oparms->print(str);
}

//  -------------------------------------------------------------------------
//
//  Collector
//
//  -------------------------------------------------------------------------

//  -------------------------------------------------------------------------
//
//  Call
//
//  -------------------------------------------------------------------------

Call::message(MessageIAM * m)
{
	switch (c_state) {
	case CTS_IDLE:
	case CTS_WAIT_IAM:
	case CTS_WAIT_LPA:
	case CTS_ICC_WAIT_COT_CCR:
	case CTS_OGC_WAIT_COT_CCR:
	case CTS_ICC_WAIT_LPA_CCR:
	case CTS_OGC_WAIT_LPA_CCR:
	case CTS_ICC_WAIT_CCR:
	case CTS_OGC_WAIT_CCR:
	case CTS_ICC_WAIT_COR_SAM:
	case CTS_OGC_WAIT_COR_SAM:
	case CTS_ICC_WAIT_COT_SAM:
	case CTS_OGC_WAIT_COT_SAM:
	case CTS_ICC_WAIT_LPA_SAM:
	case CTS_OGC_WAIT_LPA_SAM:
	case CTS_ICC_WAIT_SAM:
	case CTS_OGC_WAIT_SAM:
	case CTS_ICC_WAIT_COR_ACM:
	case CTS_OGC_WAIT_COR_ACM:
	case CTS_ICC_WAIT_COT_ACM:
	case CTS_OGC_WAIT_COT_ACM:
	case CTS_ICC_WAIT_LPA_ACM:
	case CTS_OGC_WAIT_LPA_ACM:
	case CTS_ICC_WAIT_ACM:
	case CTS_OGC_WAIT_ACM:
	case CTS_ICC_WAIT_ANM:
	case CTS_OGC_WAIT_ANM:
	case CTS_ICC_ANSWERED:
	case CTS_OGC_ANSWERED:
	case CTS_ICC_SUSPENDED:
	case CTS_OGC_SUSPENDED:
	case CTS_ICC_WAIT_RLC:
	case CTS_OGC_WAIT_RLC:
	case CTS_ICC_SEND_RLC:
	case CTS_OGC_SEND_RLC:
	}
}

Call::message(MessageSAM * m)
{
}

Call::message(MessageINR * m)
{
}

Call::message(MessageINF * m)
{
}

Call::message(MessageCOT * m)
{
}

Call::message(MessageACM * m)
{
}

Call::message(MessageCON * m)
{
}

Call::message(MessageFOT * m)
{
}

Call::message(MessageANM * m)
{
}

Call::message(MessageREL * m)
{
}

Call::message(MessageSUS * m)
{
}

Call::message(MessageRES * m)
{
}

Call::message(MessageRLC * m)
{
}

Call::message(MessageCCR * m)
{
}

Call::message(MessageRSC * m)
{
}

Call::message(MessageBLO * m)
{
}

Call::message(MessageUBL * m)
{
}

Call::message(MessageBLA * m)
{
}

Call::message(MessageUBA * m)
{
}

Call::message(MessageGRS * m)
{
}

Call::message(MessageCGB * m)
{
}

Call::message(MessageCGU * m)
{
}

Call::message(MessageCGBA * m)
{
}

Call::message(MessageCGUA * m)
{
}

Call::message(MessageCMR * m)
{
}

Call::message(MessageCMC * m)
{
}

Call::message(MessageCMRJ * m)
{
}

Call::message(MessageFAR * m)
{
}

Call::message(MessageFAA * m)
{
}

Call::message(MessageFRJ * m)
{
}

Call::message(MessageFAD * m)
{
}

Call::message(MessageFAI * m)
{
}

Call::message(MessageLPA * m)
{
}

Call::message(MessageDRS * m)
{
}

Call::message(MessagePAM * m)
{
}

Call::message(MessageGRA * m)
{
}

Call::message(MessageCQM * m)
{
}

Call::message(MessageCQR * m)
{
}

Call::message(MessageCPG * m)
{
}

Call::message(MessageUSR * m)
{
}

Call::message(MessageUCIC * m)
{
}

Call::message(MessageCFN * m)
{
}

Call::message(MessageOLM * m)
{
}

Call::message(MessageCRG * m)
{
}

Call::message(MessageNRM * m)
{
}

Call::message(MessageFAC * m)
{
}

Call::message(MessageUPT * m)
{
}

Call::message(MessageUPA * m)
{
}

Call::message(MessageIDR * m)
{
}

Call::message(MessageIRS * m)
{
}

Call::message(MessageSGM * m)
{
}

Call::message(MessageCRA * m)
{
}

Call::message(MessageCRM * m)
{
}

Call::message(MessageCVR * m)
{
}

Call::message(MessageCVT * m)
{
}

Call::message(MessageEXM * m)
{
}

Call::message(MessageNON * m)
{
}

Call::message(MessageLLM * m)
{
}

Call::message(MessageCAK * m)
{
}

Call::message(MessageTCM * m)
{
}

Call::message(MessageMCP * m)
{
}


Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/daemons/isupmon/isupmon.cpp

OpenSS7
SS7 for the
Common Man
Home Overview Status News Documentation Resources About

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified: