[libss7-commits] mattf: trunk r2 - /trunk/

libss7-commits at lists.digium.com libss7-commits at lists.digium.com
Tue Aug 1 16:51:54 MST 2006


Author: mattf
Date: Tue Aug  1 18:51:53 2006
New Revision: 2

URL: http://svn.digium.com/view/libss7?rev=2&view=rev
Log:
Inital check-in of libss7.  Yay!!!!

Added:
    trunk/Makefile
    trunk/isup.c
    trunk/isup.h
    trunk/libss7.h
    trunk/mkdep   (with props)
    trunk/mtp2.c
    trunk/mtp2.h
    trunk/mtp3.c
    trunk/mtp3.h
    trunk/ss7.c
    trunk/ss7_internal.h
    trunk/ss7_sched.c
    trunk/ss7linktest.c
    trunk/ss7test.c

Added: trunk/Makefile
URL: http://svn.digium.com/view/libss7/trunk/Makefile?rev=2&view=auto
==============================================================================
--- trunk/Makefile (added)
+++ trunk/Makefile Tue Aug  1 18:51:53 2006
@@ -1,0 +1,58 @@
+CC=gcc
+
+OSARCH=$(shell uname -s)
+
+INSTALL_PREFIX?=
+INSTALL_BASE=/usr
+STATIC_OBJS=mtp2.o ss7_sched.o ss7.o mtp3.o isup.o
+DYNAMIC_OBJS=mtp2.o ss7_sched.o ss7.o mtp3.o isup.o
+STATIC_LIBRARY=libss7.a
+DYNAMIC_LIBRARY=libss7.so.1.0
+CFLAGS=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -g -fPIC
+LDCONFIG_FLAGS=-n
+SOFLAGS=-Wl,-hlibss7.so.1
+LDCONFIG=/sbin/ldconfig
+
+all: depend $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY) ss7test ss7linktest
+
+%.lo : %.c
+	$(CC) -g -fPIC $(CFLAGS) -o $@ -c $<
+
+clean:
+	rm -f *.o *.so *.lo *.so.1 *.so.1.0
+	rm -f ss7linktest ss7test $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
+	rm -f .depend
+
+install: $(STATIC_LIBRARY) $(DYNAMIC_LIBRARY)
+	mkdir -p $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
+	mkdir -p $(INSTALL_PREFIX)$(INSTALL_BASE)/include
+
+	install -m 644 libss7.h $(INSTALL_PREFIX)$(INSTALL_BASE)/include
+	install -m 755 $(DYNAMIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
+	( cd $(INSTALL_PREFIX)$(INSTALL_BASE)/lib ; ln -sf libss7.so.1 libss7.so ; $(SOSLINK) )
+	install -m 644 $(STATIC_LIBRARY) $(INSTALL_PREFIX)$(INSTALL_BASE)/lib
+
+	if test $$(id -u) = 0; then $(LDCONFIG); fi
+
+$(STATIC_LIBRARY): $(STATIC_OBJS)
+	ar rcs $(STATIC_LIBRARY) $(STATIC_OBJS)
+	ranlib $(STATIC_LIBRARY)
+
+$(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS)
+	$(CC) -shared $(SOFLAGS) -o $@ $(DYNAMIC_OBJS)
+	$(LDCONFIG) $(LDCONFIG_FLAGS) .
+	ln -sf libss7.so.1 libss7.so
+	$(SOSLINK)
+
+ss7test: ss7test.c $(STATIC_LIBRARY)
+	gcc -g -o ss7test ss7test.c libss7.a -lpthread
+
+ss7linktest: ss7linktest.c $(STATIC_LIBRARY)
+	gcc -g -o ss7linktest ss7linktest.c libss7.a -lpthread
+
+libss7: ss7_mtp.o mtp.o ss7.o ss7_sched.o
+
+depend: .depend
+
+.depend:
+	./mkdep ${CLAGS} `ls *.c`

Added: trunk/isup.c
URL: http://svn.digium.com/view/libss7/trunk/isup.c?rev=2&view=auto
==============================================================================
--- trunk/isup.c (added)
+++ trunk/isup.c Tue Aug  1 18:51:53 2006
@@ -1,0 +1,967 @@
+/*
+libss7: An implementation of Signalling System 7
+
+Written by Matthew Fredrickson <creslin at digium.com>
+
+Copyright (C) 2005
+All Rights Reserved.
+
+This program is free software; you can redistribute it under the
+terms of the GNU General Public License as published by the Free
+Software Foundation
+
+Contains definitions and data structurs for the ISUP portion of SS7
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include "libss7.h"
+#include "isup.h"
+#include "ss7_internal.h"
+#include "mtp3.h"
+
+#define FUNC_DUMP(name) int ((name))(struct ss7 *ss7, struct isup_call *c, int messagetype, unsigned char *parm, int len)
+/* Length here is paramter length */
+#define FUNC_RECV(name) int ((name))(struct ss7 *ss7, struct isup_call *c, int messagetype, unsigned char *parm, int len)
+/* Length here is maximum length */
+#define FUNC_SEND(name) int ((name))(struct ss7 *ss7, struct isup_call *c, int messagetype, unsigned char *parm, int len)
+
+#define PARM_TYPE_FIXED 0x01
+#define PARM_TYPE_VARIABLE 0x02
+#define PARM_TYPE_OPTIONAL 0x03
+
+#define CODE_CCITT 0x0
+
+#define LOC_PRIV_NET_LOCAL_USER 0x1
+
+struct parm_func {
+	int parm;
+	char *name;
+	FUNC_DUMP(*dump);
+	FUNC_RECV(*receive);
+	FUNC_SEND(*transmit);
+};
+
+static int iam_params[] = {ISUP_PARM_NATURE_OF_CONNECTION_IND, ISUP_PARM_FORWARD_CALL_IND, ISUP_PARM_CALLING_PARTY_CAT,
+	ISUP_PARM_TRANSMISSION_MEDIUM_REQS, ISUP_PARM_CALLED_PARTY_NUM, ISUP_PARM_CALLING_PARTY_NUM, -1}; /* Don't have optional IEs */
+
+static int acm_params[] = {ISUP_PARM_BACKWARD_CALL_IND, -1};
+
+static int anm_params[] = { -1};
+
+static int rel_params[] = { ISUP_PARM_CAUSE, -1};
+
+static int rlc_params[] = { -1};
+
+static int grs_params[] = { ISUP_PARM_RANGE_AND_STATUS, -1};
+
+static struct message_data {
+	int messagetype;
+	int mand_fixed_params;
+	int mand_var_params;
+	int opt_params;
+	int *param_list;
+} messages[] = {
+	{ISUP_IAM, 4, 1, 1, iam_params},
+	{ISUP_ACM, 1, 0, 1, acm_params},
+	{ISUP_ANM, 0, 0, 1, anm_params},
+	{ISUP_REL, 0, 1, 1, rel_params},
+	{ISUP_RLC, 0, 0, 1, rlc_params},
+	{ISUP_GRS, 0, 1, 0, grs_params},
+	{ISUP_GRA, 0, 1, 0, grs_params},
+};
+
+static int isup_send_message(struct ss7 *ss7, struct isup_call *c, int messagetype, int parms[]);
+
+static char * message2str(unsigned char message)
+{
+	switch (message) {
+		case ISUP_IAM:
+			return "IAM";
+		case ISUP_ACM:
+			return "ACM";
+		case ISUP_ANM:
+			return "ANM";
+		case ISUP_REL:
+			return "REL";
+		case ISUP_RLC:
+			return "RLC";
+		case ISUP_GRS:
+			return "GRS";
+		case ISUP_GRA:
+			return "GRA";
+		default:
+			return "Unknown";
+	}
+}
+
+static char char2digit(char localchar)
+{
+	switch (localchar) {
+		case '0':
+			return 0;
+		case '1':
+			return 1;
+		case '2':
+			return 2;
+		case '3':
+			return 3;
+		case '4':
+			return 4;
+		case '5':
+			return 5;
+		case '6':
+			return 6;
+		case '7':
+			return 7;
+		case '8':
+			return 8;
+		case '9':
+			return 9;
+		case '*':
+			return 0xf;
+		default:
+			return 0;
+	}
+}
+
+static char digit2char(unsigned char digit)
+{
+	switch (digit & 0xf) {
+		case 0:
+			return '0';
+		case 1:
+			return '1';
+		case 2:
+			return '2';
+		case 3:
+			return '3';
+		case 4:
+			return '4';
+		case 5:
+			return '5';
+		case 6:
+			return '6';
+		case 7:
+			return '7';
+		case 8:
+			return '8';
+		case 9:
+			return '9';
+		case 15:
+			return '*';
+		default:
+			return 0;
+	}
+}
+
+static void isup_dump_buffer(struct ss7 *ss7, unsigned char *data, int len)
+{
+	int i;
+
+	ss7_message(ss7, "[");
+	for (i = 0; i < len; i++) {
+		ss7_message(ss7, "0x%x ", data[i]);
+	}
+	ss7_message(ss7, "]\n");
+}
+
+static void isup_get_number(char *dest, char *src, int srclen, int oddeven)
+{
+	int i;
+	for (i = 0; i < ((srclen * 2) - oddeven); i++)
+		dest[i] = digit2char(src[i/2] >> ((i % 2) ? 4 : 0));
+
+	dest[i] = '\0'; 
+}
+
+static void isup_put_number(char *dest, char *src, int *len, int *oddeven)
+{
+	int i = 0;
+	int numlen = strlen(src);
+
+	if (numlen % 2) {
+		*oddeven = 1;
+		*len = numlen/2 + 1;
+	} else {
+		*oddeven = 0;
+		*len = numlen/2;
+	}
+
+	while (i < numlen) {
+		if (!(i % 2))
+			dest[i/2] |= char2digit(src[i]) & 0xf;
+		else
+			dest[i/2] |= (char2digit(src[i]) << 4) & 0xf0;
+		i++;
+	}
+}
+
+static FUNC_SEND(nature_of_connection_ind_transmit)
+{
+	parm[0] = 0x00;
+	
+	return 1; /* Length plus size of type header */
+}
+
+static FUNC_RECV(nature_of_connection_ind_receive)
+{
+	c->echocan = (parm[0] & 0x10) >> 4;
+	c->satellites = parm[0] & 0x3;
+	return 1;
+}
+
+static FUNC_DUMP(nature_of_connection_ind_dump)
+{
+	unsigned char con = parm[0];
+	char *continuity;
+	
+	ss7_message(ss7, "PARM: Nature of Connection\n");
+	ss7_message(ss7, "	Satellites in connection: %d\n", con&0x03);
+	con>>=2; 
+	switch (con & 0x03) {
+		case 0:
+			continuity = "Check not required";
+			break;
+		case 1:
+			continuity = "Check required on this circuit";
+			break;
+		case 2:
+			continuity = "Check required on previous circuit";
+			break;
+		case 3:
+			continuity = "spare";
+			break;
+	}
+	ss7_message(ss7, "	Continuity Check: %s\n", continuity);
+	con>>=2;
+	con &= 0x01;
+
+	ss7_message(ss7, "	Outgoing half echo control device %s\n", con ? "included" : "not included");
+
+	return 2;
+}
+
+
+static FUNC_SEND(forward_call_ind_transmit)
+{
+	parm[0] = 0x60;
+
+#if 0
+	if (c->international)
+		parm[0] |= 0x01;
+#endif
+
+	parm[1] = 0x01;
+
+#if 0
+	if (c->originatedisdn)
+		parm[1] |= 0x01;
+#endif
+	
+	return 2;
+}
+
+static FUNC_RECV(forward_call_ind_receive)
+{
+#if 0
+	c->international = parm[0] & 0x01;
+	c->originatedisdn = parm[1] & 0x01;
+#endif
+	return 2;
+}
+
+static FUNC_RECV(calling_party_cat_receive)
+{
+	/* TODO */
+	return 1;
+}
+	
+static FUNC_SEND(calling_party_cat_transmit)
+{
+	/* Default to unknown */
+	parm[0] = 0x0a;
+	return 1;
+}
+
+static FUNC_RECV(user_service_info_receive)
+{
+	return 3;
+}
+
+static FUNC_SEND(user_service_info_transmit)
+{
+	parm[0] = 0x80; /* Default to ITU standardized coding */
+	parm[0] |= c->transcap;
+
+	parm[1] = 0x90; /* Assume 64kbps, circuit mode */
+
+	parm[2] = 0xa0; /* Layer 1 ID */
+	parm[2] |= c->l1prot;
+	return 3;
+}
+
+static FUNC_SEND(transmission_medium_reqs_transmit)
+{
+	/* Speech */
+	parm[0] = 0;
+	return 1;
+}
+
+static FUNC_RECV(transmission_medium_reqs_receive)
+{
+	c->transcap = parm[0] & 0x7f;
+	return 1;
+}
+
+/* For variable length parameters we pass in the length of the parameter */
+static FUNC_RECV(called_party_num_receive)
+{
+	int odd = 0;
+
+	if (parm[0] & 0x80)
+		odd = 1;
+	
+	isup_get_number(c->called_party_num, &parm[2], len - 2, odd);
+
+	return len;
+}
+
+static FUNC_SEND(called_party_num_transmit)
+{
+	int numlen, oddeven;
+
+	isup_put_number(&parm[2], c->called_party_num, &numlen, &oddeven);
+
+	parm[0] = 0x03; /* Assume unknown */
+	
+	if (oddeven)
+		parm[0] |= 0x80; /* Odd number of digits */
+
+	parm[1] = 0x00; /* Assume unknown numbering plan */
+
+	return numlen + 2;
+}
+
+static FUNC_RECV(backward_call_ind_receive)
+{
+	if (parm[1] & 0x20)
+		c->echocan = 1;
+	else 
+		c->echocan = 0;
+
+	return 2;
+}
+
+static FUNC_SEND(backward_call_ind_transmit)
+{
+	parm[0] = 0x40;
+	parm[1] = 0x14;
+	if (c->echocan)
+		parm[1] |= 0x20;
+	return 2;
+}
+
+static FUNC_RECV(cause_receive)
+{
+	c->causeloc = parm[0] & 0xf;
+	c->causecode = (parm[0] & 0x60) >> 5;
+	c->cause = (parm[1] & 0x7f);
+
+	return 2;
+}
+
+static FUNC_SEND(cause_transmit)
+{
+	parm[0] = 0x80 | (c->causecode << 5) | c->causeloc;
+	parm[1] = 0x80 | c->cause;
+	return 2;
+}
+
+
+static FUNC_DUMP(range_and_status_dump)
+{
+	ss7_message(ss7, "\tPARM: Range and Status\n");
+	ss7_message(ss7, "\t	Range: %d\n", parm[0] & 0xff);
+	return len;
+}
+
+static FUNC_RECV(range_and_status_receive)
+{
+	c->range = parm[0];
+
+	return len;
+}
+
+static FUNC_SEND(range_and_status_transmit)
+{
+	int i, statuslen = 0;
+	int numcics = c->range + 1;
+
+	parm[0] = c->range & 0xff;
+
+	if (messagetype == ISUP_GRS)
+		return 1;
+	
+	statuslen = (numcics / 8) + !!(numcics % 8);
+
+	for (i = 0; i < statuslen; i++) {
+		parm[1 + i] = 0;
+	}
+
+	return statuslen + 1;
+}
+
+static FUNC_DUMP(calling_party_num_dump)
+{
+	int oddeven = (parm[0] >> 7) & 0x1;
+	char numbuf[64] = "";
+
+	ss7_message(ss7, "PARM: Calling Party Number\n");
+	ss7_message(ss7, "Odd/even: %x\n", (parm[0] >> 7) & 0x1);
+	ss7_message(ss7, "Nature of address: %x\n", parm[0] & 0x7f);
+	ss7_message(ss7, "NI: %x\n", (parm[1] >> 7) & 0x1);
+	ss7_message(ss7, "Numbering plan: %x\n", (parm[1] >> 4) & 0x7);
+	ss7_message(ss7, "Presentation: %x\n", (parm[1] >> 2) & 0x3);
+	ss7_message(ss7, "Screening: %x\n", parm[1] & 0x3);
+
+	isup_get_number(numbuf, &parm[2], len - 2, oddeven);
+
+	ss7_message(ss7, "Address signals: %s\n", numbuf);
+
+	return len;
+}
+
+static FUNC_RECV(calling_party_num_receive)
+{
+	int oddeven = (parm[0] >> 7) & 0x1;
+
+	isup_get_number(c->calling_party_num, &parm[2], len - 2, oddeven);
+
+	return len;
+}
+
+static FUNC_SEND(calling_party_num_transmit)
+{
+	int oddeven, datalen;
+
+	if (!c->calling_party_num[0])
+		return 0;
+
+	isup_put_number(&parm[2], c->calling_party_num, &datalen, &oddeven);
+
+	parm[0] = (oddeven << 7) | 0x3;
+	parm[1] = 0x11;
+
+	return datalen + 2;
+}
+
+static struct parm_func parms[] = {
+	{ISUP_PARM_NATURE_OF_CONNECTION_IND, "Nature of Connection Indicator", nature_of_connection_ind_dump, nature_of_connection_ind_receive, nature_of_connection_ind_transmit },
+	{ISUP_PARM_FORWARD_CALL_IND, "Forward Call Indicator", NULL, forward_call_ind_receive, forward_call_ind_transmit },
+	{ISUP_PARM_CALLING_PARTY_CAT, "Calling Party Category", NULL, calling_party_cat_receive, calling_party_cat_transmit},
+	{ISUP_PARM_TRANSMISSION_MEDIUM_REQS, "Transmission Medium Requirements", NULL, transmission_medium_reqs_receive, transmission_medium_reqs_transmit},
+	{ISUP_PARM_USER_SERVICE_INFO, "User Service Information", NULL, user_service_info_receive, user_service_info_transmit},
+	{ISUP_PARM_CALLED_PARTY_NUM, "Called Party Number", NULL, called_party_num_receive, called_party_num_transmit},
+	{ISUP_PARM_CAUSE, "Cause Indicator", NULL, cause_receive, cause_transmit},
+	{ISUP_PARM_ACCESS_TRANS, "Access Transport"},
+	{ISUP_PARM_BUSINESS_GRP, "Business Group"},
+	{ISUP_PARM_CALL_REF, "Call Reference"},
+	{ISUP_PARM_CALLING_PARTY_NUM, "Calling Party Number", calling_party_num_dump, calling_party_num_receive, calling_party_num_transmit},
+	{ISUP_PARM_CARRIER_ID, "Carrier Identification"},
+	{ISUP_PARM_SELECTION_INFO, "Selection Information"},
+	{ISUP_PARM_CHARGE_NUMBER, "Charge Number"},
+	{ISUP_PARM_CIRCUIT_ASSIGNMENT_MAP, "Circuit Assignment Map"},
+	{ISUP_PARM_CONNECTION_REQ, "Connection Request"},
+	{ISUP_PARM_CUG_INTERLOCK_CODE, "Interlock Code"},
+	{ISUP_PARM_EGRESS_SERV, "Egress Service"},
+	{ISUP_PARM_GENERIC_ADDR, "Generic Address"},
+	{ISUP_PARM_GENERIC_DIGITS, "Generic Digits"},
+	{ISUP_PARM_GENERIC_NAME, "Generic Name"},
+	{ISUP_PARM_GENERIC_NOTIFICATION_IND, "Generic Notification Indication"},
+	{ISUP_PARM_BACKWARD_CALL_IND, "Backward Call Indicator", NULL, backward_call_ind_receive, backward_call_ind_transmit},
+	{ISUP_PARM_RANGE_AND_STATUS, "Range and status", range_and_status_dump, range_and_status_receive, range_and_status_transmit},
+};
+
+static char * param2str(int parm)
+{
+	int x;
+	int totalparms = sizeof(parms)/sizeof(struct parm_func);
+	for (x = 0; x < totalparms; x++)
+		if (parms[x].parm == parm)
+			return parms[x].name;
+
+	return "Unknown";
+}
+
+struct isup_call * isup_new_call(struct ss7 *ss7)
+{
+	struct isup_call *c, *cur;
+	c = calloc(1, sizeof(struct isup_call));
+	if (!c)
+		return NULL;
+	cur = ss7->calls;
+	if (cur) {
+		while (cur->next)
+			cur = cur->next;
+		cur->next = c;
+	} else
+		ss7->calls = c;
+
+	return c;
+}
+
+void isup_init_call(struct isup_call *c, int cic, char *calledpartynum, char *callingpartynum)
+{
+	c->cic = cic;
+	if (calledpartynum && calledpartynum[0])
+		snprintf(c->called_party_num, sizeof(c->called_party_num), "%s*", calledpartynum);
+
+	if (callingpartynum && callingpartynum[0])
+		strncpy(c->calling_party_num, callingpartynum, sizeof(c->calling_party_num));
+
+}
+
+static struct isup_call * isup_find_call(struct ss7 *ss7, int cic)
+{
+	struct isup_call *cur, *winner = NULL;
+
+	cur = ss7->calls;
+	while (cur) {
+		if (cur->cic == cic) {
+			winner = cur;
+			break;
+		}
+		cur = cur->next;
+	}
+
+	if (!winner) {
+		winner = isup_new_call(ss7);
+		winner->cic = cic;
+	}
+
+	return winner;
+}
+
+static void isup_free_call(struct ss7 *ss7, struct isup_call *c)
+{
+	struct isup_call *cur, *prev = NULL, *winner = NULL;
+
+	cur = ss7->calls;
+	while (cur) {
+		if (cur == c) {
+			winner = cur;
+			break;
+		}
+		prev = cur;
+		cur = cur->next;
+	}
+
+	if (!prev)
+		ss7->calls = winner->next;
+	else
+		prev->next = winner->next;
+
+	if (winner)
+		free(winner);
+
+	return;
+}
+
+static int do_parm(struct ss7 *ss7, struct isup_call *c, int message, int parm, unsigned char *parmbuf, int maxlen, int parmtype, int tx)
+{
+	struct isup_parm_opt *optparm = NULL;
+	int x;
+	int res = 0;
+	int totalparms = sizeof(parms)/sizeof(struct parm_func);
+
+	for (x = 0; x < totalparms; x++) {
+		if (parms[x].parm == parm) {
+			if ((tx && parms[x].transmit) || (!tx && parms[x].receive)) {
+				switch (parmtype) {
+					case PARM_TYPE_FIXED:
+						if (tx)
+							return parms[x].transmit(ss7, c, message, parmbuf, maxlen);
+						else
+							return parms[x].receive(ss7, c, message, parmbuf, maxlen);
+					case PARM_TYPE_VARIABLE:
+						if (tx) {
+							res = parms[x].transmit(ss7, c, message, parmbuf + 1, maxlen);
+							if (res > 0) {
+								parmbuf[0] = res;
+								return res + 1;
+							}
+							return res;
+						} else 
+							return 1 + parms[x].receive(ss7, c, message, parmbuf + 1, parmbuf[0]);
+					case PARM_TYPE_OPTIONAL:
+						optparm = (struct isup_parm_opt *)parmbuf;
+						if (tx) {
+							optparm->type = parms[x].parm;
+							res = parms[x].transmit(ss7, c, message, optparm->data, maxlen);
+							if (res > 0) {
+								optparm->len = res;
+							} else
+								return res;
+						} else
+							res = parms[x].receive(ss7, c, message, optparm->data, optparm->len);
+						return res + 2;
+				}
+			}
+		}
+	}
+	return -1;
+}
+
+static int isup_send_message(struct ss7 *ss7, struct isup_call *c, int messagetype, int parms[])
+{
+	struct ss7_msg *msg;
+	struct isup_h *mh = NULL;
+	unsigned char *rlptr;
+	int ourmessage = -1;
+	int rlsize;
+	unsigned char *varoffsets = NULL, *opt_ptr;
+	int varparams = 0;
+	int len = sizeof(struct ss7_msg);
+	struct routing_label rl;
+	int res = 0;
+	int offset = 0;
+	int x = 0;
+	int i = 0;
+
+	/* Do init stuff */
+	msg = ss7_msg_new();
+
+	if (!msg) {
+		ss7_error(ss7, "Allocation failed!\n");
+		return -1;
+	}
+
+	rlptr = ss7_msg_userpart(msg);
+	rl.opc = ss7->pc;
+	rl.sls = sls_next(ss7);
+	rl.dpc = ss7->def_dpc;
+	rl.type = ss7->switchtype;
+	rlsize = set_routinglabel(rlptr, &rl);
+	mh = (struct isup_h *)(rlptr + rlsize); /* Note to self, do NOT put a typecasted pointer next to an addition operation */
+
+	/* Set the CIC - ITU style */
+	if (ss7->switchtype == SS7_ITU) {
+		mh->cic[0] = c->cic & 0xff;
+		mh->cic[1] = (c->cic >> 8) & 0x0f;
+	} else {
+		ss7_error(ss7, "Incomplete support for non ITU style switchtypes\n");
+		return -1;
+	}
+
+	mh->type = messagetype;
+	/* Find the metadata for our message */
+	for (x = 0; x < sizeof(messages)/sizeof(struct message_data); x++)
+		if (messages[x].messagetype == messagetype)
+			ourmessage = x;
+			
+	if (ourmessage < 0) {
+		ss7_error(ss7, "Unable to find message %d in message list!\n", mh->type);
+		return -1;
+	}
+
+	/* Add fixed params */
+	for (x = 0; x < messages[ourmessage].mand_fixed_params; x++) {
+		res = do_parm(ss7, c, mh->type, parms[x], (void *)(mh->data + offset), len, PARM_TYPE_FIXED, 1);
+
+		if (res < 0) {
+			ss7_error(ss7, "!! Unable to add mandatory fixed parameter '%s'\n", param2str(parms[x]));
+			return -1;
+		}
+
+		len -= res;
+		offset += res;
+	}
+
+	varparams = messages[ourmessage].mand_var_params;
+	varoffsets = &mh->data[offset];
+	/* Make sure we grab our opional parameters */
+	if (messages[ourmessage].opt_params) {
+		opt_ptr = &mh->data[offset + varparams];
+		offset += varparams + 1; /* add one for the optionals */
+		len -= varparams + 1;
+	} else {
+		offset += varparams;
+		len -= varparams;
+	}
+	i = 0;
+
+	/* Whew, some complicated math for all of these offsets and different sections */
+	for (; (x - messages[ourmessage].mand_fixed_params) < varparams; x++) {
+		varoffsets[i] = &mh->data[offset] - &varoffsets[i];
+		i++;
+		res = do_parm(ss7, c, mh->type, parms[x], (void *)(mh->data + offset), len, PARM_TYPE_VARIABLE, 1); /* Find out what else we need to add */
+
+		if (res < 0) {
+			ss7_error(ss7, "!! Unable to add mandatory variable parameter '%s'\n", param2str(parms[x]));
+			return -1;
+		}
+
+		len -= res;
+		offset += res;
+	}
+       	/* Optional parameters */
+	if (messages[ourmessage].opt_params) {
+		int addedparms = 0;
+		int offsetbegins = offset;
+		while (parms[x] > -1) {
+			res = do_parm(ss7, c, mh->type, parms[x], (void *)(mh->data + offset), len, PARM_TYPE_OPTIONAL, 1); /* Find out what else we need to add */
+			x++;
+	
+			if (res < 0) {
+				ss7_error(ss7, "!! Unable to add optional parameter '%s'\n", param2str(parms[x]));
+				return -1;
+			}
+
+			if (res > 0)
+				addedparms++;
+	
+			len -= res;
+			offset += res;
+		}
+
+		if (addedparms) {
+			*opt_ptr = &mh->data[offsetbegins] - opt_ptr;
+			/* Add end of optional parameters */
+			mh->data[offset++] = 0;
+		} else
+			*opt_ptr = 0;
+
+	}
+
+	ss7_msg_userpart_len(msg, offset + rlsize + CIC_SIZE + 1);   /* Message type length is 1 */
+
+	return mtp3_transmit(ss7, SIG_ISUP, rl.sls, msg);
+}
+
+int isup_dump(struct ss7 *ss7, struct mtp2 *link, unsigned char *buf, int len)
+{
+	struct isup_h *mh;
+	unsigned short cic;
+	int ourmessage = -1;
+	int x;
+
+	mh = (struct isup_h*) buf;
+
+	if (ss7->switchtype == SS7_ITU) {
+		cic = mh->cic[0] | ((mh->cic[1] << 8) & 0x0f);
+	} else {
+		ss7_error(ss7, "Don't handle non ITU switchtypes yet\n");
+		return -1;
+	}
+	/* Find us in the message list */
+	for (x = 0; x < sizeof(messages)/sizeof(struct message_data); x++)
+		if (messages[x].messagetype == mh->type)
+			ourmessage = x;
+
+	if (ourmessage < 0) {
+		ss7_error(ss7, "!! Unable to handle message of type 0x%x\n", mh->type);
+		return -1;
+	}
+
+	ss7_message(ss7, "\t\tMessage Type: %s (%x)\n", message2str(mh->type), mh->type & 0xff);
+	ss7_message(ss7, "\t\tCIC: %d\n", cic);
+
+	return 0;
+}
+
+int isup_receive(struct ss7 *ss7, struct mtp2 *link, unsigned char *buf, int len)
+{
+	unsigned short cic;
+	struct isup_h *mh;
+	struct isup_call *c;
+	int i;
+	int *parms = NULL;
+	int offset = 0;
+	int ourmessage = -1;
+	int varparams = 0;
+	int res, x;
+	unsigned char *opt_ptr = NULL;
+	ss7_event *e;
+
+	mh = (struct isup_h*) buf;
+	if (ss7->switchtype == SS7_ITU) {
+		cic = mh->cic[0] | ((mh->cic[1] << 8) & 0x0f);
+	} else {
+		ss7_error(ss7, "Don't handle non ITU switchtypes yet\n");
+		return -1;
+	}
+
+	/* Find us in the message list */
+	for (x = 0; x < sizeof(messages)/sizeof(struct message_data); x++)
+		if (messages[x].messagetype == mh->type)
+			ourmessage = x;
+
+
+	if (ourmessage < 0) {
+		ss7_error(ss7, "!! Unable to handle message of type 0x%x\n", mh->type);
+		return -1;
+	}
+
+	c = isup_find_call(ss7, cic);
+
+	parms = messages[ourmessage].param_list;
+
+	/* Parse fixed parms */
+	for (x = 0; x < messages[ourmessage].mand_fixed_params; x++) {
+		res = do_parm(ss7, c, mh->type, parms[x], (void *)(mh->data + offset), len, PARM_TYPE_FIXED, 0);
+
+		if (res < 0) {
+			ss7_error(ss7, "!! Unable to parse mandatory fixed parameter '%s'\n", param2str(parms[x]));
+			return -1;
+		}
+
+		len -= res;
+		offset += res;
+	}
+
+	varparams = messages[ourmessage].mand_var_params;
+
+	if (varparams) {
+		offset += varparams; /* add one for the optionals */
+		res -= varparams;
+	}
+	if (messages[ourmessage].opt_params) {
+		opt_ptr = &mh->data[offset++];
+	}
+
+	i = 0;
+
+	for (; (x - messages[ourmessage].mand_fixed_params) < varparams; x++) {
+		res = do_parm(ss7, c, mh->type, parms[x], (void *)(mh->data + offset), len, PARM_TYPE_VARIABLE, 0); /* Find out what else we need to add */
+
+		if (res < 0) {
+			ss7_error(ss7, "!! Unable to parse mandatory variable parameter '%s'\n", param2str(parms[x]));
+			return -1;
+		}
+
+		len -= res;
+		offset += res;
+	}
+
+	/* Optional paramter parsing code */
+	if (messages[ourmessage].opt_params && *opt_ptr) {
+		while ((len > 0) && (mh->data[offset] != 0)) {
+			struct isup_parm_opt *optparm = (struct isup_parm_opt *)(mh->data + offset);
+
+			res = do_parm(ss7, c, mh->type, optparm->type, mh->data + offset, len, PARM_TYPE_OPTIONAL, 0); /* Find out what else we need to add */
+
+			if (res < 0) {
+				ss7_error(ss7, "!! Unable to parse optional parameter 0x%x '%s'\n", optparm->type, param2str(optparm->type));
+				isup_dump_buffer(ss7, mh->data + offset, len);
+				return -1;
+			}
+
+			len -= res;
+			offset += res;
+		}
+	}
+
+	e = ss7_next_empty_event(ss7);
+	if (!e) {
+		ss7_error(ss7, "Event queue full, unable to get next empty event\n");
+		return -1;
+	}
+
+	switch (mh->type) {
+		case ISUP_IAM:
+			e->e = ISUP_EVENT_IAM;
+			e->iam.cic = c->cic;
+			e->iam.transcap = c->transcap;
+			strncpy(e->iam.called_party_num, c->called_party_num, sizeof(e->iam.called_party_num));
+			strncpy(e->iam.calling_party_num, c->calling_party_num, sizeof(e->iam.calling_party_num));
+			e->iam.call = c;
+			return 0;
+		case ISUP_GRS:
+			e->e = ISUP_EVENT_GRS;
+			e->grs.startcic = cic;
+			e->grs.endcic = cic + c->range;
+			isup_free_call(ss7, c); /* Won't need this again */
+			return 0;
+		case ISUP_GRA:
+			e->e = ISUP_EVENT_GRA;
+			e->gra.startcic = cic;
+			e->gra.endcic = cic + c->range;
+			isup_free_call(ss7, c); /* Won't need this again */
+			return 0;
+		case ISUP_REL:
+			e->e = ISUP_EVENT_REL;
+			e->rel.cic = c->cic;
+			e->rel.call = c;
+			return 0;
+		case ISUP_ACM:
+			e->e = ISUP_EVENT_ACM;
+			e->acm.cic = c->cic;
+			e->acm.call = c;
+			return 0;
+		case ISUP_ANM:
+			e->e = ISUP_EVENT_ANM;
+			e->anm.cic = c->cic;
+			e->anm.call = c;
+			return 0;
+		case ISUP_RLC:
+			e->e = ISUP_EVENT_RLC;
+			e->rlc.cic = c->cic;
+			isup_free_call(ss7, c);
+			return 0;
+		default:
+			ss7_error(ss7, "!! Unable to handle message type %s\n", message2str(mh->type));
+			return -1;
+	}
+}
+
+int isup_grs(struct ss7 *ss7, int begincic, int endcic)
+{
+	struct isup_call call;
+	call.cic = begincic;
+	call.range = endcic - begincic;
+	return isup_send_message(ss7, &call, ISUP_GRS, grs_params);
+}
+
+int isup_gra(struct ss7 *ss7, int begincic, int endcic)
+{
+	struct isup_call call;
+	call.cic = begincic;
+	call.range = endcic - begincic;
+	return isup_send_message(ss7, &call, ISUP_GRA, grs_params);
+}
+
+int isup_iam(struct ss7 *ss7, struct isup_call *c)
+{
+	return isup_send_message(ss7, c, ISUP_IAM, iam_params);
+}
+
+int isup_acm(struct ss7 *ss7, struct isup_call *c)
+{
+	return isup_send_message(ss7, c, ISUP_ACM, acm_params);
+}
+
+int isup_anm(struct ss7 *ss7, struct isup_call *c)
+{
+	return isup_send_message(ss7, c, ISUP_ANM, anm_params);
+}
+
+int isup_rel(struct ss7 *ss7, struct isup_call *c, int cause)
+{
+	if (cause < 0)
+		cause = 16;
+
+	c->cause = cause;
+	c->causecode = CODE_CCITT;
+	c->causeloc = LOC_PRIV_NET_LOCAL_USER;
+	return isup_send_message(ss7, c, ISUP_REL, rel_params);
+}
+
+int isup_rlc(struct ss7 *ss7, struct isup_call *c)
+{
+	int res;
+	res = isup_send_message(ss7, c, ISUP_RLC, rlc_params);
+	isup_free_call(ss7, c);
+	return res;
+}
+/* Janelle is the bomb (Again) */

Added: trunk/isup.h
URL: http://svn.digium.com/view/libss7/trunk/isup.h?rev=2&view=auto
==============================================================================
--- trunk/isup.h (added)
+++ trunk/isup.h Tue Aug  1 18:51:53 2006
@@ -1,0 +1,137 @@
+/*
+libss7: An implementation of Signalling System 7
+
+Written by Matthew Fredrickson <creslin at digium.com>
+
+Copyright (C) 2005
+All Rights Reserved.
+
+This program is free software; you can redistribute it under the
+terms of the GNU General Public License as published by the Free
+Software Foundation
+
+Contains definitions and data structurs for the ISUP portion of SS7
+*/
+#ifndef _SS7_ISUP_H
+#define _SS7_ISUP_H
+
+/* ISUP messages */
+#define ISUP_IAM	0x01
+#define ISUP_SAM	0x02
+#define ISUP_INR	0x03
+#define ISUP_INF	0x04
+#define ISUP_COT	0x05
+#define ISUP_ACM	0x06
+#define ISUP_CON	0x07
+#define ISUP_FOT	0x08
+#define ISUP_ANM	0x09
+#define ISUP_REL	0x0c
+#define ISUP_SUS	0x0d
+#define ISUP_RES	0x0e
+#define ISUP_RLC	0x10
+#define ISUP_CCR	0x11
+#define ISUP_RSC	0x12
+#define ISUP_BLO	0x13
+#define ISUP_UBL	0x14
+#define ISUP_BLA	0x15
+#define ISUP_UBA	0x16
+#define ISUP_GRS	0x17
+#define ISUP_CGB	0x18
+#define ISUP_CGU	0x19
+#define ISUP_CGBA	0x1a
+#define ISUP_CGUA	0x1b
+#define ISUP_CMR	0x1c
+#define ISUP_CMC	0x1d
+#define ISUP_CMRJ	0x1e
+#define ISUP_FAR	0x1f
+#define ISUP_FAA	0x20
+#define ISUP_FRJ	0x21
+#define ISUP_FAD	0x22
+#define ISUP_FAI	0x23
+#define ISUP_LPA	0x24
+#define ISUP_CSVR	0x25
+#define ISUP_CSVS	0x26
+#define ISUP_DRS	0x27
+#define ISUP_PAM	0x28
+#define ISUP_GRA	0x29
+#define ISUP_CQM	0x2a
+#define ISUP_CQR	0x2b
+#define ISUP_CPG	0x2c
+#define ISUP_USR	0x2d
+#define ISUP_UCIC	0x2e
+#define ISUP_CFN	0x2f
+#define ISUP_OLM	0x30
+#define ISUP_CRG	0x31
+#define ISUP_FAC	0x33
+#define ISUP_CRA	0xe9
+#define ISUP_CRM	0xea
+#define ISUP_CVR	0xeb
+#define ISUP_CVT	0xec
+#define ISUP_EXM	0xed
+
+/* ISUP Parameters */
+#define ISUP_PARM_NATURE_OF_CONNECTION_IND 0x06
+#define ISUP_PARM_FORWARD_CALL_IND 0x07
+#define ISUP_PARM_CALLING_PARTY_CAT 0x09
+#define ISUP_PARM_USER_SERVICE_INFO 0x1d
+#define ISUP_PARM_TRANSMISSION_MEDIUM_REQS 0x02
+#define ISUP_PARM_CALLED_PARTY_NUM 0x04
+#define ISUP_PARM_ACCESS_TRANS 0x03
+#define ISUP_PARM_BUSINESS_GRP 0xc6
+#define ISUP_PARM_CALL_REF 0x01
+#define ISUP_PARM_CALLING_PARTY_NUM 0x0a
+#define ISUP_PARM_CARRIER_ID 0xc5
+#define ISUP_PARM_SELECTION_INFO 0xee
+#define ISUP_PARM_CHARGE_NUMBER 0xeb
+#define ISUP_PARM_CIRCUIT_ASSIGNMENT_MAP 0x25
+#define ISUP_PARM_CONNECTION_REQ 0x0d
+#define ISUP_PARM_CUG_INTERLOCK_CODE 0x1c
+#define ISUP_PARM_EGRESS_SERV 0xc3
+#define ISUP_PARM_GENERIC_ADDR 0xc0
+#define ISUP_PARM_GENERIC_DIGITS 0xc1
+#define ISUP_PARM_GENERIC_NAME 0xc7
+#define ISUP_PARM_GENERIC_NOTIFICATION_IND 0x2c
+#define ISUP_PARM_BACKWARD_CALL_IND 0x11
+#define ISUP_PARM_CAUSE 0x12
+#define ISUP_PARM_RANGE_AND_STATUS 0x16
+
+/* ISUP Parameter Pseudo-type */
+struct isup_parm_opt {
+	unsigned char type;
+	unsigned char len;
+	unsigned char data[0];
+};
+
+struct isup_h {
+	unsigned char cic[2];
+	unsigned char type;
+	unsigned char data[0]; /* This is the contents of the message */
+};
+
+#define CIC_SIZE 2
+#define ISUP_MAX_NUM 64
+
+struct mtp2;
+
+struct isup_call {
+	char called_party_num[ISUP_MAX_NUM];
+	char calling_party_num[ISUP_MAX_NUM];
+	int range;
+	int echocan;
+	int satellites;
+	int international;
+	int originatedisdn;
+	int transcap;
+	int l1prot;
+	int cause;
+	int causecode;
+	int causeloc;
+	unsigned short cic;
+	unsigned short slc;
+	struct isup_call *next;
+};
+
+int isup_receive(struct ss7 *ss7, struct mtp2 *sl, unsigned char *sif, int len);
+
+int isup_dump(struct ss7 *ss7, struct mtp2 *sl, unsigned char *sif, int len);
+#endif /* _SS7_ISUP_H */

Added: trunk/libss7.h
URL: http://svn.digium.com/view/libss7/trunk/libss7.h?rev=2&view=auto
==============================================================================
--- trunk/libss7.h (added)
+++ trunk/libss7.h Tue Aug  1 18:51:53 2006
@@ -1,0 +1,154 @@
+#ifndef _LIBSS7_H
+#define _LIBSS7_H
+
+/* Internal -- MTP2 events */
+#define SS7_EVENT_UP		1
+#define SS7_EVENT_DOWN		2
+#define MTP2_LINK_UP		3
+#define MTP2_LINK_DOWN		4
+#define ISUP_EVENT_IAM		5
+#define ISUP_EVENT_ACM		6
+#define ISUP_EVENT_ANM		7
+#define ISUP_EVENT_REL		8
+#define ISUP_EVENT_RLC		9
+/* Circuit group reset */
+#define ISUP_EVENT_GRS		10
+#define ISUP_EVENT_GRA		11
+
+/* Different SS7 types */
+#define SS7_ITU		(1 << 0)
+#define SS7_ANSI	(1 << 1)
+
+/* Debug levels */
+#define SS7_DEBUG_MTP2	(1 << 0)
+#define SS7_DEBUG_MTP3	(1 << 1)
+#define SS7_DEBUG_ISUP	(1 << 2)
+
+/* Network indicator */
+#define SS7_NI_INT			0x00
+#define SS7_NI_INT_SPARE		0x01
+#define SS7_NI_NAT			0x02
+#define SS7_NI_NAT_SPARE		0x03
+
+struct ss7;
+struct isup_call;
+
+typedef struct {
+	int e;
+	int cic;
+	int transcap;
+	char called_party_num[50];
+	char calling_party_num[50];
+	struct isup_call *call;
+} ss7_event_iam;
+
+typedef struct {
+	int e;
+	int cic;
+	struct isup_call *call;
+} ss7_event_rel;
+
+typedef struct {
+	int e;
+	int cic;
+} ss7_event_rlc;
+
+typedef struct {
+	int e;
+	int cic;
+	struct isup_call *call;
+} ss7_event_anm;
+
+typedef struct {
+	int e;
+	int cic;
+	struct isup_call *call;
+} ss7_event_acm;
+
+typedef struct {
+	int e;
+	int startcic;
+	int endcic;
+} ss7_event_grs;
+
+typedef struct {
+	int e;
+	int startcic;
+	int endcic;
+} ss7_event_gra;
+
+typedef struct {
+	int e;
+	unsigned int data;
+} ss7_event_generic;
+
+typedef union {
+	int e;
+	ss7_event_generic gen;
+	ss7_event_iam iam;
+	ss7_event_grs grs;
+	ss7_event_gra gra;
+	ss7_event_rel rel;
+	ss7_event_rlc rlc;
+	ss7_event_anm anm;
+	ss7_event_acm acm;
+} ss7_event;
+
+void ss7_set_message(void (*func)(struct ss7 *ss7, char *message));
+
+void ss7_set_error(void (*func)(struct ss7 *ss7, char *message));
+
+void ss7_set_debug(struct ss7 *ss7, unsigned int flags);
+
+/* SS7 Link control related functions */
+int ss7_schedule_run(struct ss7 *ss7);
+
+struct timeval *ss7_schedule_next(struct ss7 *ss7);
+
+int ss7_add_link(struct ss7 *ss7, int fd);
+
+int ss7_set_adjpc(struct ss7 *ss7, int fd, unsigned int pc);
+
+int ss7_set_network_ind(struct ss7 *ss7, int ni);
+
+int ss7_set_pc(struct ss7 *ss7, unsigned int pc);
+
+int ss7_set_default_dpc(struct ss7 *ss7, unsigned int pc);
+
+struct ss7 *ss7_new(int switchtype);
+
+ss7_event *ss7_check_event(struct ss7 *ss7);
+
+int ss7_start(struct ss7 *ss7);
+
+int ss7_read(struct ss7 *ss7, int fd);
+
+int ss7_write(struct ss7 *ss7, int fd);
+
+char * ss7_event2str(int event);
+
+/* ISUP call related message functions */
+
+/* Send an IAM */
+int isup_iam(struct ss7 *ss7, struct isup_call *c);
+
+int isup_anm(struct ss7 *ss7, struct isup_call *c);
+
+#if 0
+int isup_call_setcalled(struct isup_call *c, int cic);
+#endif
+
+struct isup_call * isup_new_call(struct ss7 *ss7);
+
+int isup_acm(struct ss7 *ss7, struct isup_call *c);
+
+int isup_rel(struct ss7 *ss7, struct isup_call *c, int cause);
+
+int isup_rlc(struct ss7 *ss7, struct isup_call *c);
+
+int isup_gra(struct ss7 *ss7, int begincic, int endcic);
+
+int isup_grs(struct ss7 *ss7, int begincic, int endcic);
+
+void isup_init_call(struct isup_call *c, int cic, char *calledpartynum, char *callingpartynum);
+#endif /* _LIBSS7_H */

Added: trunk/mkdep
URL: http://svn.digium.com/view/libss7/trunk/mkdep?rev=2&view=auto
==============================================================================
--- trunk/mkdep (added)
+++ trunk/mkdep Tue Aug  1 18:51:53 2006
@@ -1,0 +1,125 @@
+#!/bin/bash -
+#
+#	$OpenBSD: mkdep.gcc.sh,v 1.8 1998/09/02 06:40:07 deraadt Exp $
+#	$NetBSD: mkdep.gcc.sh,v 1.9 1994/12/23 07:34:59 jtc Exp $
+#
+# Copyright (c) 1991, 1993
+#	The Regents of the University of California.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+#    must display the following acknowledgement:
+#	This product includes software developed by the University of
+#	California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+#    may be used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#	@(#)mkdep.gcc.sh	8.1 (Berkeley) 6/6/93
+#
+
+D=.depend			# default dependency file is .depend
+append=0
+pflag=
+
+while :
+	do case "$1" in
+		# -a appends to the depend file
+		-a)
+			append=1
+			shift ;;
+
+		# -f allows you to select a makefile name
+		-f)
+			D=$2
+			shift; shift ;;
+
+		# the -p flag produces "program: program.c" style dependencies
+		# so .o's don't get produced
+		-p)
+			pflag=p
+			shift ;;
+		*)
+			break ;;
+	esac
+done
+
+if [ $# = 0 ] ; then
+	echo 'usage: mkdep [-p] [-f depend_file] [cc_flags] file ...'
+	exit 1
+fi
+
+DTMP=/tmp/mkdep$$
+TMP=$DTMP/mkdep
+
+um=`umask`
+umask 022
+if ! mkdir $DTMP ; then
+	echo failed to create tmp dir $DTMP
+	exit 1
+fi
+
+umask $um
+trap 'rm -rf $DTMP ; trap 2 ; kill -2 $$' 1 2 3 13 15
+
+if [ x$pflag = x ]; then
+	${CC:-cc} -M "$@" 2>/dev/null | sed -e 's; \./; ;g' > $TMP
+else
+	${CC:-cc} -M "$@" 2>/dev/null | sed -e 's;\.o :; :;' -e 's; \./; ;g' > $TMP
+fi
+
+if [ $? != 0 ]; then
+	echo 'mkdep: compile failed.'
+	rm -rf $DTMP
+	exit 1
+fi
+
+if [ $append = 1 ]; then
+	cat $TMP >> $D
+	if [ $? != 0 ]; then
+		echo 'mkdep: append failed.'
+		rm -rf $DTMP
+		exit 1
+	fi
+	cat $TMP | sed -e 's/\.o:/.lo:/g' >>$D
+	if [ $? != 0 ]; then
+		echo 'mkdep: append failed.'
+		rm -rf $DTMP
+		exit 1
+	fi
+else
+	cat $TMP > $D
+	if [ $? != 0 ]; then
+		echo 'mkdep: overwrite failed.'
+		rm -rf $DTMP
+		exit 1
+	fi
+	cat $TMP | sed -e 's/\.o:/.lo:/g' >>$D
+	if [ $? != 0 ]; then
+		echo 'mkdep: append failed.'
+		rm -rf $DTMP
+		exit 1
+	fi
+fi
+
+rm -rf $DTMP
+exit 0

Propchange: trunk/mkdep
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/mtp2.c
URL: http://svn.digium.com/view/libss7/trunk/mtp2.c?rev=2&view=auto
==============================================================================
--- trunk/mtp2.c (added)
+++ trunk/mtp2.c Tue Aug  1 18:51:53 2006
@@ -1,0 +1,769 @@
+/*
+libss7: An implementation of Signaling System 7
+
+Written by Matthew Fredrickson <matt at fredricknet.net>
+
+Copyright (C), 2005
+All Rights Reserved.
+
+This program is free software; you can redistribute it under the
+terms of the GNU General Public License as published by the Free
+Software Foundation
+
+Contains user interface to ss7 library
+*/
+
+#include "ss7_internal.h"
+#include "mtp3.h"
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "mtp2.h"
+
+#define mtp_error ss7_error
+#define mtp_message ss7_message
+#define SOCKET_TEST
+
+/* #define DEBUG_MTP2 */
+#define DEBUG_MTP2
+
+
+#if 0
+static inline int len_txbuf(struct mtp2 *link)
+{
+	int res = 0;
+	struct ss7_msg *cur = link->tx_buf;
+
+	while (cur) {
+		res++;
+		cur = cur->next;
+	}
+	return res;
+}
+#endif
+		
+static inline char * linkstate2str(int linkstate)
+{
+	char *statestr = NULL;
+
+	switch (linkstate) {
+		case 0:
+			statestr = "IDLE";
+			break;
+		case 1:
+			statestr = "NOTALIGNED";
+			break;
+		case 2:
+			statestr = "ALIGNED";
+			break;
+		case 3:
+			statestr = "PROVING";
+			break;
+		case 4:
+			statestr = "ALIGNEDREADY";
+			break;
+		case 5:
+			statestr = "INSERVICE";
+			break;
+	}
+
+	return statestr;
+}
+
+static inline void init_mtp2_header(struct mtp2 *link, struct mtp_su_head *h, int new, int nack)
+{
+	if (new)
+		link->curfsn += 1;
+
+	h->fib = link->curfib;
+	h->fsn = link->curfsn;
+	
+	if (nack)
+		link->curfib = !link->curfib;
+
+	h->bib = link->curfib;
+	h->bsn = link->lastfsnacked;
+}
+
+static inline int lssu_type(struct mtp_su_head *h)
+{
+	return h->data[0];
+}
+
+static void flush_bufs(struct mtp2 *link)
+{
+	struct ss7_msg *list, *cur;
+
+	list = link->tx_buf;
+
+	link->tx_buf = NULL;
+
+	while (list) {
+		cur = list;
+		free(cur);
+		list = list->next;
+	}
+
+	list = link->tx_q;
+
+	link->tx_q = NULL;
+
+	while (list) {
+		cur = list;
+		free(cur);
+		list = list->next;
+	}
+}
+
+static void reset_mtp(struct mtp2 *link)
+{
+	link->curfsn = 127;
+	link->curfib = 1;
+	link->lastfsnacked = 127;
+
+	flush_bufs(link);
+}
+

[... 2246 lines stripped ...]


More information about the libss7-commits mailing list