[libss7-commits] mattf: branch mattf/bug13495 r240 - /team/mattf/bug13495/isup_masq.c

SVN commits to the libss7 project libss7-commits at lists.digium.com
Thu Dec 11 11:59:26 CST 2008


Author: mattf
Date: Thu Dec 11 11:59:26 2008
New Revision: 240

URL: http://svn.digium.com/view/libss7?view=rev&rev=240
Log:
Forgot to add the new isup_masq.c file

Added:
    team/mattf/bug13495/isup_masq.c

Added: team/mattf/bug13495/isup_masq.c
URL: http://svn.digium.com/view/libss7/team/mattf/bug13495/isup_masq.c?view=auto&rev=240
==============================================================================
--- team/mattf/bug13495/isup_masq.c (added)
+++ team/mattf/bug13495/isup_masq.c Thu Dec 11 11:59:26 2008
@@ -1,0 +1,252 @@
+/*
+libss7: An implementation of Signalling System 7
+
+Written by Matthew Fredrickson <creslin at digium.com>
+
+Copyright Digium, Inc. (C) 2006
+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 "libss7.h"
+//#include "isuptcp.h"
+#include "ss7_internal.h"
+#include "isup.h"
+#include "mtp3.h"
+#include "mtp2.h"
+
+#include <stdlib.h>
+#include <poll.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+
+static void isup_set_event(struct ss7 *ss7, int event)
+{
+	/* A little worker function to put events into the event q */
+	
+	ss7_event *e = ss7_next_empty_event(ss7);
+	e->e = event;
+	
+	return;
+}	
+
+static int isup_ip_receive_buffer(struct mtp2 *mtp2, unsigned char *msg, int len)
+{  
+	unsigned char *buf = (unsigned char *)msg;
+	int msgstate = (int) buf[0];
+	unsigned char *newmsg;
+	
+	/*Finds second byte of msg and determines how to handle message. Used to let client know
+      if the ss7 link is down on server. SS7 socket server will send the
+	correct state byte for each message. It does not need to keep sending the UP or DOWN states. Only
+	needs to send them when it's own ss7 link is in alarm. So during normal UP state all messages will 
+	be of CASE 5 */
+	
+	switch (msgstate) {
+		case SS7_EVENT_UP:
+			isup_set_event(mtp2->master, SS7_EVENT_UP);
+			return 1;
+		case SS7_EVENT_DOWN:
+			isup_set_event(mtp2->master, SS7_EVENT_DOWN);
+			return 1;
+		case 3:	
+		case 4:
+			return 0;
+		case 5: /*This is the case for all ISUP messages such as IAM's, RLC,ANMs,ACMs..etc */
+			newmsg = &buf[1]; /*Get the buf minus the event byte */
+			if (mtp2->master->debug > 0) { /* Send data to be decode for debug */
+				mtp3_dump(mtp2->master,NULL, (void *)newmsg, len-1);
+			}
+			mtp3_receive(mtp2->master, NULL, (void *)newmsg, len-1);
+			return 1; 	
+		default:
+			return 0;
+	}
+}	
+
+static int get_msg_length(struct mtp2 *mtp2)
+{
+	char lenbuf[10] = {0,};
+	int i = 0;
+
+	do {
+		if (read(mtp2->fd, &lenbuf[i++], 1) < 0) {
+			ss7_message(mtp2->master, "Read returned -1in get_msg_length\n");
+			return -1;
+		}
+	} while ((i < 10) && lenbuf[i - 1] != 0);
+
+	if (i == 10) {
+		ss7_message(mtp2->master, "Reached read limit length, huh?");
+		return -1;
+	}
+
+	sscanf(lenbuf, "%d", &i);
+
+	return i;
+}
+
+int isup_ip_receive(struct mtp2 *mtp2)
+{
+	unsigned char msg[1024];
+	int len;
+	int res = -1;
+
+	len = get_msg_length(mtp2);
+
+	if (len < 0)
+		return -1;
+
+	res = read(mtp2->fd, msg, len);
+
+	if (res < 0) {
+		ss7_message(mtp2->master, "Read problem from socket: %s\n", strerror(errno));
+		return -1;
+	}
+
+	if (res != len) {
+		ss7_message(mtp2->master, "Short read from socket\n");
+		return -1;
+	}
+
+	res = isup_ip_receive_buffer(mtp2, msg, len);
+
+	return res;
+}
+
+static unsigned char * itoa(int val, int base)
+{
+	static unsigned char buf[32] = {0};
+	int i = 30;
+	
+	for(; val && i ; --i, val /= base)
+		buf[i] = "0123456789abcdef"[val % base];
+	
+	return &buf[i+1];
+}  
+
+static int isup_carefulwrite(int fd, unsigned char *s, int len, int timeoutms) 
+{
+	/*This was copied from AST_CAREFULWRITE
+	 Try to write string, but wait no more than ms milliseconds
+	   before timing out*/
+	int res = 0;
+	struct pollfd fds[1];
+	while (len) {
+		res = write(fd, s, len);
+		if ((res < 0) && (errno != EAGAIN)) {
+			return -1;
+		}
+		if (res < 0)
+			res = 0;
+		len -= res;
+		s += res;
+		res = 0;
+		if (len) {
+			fds[0].fd = fd;
+			fds[0].events = POLLOUT;
+			/*Wait until writable again */
+			res = poll(fds, 1, timeoutms);
+			if (res < 1)
+				return -1;
+		}
+	}
+	return res;
+}
+
+static int isup_ip_send(struct mtp2 *mtp2, unsigned char *data, int len)
+{
+	int i;
+	
+	if (mtp2->master->debug > 0) { /* Send data to be decode for debug */
+		mtp3_dump(mtp2->master, mtp2, data, len);}
+	
+	/* Send the length of entire ISUP message first */
+	i = isup_carefulwrite(mtp2->fd, itoa(len,10), 4, 50);
+	
+	return isup_carefulwrite(mtp2->fd, data, len, 50);
+}
+
+int isup_ip_msu(struct mtp2 *mtp2, struct ss7_msg *msg)
+{
+	int res;
+
+	res = isup_ip_send(mtp2, msg->buf + MTP2_SIZE, msg->size - MTP2_SIZE);
+
+	ss7_msg_free(msg);
+	
+	return res;
+}
+
+int isup_masquerade_add_route(struct ss7 *ss7, int fd, int startcic, int endcic, unsigned int opc)
+{
+	struct isup_masq *masq_table = &ss7->isup_masq_table;
+	int i, j;
+
+	if (!ss7)
+		return -1;
+
+	if (masq_table->numentries >= ISUP_MASQ_MAX_ENTRIES)
+		return -1;
+
+	i = masq_table->numentries;
+
+	masq_table->routes[i].startcic = startcic;
+	masq_table->routes[i].endcic = endcic;
+	masq_table->routes[i].opc = opc;
+
+	ss7_add_slave_link(ss7, SS7_TRANSPORT_TCP, fd, 0, 0);
+
+	for (j = 0; j < ss7->numslavelinks; j++) {
+		if (ss7->slavelinks[j]->fd == fd)
+			break;
+	}
+
+	masq_table->routes[i].mtp2 = ss7->slavelinks[j];
+	
+	return 0;
+}
+
+static int isup_masquerade_transmit(struct mtp2 *link, struct routing_label *rl, unsigned char *buf, int len)
+{
+	/* Rebuild our message here */
+	unsigned char txbuf[512];
+	int rlsize;
+
+	txbuf[0] = 5; /* ISUP MESSAGE */
+	txbuf[1] = (link->master->ni << 6) | SIG_ISUP;
+	rlsize = set_routinglabel(&txbuf[1], rl);
+
+	memcpy(&txbuf[rlsize], buf, len);
+
+	isup_ip_send(link, txbuf, len);
+
+	return 0;
+}
+
+int isup_needs_masquerade(struct ss7 *ss7, struct routing_label *rl, unsigned int cic, unsigned char *buf, int len)
+{
+	struct isup_masq * isup_masq_table = &ss7->isup_masq_table;
+	int i;
+
+	for (i = 0; i <  isup_masq_table->numentries; i++) {
+		if ((isup_masq_table->routes[i].opc == rl->opc)
+		&& (cic >= isup_masq_table->routes[i].startcic)
+		&& (cic <= isup_masq_table->routes[i].endcic)) {
+			isup_masquerade_transmit(isup_masq_table->routes[i].mtp2, rl, buf, len);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+




More information about the libss7-commits mailing list