aboutsummaryrefslogtreecommitdiffstats
path: root/sualibrary/sua
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-07-09 20:55:33 +0200
committerHarald Welte <laforge@gnumonks.org>2010-07-09 20:55:33 +0200
commit86d1df86c7da9a35004e6a9a326f10b8167c9179 (patch)
treedbc1d77a33fe77d9e23a66115b899a271d3c5d39 /sualibrary/sua
import sualibrary-0.1.0 from 2002-02-15
Diffstat (limited to 'sualibrary/sua')
-rw-r--r--sualibrary/sua/Makefile.am30
-rw-r--r--sualibrary/sua/sua.h388
-rw-r--r--sualibrary/sua/sua_adapt.cpp222
-rw-r--r--sualibrary/sua/sua_adapt.h79
-rw-r--r--sualibrary/sua/sua_asp_mgnt.cpp1030
-rw-r--r--sualibrary/sua/sua_asp_mgnt.h190
-rw-r--r--sualibrary/sua/sua_cl.cpp550
-rw-r--r--sualibrary/sua/sua_cl.h88
-rw-r--r--sualibrary/sua/sua_co.cpp1768
-rw-r--r--sualibrary/sua/sua_co.h170
-rw-r--r--sualibrary/sua/sua_database.cpp642
-rw-r--r--sualibrary/sua/sua_database.h397
-rw-r--r--sualibrary/sua/sua_dataname.cpp174
-rw-r--r--sualibrary/sua/sua_datassoc.cpp1000
-rw-r--r--sualibrary/sua/sua_debug.h79
-rw-r--r--sualibrary/sua/sua_distribution.cpp1167
-rw-r--r--sualibrary/sua/sua_distribution.h170
-rw-r--r--sualibrary/sua/sua_file.cpp401
-rw-r--r--sualibrary/sua/sua_file.h74
-rw-r--r--sualibrary/sua/sua_logging.cpp268
-rw-r--r--sualibrary/sua/sua_logging.h72
-rw-r--r--sualibrary/sua/sua_sual.cpp686
-rw-r--r--sualibrary/sua/sua_sual.h459
-rw-r--r--sualibrary/sua/sua_syntax.cpp4733
-rw-r--r--sualibrary/sua/sua_syntax.h447
-rw-r--r--sualibrary/sua/sua_tcb.cpp218
-rw-r--r--sualibrary/sua/sua_tcb.h153
27 files changed, 15655 insertions, 0 deletions
diff --git a/sualibrary/sua/Makefile.am b/sualibrary/sua/Makefile.am
new file mode 100644
index 0000000..b7fa555
--- /dev/null
+++ b/sualibrary/sua/Makefile.am
@@ -0,0 +1,30 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+noinst_LIBRARIES = libsua.a
+
+libsua_a_SOURCES = sua_tcb.cpp sua_syntax.cpp sua_sual.cpp sua_logging.cpp sua_file.cpp sua_distribution.cpp sua_dataname.cpp sua_database.cpp sua_co.cpp sua_datassoc.cpp sua_cl.cpp sua_asp_mgnt.cpp sua_adapt.cpp
+
+
+EXTRA_DIST = sua.h sua_adapt.cpp sua_adapt.h sua_asp_mgnt.cpp sua_asp_mgnt.h sua_cl.cpp sua_cl.h sua_datassoc.cpp sua_co.cpp sua_co.h sua_database.cpp sua_database.h sua_dataname.cpp sua_debug.h sua_distribution.cpp sua_distribution.h sua_file.cpp sua_file.h sua_logging.cpp sua_logging.h sua_sual.cpp sua_sual.h sua_syntax.cpp sua_syntax.h sua_tcb.cpp sua_tcb.h
+
+####### kdevelop will overwrite this part!!! (end)############
+SOMAJOR = 1
+SOMINOR = 0
+SOSUBMINOR = 0
+
+libsua_la_LIBADD = @glib_LIBS@ @sctp_LIBS@
+
+# here you should add all header files, which contains the functionality
+# of your shared lib (published for the users)
+include_HEADERS = sua.h
+
+INCLUDES = -I/usr/local/include
+
+#build a libtool library for installation in libdir
+lib_LTLIBRARIES = libsua.la
+libsua_la_SOURCES = sua_tcb.cpp sua_syntax.cpp sua_sual.cpp sua_logging.cpp sua_file.cpp sua_distribution.cpp sua_dataname.cpp sua_database.cpp sua_co.cpp sua_datassoc.cpp sua_cl.cpp sua_asp_mgnt.cpp sua_adapt.cpp
+
+
+libsua_la_LDFLAGS = -no-undefined -version-info $(SOMAJOR):$(SOMINOR):$(SOSUBMINOR) $(LDFLAGS)
+
+
+
diff --git a/sualibrary/sua/sua.h b/sualibrary/sua/sua.h
new file mode 100644
index 0000000..d0e5e02
--- /dev/null
+++ b/sualibrary/sua/sua.h
@@ -0,0 +1,388 @@
+/***************************************************************************
+ sua.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua.h,v 1.3 2002/02/15 16:19:46 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Marleen
+ * "El Loco was here."
+ * "He drinks boiling motor oil and likes his meat alive in the cantina."
+ *
+ * Purpose: This header-file defines the SUA interface used by the
+ * SUA application for:
+ * - SUA address information structure
+ * - SUA Quality-Of-Service(QOS) structure
+ * - SUA callback function structure
+ * and adaptation functions used by the SUA application for:
+ * - initialising the SUA layer
+ * - reading the SUA configuration file
+ * - registering a local SUA instance
+ * - Setting up the association with a remote SUA node
+ * - get info on a certain (SUA) association
+ * - terminate a association
+ * - Send a SUA primtive to SUA
+ * - Receive a SUA primitive from SUA
+ * - convert Hostname(string) to SUAname(Character array)
+ * - convert SUAname(Character array) to Hostname(Character array)
+ */
+
+#define __EXTENSIONS__
+#ifndef SUA_GLOBAL_H
+#define SUA_GLOBAL_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string>
+
+#ifdef STDC_HEADERS
+ #ifdef HAVE_SYS_TIME_H
+ #include <sys/time.h>
+ #ifdef TIME_WITH_SYS_TIME
+ #include <time.h>
+ #endif
+ #endif
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+#endif
+
+#ifdef FreeBSD
+#include <netinet/in_systm.h>
+#include <sys/types.h>
+#endif
+
+#ifdef SOLARIS
+#include <netinet/in_systm.h>
+#include <stdarg.h>
+#endif
+
+#include <netinet/in.h>
+
+
+/* turn on Posix 1g for compatible cmsg structure */
+#ifdef USE_RFC2292BIS
+ #define _XPG4_2
+#endif
+
+#include <sys/socket.h>
+
+/* turn off Posix 1g for compatible cmsg structure */
+#ifdef USE_RFC2292BIS
+ #undef _XPG4_2
+#endif
+
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include "sctp.h" /* SCTP library */
+
+#define SUA_PORT 14001
+#define SUA_PPI 4
+#define IPPROTO_SCTP 132
+
+#define SUA_MAX_MSG_LEN 2000
+
+/*#define HAVE_UNISTD_H TRUE */
+
+#define N_UNITDATA 1
+#define N_NOTICE 2
+#define N_CONNECT_REQ 10
+#define N_CONNECT_IND 11
+#define N_CONNECT_REFUSED 12
+#define N_CONNECT_RESP 13
+#define N_CONNECT_CONF 14
+#define N_DATA_REQ 20
+#define N_DATA_IND 21
+#define N_RELEASE_REQ 30
+#define N_RELEASE_CONF 31
+
+typedef unsigned char boolean;
+
+#define FALSE (0)
+#define TRUE (!FALSE)
+
+
+#define OK 0
+#define PROTOCOL_CLASS_NOT_SPECIFIED -10
+#define INVALID_CLG_ADDRESS -20
+#define INVALID_CLD_ADDRESS -30
+#define MSG_ENCODING_FAILED -40
+
+/* shortcut macro to specify address field of struct sockaddr */
+#define sockunion_family(X) (X)->sa.sa_family
+#define sock2ip(X) (((struct sockaddr_in *)(X))->sin_addr.s_addr)
+#define sock2ip6(X) (((struct sockaddr_in6 *)(X))->sin6_addr.s6_addr)
+
+#define SUPPORT_ADDRESS_TYPE_IPV4 0x00000001
+#define SUPPORT_ADDRESS_TYPE_IPV6 0x00000002
+#define SUPPORT_ADDRESS_TYPE_DNS 0x00000004
+
+
+/* union for handling either type of addresses: ipv4 and ipv6 */
+/*#ifndef SOCKUNION_DEFINE*/
+#define SOCKUNION_DEFINE 1
+/* define structure of IPv4/6 address */
+union sockunion
+{
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ unsigned char ch[SCTP_MAX_IP_LEN];
+};
+/*#endif SOCKUNION_DEFINE */
+
+#define ipvxunion sockunion
+
+/*union ipvxunion
+{
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ unsigned char ch[SCTP_MAX_IP_LEN];
+};*/
+
+typedef enum { ITU14bit,
+ ITU24bit,
+ ANSI24bit
+} SS7pc_set;
+
+typedef struct {
+ SS7pc_set family;
+ uint32_t pc;
+} SS7_ITU14_str;
+
+/* define structure of SS7 MTP pointcode (ITU/ANSI/other...) */
+union SS7union
+{
+ SS7_ITU14_str ITU14;
+ SS7_ITU14_str ITU24;
+ SS7_ITU14_str ANSI24;
+};
+
+typedef enum { no_pc_present,
+ ipvx_pc_present, // IPvx(4 or 6) present in pc field
+ ss7_pc_present // SS7 pointcode present in pc field
+} pointcode_set;
+
+typedef enum { no_name_present,
+ hostname_present,
+ GT_present
+} name_gt_set;
+
+typedef enum { no_sap_present,
+ ssn_present,
+ portnumber_presentr
+} application_SAP_set;
+
+typedef enum { include_nothing,
+ include_pc_in_header,
+ include_ssn_port_in_header
+} sua_header_set;
+
+typedef struct {
+ pointcode_set pc;
+ name_gt_set name_gt;
+ application_SAP_set ssn_port;
+ sua_header_set field_in_header;
+} addr_elements_str;
+
+typedef struct {
+ SS7union ss7;
+ sockunion ipvx;
+ /*ipvxunion ipvx;*/
+} pointcode_str;
+
+typedef char hostname_str[255];
+
+typedef char global_title_str[255];
+
+typedef union {
+ global_title_str GT;
+ hostname_str HostName;
+}name_str;
+
+typedef short application_sap_str;
+
+typedef enum { route_on_ssn, // use pointcode for routing
+ route_on_name_gt, // use gt/name for routing
+ route_on_name_gt_next_office, // perform GTT in next node
+ no_address_present // no routing requested
+} routing_type_set;
+
+typedef struct {
+ addr_elements_str address_fields_present; // which fields are present?
+ pointcode_str pc; // pointcode field
+ name_str name; //global title/hostname field
+ application_sap_str ssn; // application ssn/port
+ routing_type_set routing_ind; // how must msg be routed
+ short network_apperance;
+} sccp_addr_str;
+
+typedef enum { class0, // connectionless transport, non-sequenced
+ class1, // connectionless transport, sequenced
+ class2, // connectionoriented
+ class3 // connectionoriented with flow control
+} protocol_class_set;
+
+typedef struct {
+ protocol_class_set prot_class; // class 0, 1 or 2
+ bool in_sequence; // msg delivevered in sequence
+ short sequence_number; // = stream number
+ bool return_msg_on_error; // return a UDT service on err
+ short importance; // importance of msg(0..7)
+ short hopcounter; // hopcounter
+} sccp_QOS_str;
+
+typedef struct {
+ void (*ulp_ClDataIndNotif) ( unsigned int local_sua_Id,
+ unsigned int primitive,
+ unsigned int datalen
+ );
+ void (*ulp_ConnIndNotif) ( unsigned int local_sua_id,
+ unsigned int local_sua_ref,
+ unsigned int datalen
+ );
+ void (*ulp_ConnConfIndNotif) ( unsigned int local_sua_id,
+ unsigned int local_sua_ref,
+ unsigned int datalen
+ );
+ void (*ulp_ConnDataIndNotif) ( unsigned int local_sua_id,
+ unsigned int local_sua_ref,
+ unsigned int datalen
+ );
+ void (*ulp_DisConnIndNotif) ( unsigned int local_sua_id,
+ unsigned int local_sua_ref,
+ unsigned int reason,
+ unsigned int datalen
+ );
+} Sua_ULP_CallBacks;
+
+
+void sua_initialisation();
+
+#define SUA_CFG_NO_ERROR 0
+#define SUA_CFG_FILE_UNKNOWN 1
+#define SUA_CFG_NO_SOURCE_ADDR 2
+#define SUA_CFG_NO_SOURCE_SSN 3
+#define SUA_CFG_NO_SOURCE_PORT 4
+
+unsigned int sua_read_config_file
+ ( char *pConfFile
+ );
+
+#define SUA_REG_NO_ERROR 0
+
+unsigned int sua_registerInstance
+ ( short local_ssn,
+ Sua_ULP_CallBacks ulp_callback
+ );
+
+
+#define SUA_ASS_NO_ERROR 0
+
+unsigned int sua_associate ( );
+
+typedef struct {
+ sccp_addr_str remote_addr;
+ sccp_addr_str local_addr;
+ int blabla;
+ unsigned int ASP_status;
+} sua_Path_str;
+
+#define SUA_PATH_NO_ERROR 0
+#define SUA_PATH_NO_DEST_ADDR_PRESENT 1
+
+unsigned int sua_getPath( unsigned int assoc_id,
+ sua_Path_str &pathinfo
+ );
+
+#define SUA_TERM_NO_ERROR 0
+#define SUA_TERM_NO_DEST_ADDR_PRESENT 1
+
+unsigned int sua_terminate();
+
+
+#define SUA_SEND_NO_ERROR 0
+#define SUA_SEND_PRIM_NOT_SENT 1
+
+unsigned int Send_sua_primitive( unsigned int primitive,
+ unsigned int &sua_ConnId,
+ sccp_QOS_str &QOS,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address,
+ char *buffer,
+ unsigned int len
+ );
+
+#define SUA_REC_NO_ERROR 0
+#define SUA_REC_NO_DATA_PRESENT 1
+
+unsigned int Receive_sua_primitive( unsigned int &primitive,
+ unsigned int &sua_ConnId,
+ sccp_QOS_str &QOS,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address,
+ char *buffer,
+ unsigned int len
+ );
+
+
+
+#endif // SUA_GLOBAL_H
+
+// end of module sua.h
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_adapt.cpp b/sualibrary/sua/sua_adapt.cpp
new file mode 100644
index 0000000..5dcb396
--- /dev/null
+++ b/sualibrary/sua/sua_adapt.cpp
@@ -0,0 +1,222 @@
+/***************************************************************************
+ sua_adapt.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_adapt.cpp,v 1.2 2002/02/15 16:19:46 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Katrien
+ * "Come on barbie, let's go party"
+ *
+ * Purpose: This code-file defines the SUA adaptation functions used by
+ * the SUA application for:
+ * - initialising the SUA layer
+ * - reading the SUA configuration file
+ * - registering a local SUA instance
+ * - Setting up the association with a remote SUA node
+ * - get info on a certain (SUA) association
+ * - terminate a association
+ * - convert Hostname(string) to SUAname(Character array)
+ * - convert SUAname(Character array) to Hostname(Character array)
+ */
+
+// sua_adapt.c++
+// SCCP user adaptation program
+
+#include "sua_debug.h"
+#include "sua_database.h"
+#include "sua_file.h"
+#include "sua_distribution.h"
+#include "sua_logging.h"
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+#include <sctp.h>
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h> /* includes <netinet/in.h> also ! */
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+using namespace std;
+/* definition of SUA local object and of remote object */
+db_Sua_LocalList local_sua;
+db_Sua_RemoteList remote_sua;
+db_Sua_AssociationList Assoc_sua;
+db_Sua_NameList NameDB_sua;
+db_Sua_ASList ApplicServ_sua;
+
+/***********************************************************************/
+/* sua_initialisation */
+/***********************************************************************/
+void sua_initialisation()
+{
+ int res;
+ cout << "Initialising SCTP & SUA\n ";
+ res = sctp_initLibrary();
+ init_logging_file();
+ local_sua.initialize();
+ remote_sua.initialize();
+ Assoc_sua.initialize();
+ cout << "Finished initialising SUA data\n ";
+
+} /* end of sua_initialisation */
+
+/***********************************************************************/
+/* sua_read_configuration file */
+/***********************************************************************/
+unsigned int sua_read_config_file( char *pConfFile)
+{
+ unsigned int result = SUA_CFG_NO_ERROR;
+ string sua_filename;
+ sua_filename = pConfFile;
+ result = read_sua_file( sua_filename,
+ local_sua,
+ remote_sua,
+ Assoc_sua,
+ NameDB_sua,
+ ApplicServ_sua
+ );
+ return(result);
+}
+
+/***********************************************************************/
+/* sua_registerInstance */
+/***********************************************************************/
+unsigned int sua_registerInstance ( short local_ssn,
+ Sua_ULP_CallBacks ulp_callback
+ )
+{
+ unsigned int result = SUA_REG_NO_ERROR;
+ SCTP_ulp_Callbacks SCTPCallbackFunctions;
+
+ SCTPCallbackFunctions.dataArriveNotif = &sctp_DataArriveNotif;
+ SCTPCallbackFunctions.networkStatusChangeNotif = &sctp_NetworkStatusChangeNotif;
+ SCTPCallbackFunctions.sendFailureNotif = &sctp_SentFailureNotif;
+ SCTPCallbackFunctions.communicationLostNotif = &sctp_CommunicationLostNotif;
+ SCTPCallbackFunctions.communicationUpNotif = &sctp_CommunicationUpNotif;
+ SCTPCallbackFunctions.communicationErrorNotif = &sctp_CommunicationErrorNotif;
+ SCTPCallbackFunctions.restartNotif = &sctp_RestartNotif;
+ SCTPCallbackFunctions.shutdownCompleteNotif = &sctp_ShutDownCompleteNotif;
+
+ result = Assoc_sua.register_instance ( SCTPCallbackFunctions,
+ ulp_callback,
+ local_sua
+ );
+
+ return(result);
+}
+
+
+/***********************************************************************/
+/* sua_associate */
+/***********************************************************************/
+unsigned int sua_associate ( )
+{
+ unsigned int result = SUA_ASS_NO_ERROR;
+ result = Assoc_sua.associate_instance( local_sua,
+ remote_sua
+ );
+ return(result);
+
+}
+
+
+/***********************************************************************/
+/* sua_getPath */
+/***********************************************************************/
+unsigned int sua_getPath( unsigned int assoc_id,
+ sua_Path_str &pathinfo
+ )
+{
+ unsigned int result = SUA_PATH_NO_ERROR;
+
+ if ( Assoc_sua.instance[assoc_id].Dest.nr_of_addrs > 0)
+ {
+ /*pathinfo.remote_addr.*/
+ pathinfo.remote_addr.pc.ipvx = Assoc_sua.instance[assoc_id].Dest.addrs[0];
+ /*pathinfo.remote_addr.pc.ss7 = Assoc_sua.instance[assoc_id].Dest.pc;*/
+ pathinfo.remote_addr.ssn = remote_sua.instance[Assoc_sua.instance[assoc_id].remote_sua_id].ssn.ssn;
+
+ pathinfo.ASP_status = Assoc_sua.instance[assoc_id].asp.status;
+
+#ifdef DEBUG
+ //cout << "remote ssn = " << pathinfo.remote_addr.ssn << "\n";
+ //cout << "remote sua_id = " << Assoc_sua.instance[assoc_id].remote_sua_id << "\n";
+#endif
+ }
+ else
+ result = SUA_PATH_NO_DEST_ADDR_PRESENT;
+ pathinfo.local_addr.pc.ipvx = Assoc_sua.instance[assoc_id].Source.addrs[0];
+ pathinfo.local_addr.pc.ss7 = Assoc_sua.instance[assoc_id].Source.pc;
+ pathinfo.local_addr.ssn = local_sua.instance[Assoc_sua.instance[assoc_id].local_sua_id].ssn.ssn;
+
+ return (result);
+
+}
+
+/***********************************************************************/
+/* sua_terminate */
+/***********************************************************************/
+unsigned int sua_terminate( )
+{
+ unsigned int result = SUA_TERM_NO_ERROR;
+
+ Assoc_sua.shutdown();
+ close_logging_file();
+
+ return (result);
+
+}
+
+
+
+// end of module sua_adapt.c++
diff --git a/sualibrary/sua/sua_adapt.h b/sualibrary/sua/sua_adapt.h
new file mode 100644
index 0000000..190c425
--- /dev/null
+++ b/sualibrary/sua/sua_adapt.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ sua_adapt.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_adapt.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * Purpose: This header-file defines the SUA adaptation functions used by
+ * the SUA application for:
+ * - Nope
+ */
+
+#include "sua_database.h"
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h> /* includes <netinet/in.h> also ! */
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+
+using namespace std;
+
+
+
+
+
+// end of module sua_adapt.h
+
+
diff --git a/sualibrary/sua/sua_asp_mgnt.cpp b/sualibrary/sua/sua_asp_mgnt.cpp
new file mode 100644
index 0000000..93f0b9e
--- /dev/null
+++ b/sualibrary/sua/sua_asp_mgnt.cpp
@@ -0,0 +1,1030 @@
+/***************************************************************************
+ sua_asp_mgnt.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_asp_mgnt.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Sabine
+ * "Due to small parts(Booleans), this code is not suitable for"
+ * "childeren under 3 years."
+ *
+ * Purpose: This code-file defines the SUA management handling functions for
+ * sending and receiving Application Server Process(ASP) messages:
+ * - send a ASP-UP msg to remote node
+ * - send a ASP-UP ACKnowledge msg to remote node
+ * - send a ASP-DOWN ACKnowledge msg to remote node
+ * - send a Hearbeat msg to remote node
+ * - send a Heartbeat ACKnowledge msg to remote node
+ * - send a ASP-ACTIVE msg to remote node
+ * - send a ASP-ACTIVE ACKnowledge msg to remote node
+ * - send a ASP-INactive Acknowledge msg to remote node
+ * - Receive/process ASP UP msg
+ * - Receive/process ASP UP ACKnowladge msg
+ * - Receive/process ASP DOWN msg
+ * - Receive/process ASP DOWN ACKnowledge msg
+ * - Receive/process Heartbeat msg
+ * - Receive/process Heartbeat ACKnowledge msg
+ * - Receive/process ASP ACTIVE msg
+ * - Receive/process ASP ACTIVE ACKnowladge msg
+ * - Receive/process ASP INactive msg
+ * - Receive/process ASP INactive ACKnowledge msg
+ */
+
+#include "sua_debug.h"
+#include "sua_asp_mgnt.h"
+#include "sua_database.h"
+#include "sua_syntax.h"
+#include "sua_logging.h"
+#include "sua_tcb.h"
+
+#include <cstdio>
+#include <string>
+
+extern db_Sua_LocalList local_sua;
+extern db_Sua_RemoteList remote_sua;
+extern db_Sua_AssociationList Assoc_sua;
+extern db_Sua_ASList ApplicServ_sua;
+extern tcb_Sua_msgqueue_pool msg_store;
+
+/***********************************************************************/
+/* Sending SUA Management msg */
+/***********************************************************************/
+/***********************************************************************/
+/* sua_send_ASPUP */
+/***********************************************************************/
+int sua_send_ASPUP( unsigned int Sua_assoc_id
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value = 0;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_aspsm;
+ msg.sua_prim.hdr_msg_type.aspsm = aspsm_up;
+ msg.sua_prim.ASP_id_pres = TRUE;
+ msg.sua_prim.ASP_id = 1;
+ msg.sua_prim.asp_cap_pres = FALSE;
+ msg.sua_prim.info_pres = FALSE;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ sctp_assoc_id = Assoc_sua.instance[Sua_assoc_id].SCTP_assoc_id;
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_asp_mgnt.c",logstring);
+ log_byte_array("sua_asp_mgnt.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result ASPUP sctp send = "<< result << "\n";
+#endif
+ }
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_ASPUP_ACK */
+/***********************************************************************/
+int sua_send_ASPUP_ACK( unsigned int Sua_assoc_id,
+ boolean ASP_id_pres,
+ uint32_t ASP_id
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value = 0;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_aspsm;
+ msg.sua_prim.hdr_msg_type.aspsm = aspsm_up_ack;
+ /* rest is optional */
+ msg.sua_prim.ASP_id_pres = ASP_id_pres;
+ if ( ASP_id_pres)
+ msg.sua_prim.ASP_id = ASP_id;
+
+ msg.sua_prim.info_pres = FALSE;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ sctp_assoc_id = Assoc_sua.instance[Sua_assoc_id].SCTP_assoc_id;
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_asp_mgnt.c",logstring);
+ log_byte_array("sua_asp_mgnt.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result ASPUP_ACK sctp send = "<< result << "\n";
+#endif
+ }
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_ASPDOWN_ACK */
+/***********************************************************************/
+int sua_send_ASPDOWN_ACK( unsigned int Sua_assoc_id
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value = 0;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_aspsm;
+ msg.sua_prim.hdr_msg_type.aspsm = aspsm_down_ack;
+ msg.sua_prim.info_pres = FALSE;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ sctp_assoc_id = Assoc_sua.instance[Sua_assoc_id].SCTP_assoc_id;
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_asp_mgnt.c",logstring);
+ log_byte_array("sua_asp_mgnt.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result ASPDOWN_ACK sctp send = "<< result << "\n";
+#endif
+ }
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_BEAT */
+/***********************************************************************/
+int sua_send_BEAT( unsigned int Sua_assoc_id
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value = 0;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_aspsm;
+ msg.sua_prim.hdr_msg_type.aspsm = aspsm_beat;
+ msg.sua_prim.hb_data_pres = FALSE;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ sctp_assoc_id = Assoc_sua.instance[Sua_assoc_id].SCTP_assoc_id;
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_asp_mgnt.c",logstring);
+ log_byte_array("sua_asp_mgnt.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result BEAT sctp send = "<< result << "\n";
+#endif
+ }
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_BEAT_ACK */
+/***********************************************************************/
+int sua_send_BEAT_ACK( unsigned int Sua_assoc_id,
+ bool HB_data_present,
+ string HB_data
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value = 0;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_aspsm;
+ msg.sua_prim.hdr_msg_type.aspsm = aspsm_beat_ack;
+ msg.sua_prim.hb_data_pres = HB_data_present;
+ if (HB_data_present)
+ msg.sua_prim.hb_data = HB_data;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ sctp_assoc_id = Assoc_sua.instance[Sua_assoc_id].SCTP_assoc_id;
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_asp_mgnt.c",logstring);
+ log_byte_array("sua_asp_mgnt.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result BEAT_ACK sctp send = "<< result << "\n";
+#endif
+ }
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_ASPAC */
+/***********************************************************************/
+int sua_send_ASPAC( unsigned int Sua_assoc_id
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value = 0;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_asptm;
+ msg.sua_prim.hdr_msg_type.asptm = asptm_act;
+ /* traffic mode is optional mandatory */
+ msg.sua_prim.traf_mode_pres = TRUE;
+ msg.sua_prim.traf_mode = tmt_loadshare;
+ /* rest is optional */
+ msg.sua_prim.rout_con_pres = FALSE;
+ msg.sua_prim.info_pres = FALSE;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ sctp_assoc_id = Assoc_sua.instance[Sua_assoc_id].SCTP_assoc_id;
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_asp_mgnt.c",logstring);
+ log_byte_array("sua_asp_mgnt.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result ASPAC sctp send = "<< result << "\n";
+#endif
+ }
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_ASPAC_ACK */
+/***********************************************************************/
+int sua_send_ASPAC_ACK( unsigned int Sua_assoc_id,
+ boolean traffic_mode_present,
+ Sua_traffic_mode_type traffic_mode,
+ boolean routing_context_present,
+ uint32_t routing_context
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value = 0;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_asptm;
+ msg.sua_prim.hdr_msg_type.asptm = asptm_act_ack;
+
+ /* rest is optional */
+ msg.sua_prim.traf_mode_pres = traffic_mode_present;
+ if ( traffic_mode_present)
+ msg.sua_prim.traf_mode = traffic_mode;
+
+ msg.sua_prim.rout_con_pres = routing_context_present;
+ if (routing_context_present)
+ msg.sua_prim.rout_con = routing_context;
+
+ msg.sua_prim.info_pres = FALSE;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ sctp_assoc_id = Assoc_sua.instance[Sua_assoc_id].SCTP_assoc_id;
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_asp_mgnt.c",logstring);
+ log_byte_array("sua_asp_mgnt.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result ASPAC_ACK sctp send = "<< result << "\n";
+#endif
+ }
+
+ return(error_value);
+}
+
+
+/***********************************************************************/
+/* sua_send_ASPINAC_ACK */
+/***********************************************************************/
+int sua_send_ASPINAC_ACK( unsigned int Sua_assoc_id
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value = 0;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_asptm;
+ msg.sua_prim.hdr_msg_type.asptm = asptm_inact_ack;
+ msg.sua_prim.rout_con_pres = FALSE;
+ msg.sua_prim.info_pres = FALSE;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ sctp_assoc_id = Assoc_sua.instance[Sua_assoc_id].SCTP_assoc_id;
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_asp_mgnt.c",logstring);
+ log_byte_array("sua_asp_mgnt.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result ASPINAC_ACK sctp send = "<< result << "\n";
+#endif
+ }
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* Receiving SUA Management msg */
+/***********************************************************************/
+/***********************************************************************/
+/* sua_process_ASPUP_msg */
+/***********************************************************************/
+int process_ASPUP_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+
+ int error_value;
+
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:ASPUP received, send back a ASPUP_ACK and set state to ASP-INACTIVE.\n";
+#endif
+
+ Assoc_sua.up(sua_assoc_id,0);
+
+ error_value = sua_send_ASPUP_ACK( sua_assoc_id ,
+ sua_asp_msg.sua_prim.ASP_id_pres,
+ sua_asp_msg.sua_prim.ASP_id
+ );
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result send ASPUP_ACK = "<< error_value << "\n";
+ cout << "sua_asp_mgnt.c:ASPUP processing state = "<< Assoc_sua.instance[sua_assoc_id].asp.status << "\n";
+#endif
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_ASPUP_ACK_msg */
+/***********************************************************************/
+int process_ASPUP_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+ int error_value = 0;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:ASPUP_ACK received, looks like remote is inactive.\n";
+#endif
+
+ Assoc_sua.up(sua_assoc_id,0);
+
+ /* send activation to remote */
+ error_value = sua_send_ASPAC( sua_assoc_id );
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result send ASPAC = "<< error_value << "\n";
+ cout << "sua_asp_mgnt.c:ASPUP_ACK processing state = "<< Assoc_sua.instance[sua_assoc_id].asp.status << "\n";
+#endif
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_ASPDOWN_msg */
+/***********************************************************************/
+int process_ASPDOWN_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+
+ int error_value;
+
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:ASPDOWN received, send back a ASPDOWN_ACK and set state to ASP-DOWN.\n";
+#endif
+
+ Assoc_sua.down(sua_assoc_id,0);
+
+
+ error_value = sua_send_ASPDOWN_ACK( sua_assoc_id );
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result send ASPDOWN_ACK = "<< error_value << "\n";
+#endif
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_ASPDOWN_ACK_msg */
+/***********************************************************************/
+int process_ASPDOWN_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+ int error_value = 0;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:ASPDOWN_ACK received, remote looks down.\n";
+#endif
+
+ Assoc_sua.down(sua_assoc_id,0);
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_BEAT_msg */
+/***********************************************************************/
+int process_BEAT_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+
+ int error_value;
+
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:HEARTBEAT received, send back a HEARTBEAT_ACK.\n";
+#endif
+
+ error_value = sua_send_BEAT_ACK( sua_assoc_id,
+ sua_asp_msg.sua_prim.hb_data_pres,
+ sua_asp_msg.sua_prim.hb_data
+ );
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result send HEARTBEAT_ACK = "<< error_value << "\n";
+#endif
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_BEAT_ACK_msg */
+/***********************************************************************/
+int process_BEAT_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+ int error_value = 0;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:HEARTBEAT_ACK received, nothing further to do.\n";
+#endif
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_ASPAC_msg */
+/***********************************************************************/
+int process_ASPAC_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+ bool holdtraffic_pres = FALSE;
+ int error_value;
+ tcb_Sua_msg_elem sua_msg;
+ int datalen;
+ signed int sctp_assoc_id;
+ int result;
+
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:ASPAC received, send back a ASPAC_ACK and set state to ASP-ACTIVE.\n";
+#endif
+
+ if (sua_asp_msg.sua_prim.traf_mode_pres)
+ holdtraffic_pres = Assoc_sua.activate(sua_assoc_id,
+ sua_asp_msg.sua_prim.traf_mode);
+ else
+ holdtraffic_pres = Assoc_sua.activate(sua_assoc_id,0);
+
+ error_value = sua_send_ASPAC_ACK( sua_assoc_id,
+ sua_asp_msg.sua_prim.traf_mode_pres,
+ sua_asp_msg.sua_prim.traf_mode,
+ sua_asp_msg.sua_prim.rout_con_pres,
+ sua_asp_msg.sua_prim.rout_con
+ );
+
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result ASPAC_ACK send = "<< error_value << "\n";
+ cout << "sua_asp_mgnt.c:ASPAC processing state = "<< Assoc_sua.instance[sua_assoc_id].asp.status << "\n";
+#endif
+
+ if (holdtraffic_pres)
+ {
+ /* send all stored msg for this association to remote side */
+ /* should be looping to get all waiting messages */
+ /* - get the saved msg ansd send it on the association that is setup */
+ sua_msg = msg_store.get_msg ( sua_assoc_id );
+
+ while ( sua_msg.valid)
+ {
+ char* databuf = new char[sua_msg.byte.length()];
+ sua_msg.byte.copy(databuf, sua_msg.byte.length());
+ datalen = sua_msg.byte.length();
+
+ /* msg retrieved and copied, may now remove it from queue */
+ msg_store.delete_msg ( sua_assoc_id );
+
+ sctp_assoc_id = Assoc_sua.instance[sua_assoc_id].SCTP_assoc_id;
+
+#ifdef DEBUG
+ display_byte_array(databuf , sua_msg.byte.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_distribution.c",logstring);
+ log_byte_array("sua_distribution.c", databuf,sua_msg.byte.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ sua_msg.stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ sua_msg.delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result sctp send = "<< result << "\n";
+#endif
+ /* get the next saved msg ansd send if any ? */
+ sua_msg = msg_store.get_msg ( sua_assoc_id );
+
+ }
+
+ }
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_ASPAC_ACK_msg */
+/***********************************************************************/
+int process_ASPAC_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+ int error_value = 0;
+ bool holdtraffic_pres = FALSE;
+
+#ifdef SG_ASP_MODE
+ if (sua_asp_msg.sua_prim.traf_mode_pres)
+ holdtraffic_pres = Assoc_sua.activate(sua_assoc_id,
+ sua_asp_msg.sua_prim.traf_mode);
+ else
+ holdtraffic_pres = Assoc_sua.activate(sua_assoc_id,0);
+
+#endif
+
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:ASPAC_ACK received, nothing further to do.\n";
+#endif
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_ASPINAC_msg */
+/***********************************************************************/
+int process_ASPINAC_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+ int error_value;
+ tcb_Sua_msg_elem sua_msg;
+
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:ASPINAC received, send back a ASPINAC_ACK and set state to ASP-INACTIVE.\n";
+#endif
+ Assoc_sua.deactivate(sua_assoc_id,0);
+
+ error_value = sua_send_ASPINAC_ACK( sua_assoc_id );
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:result ASPINAC_ACK send = "<< error_value << "\n";
+#endif
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_process_ASPINAC_ACK_msg */
+/***********************************************************************/
+int process_ASPINAC_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ )
+{
+ int error_value = 0;
+#ifdef DEBUG
+ cout << "sua_asp_mgnt.c:ASPINAC_ACK received, nothing further to do.\n";
+#endif
+ return(error_value);
+}
+
+/***********************************************************************/
+/* Asp_mngt_standby */
+/***********************************************************************/
+void Asp_mngt_standby ( unsigned int sua_AS_id,
+ unsigned int sua_asp_id,
+ short mode
+ )
+{
+ ApplicServ_sua.override_ASP( sua_asp_id,
+ sua_AS_id,
+ mode
+ );
+}
+
+void asp_activate_override ( unsigned int asp_sua_assoc_id )
+{
+ Assoc_sua.activate(asp_sua_assoc_id,0);
+}
+
+void asp_deactivate ( unsigned int asp_sua_assoc_id)
+{
+ Assoc_sua.deactivate(asp_sua_assoc_id,0);
+}
+
+
+//end of module sua_asp_mgnt.c++
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_asp_mgnt.h b/sualibrary/sua/sua_asp_mgnt.h
new file mode 100644
index 0000000..6531d17
--- /dev/null
+++ b/sualibrary/sua/sua_asp_mgnt.h
@@ -0,0 +1,190 @@
+/***************************************************************************
+ sua_asp_mgnt.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_asp_mgnt.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * Purpose: This header-file defines the SUA management handling functions for
+ * sending and receiving Application Server Process(ASP) messages:
+ * - send a ASP-UP msg to remote node
+ * - send a ASP-ACTIVE msg to remote node
+ * - Receive/process ASP UP msg
+ * - Receive/process ASP UP ACKnowladge msg
+ * - Receive/process ASP DOWN msg
+ * - Receive/process ASP DOWN ACKnowledge msg
+ * - Receive/process Heartbeat msg
+ * - Receive/process Heartbeat ACKnowledge msg
+ * - Receive/process ASP ACTIVE msg
+ * - Receive/process ASP ACTIVE ACKnowladge msg
+ * - Receive/process ASP INactive msg
+ * - Receive/process ASP INactive ACKnowledge msg
+ * Contains also the ASP management states set
+ */
+
+#ifndef SUA_ASP_MGNT_H
+#define SUA_ASP_MGNT_H
+
+#include "sua.h"
+#include "sua_syntax.h"
+
+#include <string>
+
+
+
+typedef enum {asp_idle, // 0
+ asp_down, // 1
+ asp_down_traf_hold, // 2
+ asp_inactive, // 3
+ asp_inactive_traf_hold, // 4
+ asp_active // 5
+} asp_Sua_asp_state_set;
+
+
+typedef enum {as_idle, // 0
+ as_down, // 1
+ as_pending, // 2
+ as_inactive, // 3
+ as_active // 4
+} asp_Sua_as_state_set;
+
+typedef enum { lm_override, // 0: standard loadshare: only 1 ASP
+ lm_share_RR, // 1: Round robin load sharing
+ lm_share_XX, // 2: unknown load sharing
+ lm_share_BC // 3: Broadcasting
+}asp_Sua_loadmode_set;
+
+int sua_send_ASPUP( unsigned int Sua_assoc_id
+ );
+
+int sua_send_ASPAC( unsigned int Sua_assoc_id
+ );
+
+
+int process_ASPUP_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_ASPUP_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_ASPDOWN_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_ASPDOWN_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_BEAT_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_BEAT_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_ASPAC_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_ASPAC_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_ASPINAC_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+int process_ASPINAC_ACK_msg ( unsigned int sua_assoc_id,
+ int local_sua_id,
+ int remote_sua_id,
+ Sua_container sua_asp_msg
+ );
+
+void Asp_mngt_standby ( unsigned int sua_AS_id,
+ unsigned int sua_asp_id,
+ short mode
+ );
+
+void asp_activate_override ( unsigned int asp_sua_assoc_id );
+
+void asp_deactivate ( unsigned int asp_sua_assoc_id);
+
+
+
+
+#endif // SUA_ASP_MGNT_H
+
+//end of module sua_asp_mgnt.h
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_cl.cpp b/sualibrary/sua/sua_cl.cpp
new file mode 100644
index 0000000..4ec0bb7
--- /dev/null
+++ b/sualibrary/sua/sua_cl.cpp
@@ -0,0 +1,550 @@
+/***************************************************************************
+ sua_cl.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_cl.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Dorothee
+ * "Always admire the local beauties in their natural enviroment."
+ *
+ * Purpose: This code-file defines the SUA connectionless message handling:
+ * - send a Unitdata msg to remote node
+ * (- send a Unitdata Service msg to remote node)
+ * - Process a Unitdata msg
+ * (- Process a Unitdata Service msg)
+ */
+
+
+#include "sua_debug.h"
+#include "sua_syntax.h"
+#include "sua_database.h"
+#include "sua_logging.h"
+#include "sua_distribution.h"
+#include "sua_tcb.h"
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h> /* includes <netinet/in.h> also ! */
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+using namespace std;
+
+// import the dataobjects of SUA
+extern db_Sua_LocalList local_sua;
+extern db_Sua_RemoteList remote_sua;
+extern db_Sua_AssociationList Assoc_sua;
+
+extern tcb_Sua_msgqueue_pool msg_store;
+
+// import the received msg pool
+extern vector<sua_save_str> rec_msg_pool;
+
+/***********************************************************************/
+/* sua_send_Unitdata */
+/***********************************************************************/
+int sua_send_Unitdata(sccp_QOS_str &QOS,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address,
+ char *buffer,
+ unsigned int len
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value;
+ int string_size, datalen;
+ signed int sctp_assoc_id;
+ unsigned int sua_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+ tcb_Sua_msg_elem sua_msg;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_cl;
+ msg.sua_prim.hdr_msg_type.cl = cl_data_transfer;
+
+ msg.sua_prim.rout_con_pres = TRUE;
+ msg.sua_prim.rout_con = 1;
+ msg.sua_prim.importance_pres = TRUE;
+ msg.sua_prim.importance = 5;
+ msg.sua_prim.hop_count_pres = TRUE;
+ msg.sua_prim.hop_count = 15;
+
+ // QOS choice
+ switch (QOS.prot_class)
+ {
+ case(class0): // connectionless transport, non-sequenced
+ msg.sua_prim.prot_class_pres = TRUE;
+ msg.sua_prim.prot_class.pcl = prot_class_0;
+ msg.sua_prim.seq_control_pres = TRUE;
+ msg.sua_prim.seq_control = QOS.sequence_number;
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ case(class1):
+ msg.sua_prim.prot_class_pres = TRUE;
+ msg.sua_prim.prot_class.pcl = prot_class_1;
+ msg.sua_prim.seq_control_pres = TRUE;
+ msg.sua_prim.seq_control = QOS.sequence_number;
+ delivery_type = SCTP_ORDERED_DELIVERY;
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+
+ if (QOS.return_msg_on_error)
+ msg.sua_prim.prot_class.return_option = TRUE;
+ else
+ msg.sua_prim.prot_class.return_option = FALSE;
+
+ // fill in the source address (=local sua address/CLG)
+ switch (calling_pty_address.routing_ind)
+ {
+ case (route_on_ssn):
+
+ if (calling_pty_address.address_fields_present.pc == ipvx_pc_present)
+ {
+ msg.sua_prim.source_addr.ip_addr_pres = TRUE;
+ msg.sua_prim.source_addr.pc_pres = FALSE;
+ if (calling_pty_address.pc.ipvx.sa.sa_family == AF_INET)
+ {
+ msg.sua_prim.source_addr.ip_addr_type = ip_v4;
+ msg.sua_prim.source_addr.ip_addr.ipv4 = calling_pty_address.pc.ipvx.sin;
+ }
+ else if (calling_pty_address.pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ msg.sua_prim.source_addr.ip_addr_type = ip_v6;
+ msg.sua_prim.source_addr.ip_addr.ipv6 = calling_pty_address.pc.ipvx.sin6;
+ }
+ else
+ cout << "error filling in CLG IP address \n";
+
+ msg.sua_prim.source_addr_pres = TRUE;
+ msg.sua_prim.source_addr.rout_ind = ri_route_IP_SSN;
+ msg.sua_prim.source_addr.ssn_incl = TRUE;
+ msg.sua_prim.source_addr.pc_incl = FALSE;
+ msg.sua_prim.source_addr.gt_incl = FALSE;
+ msg.sua_prim.source_addr.ssn = calling_pty_address.ssn;
+ }
+ else if (calling_pty_address.address_fields_present.pc == ss7_pc_present)
+ {
+ msg.sua_prim.source_addr_pres = TRUE;
+ msg.sua_prim.source_addr.ip_addr_pres = FALSE;
+ msg.sua_prim.source_addr.pc_pres = TRUE;
+ msg.sua_prim.source_addr.pc = calling_pty_address.pc.ss7.ITU24.pc;
+ msg.sua_prim.source_addr.rout_ind = ri_route_PC_SSN;
+ msg.sua_prim.source_addr.ssn_incl = TRUE;
+ msg.sua_prim.source_addr.pc_incl = TRUE;
+ msg.sua_prim.source_addr.gt_incl = FALSE;
+ msg.sua_prim.source_addr.ssn = calling_pty_address.ssn;
+ cout << "SS7 PC in CLG address \n";
+ }
+ else
+ cout << "unsupported CLG address option\n";
+ break;
+ case(route_on_name_gt):
+ msg.sua_prim.source_addr.ip_addr_pres = FALSE;
+ msg.sua_prim.source_addr.pc_pres = FALSE;
+ msg.sua_prim.source_addr.hostname_pres = TRUE;
+ msg.sua_prim.source_addr.hostname = calling_pty_address.name.HostName;
+ msg.sua_prim.source_addr_pres = TRUE;
+ msg.sua_prim.source_addr.rout_ind = ri_route_hostname;
+ msg.sua_prim.source_addr.ssn_incl = TRUE;
+ msg.sua_prim.source_addr.pc_incl = FALSE;
+ msg.sua_prim.source_addr.gt_incl = TRUE;
+ msg.sua_prim.source_addr.ssn = called_pty_address.ssn;
+ break;
+ case(route_on_name_gt_next_office):
+ break;
+ default:
+ return(INVALID_CLG_ADDRESS);
+ break;
+ }
+
+
+ // fill in the destination address(=remote sua address/CLD)
+ switch (called_pty_address.routing_ind)
+ {
+ case (route_on_ssn):
+
+ if (called_pty_address.address_fields_present.pc == ipvx_pc_present)
+ {
+ msg.sua_prim.dest_addr.ip_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.pc_pres = FALSE;
+ if (called_pty_address.pc.ipvx.sa.sa_family == AF_INET)
+ {
+ msg.sua_prim.dest_addr.ip_addr_type = ip_v4;
+ msg.sua_prim.dest_addr.ip_addr.ipv4 = called_pty_address.pc.ipvx.sin;
+ }
+ else if (called_pty_address.pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ msg.sua_prim.dest_addr.ip_addr_type = ip_v6;
+ msg.sua_prim.dest_addr.ip_addr.ipv6 = called_pty_address.pc.ipvx.sin6;
+ }
+ else
+ cout << "error filling in CLD IP address \n";
+ msg.sua_prim.dest_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.rout_ind = ri_route_IP_SSN;
+ msg.sua_prim.dest_addr.ssn_incl = TRUE;
+ msg.sua_prim.dest_addr.pc_incl = FALSE;
+ msg.sua_prim.dest_addr.gt_incl = FALSE;
+ msg.sua_prim.dest_addr.ssn = called_pty_address.ssn;
+ }
+ else if (called_pty_address.address_fields_present.pc == ss7_pc_present)
+ {
+ msg.sua_prim.dest_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.ip_addr_pres = FALSE;
+ msg.sua_prim.dest_addr.pc_pres = TRUE;
+ msg.sua_prim.dest_addr.pc = called_pty_address.pc.ss7.ITU24.pc;
+ msg.sua_prim.dest_addr.rout_ind = ri_route_PC_SSN;
+ msg.sua_prim.dest_addr.ssn_incl = TRUE;
+ msg.sua_prim.dest_addr.pc_incl = TRUE;
+ msg.sua_prim.dest_addr.gt_incl = FALSE;
+ msg.sua_prim.dest_addr.ssn = called_pty_address.ssn;
+ cout << "SS7 PC in CLD address \n";
+ }
+ else
+ cout << "unsupported CLD address option\n";
+
+ break;
+ case(route_on_name_gt):
+ msg.sua_prim.dest_addr.ip_addr_pres = FALSE;
+ msg.sua_prim.dest_addr.hostname_pres = TRUE;
+ msg.sua_prim.dest_addr.pc_pres = FALSE;
+ msg.sua_prim.dest_addr.hostname = called_pty_address.name.HostName;
+ msg.sua_prim.dest_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.rout_ind = ri_route_hostname;
+ msg.sua_prim.dest_addr.ssn_incl = TRUE;
+ msg.sua_prim.dest_addr.pc_incl = FALSE;
+ msg.sua_prim.dest_addr.gt_incl = TRUE;
+ msg.sua_prim.dest_addr.ssn = called_pty_address.ssn;
+ break;
+ case(route_on_name_gt_next_office):
+ break;
+ default:
+ return(INVALID_CLD_ADDRESS);
+ break;
+ }
+
+ // fill in the user data
+ msg.sua_prim.data_pres = TRUE;
+ string stemp(buffer,len);
+ msg.sua_prim.data_string = stemp;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ // call routing to figure out which association to take for sending
+ // out the message
+#ifdef DEBUG
+ cout << "call routing function\n";
+#endif
+ sctp_assoc_id = Assoc_sua.route_msg( called_pty_address,
+ calling_pty_address
+ );
+#ifdef DEBUG
+ cout << "routed to SCTP assoc " << sctp_assoc_id << "\n";
+#endif
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_cl.c",logstring);
+ log_byte_array("sua_cl.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_cl.c:result sctp send = "<< result << "\n";
+#endif
+ }
+ else if (sctp_assoc_id < 0)
+ {
+#ifdef DEBUG
+ cout << "sua_cl.c:sending msg prohibited \n";
+#endif
+ error_value = -1;
+ }
+ else
+ {
+ /* NO it does NOT exist. */
+ /* - Try to set up the association */
+ sua_assoc_id = Assoc_sua.Dynamic_Associate ( local_sua,
+ remote_sua,
+ called_pty_address,
+ calling_pty_address,
+ 1,
+ 1,
+ 1
+ );
+
+ /* - save the msg till the association is setup or */
+ /* association setup fails -> drop saved msg */
+ sua_msg.byte = msg.sua_msg;
+ sua_msg.delivery_type = delivery_type;
+ sua_msg.stream_id = stream_id;
+ sua_msg.valid = true;
+ msg_store.add_msg ( sua_assoc_id,
+ sua_msg
+ );
+
+ error_value = -1;
+ }
+ return(error_value);
+}
+
+
+/***********************************************************************/
+/* SUA receive a connectionless message */
+/***********************************************************************/
+/***********************************************************************/
+/* sua_process_unitdata */
+/***********************************************************************/
+short process_unitdata_msg ( int local_sua_id,
+ unsigned int sua_assoc_id,
+ Sua_container &msg
+ )
+{
+
+ sua_save_str temp;
+
+ temp.primitive = N_UNITDATA;
+ temp.user_ref = 0;
+
+ if (msg.sua_prim.prot_class_pres)
+ {
+ // QOS choice
+ switch ( msg.sua_prim.prot_class.pcl)
+ {
+ case(prot_class_0): // connectionless transport, non-sequenced
+ temp.QOS.prot_class = class0;
+ temp.QOS.in_sequence = false;
+ break;
+ case(prot_class_1):
+ temp.QOS.prot_class = class1;
+ temp.QOS.in_sequence = true;
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+ temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE);
+ }
+
+ temp.QOS.sequence_number = 0;
+ temp.QOS.importance = msg.sua_prim.importance;
+
+ // retrieve the clg(=source) address (=remote sua address)
+ // which types are present in the address(ip pc, SS7 pc, GT, hostname)
+ if (msg.sua_prim.source_addr.ip_addr_pres == TRUE)
+ {
+ temp.calling_pty_address.address_fields_present.pc = ipvx_pc_present;
+ if (msg.sua_prim.source_addr.ip_addr_type == ip_v4) {
+ temp.calling_pty_address.pc.ipvx.sin = msg.sua_prim.source_addr.ip_addr.ipv4;
+ temp.calling_pty_address.pc.ipvx.sa.sa_family = AF_INET;
+ temp.calling_pty_address.pc.ipvx.sin.sin_port = Assoc_sua.instance[sua_assoc_id].Dest.addrs[0].sin.sin_port;
+ }
+ else if (msg.sua_prim.source_addr.ip_addr_type == ip_v6) {
+ temp.calling_pty_address.pc.ipvx.sin6 = msg.sua_prim.source_addr.ip_addr.ipv6;
+ temp.calling_pty_address.pc.ipvx.sa.sa_family = AF_INET6;
+ temp.calling_pty_address.pc.ipvx.sin6.sin6_port = Assoc_sua.instance[sua_assoc_id].Dest.addrs[0].sin.sin_port;
+ }
+ else
+ cout << "Unknown IP address format\n";
+ }
+ if (msg.sua_prim.source_addr.pc_pres == TRUE)
+ {
+ temp.calling_pty_address.address_fields_present.pc = ss7_pc_present;
+ temp.calling_pty_address.pc.ss7.ITU24.family = ITU24bit;
+ temp.calling_pty_address.pc.ss7.ITU24.pc = msg.sua_prim.source_addr.pc;
+ }
+ if (msg.sua_prim.source_addr.gt_pres == TRUE)
+ {
+ cout << "Global Title : unsupported address format\n";
+ }
+ if (msg.sua_prim.source_addr.hostname_pres == TRUE)
+ {
+ temp.calling_pty_address.address_fields_present.name_gt = hostname_present;
+ msg.sua_prim.source_addr.hostname.copy( temp.calling_pty_address.name.HostName,
+ (msg.sua_prim.source_addr.hostname.length()+1 )
+ );
+ temp.calling_pty_address.name.HostName[msg.sua_prim.source_addr.hostname.length()] = '\0';
+ }
+ if ((msg.sua_prim.source_addr.ip_addr_pres /= TRUE) &&
+ (msg.sua_prim.source_addr.pc_pres /= TRUE) &&
+ (msg.sua_prim.source_addr.gt_pres /= TRUE) &&
+ (msg.sua_prim.source_addr.hostname_pres /= TRUE))
+ {
+ cout << "No valid address format found in msg\n";
+ }
+
+ // routing indicator
+ switch (msg.sua_prim.source_addr.rout_ind)
+ {
+ case(ri_route_PC_SSN):
+ temp.calling_pty_address.routing_ind = route_on_ssn;
+ break;
+ case(ri_route_IP_SSN):
+ temp.calling_pty_address.routing_ind = route_on_ssn;
+ break;
+ case (ri_route_GT):
+ temp.calling_pty_address.routing_ind = route_on_name_gt;
+ break;
+ case (ri_route_hostname):
+ temp.calling_pty_address.routing_ind = route_on_name_gt;
+ break;
+ default:
+ break;
+ }
+
+ temp.calling_pty_address.address_fields_present.ssn_port = ssn_present;
+ temp.calling_pty_address.ssn = msg.sua_prim.source_addr.ssn;
+
+
+ // retrieve the called(=destination) address(=should be our own local addr)
+ // not completely done yet
+ if (msg.sua_prim.dest_addr.pc_pres == TRUE)
+ {
+ temp.called_pty_address.address_fields_present.pc = ss7_pc_present;
+ temp.called_pty_address.pc.ss7.ITU24.family = ITU24bit;
+ temp.called_pty_address.pc.ss7.ITU24.pc = msg.sua_prim.source_addr.pc;
+ }
+
+ if (msg.sua_prim.dest_addr.hostname_pres == TRUE)
+ {
+ temp.called_pty_address.address_fields_present.name_gt = hostname_present;
+ msg.sua_prim.dest_addr.hostname.copy( temp.called_pty_address.name.HostName,
+ (msg.sua_prim.dest_addr.hostname.length()+1 )
+ );
+ temp.called_pty_address.name.HostName[msg.sua_prim.dest_addr.hostname.length()] = '\0';
+ }
+ // routing indicator
+ switch (msg.sua_prim.dest_addr.rout_ind)
+ {
+ case(ri_route_PC_SSN):
+ temp.called_pty_address.routing_ind = route_on_ssn;
+ break;
+ case(ri_route_IP_SSN):
+ temp.called_pty_address.routing_ind = route_on_ssn;
+ break;
+ case (ri_route_GT):
+ temp.called_pty_address.routing_ind = route_on_name_gt;
+ break;
+ case (ri_route_hostname):
+ temp.called_pty_address.routing_ind = route_on_name_gt;
+ break;
+ default:
+ break;
+ }
+
+ temp.called_pty_address.address_fields_present.ssn_port = ssn_present;
+ temp.called_pty_address.ssn = msg.sua_prim.dest_addr.ssn;
+
+
+ if (msg.sua_prim.data_pres == TRUE)
+ temp.userdata = msg.sua_prim.data_string;
+ else
+ cout << "sua_cl.c: no sua user data in unitdata msg \n";
+
+ // store primitive in a list(is retrieve via sua_receive_msg)
+ rec_msg_pool.push_back(temp);
+
+
+
+ /* call the application/user callBack function */
+ local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_ClDataIndNotif
+ ( local_sua_id,
+ N_UNITDATA,
+ temp.userdata.length()
+ );
+
+ return(0);
+}
+
+
+// end of module sua_cl.c
+
+
+
+
+
diff --git a/sualibrary/sua/sua_cl.h b/sualibrary/sua/sua_cl.h
new file mode 100644
index 0000000..6c32df3
--- /dev/null
+++ b/sualibrary/sua/sua_cl.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+ sua_cl.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_cl.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * Purpose: This header-file defines the SUA connectionless message handling:
+ * - send a Unitdata msg to remote node
+ * (- send a Unitdata Service msg to remote node)
+ * - Process a Unitdata msg
+ * (- Process a Unitdata Service msg)
+ */
+
+#ifndef SUA_CL_H
+#define SUA_CL_H
+
+#include "sua_database.h"
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+
+
+using namespace std;
+
+int sua_send_Unitdata(sccp_QOS_str &QOS,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address,
+ char *buffer,
+ unsigned int len
+ );
+
+short process_unitdata_msg ( int local_sua_id,
+ unsigned int sua_assoc_id,
+ Sua_container &sua_msg
+ );
+
+#endif // SUA_CL_H
+
+// end of module sua_cl.h
+
+
diff --git a/sualibrary/sua/sua_co.cpp b/sualibrary/sua/sua_co.cpp
new file mode 100644
index 0000000..0b08a1f
--- /dev/null
+++ b/sualibrary/sua/sua_co.cpp
@@ -0,0 +1,1768 @@
+/***************************************************************************
+ sua_co.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_co.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Virginie
+ * "This code was written using the KISS methodology. (Yes, we kissed a "
+ * "lot of beautifull girls) We always use this method."
+ *
+ * Purpose: This code-file defines the SUA connection-oriented message
+ * handling:
+ * - send a COnnect REquest msg to remote node
+ * - send a COnnect RESPonse msg to remote node
+ * - send a CO DATA msg to remote node
+ * - send a CO RELease REQuest msg to remote node
+ * - send a CO RELease COnfirm msg to remote node
+ * - Process a COnnect REquest msg
+ * - Process a COnnect RESPonse msg
+ * - Process a CO DATA msg
+ * - Process a CO RELease REQuest msg
+ * - Process a CO RELease COnfirm msg
+ * - Process a COnnect REFuse msg
+ */
+
+#include "sua_debug.h"
+#include "sua_syntax.h"
+#include "sua_database.h"
+#include "sua_distribution.h"
+#include "sua_logging.h"
+#include "sua_tcb.h"
+
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h> /* includes <netinet/in.h> also ! */
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+using namespace std;
+
+// import the dataobjects of SUA
+extern db_Sua_LocalList local_sua;
+extern db_Sua_RemoteList remote_sua;
+extern db_Sua_AssociationList Assoc_sua;
+
+// import the TCB pool of SUA
+extern tcb_Sua_TCB_arr tcb_pool;
+extern tcb_Sua_msgqueue_pool msg_store;
+
+// import the received msg pool
+extern vector<sua_save_str> rec_msg_pool;
+
+/***********************************************************************/
+/* Send sua connection-oriented request primitive to remote side */
+/***********************************************************************/
+/***********************************************************************/
+/* sua_send_CORE */
+/***********************************************************************/
+int sua_send_CORE( sccp_QOS_str &QOS,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value;
+ int string_size, datalen;
+ signed int SCTP_assoc_id;
+ unsigned int sua_assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+ tcb_Sua_msg_elem sua_msg;
+
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_co;
+ msg.sua_prim.hdr_msg_type.co = co_core;
+
+ msg.sua_prim.rout_con_pres = TRUE;
+ msg.sua_prim.rout_con = 1;
+ msg.sua_prim.importance_pres = TRUE;
+ msg.sua_prim.importance = 5;
+ msg.sua_prim.hop_count_pres = TRUE;
+ msg.sua_prim.hop_count = 15;
+
+ // QOS choice
+ switch (QOS.prot_class)
+ {
+ case(class2): // connectionless transport, non-sequenced
+ msg.sua_prim.prot_class_pres = TRUE;
+ msg.sua_prim.prot_class.pcl = prot_class_2;
+ msg.sua_prim.seq_control_pres = TRUE;
+ msg.sua_prim.seq_control = 1;
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ case(class3):
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+ if (QOS.return_msg_on_error)
+ msg.sua_prim.prot_class.return_option = TRUE;
+ else
+ msg.sua_prim.prot_class.return_option = FALSE;
+
+ // fill in the source address (=local sua address/CLG)
+ switch (calling_pty_address.routing_ind)
+ {
+ case (route_on_ssn):
+
+ if (calling_pty_address.address_fields_present.pc == ipvx_pc_present)
+ {
+ msg.sua_prim.source_addr.ip_addr_pres = TRUE;
+ msg.sua_prim.source_addr.pc_pres = FALSE;
+ if (calling_pty_address.pc.ipvx.sa.sa_family == AF_INET)
+ {
+ msg.sua_prim.source_addr.ip_addr_type = ip_v4;
+ msg.sua_prim.source_addr.ip_addr.ipv4 = calling_pty_address.pc.ipvx.sin;
+ }
+ else if (calling_pty_address.pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ msg.sua_prim.source_addr.ip_addr_type = ip_v6;
+ msg.sua_prim.source_addr.ip_addr.ipv6 = calling_pty_address.pc.ipvx.sin6;
+ }
+ else
+ cout << "error filling in CLG IP address \n";
+
+ msg.sua_prim.source_addr_pres = TRUE;
+ msg.sua_prim.source_addr.rout_ind = ri_route_IP_SSN;
+ msg.sua_prim.source_addr.ssn_incl = TRUE;
+ msg.sua_prim.source_addr.pc_incl = FALSE;
+ msg.sua_prim.source_addr.gt_incl = FALSE;
+ msg.sua_prim.source_addr.ssn = calling_pty_address.ssn;
+ }
+ else if (calling_pty_address.address_fields_present.pc == ss7_pc_present)
+ {
+ msg.sua_prim.source_addr_pres = TRUE;
+ msg.sua_prim.source_addr.ip_addr_pres = FALSE;
+ msg.sua_prim.source_addr.pc_pres = TRUE;
+ msg.sua_prim.source_addr.pc = calling_pty_address.pc.ss7.ITU24.pc;
+ msg.sua_prim.source_addr.rout_ind = ri_route_PC_SSN;
+ msg.sua_prim.source_addr.ssn_incl = TRUE;
+ msg.sua_prim.source_addr.pc_incl = TRUE;
+ msg.sua_prim.source_addr.gt_incl = FALSE;
+ msg.sua_prim.source_addr.ssn = calling_pty_address.ssn;
+ cout << "SS7 PC in CLG address \n";
+ }
+ else
+ cout << "unsupported CLG address option\n";
+
+ break;
+ case(route_on_name_gt):
+ msg.sua_prim.source_addr.ip_addr_pres = FALSE;
+ msg.sua_prim.source_addr.pc_pres = FALSE;
+ msg.sua_prim.source_addr.hostname_pres = TRUE;
+ msg.sua_prim.source_addr.hostname = calling_pty_address.name.HostName;
+ msg.sua_prim.source_addr_pres = TRUE;
+ msg.sua_prim.source_addr.rout_ind = ri_route_hostname;
+ msg.sua_prim.source_addr.ssn_incl = TRUE;
+ msg.sua_prim.source_addr.pc_incl = FALSE;
+ msg.sua_prim.source_addr.gt_incl = TRUE;
+ msg.sua_prim.source_addr.ssn = called_pty_address.ssn;
+ break;
+ case(route_on_name_gt_next_office):
+ break;
+ default:
+ return(INVALID_CLG_ADDRESS);
+ break;
+ }
+
+
+ // fill in the destination address(=remote sua address/CLD)
+ switch (called_pty_address.routing_ind)
+ {
+ case (route_on_ssn):
+
+ if (called_pty_address.address_fields_present.pc == ipvx_pc_present)
+ {
+ msg.sua_prim.dest_addr.ip_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.pc_pres = FALSE;
+ if (called_pty_address.pc.ipvx.sa.sa_family == AF_INET)
+ {
+ msg.sua_prim.dest_addr.ip_addr_type = ip_v4;
+ msg.sua_prim.dest_addr.ip_addr.ipv4 = called_pty_address.pc.ipvx.sin;
+ }
+ else if (called_pty_address.pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ msg.sua_prim.dest_addr.ip_addr_type = ip_v6;
+ msg.sua_prim.dest_addr.ip_addr.ipv6 = called_pty_address.pc.ipvx.sin6;
+ }
+ else
+ cout << "error filling in CLD IP address \n";
+
+ msg.sua_prim.dest_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.rout_ind = ri_route_IP_SSN;
+ msg.sua_prim.dest_addr.ssn_incl = TRUE;
+ msg.sua_prim.dest_addr.pc_incl = FALSE;
+ msg.sua_prim.dest_addr.gt_incl = FALSE;
+ msg.sua_prim.dest_addr.ssn = called_pty_address.ssn;
+ }
+ else if (called_pty_address.address_fields_present.pc == ss7_pc_present)
+ {
+ msg.sua_prim.dest_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.ip_addr_pres = FALSE;
+ msg.sua_prim.dest_addr.pc_pres = TRUE;
+ msg.sua_prim.dest_addr.pc = called_pty_address.pc.ss7.ITU24.pc;
+ msg.sua_prim.dest_addr.rout_ind = ri_route_PC_SSN;
+ msg.sua_prim.dest_addr.ssn_incl = TRUE;
+ msg.sua_prim.dest_addr.pc_incl = TRUE;
+ msg.sua_prim.dest_addr.gt_incl = FALSE;
+ msg.sua_prim.dest_addr.ssn = called_pty_address.ssn;
+ cout << "SS7 PC in CLD address \n";
+ }
+ else
+ cout << "unsupported CLD address option\n";
+
+ break;
+ case(route_on_name_gt):
+ msg.sua_prim.dest_addr.ip_addr_pres = FALSE;
+ msg.sua_prim.dest_addr.hostname_pres = TRUE;
+ msg.sua_prim.dest_addr.pc_pres = FALSE;
+ msg.sua_prim.dest_addr.hostname = called_pty_address.name.HostName;
+ msg.sua_prim.dest_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.rout_ind = ri_route_hostname;
+ msg.sua_prim.dest_addr.ssn_incl = TRUE;
+ msg.sua_prim.dest_addr.pc_incl = FALSE;
+ msg.sua_prim.dest_addr.gt_incl = TRUE;
+ msg.sua_prim.dest_addr.ssn = called_pty_address.ssn;
+ break;
+ case(route_on_name_gt_next_office):
+ break;
+ default:
+ return(INVALID_CLD_ADDRESS);
+ break;
+ }
+
+ // fill in the connection-oriented specific data of the msg
+ msg.sua_prim.source_ref_pres = TRUE;
+ msg.sua_prim.source_ref = Sua_ConnId;
+ msg.sua_prim.dest_ref = FALSE;
+
+ // fill in the user data
+ msg.sua_prim.data_pres = TRUE;
+ string stemp(buffer,len);
+ msg.sua_prim.data_string = stemp;
+
+#ifdef DEBUG
+ cout << "Data = " << stemp << "\n";
+ cout << "Source LR = " << Sua_ConnId << "\n";
+#endif
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ // call routing to figure out which association to take for sending
+ // out the message
+#ifdef DEBUG
+ cout << "call routing function\n";
+#endif
+ SCTP_assoc_id = Assoc_sua.route_msg( called_pty_address,
+ calling_pty_address
+ );
+#ifdef DEBUG
+ cout << "routed to SCTP assoc " << SCTP_assoc_id << "\n";
+#endif
+
+ // fill in the TCB
+ tcb_ptr->Source_LR = Sua_ConnId;
+ tcb_ptr->User_ref_id = 1;
+ tcb_ptr->sctp_Association_id = SCTP_assoc_id;
+ tcb_ptr->state = scoc_outgoing;
+ tcb_ptr->remote_address = called_pty_address;
+ tcb_ptr->seq_number = Sua_ConnId % 256 ;
+
+ /* does association exist? */
+ if (SCTP_assoc_id > 0)
+ {
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", SCTP_assoc_id);
+ event_log("sua_co.c",logstring);
+ log_byte_array("sua_co.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( SCTP_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_co.c:result sctp send = "<< result << "\n";
+#endif
+ }
+ else if (SCTP_assoc_id < 0)
+ {
+#ifdef DEBUG
+ cout << "sua_co.c:sending msg prohibited \n";
+#endif
+ error_value = -1;
+ }
+ else
+ {
+ /* NO it does NOT exist. */
+ /* - Try to set up the association */
+ sua_assoc_id = Assoc_sua.Dynamic_Associate ( local_sua,
+ remote_sua,
+ called_pty_address,
+ calling_pty_address,
+ 1,
+ 1,
+ 1
+ );
+ /* save newly assigned SCTP association id in SCOC TCB */
+ tcb_ptr->sctp_Association_id = Assoc_sua.instance[sua_assoc_id].SCTP_assoc_id;
+
+ /* - save the msg till the association is setup or */
+ /* association setup fails -> drop saved msg */
+ sua_msg.byte = msg.sua_msg;
+ sua_msg.delivery_type = delivery_type;
+ sua_msg.stream_id = stream_id;
+ sua_msg.valid = true;
+ msg_store.add_msg ( sua_assoc_id,
+ sua_msg
+ );
+
+ error_value = -1;
+ }
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_CORESP */
+/***********************************************************************/
+int sua_send_CORESP( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value;
+ int string_size, datalen;
+ unsigned int SCTP_assoc_id;
+ unsigned int sua_assoc_id;
+ unsigned int local_sua_id,remote_sua_id;
+ short stream_id = 0;
+ int delivery_type, result = 0;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_co;
+ msg.sua_prim.hdr_msg_type.co = co_coak;
+
+ msg.sua_prim.rout_con_pres = TRUE;
+ msg.sua_prim.rout_con = 1;
+ msg.sua_prim.importance_pres = TRUE;
+ msg.sua_prim.importance = 5;
+ msg.sua_prim.hop_count_pres = TRUE;
+ msg.sua_prim.hop_count = 15;
+
+ // QOS choice
+ switch (QOS.prot_class)
+ {
+ case(class2): // connectionless transport, non-sequenced
+ msg.sua_prim.prot_class_pres = TRUE;
+ msg.sua_prim.prot_class.pcl = prot_class_2;
+ msg.sua_prim.seq_control_pres = TRUE;
+ msg.sua_prim.seq_control = tcb_ptr->seq_number ;
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ case(class3):
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+ if (QOS.return_msg_on_error)
+ msg.sua_prim.prot_class.return_option = TRUE;
+ else
+ msg.sua_prim.prot_class.return_option = FALSE;
+
+ // fill in the connection-oriented specific data of the msg
+ msg.sua_prim.source_ref_pres = TRUE;
+ msg.sua_prim.source_ref = tcb_ptr->Source_LR ;
+ msg.sua_prim.dest_ref_pres = TRUE;
+ msg.sua_prim.dest_ref = tcb_ptr->Dest_LR ;
+
+ tcb_ptr->state = scoc_active;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ // fill in the user data
+ if (len > 0)
+ {
+ msg.sua_prim.data_pres = TRUE;
+ string stemp(buffer,len);
+ msg.sua_prim.data_string = stemp;
+ }
+ else
+ msg.sua_prim.data_pres = FALSE;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ SCTP_assoc_id = tcb_ptr->sctp_Association_id;
+
+#ifdef DEBUG
+ cout << "routed to SCTP assoc " << SCTP_assoc_id << "\n";
+#endif
+
+#ifdef SUA_MANAGEMENT
+ sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active)
+ {
+#endif
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", SCTP_assoc_id);
+ event_log("sua_co.c",logstring);
+ log_byte_array("sua_co.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( SCTP_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef SUA_MANAGEMENT
+ }
+ else
+ {
+#ifdef DEBUG
+ cout << "sua_co.c:message sending prohibited\n";
+#endif
+ error_value = -1;
+ }
+#endif
+
+#ifdef DEBUG
+ cout << "sua_co.c:result sctp send = "<< result << "\n";
+#endif
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_CODATA */
+/***********************************************************************/
+int sua_send_CODATA( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value;
+ int string_size, datalen;
+ unsigned int SCTP_assoc_id;
+ unsigned int sua_assoc_id;
+ unsigned int local_sua_id,remote_sua_id;
+ short stream_id = 0;
+ int delivery_type, result = 0;
+
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_co;
+ msg.sua_prim.hdr_msg_type.co = co_data;
+
+ msg.sua_prim.rout_con_pres = TRUE;
+ msg.sua_prim.rout_con = 1;
+ msg.sua_prim.importance_pres = TRUE;
+ msg.sua_prim.importance = 5;
+ msg.sua_prim.hop_count_pres = TRUE;
+ msg.sua_prim.hop_count = 15;
+
+ // QOS choice
+ switch (QOS.prot_class)
+ {
+ case(class2): // connectionless transport, non-sequenced
+ msg.sua_prim.prot_class_pres = TRUE;
+ msg.sua_prim.prot_class.pcl = prot_class_2;
+ msg.sua_prim.seq_control_pres = TRUE;
+ msg.sua_prim.seq_control = tcb_ptr->seq_number ;
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ case(class3):
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+ if (QOS.return_msg_on_error)
+ msg.sua_prim.prot_class.return_option = TRUE;
+ else
+ msg.sua_prim.prot_class.return_option = FALSE;
+
+
+ // fill in the connection-oriented specific data of the msg
+ msg.sua_prim.source_ref_pres = FALSE;
+ msg.sua_prim.dest_ref_pres = TRUE;
+ msg.sua_prim.dest_ref = tcb_ptr->Dest_LR ;
+ msg.sua_prim.seq_nr_pres = TRUE;
+ msg.sua_prim.seq_nr.more_data = FALSE;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ // fill in the user data
+ msg.sua_prim.data_pres = TRUE;
+ string stemp(buffer,len);
+ msg.sua_prim.data_string = stemp;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ SCTP_assoc_id = tcb_ptr->sctp_Association_id;
+
+#ifdef DEBUG
+ cout << "routed to SCTP assoc " << SCTP_assoc_id << "\n";
+#endif
+#ifdef SUA_MANAGEMENT
+ sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active)
+ {
+#endif
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", SCTP_assoc_id);
+ event_log("sua_co.c",logstring);
+ log_byte_array("sua_co.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( SCTP_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef SUA_MANAGEMENT
+ }
+ else
+ {
+#ifdef DEBUG
+ cout << "sua_co.c:message sending prohibited\n";
+#endif
+ error_value = -1;
+ }
+#endif
+
+#ifdef DEBUG
+ cout << "sua_co.c:result sctp send = "<< result << "\n";
+#endif
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_CO Release request */
+/***********************************************************************/
+int sua_send_CORELRQ( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value;
+ int string_size, datalen;
+ unsigned int SCTP_assoc_id;
+ unsigned int sua_assoc_id;
+ unsigned int local_sua_id,remote_sua_id;
+ short stream_id = 0;
+ int delivery_type, result = 0;
+
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_co;
+ msg.sua_prim.hdr_msg_type.co = co_relre;
+
+ msg.sua_prim.rout_con_pres = TRUE;
+ msg.sua_prim.rout_con = 1;
+ msg.sua_prim.importance_pres = TRUE;
+ msg.sua_prim.importance = 5;
+ msg.sua_prim.hop_count_pres = TRUE;
+ msg.sua_prim.hop_count = 15;
+
+ // QOS choice
+ switch (QOS.prot_class)
+ {
+ case(class2): // connectionless transport, non-sequenced
+ msg.sua_prim.prot_class_pres = TRUE;
+ msg.sua_prim.prot_class.pcl = prot_class_2;
+ msg.sua_prim.seq_control_pres = TRUE;
+ msg.sua_prim.seq_control = tcb_ptr->seq_number ;
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ case(class3):
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+ if (QOS.return_msg_on_error)
+ msg.sua_prim.prot_class.return_option = TRUE;
+ else
+ msg.sua_prim.prot_class.return_option = FALSE;
+
+
+ // fill in the connection-oriented specific data of the msg
+ msg.sua_prim.source_ref_pres = TRUE;
+ msg.sua_prim.source_ref = tcb_ptr->Source_LR ;
+ msg.sua_prim.dest_ref_pres = TRUE;
+ msg.sua_prim.dest_ref = tcb_ptr->Dest_LR ;
+ msg.sua_prim.SCCP_cause_pres = TRUE;
+ msg.sua_prim.SCCP_cause.cause_type = ctp_release_cause;
+ msg.sua_prim.SCCP_cause.cause_value = 3;
+
+ tcb_ptr->state = scoc_disconnect;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ // fill in the user data
+ msg.sua_prim.data_pres = TRUE;
+ string stemp(buffer,len);
+ msg.sua_prim.data_string = stemp;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ SCTP_assoc_id = tcb_ptr->sctp_Association_id;
+
+#ifdef DEBUG
+ cout << "routed to SCTP assoc " << SCTP_assoc_id << "\n";
+#endif
+
+#ifdef SUA_MANAGEMENT
+ sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active)
+ {
+#endif
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", SCTP_assoc_id);
+ event_log("sua_co.c",logstring);
+ log_byte_array("sua_co.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( SCTP_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef SUA_MANAGEMENT
+ }
+ else
+ {
+#ifdef DEBUG
+ cout << "sua_co.c:message sending prohibited\n";
+#endif
+ error_value = -1;
+ }
+#endif
+
+#ifdef DEBUG
+ cout << "sua_co.c:result sctp send = "<< result << "\n";
+#endif
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_CO Release Confirm */
+/***********************************************************************/
+int sua_send_CORELCO( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value;
+ int string_size, datalen;
+ unsigned int SCTP_assoc_id;
+ unsigned int sua_assoc_id;
+ unsigned int local_sua_id,remote_sua_id;
+ short stream_id = 0;
+ int delivery_type, result = 0;
+
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_co;
+ msg.sua_prim.hdr_msg_type.co = co_relco;
+
+ msg.sua_prim.rout_con_pres = TRUE;
+ msg.sua_prim.rout_con = 1;
+ msg.sua_prim.importance_pres = TRUE;
+ msg.sua_prim.importance = 7;
+ msg.sua_prim.hop_count_pres = TRUE;
+ msg.sua_prim.hop_count = 15;
+
+ // QOS choice
+ switch (QOS.prot_class)
+ {
+ case(class2): // connectionless transport, non-sequenced
+ msg.sua_prim.prot_class_pres = TRUE;
+ msg.sua_prim.prot_class.pcl = prot_class_2;
+ msg.sua_prim.seq_control_pres = TRUE;
+ msg.sua_prim.seq_control = tcb_ptr->seq_number ;
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ case(class3):
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+ if (QOS.return_msg_on_error)
+ msg.sua_prim.prot_class.return_option = TRUE;
+ else
+ msg.sua_prim.prot_class.return_option = FALSE;
+
+
+ // fill in the connection-oriented specific data of the msg
+ msg.sua_prim.source_ref_pres = TRUE;
+ msg.sua_prim.source_ref = tcb_ptr->Source_LR ;
+ msg.sua_prim.dest_ref_pres = TRUE;
+ msg.sua_prim.dest_ref = tcb_ptr->Dest_LR ;
+ msg.sua_prim.SCCP_cause_pres = TRUE;
+ msg.sua_prim.SCCP_cause.cause_type = ctp_release_cause;
+ msg.sua_prim.SCCP_cause.cause_value = 3;
+
+ // fill in the user data
+ msg.sua_prim.data_pres = TRUE;
+ string stemp(buffer,len);
+ msg.sua_prim.data_string = stemp;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ SCTP_assoc_id = tcb_ptr->sctp_Association_id;
+
+ tcb_ptr->state = scoc_idle;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+#ifdef SUA_MANAGEMENT
+ sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active)
+ {
+#endif
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", SCTP_assoc_id);
+ event_log("sua_co.c",logstring);
+ log_byte_array("sua_co.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( SCTP_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef SUA_MANAGEMENT
+ }
+ else
+ {
+#ifdef DEBUG
+ cout << "sua_co.c:message sending prohibited\n";
+#endif
+ error_value = -1;
+ }
+#endif
+
+#ifdef DEBUG
+ cout << "sua_co.c:result sctp send = "<< result << "\n";
+#endif
+
+ // release the TCB of this connection
+ tcb_pool.release_TCB(Sua_ConnId);
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* sua_send_CO Connection Refused */
+/***********************************************************************/
+int sua_send_COREF( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ )
+{
+ Sua_container msg;
+ Sua_syntax_error_struct error;
+ int error_value;
+ int string_size, datalen;
+ unsigned int SCTP_assoc_id;
+ unsigned int sua_assoc_id;
+ unsigned int local_sua_id,remote_sua_id;
+ short stream_id = 0;
+ int delivery_type, result = 0;
+ sccp_addr_str called_pty_address;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_co;
+ msg.sua_prim.hdr_msg_type.co = co_coref;
+
+ msg.sua_prim.rout_con_pres = TRUE;
+ msg.sua_prim.rout_con = 1;
+ msg.sua_prim.importance_pres = TRUE;
+ msg.sua_prim.importance = 5;
+ msg.sua_prim.hop_count_pres = TRUE;
+ msg.sua_prim.hop_count = 15;
+
+ // QOS choice
+ switch (QOS.prot_class)
+ {
+ case(class2): // connectionless transport, non-sequenced
+ msg.sua_prim.prot_class_pres = TRUE;
+ msg.sua_prim.prot_class.pcl = prot_class_2;
+ msg.sua_prim.seq_control_pres = TRUE;
+ msg.sua_prim.seq_control = tcb_ptr->seq_number ;
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ case(class3):
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+ if (QOS.return_msg_on_error)
+ msg.sua_prim.prot_class.return_option = TRUE;
+ else
+ msg.sua_prim.prot_class.return_option = FALSE;
+
+ called_pty_address = tcb_ptr->remote_address;
+
+ // fill in the destination address(=remote sua address/CLD)
+ switch (called_pty_address.routing_ind)
+ {
+ case (route_on_ssn):
+
+ if (called_pty_address.address_fields_present.pc == ipvx_pc_present)
+ {
+ msg.sua_prim.dest_addr.ip_addr_pres = TRUE;
+ if (called_pty_address.pc.ipvx.sa.sa_family == AF_INET)
+ {
+ msg.sua_prim.dest_addr.ip_addr_type = ip_v4;
+ msg.sua_prim.dest_addr.ip_addr.ipv4 = called_pty_address.pc.ipvx.sin;
+ }
+ else if (called_pty_address.pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ msg.sua_prim.dest_addr.ip_addr_type = ip_v6;
+ msg.sua_prim.dest_addr.ip_addr.ipv6 = called_pty_address.pc.ipvx.sin6;
+ }
+ else
+ cout << "error filling in CLD IP address \n";
+ }
+ else
+ cout << "unsupported CLD address option\n";
+ msg.sua_prim.dest_addr_pres = TRUE;
+ msg.sua_prim.dest_addr.rout_ind = ri_route_IP_SSN;
+ msg.sua_prim.dest_addr.ssn_incl = TRUE;
+ msg.sua_prim.dest_addr.pc_incl = FALSE;
+ msg.sua_prim.dest_addr.gt_incl = FALSE;
+ msg.sua_prim.dest_addr.ssn = called_pty_address.ssn;
+ break;
+ case(route_on_name_gt):
+ break;
+ case(route_on_name_gt_next_office):
+ break;
+ default:
+ return(INVALID_CLD_ADDRESS);
+ break;
+ }
+
+ // fill in the connection-oriented specific data of the msg
+ msg.sua_prim.source_ref_pres = FALSE;
+ msg.sua_prim.dest_ref_pres = TRUE;
+ msg.sua_prim.dest_ref = tcb_ptr->Dest_LR ;
+ msg.sua_prim.SCCP_cause_pres = TRUE;
+ msg.sua_prim.SCCP_cause.cause_type = ctp_refusal_cause;
+ msg.sua_prim.SCCP_cause.cause_value = 3;
+
+ // fill in the user data
+ msg.sua_prim.data_pres = TRUE;
+ string stemp(buffer,len);
+ msg.sua_prim.data_string = stemp;
+
+ // encode the SUA unitdata message
+ error = msg.sua_encode();
+ string_size = msg.sua_msg.size();
+
+ SCTP_assoc_id = tcb_ptr->sctp_Association_id;
+
+ tcb_ptr->state = scoc_idle;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+#ifdef SUA_MANAGEMENT
+ sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active)
+ {
+#endif
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", SCTP_assoc_id);
+ event_log("sua_co.c",logstring);
+ log_byte_array("sua_co.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( SCTP_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ error_value = result;
+ delete databuf;
+#ifdef SUA_MANAGEMENT
+ }
+ else
+ {
+#ifdef DEBUG
+ cout << "sua_co.c:message sending prohibited\n";
+#endif
+ error_value = -1;
+ }
+#endif
+
+#ifdef DEBUG
+ cout << "sua_co.c:result sctp send = "<< result << "\n";
+#endif
+
+ // release the TCB of this connection
+ tcb_pool.release_TCB(Sua_ConnId);
+
+ return(error_value);
+}
+
+/***********************************************************************/
+/* Receive a sua connection-oriented message from the remote side */
+/***********************************************************************/
+/***********************************************************************/
+/* sua_process_CORE */
+/***********************************************************************/
+short process_CORE_msg ( unsigned int sua_assoc_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &Sua_ConnId,
+ Sua_container &msg
+ )
+{
+ unsigned int local_sua_id = 0;
+ sua_save_str temp;
+
+ temp.primitive = N_CONNECT_IND;
+ temp.user_ref = Sua_ConnId;
+
+ if ( msg.sua_prim.prot_class_pres )
+ {
+ // QOS choice
+ switch ( msg.sua_prim.prot_class.pcl)
+ {
+ case(prot_class_2): // connectionoriented transport, non-sequenced
+ temp.QOS.prot_class = class2;
+ temp.QOS.in_sequence = true;
+ break;
+ case(prot_class_3):
+ temp.QOS.prot_class = class3;
+ temp.QOS.in_sequence = true;
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+
+ temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE);
+ }
+
+ temp.QOS.sequence_number = 0;
+ temp.QOS.importance = msg.sua_prim.importance;
+
+ // retrieve the clg(=source) address (=remote sua address)
+ // which types are present in the address(ip pc, SS7 pc, GT, hostname)
+ if (msg.sua_prim.source_addr.ip_addr_pres == TRUE)
+ {
+ temp.calling_pty_address.address_fields_present.pc = ipvx_pc_present;
+ if (msg.sua_prim.source_addr.ip_addr_type == ip_v4) {
+ temp.calling_pty_address.pc.ipvx.sin = msg.sua_prim.source_addr.ip_addr.ipv4;
+ temp.calling_pty_address.pc.ipvx.sa.sa_family = AF_INET;
+ temp.calling_pty_address.pc.ipvx.sin.sin_port = Assoc_sua.instance[sua_assoc_id].Dest.addrs[0].sin.sin_port;
+ }
+ else if (msg.sua_prim.source_addr.ip_addr_type == ip_v6) {
+ temp.calling_pty_address.pc.ipvx.sin6 = msg.sua_prim.source_addr.ip_addr.ipv6;
+ temp.calling_pty_address.pc.ipvx.sa.sa_family = AF_INET6;
+ temp.calling_pty_address.pc.ipvx.sin6.sin6_port = Assoc_sua.instance[sua_assoc_id].Dest.addrs[0].sin6.sin6_port;
+ }
+ else
+ cout << "Unknown IP address format\n";
+ }
+ if (msg.sua_prim.source_addr.pc_pres == TRUE)
+ {
+ temp.calling_pty_address.address_fields_present.pc = ss7_pc_present;
+ temp.calling_pty_address.pc.ss7.ITU24.family = ITU24bit;
+ temp.calling_pty_address.pc.ss7.ITU24.pc = msg.sua_prim.source_addr.pc;
+ }
+ if (msg.sua_prim.source_addr.gt_pres == TRUE)
+ {
+ cout << "Global Title : unsupported address format\n";
+ }
+ if (msg.sua_prim.source_addr.hostname_pres == TRUE)
+ {
+ temp.calling_pty_address.address_fields_present.name_gt = hostname_present;
+ msg.sua_prim.source_addr.hostname.copy( temp.calling_pty_address.name.HostName,
+ (msg.sua_prim.source_addr.hostname.length()+1 )
+ );
+ temp.calling_pty_address.name.HostName[msg.sua_prim.source_addr.hostname.length()] = '\0';
+ }
+ if ((msg.sua_prim.source_addr.ip_addr_pres /= TRUE) &&
+ (msg.sua_prim.source_addr.pc_pres /= TRUE) &&
+ (msg.sua_prim.source_addr.gt_pres /= TRUE) &&
+ (msg.sua_prim.source_addr.hostname_pres /= TRUE))
+ {
+ cout << "No valid address format found in msg\n";
+ }
+
+ // routing indicator
+ switch (msg.sua_prim.source_addr.rout_ind)
+ {
+ case(ri_route_PC_SSN):
+ temp.calling_pty_address.routing_ind = route_on_ssn;
+ break;
+ case(ri_route_IP_SSN):
+ temp.calling_pty_address.routing_ind = route_on_ssn;
+ break;
+ case (ri_route_GT):
+ temp.calling_pty_address.routing_ind = route_on_name_gt;
+ break;
+ case (ri_route_hostname):
+ temp.calling_pty_address.routing_ind = route_on_name_gt;
+ break;
+ default:
+ break;
+ }
+
+ if (msg.sua_prim.source_addr.ssn_incl == TRUE) {
+ temp.calling_pty_address.address_fields_present.ssn_port = ssn_present;
+ temp.calling_pty_address.ssn = msg.sua_prim.source_addr.ssn;
+ }
+ else
+ temp.calling_pty_address.address_fields_present.ssn_port = no_sap_present;
+
+
+ // retrieve the called(=destination) address(=should be our own local addr)
+ // not completely done yet
+ if (msg.sua_prim.dest_addr.pc_pres == TRUE)
+ {
+ temp.called_pty_address.address_fields_present.pc = ss7_pc_present;
+ temp.called_pty_address.pc.ss7.ITU24.family = ITU24bit;
+ temp.called_pty_address.pc.ss7.ITU24.pc = msg.sua_prim.source_addr.pc;
+ }
+
+ if (msg.sua_prim.dest_addr.hostname_pres == TRUE)
+ {
+ temp.called_pty_address.address_fields_present.name_gt = hostname_present;
+ msg.sua_prim.dest_addr.hostname.copy( temp.called_pty_address.name.HostName,
+ (msg.sua_prim.dest_addr.hostname.length()+1 )
+ );
+ temp.called_pty_address.name.HostName[msg.sua_prim.dest_addr.hostname.length()] = '\0';
+ }
+ // routing indicator
+ switch (msg.sua_prim.dest_addr.rout_ind)
+ {
+ case(ri_route_PC_SSN):
+ temp.called_pty_address.routing_ind = route_on_ssn;
+ break;
+ case (ri_route_GT):
+ temp.called_pty_address.routing_ind = route_on_name_gt;
+ break;
+ case (ri_route_hostname):
+ temp.called_pty_address.routing_ind = route_on_name_gt;
+ break;
+ default:
+ break;
+ }
+
+ temp.called_pty_address.address_fields_present.ssn_port = ssn_present;
+ temp.called_pty_address.ssn = msg.sua_prim.dest_addr.ssn;
+
+ // fill in the allocated TCB
+ tcb_ptr->Source_LR = Sua_ConnId;
+ tcb_ptr->Dest_LR = msg.sua_prim.source_ref;
+ tcb_ptr->User_ref_id = 1;
+ tcb_ptr->sctp_Association_id = Assoc_sua.instance[sua_assoc_id].SCTP_assoc_id;
+ tcb_ptr->state = scoc_incoming;
+ tcb_ptr->remote_address = temp.calling_pty_address;
+ tcb_ptr->seq_number = Sua_ConnId % 255;
+
+ local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ if (msg.sua_prim.data_pres == TRUE)
+ temp.userdata = msg.sua_prim.data_string;
+ else
+ cout << "sua_co.c: no sua user data in CORE msg \n";
+
+ // store primitive in a list(is retrieve via sua_receive_msg)
+ rec_msg_pool.push_back(temp);
+
+#ifdef DEBUG
+ cout << "primitive stored , local_sua_id = " << local_sua_id << "\n";
+#endif
+
+ /* call the application/user callBack function */
+ local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_ConnIndNotif
+ ( local_sua_id,
+ Sua_ConnId,
+ temp.userdata.length()
+ );
+
+ return(0);
+}
+
+/***********************************************************************/
+/* sua_process_COAK */
+/***********************************************************************/
+short process_COAK_msg ( unsigned int sua_assoc_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &sua_ConnId,
+ Sua_container &msg
+ )
+{
+ unsigned int local_sua_id = 0;
+ sua_save_str temp;
+
+ temp.primitive = N_CONNECT_CONF;
+ temp.user_ref = sua_ConnId;
+
+ if (msg.sua_prim.prot_class_pres)
+ {
+ // QOS choice
+ switch ( msg.sua_prim.prot_class.pcl)
+ {
+ case(prot_class_2): // connectionoriented transport, non-sequenced
+ temp.QOS.prot_class = class2;
+ temp.QOS.in_sequence = true;
+ break;
+ case(prot_class_3):
+ temp.QOS.prot_class = class3;
+ temp.QOS.in_sequence = true;
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+
+ temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE);
+ }
+
+ temp.QOS.sequence_number = 0;
+ temp.QOS.importance = msg.sua_prim.importance;
+
+ // retrieve the clg(=source) address (=remote sua address)
+
+ // retrieve the called(=destination) address(=should be our own local addr)
+
+ // fill in the allocated TCB
+ tcb_ptr->Dest_LR = msg.sua_prim.source_ref;
+ tcb_ptr->User_ref_id = 1;
+ tcb_ptr->state = scoc_active;
+
+ local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ if (msg.sua_prim.data_pres == TRUE)
+ temp.userdata = msg.sua_prim.data_string;
+ else
+ cout << "sua_co.c: no sua user data in CODATA msg \n";
+
+ // store primitive in a list(is retrieve via sua_receive_msg)
+ rec_msg_pool.push_back(temp);
+
+
+
+ /* call the application/user callBack function */
+ local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_ConnConfIndNotif
+ ( local_sua_id,
+ sua_ConnId,
+ temp.userdata.length()
+ );
+
+ return(0);
+
+}
+/***********************************************************************/
+/* sua_process_CODATA */
+/***********************************************************************/
+short process_CODATA_msg ( unsigned int sua_assoc_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &sua_ConnId,
+ Sua_container &msg
+ )
+{
+ unsigned int local_sua_id = 0;
+ sua_save_str temp;
+
+ //temp.primitive = N_CODATA;
+ temp.user_ref = sua_ConnId;
+
+ temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE);
+ temp.QOS.sequence_number = 0;
+ temp.QOS.importance = msg.sua_prim.importance;
+
+ // retrieve the clg(=source) address (=remote sua address)
+ // not needed -> to be found in TCB
+ // retrieve the called(=destination) address(=should be our own local addr)
+ // not needed -> to be found in TCB
+
+ local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ if (msg.sua_prim.data_pres == TRUE)
+ temp.userdata = msg.sua_prim.data_string;
+ else
+ cout << "sua_co.c: no sua user data in CODATA msg \n";
+
+ // store primitive in a list(is retrieve via sua_receive_msg)
+ rec_msg_pool.push_back(temp);
+
+
+
+ /* call the application/user callBack function */
+ local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_ConnDataIndNotif
+ ( local_sua_id,
+ sua_ConnId,
+ temp.userdata.length()
+ );
+
+ return(0);
+
+}
+
+/***********************************************************************/
+/* sua_process_CORELRQ */
+/***********************************************************************/
+short process_CORELRQ_msg ( unsigned int sua_assoc_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &sua_ConnId,
+ Sua_container &msg
+ )
+{
+ unsigned int local_sua_id = 0;
+ unsigned int release_cause = 0;
+ unsigned int routing_Contex = 0;
+ sua_save_str temp;
+
+ temp.primitive = N_RELEASE_REQ;
+ temp.user_ref = sua_ConnId;
+ routing_Contex = msg.sua_prim.rout_con;
+ temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE);
+ temp.QOS.sequence_number = 0;
+ temp.QOS.importance = msg.sua_prim.importance;
+
+ // retrieve the clg(=source) address (=remote sua address)
+
+ // retrieve the called(=destination) address(=should be our own local addr)
+ tcb_ptr->state = scoc_disconnect;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ if (msg.sua_prim.data_pres == TRUE)
+ temp.userdata = msg.sua_prim.data_string;
+ else
+ cout << "sua_co.c: no sua user data in CODATA msg \n";
+
+ // store primitive in a list(is retrieve via sua_receive_msg)
+ rec_msg_pool.push_back(temp);
+
+ // send a CORELCONF back to the remote node
+ Sua_syntax_error_struct error;
+ int datalen;
+ unsigned int assoc_id;
+ short stream_id = 0;
+ int delivery_type, result;
+
+ // init the message
+ msg.sua_init();
+
+ // fill in the main sua header
+ msg.sua_prim.hdr_msg_class = sua_co;
+ msg.sua_prim.hdr_msg_type.co = co_relco;
+
+ msg.sua_prim.rout_con_pres = TRUE;
+ msg.sua_prim.rout_con = routing_Contex;
+ msg.sua_prim.importance_pres = TRUE;
+ msg.sua_prim.importance = 7;
+
+ // QOS choice
+ delivery_type = SCTP_UNORDERED_DELIVERY;
+
+ // fill in the connection-oriented specific data of the msg
+ msg.sua_prim.source_ref_pres = TRUE;
+ msg.sua_prim.source_ref = tcb_ptr->Source_LR ;
+ msg.sua_prim.dest_ref_pres = TRUE;
+ msg.sua_prim.dest_ref = tcb_ptr->Dest_LR ;
+ msg.sua_prim.SCCP_cause_pres = FALSE;
+
+ // fill in the user data
+ msg.sua_prim.data_pres = FALSE;
+
+ // encode the SUA Release complete message
+ error = msg.sua_encode();
+ //string_size = msg.sua_msg.size();
+
+ assoc_id = tcb_ptr->sctp_Association_id;
+ local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id;
+
+#ifdef DEBUG
+ cout << "routed to SCTP assoc " << assoc_id << "\n";
+#endif
+
+ tcb_ptr->state = scoc_idle;
+
+ // send data to SCTP
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+ datalen = msg.sua_msg.length();
+
+#ifdef DEBUG
+ // display byte array
+ display_byte_array(databuf , msg.sua_msg.length());
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", assoc_id);
+ event_log("sua_co.c",logstring);
+ log_byte_array("sua_co.c", databuf,msg.sua_msg.length());
+
+ result = sctp_send ( assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ delete databuf;
+
+ // release the TCB of this connection
+ tcb_pool.release_TCB(sua_ConnId);
+
+#ifdef DEBUG
+ cout << "local_sua_id = " << local_sua_id << "\n";
+#endif
+
+ /* call the application/user callBack function */
+ local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif
+ ( local_sua_id,
+ sua_ConnId,
+ release_cause,
+ temp.userdata.length()
+ );
+
+ return(0);
+
+}
+
+/***********************************************************************/
+/* sua_process_CORELCO */
+/***********************************************************************/
+short process_CORELCO_msg ( unsigned int sua_assoc_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &sua_ConnId,
+ Sua_container &msg
+ )
+{
+ unsigned int local_sua_id = 0;
+ unsigned int release_cause = 0;
+ sua_save_str temp;
+
+ temp.primitive = N_RELEASE_CONF;
+ temp.user_ref = sua_ConnId;
+
+ temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE);
+ temp.QOS.sequence_number = 0;
+ temp.QOS.importance = msg.sua_prim.importance;
+
+ // retrieve the clg(=source) address (=remote sua address)
+
+ // retrieve the called(=destination) address(=should be our own local addr)
+
+ tcb_ptr->state = scoc_idle;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id;
+
+ // store primitive in a list(is retrieve via sua_receive_msg)
+ rec_msg_pool.push_back(temp);
+
+ // release the TCB of this connection
+ tcb_pool.release_TCB(sua_ConnId);
+
+ /* call the application/user callBack function */
+ local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif
+ ( local_sua_id,
+ sua_ConnId,
+ release_cause,
+ temp.userdata.length()
+ );
+
+ return(0);
+}
+
+
+/***********************************************************************/
+/* sua_process_COREF */
+/***********************************************************************/
+short process_COREF_msg ( unsigned int sua_assoc_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &sua_ConnId,
+ Sua_container &msg
+ )
+{
+ unsigned int local_sua_id = 0;
+ unsigned int release_cause = 0;
+ sua_save_str temp;
+
+ temp.primitive = N_CONNECT_REFUSED;
+ temp.user_ref = sua_ConnId;
+
+ if ( msg.sua_prim.prot_class_pres )
+ {
+ // QOS choice
+ switch ( msg.sua_prim.prot_class.pcl)
+ {
+ case(prot_class_2): // connectionoriented transport, non-sequenced
+ temp.QOS.prot_class = class2;
+ temp.QOS.in_sequence = true;
+ break;
+ case(prot_class_3):
+ temp.QOS.prot_class = class3;
+ temp.QOS.in_sequence = true;
+ break;
+ default:
+ return(PROTOCOL_CLASS_NOT_SPECIFIED);
+ break;
+ }
+
+ temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE);
+ }
+ temp.QOS.sequence_number = 0;
+ temp.QOS.importance = msg.sua_prim.importance;
+
+ // retrieve the clg(=source) address (=remote sua address)
+
+ // retrieve the called(=destination) address(=should be our own local addr)
+ tcb_ptr->state = scoc_idle;
+
+#ifdef DEBUG
+ cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n";
+ cout << "TCB Dest_LR = " << tcb_ptr->Dest_LR << "\n";
+ cout << "TCB Association Id = " << tcb_ptr->sctp_Association_id << "\n";
+ cout << "TCB state = " << tcb_ptr->state << "\n";
+#endif
+
+ if (msg.sua_prim.data_pres == TRUE)
+ temp.userdata = msg.sua_prim.data_string;
+ else
+ cout << "sua_co.c: no sua user data in CODATA msg \n";
+
+ // store primitive in a list(is retrieve via sua_receive_msg)
+ rec_msg_pool.push_back(temp);
+
+ // release the TCB of this connection
+ tcb_pool.release_TCB(sua_ConnId);
+
+#ifdef DEBUG
+ cout << "local_sua_id = " << local_sua_id << "\n";
+#endif
+
+ /* call the application/user callBack function */
+ local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif
+ ( local_sua_id,
+ sua_ConnId,
+ release_cause,
+ temp.userdata.length()
+ );
+
+ return(0);
+
+}
+// end of module sua_co.c
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_co.h b/sualibrary/sua/sua_co.h
new file mode 100644
index 0000000..8f4fd11
--- /dev/null
+++ b/sualibrary/sua/sua_co.h
@@ -0,0 +1,170 @@
+/***************************************************************************
+ sua_co.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_co.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * Purpose: This header-file defines the SUA connection-oriented message
+ * handling:
+ * - send a COnnect REquest msg to remote node
+ * - send a COnnect RESPonse msg to remote node
+ * - send a CO DATA msg to remote node
+ * - send a CO RELease REQuest msg to remote node
+ * - send a CO RELease COnfirm msg to remote node
+ * - Process a COnnect REquest msg
+ * - Process a COnnect RESPonse msg
+ * - Process a CO DATA msg
+ * - Process a CO RELease REQuest msg
+ * - Process a CO RELease COnfirm msg
+ * - Process a COnnect REFuse msg
+ */
+
+#ifndef SUA_CO_H
+#define SUA_CO_H
+
+#include "sua_database.h"
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+
+
+using namespace std;
+
+
+/***********************************************************************/
+/* Send sua connection-oriented request primitive to remote side */
+/***********************************************************************/
+int sua_send_CORE( sccp_QOS_str &QOS,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ );
+
+int sua_send_CORESP( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ );
+
+int sua_send_CODATA( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ );
+
+int sua_send_CORELRQ( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ );
+
+int sua_send_CORELCO( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ );
+
+int sua_send_COREF( sccp_QOS_str &QOS,
+ char *buffer,
+ unsigned int len,
+ unsigned int &Sua_ConnId,
+ tcb_Sua_TCB_str *tcb_ptr
+ );
+
+/***********************************************************************/
+/* Receive a sua connection-oriented message from the remote side */
+/***********************************************************************/
+short process_CORE_msg( unsigned int sua_Assoc_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &Sua_ConnId,
+ Sua_container &sua_msg
+ );
+
+short process_COAK_msg( unsigned int local_sua_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &Sua_ConnId,
+ Sua_container &sua_msg
+ );
+
+short process_CODATA_msg( unsigned int local_sua_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &Sua_ConnId,
+ Sua_container &sua_msg
+ );
+
+short process_CORELRQ_msg( unsigned int local_sua_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &Sua_ConnId,
+ Sua_container &sua_msg
+ );
+
+short process_CORELCO_msg( unsigned int local_sua_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &Sua_ConnId,
+ Sua_container &sua_msg
+ );
+
+short process_COREF_msg( unsigned int local_sua_id,
+ tcb_Sua_TCB_str *tcb_ptr,
+ unsigned int &Sua_ConnId,
+ Sua_container &sua_msg
+ );
+#endif // SUA_CO_H
+
+// end of module sua_co.h
+
+
diff --git a/sualibrary/sua/sua_database.cpp b/sualibrary/sua/sua_database.cpp
new file mode 100644
index 0000000..ce953e1
--- /dev/null
+++ b/sualibrary/sua/sua_database.cpp
@@ -0,0 +1,642 @@
+/***************************************************************************
+ sua_database.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_database.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Ann V.
+ * "What does reuse of code mean if the code is NOT even used yet."
+ *
+ * Purpose: This code-file defines the SUA database access functions for:
+ * - dummy Indication Notifications
+ * - dummy DISxx indciation Notifications
+ * Sybsystem Number(SSN) Object:
+ * - read SSN
+ * Address Object:
+ * - read IP address parameter
+ * - read IP portnumber
+ * Local SUA Object:
+ * - initialise Local SUA Object
+ * Local SUA List:
+ * - initialise Local SUA List
+ * - read SSN
+ * - increase instance
+ * - unregister instance
+ * - register instance
+ * Remote SUA object:
+ * - initialise Remote SUA Object
+ * Remote SUA List
+ * - initialise Remote SUA list
+ * - read SSN
+ * - increase instance
+ * SUA Application Server list
+ * - initialise AS List
+ *
+ */
+
+#include "sctp.h"
+
+#include "sua_debug.h"
+#include "sua_database.h"
+#include "sua_logging.h"
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+
+#include "unistd.h"
+
+
+
+using namespace std;
+
+
+/***********************************************************************/
+/*Initialisation dummy functions for the object class SUA List & Object*/
+/***********************************************************************/
+void db_dummy_xxxxIndNotif ( unsigned int local_sua_Id,
+ unsigned int primitive,
+ unsigned int datalen
+ )
+{
+ cout << "You've just called the dummy_xxxxIndNotif function ! \n";
+ cout << "Better check youre initialisation and registration !! \n";
+}
+
+void db_dummy_DisxIndNotif ( unsigned int local_sua_Id,
+ unsigned int primitive,
+ unsigned int cause,
+ unsigned int datalen
+ )
+{
+ cout << "You've just called the dummy_DisxIndNotif function ! \n";
+ cout << "Better check youre initialisation and registration !! \n";
+}
+/***********************************************************************/
+/* functions of the object class SUA SSN Object */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Sua_SSNObject::read_ssn */
+/***********************************************************************/
+void db_Sua_SSNObject::read_ssn(string ssn_str){
+
+ char *tokstr = new char[ssn_str.length()+1];
+ short sua_ssn;
+
+
+ ssn_str.copy(tokstr,ssn_str.length());
+ tokstr[ssn_str.length()] = '\0';
+ sua_ssn = atoi(tokstr);
+
+ ssn = sua_ssn;
+
+#ifdef DEBUG
+ //cout << "SSN value = " << sua_ssn << "\n";
+#endif
+};
+
+/***********************************************************************/
+/* functions of the object class SUA Address Object */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Sua_AddressObject::read_addr_param */
+/***********************************************************************/
+void db_Sua_AddressObject::read_addr_param(string address_str){
+ int b=0,len=0,count_punct=0, count_colon=0;
+ unsigned int i=0;
+ int tokstr_len = 0;
+ char *tokstr;
+ int result;
+
+#ifdef DEBUG
+ cout << "address = " << address_str << " len = " <<address_str.length() << "\n";
+#endif
+
+ while ((i <= address_str.length()))
+ {
+ if (address_str[i] == '.') count_punct++;
+ if (address_str[i] == ':') count_colon++;
+ if ((address_str[i] == ',') || (i == address_str.length()))
+ {
+ len = i - b;
+ string dest(address_str,b,len);
+
+ tokstr_len = dest.length()+1;
+ tokstr = new char[tokstr_len];
+
+ dest.copy(tokstr,dest.length());
+ // we are dealing with char arrays, so....
+ tokstr[dest.length()] = '\0';
+ short k;
+ for(k=0; k < tokstr_len; k++)
+ address_string[nr_of_addrs][k] = tokstr[k];
+ if (count_punct == 3)
+ { // IPv4 address parameters
+ addrs[nr_of_addrs].sa.sa_family = AF_INET;
+ addrs[nr_of_addrs].sin.sin_port = SUA_PORT;
+ result = inet_pton(AF_INET, tokstr,&addrs[nr_of_addrs].sin.sin_addr);
+ if (result != 1)
+ cout << "IPvx address conversion returned "<< result << " \n";
+#ifdef DEBUG
+ cout << "IPv4 = " << addrs[nr_of_addrs].sin.sin_addr.s_addr << " \n";
+#endif
+ }
+ if (count_colon >= 2)
+ { // IPv6 address parameters
+ addrs[nr_of_addrs].sa.sa_family = AF_INET6;
+ addrs[nr_of_addrs].sin6.sin6_port = SUA_PORT;
+ result = inet_pton(AF_INET6, tokstr,&addrs[nr_of_addrs].sin6.sin6_addr);
+ if (result != 1)
+ cout << "IPvx address conversion returned "<< result << " \n";
+#ifdef DEBUG
+ cout << "IPv6 = " << &addrs[nr_of_addrs].sin6.sin6_addr << " \n";
+#endif
+ }
+
+ nr_of_addrs++;
+ b = i + 1;
+ count_punct = 0;
+ count_colon = 0;
+
+ }
+
+ i++;
+
+ }
+#ifdef DEBUG
+ cout << "number of address = " << nr_of_addrs << " \n";
+#endif
+}
+
+/***********************************************************************/
+/* Sua_AddressObject::read_pointcode */
+/***********************************************************************/
+void db_Sua_AddressObject::read_pointcode_param(string pointcode_str) {
+ int b=0,len=0;
+ unsigned int i=0;
+ int tokstr_len = 0;
+ char *tokstr;
+
+#ifdef DEBUG
+ cout << "Pointcode string = " << pointcode_str << " len = " << pointcode_str.length() << "\n";
+#endif
+
+ while ((i <= pointcode_str.length()))
+ {
+ if (i == pointcode_str.length())
+ {
+ len = i - b;
+ string dest(pointcode_str,b,len);
+
+ tokstr_len = dest.length()+1;
+ tokstr = new char[tokstr_len];
+
+ dest.copy(tokstr,dest.length());
+ // we are dealing with char arrays, so....
+ tokstr[dest.length()] = '\0';
+
+ pc.ITU24.family = ITU24bit;
+ pc.ITU24.pc = atoi(tokstr);
+
+#ifdef DEBUG
+ cout << "Pointcode value = " << pc.ITU24.pc << " \n";
+#endif
+ b = i + 1;
+ }
+ i++;
+ }
+
+#ifdef DEBUG
+ cout << "Only 1 pointcode per association allowed \n";
+#endif
+}
+
+/***********************************************************************/
+/* Sua_AddressObject::read_port_num */
+/***********************************************************************/
+void db_Sua_AddressObject::read_port_num(string port_str){
+ int i=0;
+ char *tokstr = new char[port_str.length()+1];
+ int sua_port_number;
+
+
+ port_str.copy(tokstr,port_str.length());
+ tokstr[port_str.length()] = '\0';
+ sua_port_number = atoi(tokstr);
+
+ for(i = 0; i < nr_of_addrs ; i++)
+ addrs[i].sin6.sin6_port = sua_port_number;
+
+#ifdef DEBUG
+ //cout << "Portnumber = " << sua_port_number << " * " << nr_of_addrs << " times \n";
+#endif
+}
+
+/***********************************************************************/
+/* functions of the object class SUA Local Object */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Sua_LocalObject::initalize */
+/***********************************************************************/
+void db_Sua_LocalObject::initialize(){
+
+
+ SUA_APLCallBack.ulp_ClDataIndNotif = &db_dummy_xxxxIndNotif;
+ SUA_APLCallBack.ulp_ConnIndNotif = &db_dummy_xxxxIndNotif;
+ SUA_APLCallBack.ulp_ConnConfIndNotif = &db_dummy_xxxxIndNotif;
+ SUA_APLCallBack.ulp_ConnDataIndNotif = &db_dummy_xxxxIndNotif;
+ SUA_APLCallBack.ulp_DisConnIndNotif = &db_dummy_DisxIndNotif;
+
+}
+
+/***********************************************************************/
+/* functions of the object class SUA LocalList */
+/***********************************************************************/
+/***********************************************************************/
+/* Sua_LocalList::initialize */
+/***********************************************************************/
+void db_Sua_LocalList::initialize(){
+ short i;
+ num_of_instance = 0;
+ for (i=0; i < db_MAX_LOCAL_SUA; i++)
+ {
+ instance[i].initialize();
+ }
+}
+
+/***********************************************************************/
+/* Sua_LocalList::read_ssn */
+/***********************************************************************/
+void db_Sua_LocalList:: read_ssn(string ssn_str){
+
+ instance[num_of_instance].ssn.read_ssn(ssn_str);
+};
+
+/***********************************************************************/
+/* Sua_LocalList::increase_instance */
+/***********************************************************************/
+void db_Sua_LocalList:: increase_instance(){
+
+ num_of_instance++;
+#ifdef DEBUG
+ cout << "New instance nr " << (num_of_instance - 1) << " \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "New instance nr %d", num_of_instance - 1);
+ event_log("sua_database.c",logstring);
+
+};
+
+
+/***********************************************************************/
+/* Sua_LocalList::unregister_instance */
+/***********************************************************************/
+short db_Sua_LocalList:: unregister_instance(){
+
+ int i;
+
+ for(i=0; i < num_of_instance; i++)
+ {
+#ifdef DEBUG
+ cout << "UnRegister SUA(& SCTP) local instance nr " << i << " \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Unregister SUA(& SCTP) local instance nr %d", i);
+ event_log("sua_database.c",logstring);
+ /* result = sctp_unregisterSCTP_instance ( instance[i].assoc_id );
+ */
+ }
+ return(0);
+};
+
+/***********************************************************************/
+/* Sua_LocalList::register_instance */
+/***********************************************************************/
+short db_Sua_LocalList::
+register_instance( unsigned int local_sua_id,
+ Sua_ULP_CallBacks SUACallbackFunctions,
+ unsigned int init_association
+ ){
+
+
+ instance[local_sua_id].SUA_APLCallBack.ulp_ClDataIndNotif = SUACallbackFunctions.ulp_ClDataIndNotif;
+ instance[local_sua_id].SUA_APLCallBack.ulp_ConnIndNotif = SUACallbackFunctions.ulp_ConnIndNotif;
+ instance[local_sua_id].SUA_APLCallBack.ulp_ConnConfIndNotif = SUACallbackFunctions.ulp_ConnConfIndNotif;
+ instance[local_sua_id].SUA_APLCallBack.ulp_ConnDataIndNotif = SUACallbackFunctions.ulp_ConnDataIndNotif;
+ instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif = SUACallbackFunctions.ulp_DisConnIndNotif;
+
+ instance[local_sua_id].init_assoc_id = init_association;
+
+ return(0);
+}
+
+/***********************************************************************/
+/* functions of the object class SUA Remote Object */
+/***********************************************************************/
+/***********************************************************************/
+/* Sua_RemoteObject::initalize */
+/***********************************************************************/
+void db_Sua_RemoteObject::initialize(){
+
+ ;
+}
+
+/***********************************************************************/
+/* functions of the object class SUA RemoteList */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Sua_RemoteList::initialize */
+/***********************************************************************/
+void db_Sua_RemoteList::initialize(){
+ short i;
+ num_of_instance = 0;
+ for (i=0; i < db_MAX_REMOTE_SUA; i++)
+ {
+ instance[i].initialize();
+ }
+}
+
+/***********************************************************************/
+/* Sua_RemoteList::read_ssn */
+/***********************************************************************/
+void db_Sua_RemoteList:: read_ssn(string ssn_str){
+
+ instance[num_of_instance].ssn.read_ssn(ssn_str);
+};
+
+/***********************************************************************/
+/* Sua_RemoteList::increase_instance */
+/***********************************************************************/
+void db_Sua_RemoteList:: increase_instance(){
+
+ num_of_instance++;
+#ifdef DEBUG
+ cout << "New instance nr " << (num_of_instance - 1) << " \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "New instance nr %d", num_of_instance - 1);
+ event_log("sua_database.c",logstring);
+
+};
+/***********************************************************************/
+/* functions of the object class SUA Application Server Process (ASP) */
+/***********************************************************************/
+/***********************************************************************/
+/* Sua_ASPObject::initalize */
+/***********************************************************************/
+void db_Sua_ASPObject::initialize(){
+ short j;
+
+ status = asp_idle;
+ for (j=0; j < db_MAX_1ASP_IN_AS ; j++)
+ linked_to_AS[j] = 0;
+}
+
+/***********************************************************************/
+/* Sua_ASPObject::Activate ASP */
+/***********************************************************************/
+bool db_Sua_ASPObject::activate(unsigned int sua_assoc_id,
+ short mode
+ )
+{
+ bool traf_hold=FALSE;
+ short i;
+
+
+ switch ( status)
+ {
+ case (asp_inactive):
+ {
+ switch (mode)
+ {
+ case (tmt_override ):
+ {
+ cout << "ASP in override mode\n";
+ /* this node becomes the override node for processing */
+ /* all other ASP of this AS must be put in standby */
+ i = 0;
+ /*while (i <= db_MAX_1ASP_IN_AS)
+ {
+ if ((linked_to_AS[i] > 0) &&
+ (linked_to_AS[i] <= db_MAX_SUA_AS))
+ Asp_mngt_standby ( linked_to_AS[i],
+ sua_assoc_id,
+ mode
+ );
+ }*/
+ }
+ case (tmt_loadshare):
+ {
+ cout << "ASP in loadshare mode\n";
+ }
+ case (tmt_max/*broadcast*/):
+ {
+ cout << "ASP in broadcast -> very dangerous\n";
+ }
+ default:
+ {
+ cout << "default mode in activation\n";
+ }
+ }
+ status = asp_active;
+ }
+ case (asp_inactive_traf_hold):
+ {
+ status = asp_active;
+ traf_hold = TRUE;
+ }
+ default:
+ {
+ /* remain in same state */
+ /* depdending on the mode of the ASPAC */
+ ;
+ }
+ }
+ return(traf_hold);
+}
+
+/***********************************************************************/
+/* Sua_ASPObject::inactivate ASP */
+/***********************************************************************/
+void db_Sua_ASPObject::deactivate( unsigned int sua_assoc_id,
+ short mode
+ )
+{
+ if( status == asp_active)
+ status = asp_inactive;
+}
+
+/***********************************************************************/
+/* Sua_ASPObject::put ASP up = inactive */
+/***********************************************************************/
+void db_Sua_ASPObject::up( unsigned int sua_assoc_id,
+ short mode
+ )
+{
+ switch(status)
+ {
+ case( asp_down):
+ {
+ status = asp_inactive;
+ }
+ case (asp_down_traf_hold):
+ {
+ status = asp_inactive_traf_hold;
+ }
+ default:
+ {
+ // do nothing , state is not changed
+ }
+ }
+}
+
+/***********************************************************************/
+/* Sua_ASPObject::put ASP in down mode */
+/***********************************************************************/
+void db_Sua_ASPObject::down( unsigned int sua_assoc_id,
+ short mode
+ )
+{
+ status = asp_down;
+}
+
+/***********************************************************************/
+/* functions of the object class SUA Application Server List */
+/***********************************************************************/
+/***********************************************************************/
+/* Sua_ASList::initalize */
+/***********************************************************************/
+void db_Sua_ASList::initialize(){
+
+ short i,j;
+ num_of_instance = 0;
+ for (i=0; i < db_MAX_SUA_AS; i++)
+ {
+ instance[i].status = as_idle;
+ for (j=0; j < db_MAX_ASP_IN_1AS; j++)
+ instance[i].ASP_linked_to_this_AS[j] = 0;
+ }
+}
+
+/***********************************************************************/
+/* Sua_ASList::read_AS string */
+/***********************************************************************/
+short db_Sua_ASList::read_AS( string as_str,
+ unsigned int sua_id
+ ){
+ int i=0;
+ char *tokstr = new char[as_str.length()+1];
+ int as_number;
+ bool cont_loop;
+
+
+ as_str.copy(tokstr,as_str.length());
+ tokstr[as_str.length()] = '\0';
+ as_number = atoi(tokstr);
+
+ if ( instance[as_number].status == as_idle)
+ instance[as_number].status = as_down;
+
+ i= 0;
+ cont_loop = (i < db_MAX_ASP_IN_1AS);
+ while (cont_loop)
+ {
+ if (instance[as_number].ASP_linked_to_this_AS[i] == 0)
+ {
+ instance[as_number].ASP_linked_to_this_AS[i] = sua_id;
+ cont_loop = false;
+ }
+ }
+#ifdef DEBUG
+ cout << "Application Server number used " << as_number << " for ASP " << sua_id << "\n";
+#endif
+
+ return(as_number);
+
+}
+
+/***********************************************************************/
+/* AS_override_ASP */
+/***********************************************************************/
+void db_Sua_ASList::override_ASP( unsigned int asp_sua_assoc_id,
+ unsigned int AS_id,
+ short mode
+ )
+{
+ short i;
+ short asp_present_nr = 0;
+ unsigned short processed_ASP = 0;
+
+ for (i=0; i <= db_MAX_ASP_IN_1AS; i++){
+ processed_ASP = instance[AS_id].ASP_linked_to_this_AS[i];
+ if (processed_ASP == asp_sua_assoc_id )
+ {
+ asp_present_nr++;
+ asp_activate_override(asp_sua_assoc_id);
+ }
+ else if ((processed_ASP > 0) &&
+ (processed_ASP <= db_MAX_REMOTE_SUA))
+ {
+ asp_present_nr++;
+ asp_deactivate(asp_sua_assoc_id);
+ }
+ /*else nothing to do */
+
+ }
+ //if (asp_present_nr = 0)
+ // instance(AS_id).status = as_
+}
+
+// end of module sua_database.c
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_database.h b/sualibrary/sua/sua_database.h
new file mode 100644
index 0000000..9b2005a
--- /dev/null
+++ b/sualibrary/sua/sua_database.h
@@ -0,0 +1,397 @@
+/***************************************************************************
+ sua_database.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_database.h,v 1.2 2002/02/07 16:34:27 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 8.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Ann S.
+ * "Don't mention the war."
+ *
+ * Purpose: This code-file defines the SUA database objects for:
+ * - Sybsystem Number(SSN) Object
+ * - Address Object
+ * - Local SUA Object
+ * - Local SUA List
+ * - Remote SUA object
+ * - Remote SUA List
+ * - SUA Name Object(host names/Global Titles)
+ * - SUA Name List
+ * - SUA Association Object
+ * - SUA Association List
+ * - SUA Application Server Process (ASP) Object
+ * - SUA Application Server (AS) Object
+ * - SUA Application Server (AS) List
+ */
+
+#ifndef SUA_DATABASE_H
+#define SUA_DATABASE_H
+
+#include "sua.h"
+#include "sua_asp_mgnt.h"
+
+#include <string>
+
+
+
+typedef enum {nc_empty, nc_ipv4, nc_ipv6} db_net_class;
+
+const int db_MAX_MULTIHOME_ADDR = 10;
+const int db_MAX_LOCAL_SUA = 10;
+const int db_MAX_REMOTE_SUA = 1000;
+const int db_MAX_SSN_SUA = 256;
+const int db_MAX_SUA_AS = 100;
+const int db_MAX_ASP_IN_1AS = 8; /* maximal 8 ASP's can be covered by a single AS */
+const int db_MAX_1ASP_IN_AS = 4; /* 1 ASP can appear in maximal up till 4 different AS's */
+
+/***********************************************************************/
+/* Sua_SSNObject */
+/***********************************************************************/
+class db_Sua_SSNObject {
+ public:
+ short ssn;
+ public:
+ void read_ssn(string ssn);
+}; ///:~
+
+/***********************************************************************/
+/* Sua_LocalObject */
+/***********************************************************************/
+class db_Sua_LocalObject{
+ public:
+ db_Sua_SSNObject ssn;
+ /* contains the initial SUA association */
+ unsigned int init_assoc_id;
+ /* the local sua id with which it is linked. */
+ unsigned int sua_id;
+ Sua_ULP_CallBacks SUA_APLCallBack;
+ public:
+ // functions of the Class
+ void initialize();
+}; ///:~
+
+/***********************************************************************/
+/* Sua_LocalList */
+/***********************************************************************/
+class db_Sua_LocalList{
+ public:
+ int num_of_instance;
+ db_Sua_LocalObject instance[db_MAX_LOCAL_SUA];
+ void initialize();
+ void read_ssn(string ssn);
+ short register_instance( unsigned int local_sua_id,
+ Sua_ULP_CallBacks SUACallbackFunctions,
+ unsigned int init_assoc_id
+ );
+ short unregister_instance();
+ void increase_instance();
+}; ///:~
+
+/***********************************************************************/
+/* Sua_RemoteObject */
+/***********************************************************************/
+class db_Sua_RemoteObject{
+ public:
+ db_Sua_SSNObject ssn;
+ /* contains the SCTP assoc id */
+ unsigned int SCTP_assoc_id;
+ /* contains the local sua id with which it is linked. */
+ unsigned int sua_id;
+ public:
+ // functions of the Class
+ void initialize();
+}; ///:~
+
+/***********************************************************************/
+/* Sua_RemoteList */
+/***********************************************************************/
+class db_Sua_RemoteList{
+ public:
+ int num_of_instance;
+ public:
+ db_Sua_RemoteObject instance[db_MAX_REMOTE_SUA];
+ void initialize();
+ void read_ssn(string ssn);
+ void increase_instance();
+
+}; ///:~
+
+
+/***********************************************************************/
+/* Sua_AddressObject */
+/***********************************************************************/
+class db_Sua_AddressObject {
+ public:
+ int nr_of_addrs; // number of ip addresses used(multihoming)
+ unsigned char address_string[db_MAX_MULTIHOME_ADDR][SCTP_MAX_IP_LEN];
+ ipvxunion addrs[db_MAX_MULTIHOME_ADDR];
+ SS7union pc;
+ public:
+ void read_addr_param(string address);
+ void read_pointcode_param(string point_code);
+ void read_port_num(string port);
+}; ///:~
+
+/***********************************************************************/
+/* Sua_ApplicationServerProcessObject (ASP) */
+/***********************************************************************/
+class db_Sua_ASPObject {
+ public:
+ asp_Sua_asp_state_set status; /* status of the ASP */
+ short linked_to_AS[db_MAX_1ASP_IN_AS]; /* this ASP may belong to different Application Servers(AS) */
+ public:
+ void initialize();
+ bool activate( unsigned int sua_assoc_id, short mode );
+ void deactivate( unsigned int sua_assoc_id, short mode );
+ void down( unsigned sua_assoc_id, short mode );
+ void up( unsigned sua_assoc_id, short mode );
+}; ///:~
+
+/***********************************************************************/
+/* Sua_LS_OverRideObject (LS_OverRide) */
+/***********************************************************************/
+class db_Sua_LS_OverRideObject {
+ private:
+ short ASP_to_use; /* ASP presently being the workhorse)*/
+ public:
+ void assign_ASP(short ASP_num);
+ short ASP_used();
+}; ///:~
+
+/***********************************************************************/
+/* Sua_LS_RoundRobinObject (LS_RoundRobin) */
+/***********************************************************************/
+class db_Sua_LS_RoundRobinObject {
+ private:
+ short ASP_to_use; /* ASP presently being the workhorse)*/
+ public:
+ short ASP_used();
+};
+
+/***********************************************************************/
+/* Sua_LoadShareObject (LS_AS) */
+/***********************************************************************/
+class db_Sua_LoadShareObject {
+ public:
+ asp_Sua_loadmode_set load_mode; /* mode of loadsharing)*/
+ db_Sua_LS_OverRideObject override; /* AS has a ASP in override */
+ db_Sua_LS_RoundRobinObject RRobin; /* AS is RR all active ASP's */
+}; ///:~
+
+
+/***********************************************************************/
+/* Sua_ApplicationServerObject (AS) */
+/***********************************************************************/
+class db_Sua_ASObject {
+ public:
+ asp_Sua_as_state_set status; /* status of the AS */
+ short ASP_linked_to_this_AS[db_MAX_ASP_IN_1AS];/* AS may contain a couple of ASP's */
+ db_Sua_LoadShareObject loadshare;
+ public:
+ void initialize();
+}; ///:~
+
+/***********************************************************************/
+/* Sua_ApplicationServerList (AS list) */
+/***********************************************************************/
+class db_Sua_ASList{
+ public:
+ int num_of_instance;
+ db_Sua_ASObject instance[db_MAX_SUA_AS];
+ public:
+ void initialize();
+ short read_AS( string address_str,
+ unsigned int sua_id
+ );
+ void override_ASP( unsigned int asp_sua_assoc_id,
+ unsigned int AS_id,
+ short mode
+ );
+}; ///:~
+
+/***********************************************************************/
+/* Sua_AssociationsObject */
+/***********************************************************************/
+class db_Sua_AssociationObject {
+ public:
+ unsigned int SCTP_assoc_id;
+ unsigned int SCTP_instance_name;
+ unsigned int remote_sua_id;
+ unsigned int local_sua_id;
+ short nr_of_inbound_streams;
+ short nr_of_outbound_streams;
+ db_Sua_ASPObject asp;
+ db_net_class netw; // sort of network(v4/v6) to be used
+ // ip source/destination addresses , should be the same network type
+ db_Sua_AddressObject Source;
+ db_Sua_AddressObject Dest;
+ public:
+ void initialize();
+ short shutdown();
+}; ///:~
+
+/***********************************************************************/
+/* Sua_AssociationList */
+/***********************************************************************/
+class db_Sua_AssociationList{
+ public:
+ int num_of_instance;
+ db_Sua_AssociationObject instance[db_MAX_REMOTE_SUA];
+ public:
+ void initialize();
+ void read_Source_addr(string address);
+ void read_Dest_addr(string address);
+ void read_Source_pointcode(string address);
+ void read_Dest_pointcode(string address);
+ void read_Source_port(string port);
+ void read_Dest_port(string port);
+ void read_stream_number(string stream_num);
+ short register_instance(SCTP_ulp_Callbacks APLCallbackFunctions,
+ Sua_ULP_CallBacks SUACallbackFunctions,
+ db_Sua_LocalList& local_sua
+ );
+ short unregister_instance();
+ unsigned int Find_association( unsigned int sctp_assoc_id,
+ unsigned int &Local_sua_id,
+ unsigned int &Remote_sua_id
+ );
+ unsigned int Find_local_sua( sccp_addr_str& local_address
+ );
+ short associate_instance( db_Sua_LocalList& local_sua,
+ db_Sua_RemoteList& remote_sua
+ );
+ unsigned int passive_associate( unsigned int assoc_id,
+ db_Sua_LocalList& local_sua,
+ db_Sua_RemoteList& remote_sua,
+ unsigned short nr_of_dest_addr,
+ unsigned short nr_of_input_streams,
+ unsigned short nr_of_output_streams
+ );
+ unsigned int Dynamic_Associate( db_Sua_LocalList& local_sua,
+ db_Sua_RemoteList& remote_sua,
+ sccp_addr_str& cld,
+ sccp_addr_str& clg,
+ unsigned short nr_of_dest_addr,
+ unsigned short nr_of_input_streams,
+ unsigned short nr_of_output_streams
+ );
+ short Terminate_remote_assoc_instance();
+ short shutdown();
+ signed int route_msg(sccp_addr_str& cld,
+ sccp_addr_str& clg
+ );
+ signed int route_on_IPpc ( ipvxunion& dest_pc,
+ ipvxunion& org_pc,
+ int& sua_assoc_id
+ );
+ signed int route_on_SS7pc ( SS7union& dest_pc,
+ SS7union& org_pc,
+ int& sua_assoc_id
+ );
+ signed int route_on_GTname ( hostname_str& dest_name,
+ hostname_str& org_name,
+ int& sua_assoc_id,
+ pointcode_str& dest_pc,
+ pointcode_str& org_pc
+ );
+ void increase_instance();
+ bool activate( unsigned int sua_id,
+ short mode
+ );
+ void deactivate( unsigned int sua_id,
+ short mode
+ );
+ void down( unsigned int sua_id,
+ short mode
+ );
+ void up( unsigned int sua_id,
+ short mode
+ );
+}; ///:~
+
+/***********************************************************************/
+/* Sua_NameObject */
+/***********************************************************************/
+class db_Sua_NameObject {
+ public:
+ unsigned int SUA_assoc_id;
+ public:
+ void initialize();
+
+}; ///:~
+
+/***********************************************************************/
+/* Sua_NameList */
+/***********************************************************************/
+class db_Sua_NameList{
+ public:
+ int num_of_instance;
+ db_Sua_NameObject instance[db_MAX_REMOTE_SUA];
+ public:
+ void initialize();
+ string read_host_name(string name);
+ string read_Global_Title(string name);
+ unsigned int perform_GTT( sccp_addr_str& cld_in,
+ sccp_addr_str& clg_in,
+ sccp_addr_str& cld_out,
+ sccp_addr_str& clg_out
+ );
+ void increase_instance();
+}; ///:~
+
+#endif // SUA_DATABASE_H
+
+//end of module sua_database.h
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_dataname.cpp b/sualibrary/sua/sua_dataname.cpp
new file mode 100644
index 0000000..b1e6914
--- /dev/null
+++ b/sualibrary/sua/sua_dataname.cpp
@@ -0,0 +1,174 @@
+/***************************************************************************
+ sua_dataname.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_dataname.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Vicky
+ * "This module reuse some code, thus it will mostly reuse trouble."
+ *
+ * Purpose: This code-file defines the SUA database access functions for:
+ * SUA Name Object (host names/Global Titles):
+ * - initialise Name
+ * SUA Name List:
+ * - initialise Name List
+ * - read hostname
+ */
+
+#include "sctp.h"
+
+#include "sua_debug.h"
+#include "sua_database.h"
+#include "sua_asp_mgnt.h"
+#include "sua_logging.h"
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+
+#include "unistd.h"
+
+
+
+using namespace std;
+
+/***********************************************************************/
+/* functions of the object class SUA name Object */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Sua_NameObject::initalize */
+/***********************************************************************/
+void db_Sua_NameObject::initialize(){
+
+ // initialise to point to a invalid SUA association
+ SUA_assoc_id = 0;
+}
+
+
+
+/***********************************************************************/
+/* functions of the object class SUA NameList */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Sua_NameList::initalize */
+/***********************************************************************/
+void db_Sua_NameList::initialize(){
+ short i;
+ num_of_instance = 0;
+ for (i=0; i < db_MAX_REMOTE_SUA; i++) {
+ instance[i].initialize();
+ }
+}
+
+string db_Sua_NameList::read_host_name(string name){
+
+ char *hostname;
+ const char *ip_addr_ptr;
+ struct hostent *hptr;
+ char str[INET6_ADDRSTRLEN];
+ char **pptr;
+ string addr_str;
+
+ hostname = new char[name.length()+1];
+ name.copy(hostname,name.length());
+ // we are dealing with char arrays, so....
+ hostname[name.length()] = '\0';
+
+ if ((hptr = gethostbyname(hostname)) == NULL){
+ cout << "Determination of hostname failed\n";
+ return("127.0.0.1");
+ }
+
+#ifdef DEBUG
+ cout << "Hostname " << hptr->h_name << " has the following IP address(es)\n";
+#endif
+
+ pptr = hptr->h_addr_list;
+ for ( ; *pptr != NULL;pptr++)
+ {
+ ip_addr_ptr = inet_ntop(hptr->h_addrtype, *pptr, str,sizeof(str));
+ addr_str = addr_str + ip_addr_ptr;
+ if ((*(pptr+1)) != NULL)
+ /* another ip address is comming after the present one */
+ addr_str = addr_str + ",";
+ /*else this is the last ip address */
+#ifdef DEBUG
+ cout << ip_addr_ptr << "\n";
+#endif
+ }
+
+#ifdef DEBUG
+ cout << "output IP list = " << addr_str << "\n";
+#endif
+
+ string name_str;
+ int last= name.size();
+ unsigned int current = name.rfind('.');
+ while(current != string::npos){
+ name_str = name_str + name.substr(current+1,(last-current)) + ".";
+ last= current - 1;
+ current = name.rfind('.', last);
+ }
+ name_str = name_str + name.substr(0,last+1);
+
+#ifdef DEBUG
+ cout << "Ready for storing SUA dest hostname = " << name_str << " in NameDB\n";
+#endif
+
+
+ return(addr_str);
+
+}
+
+
+// end of module sua_dataname.c
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_datassoc.cpp b/sualibrary/sua/sua_datassoc.cpp
new file mode 100644
index 0000000..c3bcc5f
--- /dev/null
+++ b/sualibrary/sua/sua_datassoc.cpp
@@ -0,0 +1,1000 @@
+/***************************************************************************
+ sua_datassoc.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_datassoc.cpp,v 1.3 2002/02/15 16:19:46 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Vera
+ * "You ain't seen nothing yet"
+ * "said Garfield the Ripper while putting on his binbag"
+ *
+ * Purpose: This code-file defines the SUA database access functions for
+ * SUA Association Object:
+ * - initialise association object
+ * - shutdown association
+ * - Dynamic association
+ * SUA Association List:
+ * - initialise association list
+ * - read source address
+ * - read Destination address
+ * - read source port
+ * - read destination port
+ * - read stream number
+ * - register instance
+ * - associate instance(initiating)
+ * - Find a association
+ * - Find a local SUA instance
+ * - Passive association instantiation(terminating)
+ * - shutdown a association
+ * - route on IP pointcode address
+ * - route on Global Title/Hostname
+ * - route message to a association
+ * - increase instance
+ * - Dynamic association setup(initiating)
+ */
+
+#include "sctp.h"
+
+#include "sua_debug.h"
+#include "sua_database.h"
+#include "sua_asp_mgnt.h"
+#include "sua_logging.h"
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <netinet/in.h>
+
+#include "unistd.h"
+
+
+
+using namespace std;
+
+struct ulp_data_str {
+ int maximumStreamID;
+ unsigned int chunkCount;
+};
+
+static ulp_data_str ULPData[db_MAX_MULTIHOME_ADDR];
+
+
+/***********************************************************************/
+/* functions of the object class SUA Association Object */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Sua_AssociationObject::initalize */
+/***********************************************************************/
+void db_Sua_AssociationObject::initialize(){
+ short i;
+ Source.nr_of_addrs = 0;
+ Dest.nr_of_addrs = 0;
+ netw = nc_empty;
+ nr_of_inbound_streams = 0;
+ nr_of_outbound_streams = 0;
+ asp.status = asp_down;
+ for (i=0; i < db_MAX_MULTIHOME_ADDR; i++) {
+ Source.addrs[i].sa.sa_family = AF_INET;
+ Dest.addrs[i].sa.sa_family = AF_INET;
+ }
+ Source.pc.ITU24.pc = 0;
+ Dest.pc.ITU24.pc = 0;
+ for (i=0; i < db_MAX_1ASP_IN_AS; i++)
+ asp.linked_to_AS[i] = 0;
+}
+
+/***********************************************************************/
+/* Sua_RemoteObject::shutdown_instance */
+/***********************************************************************/
+short db_Sua_AssociationObject:: shutdown(){
+
+ int result;
+ result = sctp_shutdown( SCTP_assoc_id );
+
+ return(result);
+
+};
+
+/***********************************************************************/
+/* Sua_AssociationL::Dynamic_Associate */
+/***********************************************************************/
+unsigned int Dynamic_Associate( sccp_addr_str& cld,
+ sccp_addr_str& clg
+ )
+{
+ return(0);
+}
+
+/***********************************************************************/
+/* functions of the object class SUA AssociationList */
+/***********************************************************************/
+
+/***********************************************************************/
+/* Sua_AssociationList::initalize */
+/***********************************************************************/
+void db_Sua_AssociationList::initialize(){
+ short i;
+ num_of_instance = 0;
+ for (i=0; i < db_MAX_REMOTE_SUA; i++) {
+ instance[i].initialize();
+ }
+}
+
+
+/***********************************************************************/
+/* Sua_AssociationList::read_Source_addr */
+/***********************************************************************/
+void db_Sua_AssociationList:: read_Source_addr(string address){
+
+ instance[num_of_instance].Source.read_addr_param(address);
+
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::read_Dest_addr */
+/***********************************************************************/
+void db_Sua_AssociationList:: read_Dest_pointcode(string address){
+
+ instance[num_of_instance].Dest.read_pointcode_param(address);
+
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::read_Source_pointcode */
+/***********************************************************************/
+void db_Sua_AssociationList:: read_Source_pointcode(string address){
+
+ instance[num_of_instance].Source.read_pointcode_param(address);
+
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::read_Dest_addr */
+/***********************************************************************/
+void db_Sua_AssociationList:: read_Dest_addr(string address){
+
+ instance[num_of_instance].Dest.read_addr_param(address);
+
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::read_Source_port */
+/***********************************************************************/
+void db_Sua_AssociationList:: read_Source_port(string port){
+
+ instance[num_of_instance].Source.read_port_num(port);
+
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::read_Dest_port */
+/***********************************************************************/
+void db_Sua_AssociationList:: read_Dest_port(string port){
+
+ instance[num_of_instance].Dest.read_port_num(port);
+
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::read_stream_number */
+/***********************************************************************/
+void db_Sua_AssociationList:: read_stream_number(string stream_num){
+
+
+ int i=0;
+ char *tokstr = new char[stream_num.length()+1];
+ int sua_stream_nr;
+
+
+ stream_num.copy(tokstr,stream_num.length());
+ tokstr[stream_num.length()] = '\0';
+ sua_stream_nr = atoi(tokstr);
+
+ for(i = 1; i <= num_of_instance ; i++) {
+ instance[i].nr_of_inbound_streams = sua_stream_nr;
+ instance[i].nr_of_outbound_streams = sua_stream_nr;
+ }
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::register_instance */
+/***********************************************************************/
+short db_Sua_AssociationList::
+register_instance( SCTP_ulp_Callbacks APLCallbackFunctions,
+ Sua_ULP_CallBacks SUACallbackFunctions,
+ db_Sua_LocalList& local_sua
+ ){
+
+ int i;
+ unsigned int local_sua_idx;
+ short sua_portnumber = SUA_PORT;
+
+ for(i=1; i <= num_of_instance; i++)
+ {
+ local_sua_idx = instance[i].local_sua_id;
+#ifdef DEBUG
+ cout << "Register SUA(& SCTP) local instance nr " << local_sua_idx << " with association " << i << " ,SSN = "<< local_sua.instance[local_sua_idx].ssn.ssn <<" \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Register SUA(& SCTP) local instance nr %d with association %d, SSN = %d", local_sua_idx,i,local_sua.instance[local_sua_idx].ssn.ssn );
+ event_log("sua_database.c",logstring);
+ local_sua.register_instance( instance[i].local_sua_id,
+ SUACallbackFunctions,
+ i
+ );
+ if (instance[i].Source.addrs[0].sa.sa_family == AF_INET)
+ sua_portnumber = instance[i].Source.addrs[0].sin.sin_port;
+ else if (instance[i].Source.addrs[0].sa.sa_family == AF_INET6)
+ sua_portnumber = instance[i].Source.addrs[0].sin6.sin6_port;
+
+ instance[i].SCTP_instance_name =
+ sctp_registerInstance( sua_portnumber,
+ instance[i].nr_of_inbound_streams,
+ instance[i].nr_of_outbound_streams,
+ instance[i].Source.nr_of_addrs,
+ instance[i].Source.address_string,
+ APLCallbackFunctions
+ );
+
+#ifdef DEBUG
+ cout << "SCTP instance name = " << instance[i].SCTP_instance_name << " \n";
+#endif
+ sprintf(logstring, "Local SCTP instance nr %d name = %d", i, instance[i].SCTP_instance_name);
+ event_log("sua_database.c",logstring);
+
+ }
+return(0);
+};
+
+/***********************************************************************/
+/* Sua_AssociationList::associate_instance */
+/***********************************************************************/
+short db_Sua_AssociationList::
+associate_instance( db_Sua_LocalList& local_sua,
+ db_Sua_RemoteList& remote_sua
+ ){
+
+ int i;
+ SCTP_InstanceParameters SCTP_assoc_parms;
+ SCTP_InstanceParameters *SCTP_assoc_status = &SCTP_assoc_parms;
+ short sua_portnumber = SUA_PORT;
+ int res=0;
+
+ // get default values of association
+ res = sctp_getAssocDefaults( instance[1].SCTP_instance_name,
+ SCTP_assoc_status
+ );
+
+ // fill in the TOS field needed for DIFFSERV
+ SCTP_assoc_status->ipTos = 'a';
+
+ // set the new value for all associations
+ res = sctp_setAssocDefaults( instance[1].SCTP_assoc_id,
+ SCTP_assoc_status
+ );
+
+ for(i=1; i <= num_of_instance; i++)
+ {
+ if (instance[i].Dest.nr_of_addrs != 0) {
+#ifdef DEBUG
+ cout << "Associate remote SUA(& SCTP) instance nr " << i << " with local SUA(& SCTP) instance nr " << instance[i].local_sua_id <<" \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", i, instance[i].local_sua_id );
+ event_log("sua_database.c",logstring);
+
+ if (instance[i].Dest.addrs[0].sa.sa_family == AF_INET)
+ sua_portnumber = instance[i].Dest.addrs[0].sin.sin_port;
+ else if (instance[i].Dest.addrs[0].sa.sa_family == AF_INET6)
+ sua_portnumber = instance[i].Dest.addrs[0].sin6.sin6_port;
+
+ ULPData[0].maximumStreamID = -1;
+
+ short unsigned instance_name = instance[i].SCTP_instance_name ;
+ instance[i].SCTP_assoc_id =
+ sctp_associate( instance_name,
+ instance[i].nr_of_outbound_streams,
+ instance[i].Dest.address_string[0],
+ sua_portnumber,
+ NULL
+ );
+
+ /* no msg queued, mark assoc down(from sua management viewpoint)*/
+ instance[i].asp.status = asp_down;
+
+#ifdef DEBUG
+ cout << "SCTP association result = " << instance[i].SCTP_assoc_id <<" \n";
+#endif
+
+ }
+ }
+ return(0);
+};
+
+
+/***********************************************************************/
+/* Sua_AssociationList::Find_association */
+/***********************************************************************/
+unsigned int db_Sua_AssociationList::
+Find_association( unsigned int sctp_assoc_id,
+ unsigned int &Local_sua_id,
+ unsigned int &Remote_sua_id
+ )
+{
+ short i = 0;
+ unsigned int sua_assoc_id = 0;
+ bool result = FALSE;
+ Local_sua_id = 0;
+ Remote_sua_id = 0;
+
+ while ((i < db_MAX_REMOTE_SUA) && !(result))
+ {
+
+ result = (instance[i].SCTP_assoc_id == sctp_assoc_id);
+ if (result) {
+ Local_sua_id = instance[i].local_sua_id;
+ Remote_sua_id = instance[i].remote_sua_id;
+ sua_assoc_id = i;
+ }
+ i++;
+ }
+
+ return(sua_assoc_id);
+};
+
+/***********************************************************************/
+/* Sua_AssociationList::Find_local_sua */
+/***********************************************************************/
+unsigned int db_Sua_AssociationList::
+Find_local_sua( sccp_addr_str& local_address
+ )
+{
+ short i = 1, j = 0;
+ unsigned int Local_sua_id = 0;
+ bool result = FALSE;
+
+ while ((i < db_MAX_REMOTE_SUA) && !(result) && (instance[i].Source.nr_of_addrs != 0))
+ {
+ j = 0;
+ while ((j < instance[i].Source.nr_of_addrs) && !(result))
+ {
+ result = ((instance[i].Source.addrs[j].sin.sin_addr.s_addr == local_address.pc.ipvx.sin.sin_addr.s_addr) ||
+ (instance[i].Source.addrs[j].sin6.sin6_addr.s6_addr == local_address.pc.ipvx.sin6.sin6_addr.s6_addr));
+ if (result)
+ {
+ Local_sua_id = instance[i].local_sua_id;
+#ifdef DEBUG
+ cout << "local_sua_id = " << Local_sua_id << " , instance "<< i << "\n";
+#endif
+ }
+ j++;
+ }
+ i++;
+ }
+
+ return(Local_sua_id);
+};
+
+/***********************************************************************/
+/* Sua_AssociationList::passive_associate */
+/***********************************************************************/
+unsigned int db_Sua_AssociationList::
+passive_associate( unsigned int assoc_id,
+ db_Sua_LocalList &local_sua,
+ db_Sua_RemoteList &remote_sua,
+ unsigned short nr_of_dest_addr,
+ unsigned short nr_of_input_streams,
+ unsigned short nr_of_output_streams
+ ){
+
+ SCTP_AssociationStatus status;
+ int result;
+ short k;
+ int bla;
+ short i = 1, assoc_instance_idx = 1;
+ bool cont, partial_assoc_found = FALSE;
+
+ while ((i <= num_of_instance) && !(partial_assoc_found)){
+ partial_assoc_found = (instance[i].Dest.nr_of_addrs == 0);
+ if (partial_assoc_found)
+ assoc_instance_idx = i;
+
+ i++;
+ }
+
+ if (!(partial_assoc_found))
+ {
+ /* new association added */
+ num_of_instance++;
+ assoc_instance_idx = num_of_instance;
+ instance[assoc_instance_idx].Source = instance[assoc_instance_idx-1].Source;
+
+ instance[assoc_instance_idx].nr_of_inbound_streams = nr_of_input_streams ;
+ instance[assoc_instance_idx].nr_of_outbound_streams = nr_of_input_streams ;
+ }
+
+ remote_sua.increase_instance();
+
+ instance[assoc_instance_idx].SCTP_assoc_id = assoc_id;
+ instance[assoc_instance_idx].remote_sua_id = remote_sua.num_of_instance;
+ remote_sua.instance[remote_sua.num_of_instance].ssn.ssn = local_sua.instance[local_sua.num_of_instance].ssn.ssn;
+ // should search for the correct sua local instance(future)
+ instance[assoc_instance_idx].local_sua_id = local_sua.num_of_instance;
+#ifdef DEBUG
+ cout << "Associate remote SUA(& SCTP) instance nr " << assoc_id << " with local SUA(& SCTP) instance nr " << assoc_instance_idx << " \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", assoc_id, assoc_instance_idx );
+ event_log("sua_database.c",logstring);
+
+
+ result = sctp_getAssocStatus(instance[assoc_instance_idx].SCTP_assoc_id, &status);
+
+ /* conversion and fill in the destination address */
+ instance[assoc_instance_idx].Dest.nr_of_addrs = nr_of_dest_addr;
+ instance[assoc_instance_idx].Dest.address_string[0] = status.primaryDestinationAddress;
+ instance[assoc_instance_idx].Dest.addrs[0].sin.sin_port = status.destPort;
+
+ /* try to figure out ipv4 or v6 address family: get it from the source address */
+ k = 0;
+ instance[assoc_instance_idx].Dest.addrs[0].sa.sa_family = AF_LOCAL;
+ cont = true;
+ while ((k < 24) && (cont))
+ {
+ if (instance[assoc_instance_idx].Dest.address_string[0][k] == '.')
+ {
+ cont = false;
+ instance[assoc_instance_idx].Dest.addrs[0].sa.sa_family = AF_INET;
+ }
+ if (instance[assoc_instance_idx].Dest.address_string[0][k] == ':')
+ {
+ cont = false;
+ instance[assoc_instance_idx].Dest.addrs[0].sa.sa_family = AF_INET6;
+ }
+ k++;
+ }
+
+ for(k=0; k < instance[assoc_instance_idx].Dest.nr_of_addrs ; k++)
+ {
+ if (instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET)
+ bla = inet_pton( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family,
+ (char *)instance[assoc_instance_idx].Dest.address_string[k],
+ &instance[assoc_instance_idx].Dest.addrs[k].sin.sin_addr
+ );
+ else if (instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET6)
+ bla = inet_pton( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family,
+ (char *)instance[assoc_instance_idx].Dest.address_string[k],
+ &instance[assoc_instance_idx].Dest.addrs[k].sin6.sin6_addr
+ );
+ else
+ cout << "Unsupported address family in passive associate\n";
+
+ }
+
+ /* no msg queued, mark assoc down(from sua management viewpoint)*/
+ instance[assoc_instance_idx].asp.status = asp_down;
+
+ return(assoc_instance_idx);
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::shutdown_instance */
+/***********************************************************************/
+short db_Sua_AssociationList:: shutdown(){
+
+ int i;
+ short result;
+
+ for(i=1; i <= num_of_instance; i++)
+ {
+#ifdef DEBUG
+ cout << "shutdown remote SUA(& SCTP) instance nr " << i << " with local SUA(& SCTP) instance nr " << instance[i].local_sua_id <<" \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", i, instance[i].local_sua_id );
+ event_log("sua_database.c",logstring);
+
+ result = instance[i].shutdown();
+
+ }
+
+ return(0);
+};
+
+/***********************************************************************/
+/* Sua_AssociationList::route_on_IPpc */
+/***********************************************************************/
+signed int db_Sua_AssociationList::
+route_on_IPpc ( ipvxunion& dest_pc,
+ ipvxunion& org_pc,
+ int& sua_assoc_id
+ )
+{
+ int j=0,i=1,count, addr_start, addr_stop;
+ unsigned int sctp_assoc_id = 0;
+
+ sua_assoc_id = 0;
+ bool cont = (i <= num_of_instance);
+ bool found_assoc = false;
+
+ while (cont)
+ {
+ found_assoc = false;
+ j = 0;
+ while ((j < instance[i].Dest.nr_of_addrs) && (!found_assoc))
+ {
+ found_assoc = (dest_pc.sa.sa_family == instance[i].Dest.addrs[j].sa.sa_family);
+ if (dest_pc.sa.sa_family == AF_INET)
+ {
+ addr_start = 4;
+ addr_stop = addr_start + 4;
+ }
+ else if (dest_pc.sa.sa_family == AF_INET6)
+ {
+ addr_start = 8;
+ addr_stop = addr_start + 16;
+ }
+ else
+ {
+ addr_start = 0;
+ addr_stop = 0;
+ found_assoc = false;
+ cout << "ERROR route_on_IPpc: Unknown addresstype\n";
+ }
+ /* compare the address family field */
+ found_assoc = found_assoc && (dest_pc.ch[1] == instance[i].Dest.addrs[j].ch[1]);
+
+ /* compare the ipv4/ipv6 address field */
+ for (count = addr_start; count < addr_stop; count++)
+ {
+ found_assoc = found_assoc
+ && (dest_pc.ch[count] == instance[i].Dest.addrs[j].ch[count]);
+ }
+ j++;
+ }
+
+ if (found_assoc)
+ {
+ cont = false;
+ sctp_assoc_id = instance[i].SCTP_assoc_id;
+ sua_assoc_id = i;
+#ifdef DEBUG
+ cout << "Found Sua association " << i << " with SCTP assoc " << sctp_assoc_id << "\n";
+
+ if (dest_pc.sa.sa_family == AF_INET)
+ {
+ cout << "CLD ip v4 = " << dest_pc.sin.sin_addr.s_addr << "\n";
+ cout << "Remote IP = " << instance[i].Dest.addrs[0].sin.sin_addr.s_addr << "\n";
+ }
+ else if (dest_pc.sa.sa_family == AF_INET6)
+ {
+ cout << "CLD ip v6 = " << dest_pc.sin6.sin6_addr.s6_addr << "\n";
+ cout << "Remote IP = " << instance[i].Dest.addrs[0].sin6.sin6_addr.s6_addr << "\n";
+ }
+ else
+ cout << "Unknown CLD IP address type format\n";
+#endif
+ }
+ else
+ {
+ i++;
+ cont = (i <= num_of_instance);
+ }
+ }
+
+ return(sctp_assoc_id);
+};
+
+
+/***********************************************************************/
+/* Sua_AssociationList::route_on_SS7pc */
+/***********************************************************************/
+signed int db_Sua_AssociationList::
+route_on_SS7pc ( SS7union& dest_pc,
+ SS7union& org_pc,
+ int& sua_assoc_id
+ )
+{
+ int i=1;
+ unsigned int sctp_assoc_id = 0;
+
+#ifdef DEBUG
+ cout << "route on SS7 PC\n";
+ cout << "PC family = " << dest_pc.ITU24.family << "\n";
+ cout << "PC value = " << dest_pc.ITU24.pc << "\n";
+#endif
+
+ sua_assoc_id = 0;
+ bool cont = (i <= num_of_instance);
+ bool found_assoc = false;
+
+ while (cont)
+ {
+
+ if (dest_pc.ITU14.family == ITU14bit) // standard ITU: 14 bits
+ found_assoc = ((dest_pc.ITU14.pc == instance[i].Dest.pc.ITU14.pc));
+ else if (dest_pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits
+ found_assoc = ((dest_pc.ITU24.pc == instance[i].Dest.pc.ITU24.pc));
+ else if (dest_pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits
+ found_assoc = ((dest_pc.ANSI24.pc == instance[i].Dest.pc.ANSI24.pc));
+ else
+ found_assoc = false;
+
+
+ if (found_assoc)
+ {
+ cont = false;
+ sctp_assoc_id = instance[i].SCTP_assoc_id;
+ sua_assoc_id = i;
+#ifdef DEBUG
+ cout << "Found Sua association " << i << " with SCTP assoc " << sctp_assoc_id << "\n";
+
+ cout << "CLD SS7 PC = " << dest_pc.ITU24.pc << "\n";
+ cout << "Remote PC = " << instance[i].Dest.pc.ITU24.pc << "\n";
+
+#endif
+ }
+ else
+ {
+ i++;
+ cont = (i <= num_of_instance);
+ }
+ }
+
+ return(sctp_assoc_id);
+};
+
+/***********************************************************************/
+/* Sua_AssociationList::route_on_GTname */
+/***********************************************************************/
+signed int db_Sua_AssociationList::
+route_on_GTname ( hostname_str& dest_name,
+ hostname_str& org_name,
+ int& sua_assoc_id,
+ pointcode_str& dest_pc,
+ pointcode_str& org_pc
+ )
+{
+ struct hostent *hptr;
+ char **pptr;
+ unsigned int sctp_assoc_id = 0;
+ char str[INET6_ADDRSTRLEN];
+ char *dest_carr;
+
+ sua_assoc_id = 0;
+
+ /* resolving can be done via: */
+ /* - local global Titel database */
+ /* - resolve hostname via DNS(simplest for single hop translations) */
+ dest_carr = dest_name;
+
+ if ((hptr = gethostbyname( dest_carr )) == NULL)
+ {
+ cout << "Hostname " << dest_name << " not known in DNS.\n";
+ return(-1);
+ }
+
+#ifdef DEBUG
+ cout << "Hostname " << dest_name << " resolved to dest IP address(es)\n";
+ cout << "IP address length = "<< hptr->h_length << "\n";
+#endif
+
+ /* initialise the length field of the structure: */
+ /* length field is NOT always present in every Unix like operating system */
+ dest_pc.ipvx.ch[0] = 0;
+ org_pc.ipvx.ch[0] = 0;
+
+ pptr = hptr->h_addr_list;
+ for ( ; (*pptr != NULL) ;pptr++)
+ {
+ inet_ntop(hptr->h_addrtype, *pptr, str,sizeof(str));
+#ifdef DEBUG
+ cout << str << "\n";
+#endif
+ /* got IP address, look if association already exists */
+ dest_pc.ipvx.sa.sa_family = hptr->h_addrtype;
+ if (dest_pc.ipvx.sa.sa_family == AF_INET)
+ inet_pton( AF_INET,
+ str,
+ &dest_pc.ipvx.sin.sin_addr
+ );
+ else if (dest_pc.ipvx.sa.sa_family == AF_INET6)
+ inet_pton( AF_INET6,
+ str,
+ &dest_pc.ipvx.sin6.sin6_addr
+ );
+ else
+ cout << "ERROR route_on_GTname: Unknown IP addresstype\n";
+
+ sctp_assoc_id = route_on_IPpc( dest_pc.ipvx,
+ org_pc.ipvx,
+ sua_assoc_id
+ );
+
+ if (sctp_assoc_id != 0 )
+ return(sctp_assoc_id);
+
+ }
+
+ return(sctp_assoc_id);
+};
+
+/***********************************************************************/
+/* Sua_AssociationList::route_msg */
+/***********************************************************************/
+signed int db_Sua_AssociationList::
+route_msg( sccp_addr_str& cld,
+ sccp_addr_str& clg
+ ){
+
+ unsigned int sctp_assoc_id = 0;
+ int sua_assoc_id = 0;
+
+#ifdef DEBUG
+ cout << "num_of_instance : "<< num_of_instance << "\n";
+#endif
+
+ if ((cld.address_fields_present.pc == ipvx_pc_present) &&
+ (cld.routing_ind == route_on_ssn))
+ {
+ sctp_assoc_id = route_on_IPpc( cld.pc.ipvx,
+ clg.pc.ipvx,
+ sua_assoc_id
+ );
+ }
+ else if ((cld.address_fields_present.name_gt == hostname_present) &&
+ (cld.routing_ind == route_on_name_gt))
+ {
+ sctp_assoc_id = route_on_GTname( cld.name.HostName,
+ clg.name.HostName,
+ sua_assoc_id,
+ cld.pc,
+ clg.pc
+ );
+ }
+ else if ((cld.address_fields_present.name_gt == hostname_present) &&
+ (cld.address_fields_present.pc == ipvx_pc_present) &&
+ (cld.routing_ind == route_on_name_gt_next_office))
+ {
+ sctp_assoc_id = route_on_IPpc( cld.pc.ipvx,
+ clg.pc.ipvx,
+ sua_assoc_id
+ );
+ }
+ else if ((cld.address_fields_present.pc == ss7_pc_present) &&
+ (cld.routing_ind == route_on_ssn))
+ {
+ sctp_assoc_id = route_on_SS7pc( cld.pc.ss7,
+ clg.pc.ss7,
+ sua_assoc_id
+ );
+ }
+ else
+ {
+ cout << "Unknown routing requested\n";
+ }
+
+#ifdef SUA_MANAGEMENT
+ /* check if allowed to send msg over the association */
+ if ((sua_assoc_id > 0) &&
+ (sua_assoc_id <= num_of_instance) &&
+ (instance[sua_assoc_id].asp.status != asp_active))
+ {
+ sctp_assoc_id = (-sctp_assoc_id);
+ }
+#endif
+
+#ifdef DEBUG
+ cout << "route msg towards remote SUA(& SCTP) association " << sctp_assoc_id << " \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Route msg towards Remote SUA(& SCTP) instance nr %d", sctp_assoc_id );
+ event_log("sua_database.c",logstring);
+
+ return(sctp_assoc_id);
+};
+
+
+/***********************************************************************/
+/* Sua_AssociationList::increase_instance */
+/***********************************************************************/
+void db_Sua_AssociationList:: increase_instance(){
+
+ num_of_instance++;
+
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::Dynamic_Associate */
+/***********************************************************************/
+unsigned int db_Sua_AssociationList::Dynamic_Associate(
+ db_Sua_LocalList& local_sua,
+ db_Sua_RemoteList& remote_sua,
+ sccp_addr_str& cld,
+ sccp_addr_str& clg,
+ unsigned short nr_of_dest_addr,
+ unsigned short nr_of_input_streams,
+ unsigned short nr_of_output_streams
+ )
+{
+ short sua_portnumber = SUA_PORT;
+
+ short i = 1, assoc_instance_idx = 1, assoc_source_idx = 0;
+ bool partial_assoc_found = FALSE;
+
+ while ((i <= num_of_instance) && !(partial_assoc_found)){
+ partial_assoc_found = (instance[i].Dest.nr_of_addrs == 0);
+ if (partial_assoc_found)
+ assoc_instance_idx = i;
+ i++;
+ }
+
+ if (!(partial_assoc_found))
+ {
+ /* all assoc's are complete, allocate a new one */
+ num_of_instance++;
+ assoc_instance_idx = num_of_instance;
+
+ }
+
+ assoc_source_idx = Find_local_sua ( clg);
+
+#ifdef DEBUG
+ cout << " assoc source idx = " << assoc_source_idx << ", assoc_instance_idx = " << assoc_instance_idx << "\n";
+#endif
+
+ instance[assoc_instance_idx].Source = instance[assoc_source_idx].Source;
+ instance[assoc_instance_idx].SCTP_instance_name = instance[assoc_source_idx].SCTP_instance_name;
+ instance[assoc_instance_idx].local_sua_id = instance[assoc_source_idx].local_sua_id;
+ instance[assoc_instance_idx].nr_of_inbound_streams = nr_of_input_streams ;
+ instance[assoc_instance_idx].nr_of_outbound_streams = nr_of_input_streams ;
+
+ /* conversion and fill in the destination address */
+ instance[assoc_instance_idx].Dest.nr_of_addrs = 1;
+ instance[assoc_instance_idx].Dest.addrs[0] = cld.pc.ipvx;
+
+ short k;
+ const char *ptr;
+ for(k=0; k < instance[assoc_instance_idx].Dest.nr_of_addrs ; k++)
+ {
+ if ( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET )
+ ptr = inet_ntop( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family,
+ &instance[assoc_instance_idx].Dest.addrs[k].sin.sin_addr,
+ (char *)instance[assoc_instance_idx].Dest.address_string[k],
+ SCTP_MAX_IP_LEN
+ );
+ else if ( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family == AF_INET6 )
+ ptr = inet_ntop( instance[assoc_instance_idx].Dest.addrs[k].sa.sa_family,
+ &instance[assoc_instance_idx].Dest.addrs[k].sin6.sin6_addr,
+ (char *)instance[assoc_instance_idx].Dest.address_string[k],
+ SCTP_MAX_IP_LEN
+ );
+ else
+ cout << "Unsupported address family in dynamic associate\n";
+ }
+
+ remote_sua.increase_instance();
+
+ instance[assoc_instance_idx].SCTP_assoc_id =
+ sctp_associate( instance[assoc_instance_idx].SCTP_instance_name,
+ instance[assoc_instance_idx].nr_of_outbound_streams,
+ instance[assoc_instance_idx].Dest.address_string[0],
+ sua_portnumber,
+ NULL
+ );
+ instance[assoc_instance_idx].remote_sua_id = remote_sua.num_of_instance;
+ remote_sua.instance[remote_sua.num_of_instance].ssn.ssn = local_sua.instance[instance[assoc_instance_idx].local_sua_id].ssn.ssn;
+
+ /* a message is queued for this association -> send decision is taken */
+ /* on receiving the communicationUp notification of SCTP AND whether */
+ /* SUA management is going to be used */
+ instance[assoc_instance_idx].asp.status = asp_down_traf_hold;
+
+#ifdef DEBUG
+ cout << "Dynamic Associate remote SUA(& SCTP) instance nr " << assoc_instance_idx << " with local SUA(& SCTP) instance nr " << instance[assoc_instance_idx].local_sua_id << " \n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Dynamic Associate Remote SUA(& SCTP) instance nr %d with local SUA(& SCTP) instance nr %d", assoc_instance_idx, instance[assoc_instance_idx].local_sua_id );
+ event_log("sua_datasoc.c",logstring);
+
+ return(assoc_instance_idx);
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::Activate_Association */
+/***********************************************************************/
+bool db_Sua_AssociationList::activate( unsigned int sua_assoc_id,
+ short mode
+ )
+{
+ return(instance[sua_assoc_id].asp.activate(mode,
+ sua_assoc_id
+ ));
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::DeActivate_Association */
+/***********************************************************************/
+void db_Sua_AssociationList::deactivate( unsigned int sua_assoc_id,
+ short mode
+ )
+{
+ instance[sua_assoc_id].asp.deactivate(mode,
+ sua_assoc_id
+ );
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::Down_Association */
+/***********************************************************************/
+void db_Sua_AssociationList::down( unsigned int sua_assoc_id,
+ short mode
+ )
+{
+ instance[sua_assoc_id].asp.down(mode,
+ sua_assoc_id
+ );
+}
+
+/***********************************************************************/
+/* Sua_AssociationList::Up_Association */
+/***********************************************************************/
+void db_Sua_AssociationList::up( unsigned int sua_assoc_id,
+ short mode
+ )
+{
+ instance[sua_assoc_id].asp.up(mode,
+ sua_assoc_id
+ );
+}
+
+// end of module sua_database.c
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_debug.h b/sualibrary/sua/sua_debug.h
new file mode 100644
index 0000000..a4e3d83
--- /dev/null
+++ b/sualibrary/sua/sua_debug.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ sua_debug.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_debug.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ * Gery Verwimp
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Michelle
+ * "The debugger with the cape rides again"
+ * "He will hunt bugs as long as they do not reside in dark memory lanes"
+ *
+ * Purpose: This header-file defines the SUA debugging constants used
+ * for dumping debug info to the screen, dump debug info to file,
+ * activate ASP management...etc....
+ */
+
+#ifndef SUA_DEBUG_H
+#define SUA_DEBUG_H
+
+/*#define DEBUG activates debuging msg on screen */
+/*#define FILE_DEBUG activates debugging info to output file */
+#define SUA_MANAGEMENT /* activates SUA management */
+#define SG_ASP_MODE /* implementation acts as ASP towards a SG */
+
+
+#endif // SUA_DEBUG_H
+
+// end of module sua_debug.h
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_distribution.cpp b/sualibrary/sua/sua_distribution.cpp
new file mode 100644
index 0000000..c588f49
--- /dev/null
+++ b/sualibrary/sua/sua_distribution.cpp
@@ -0,0 +1,1167 @@
+/***************************************************************************
+ sua_distribution.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_distribution.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Pascale
+ * "We are continously looking for Ghostwriters."
+ * "When we find one, he will be terminated on the spot. Nobody writes (into)
+ * "my lifes variables without my permission."
+ *
+ * Purpose: This code-file defines the SUA distributor functions for:
+ * - Data arrive notification(from SCTP) -> receive the msg data
+ * from SCTP(use receive_sua_primitive function below), process it
+ * and call the aproriate SUA msg handling function
+ * - Network status change Notification(from SCTP)
+ * - Sent Failure Notification(from SCTP)
+ * - Communication Lost Notification(from SCTP)
+ * - Communication Up Notification(from SCTP)
+ * - Communication Error Notification(from SCTP)
+ * - Restart Notification(from SCTP)
+ * - Shutdown Notification(from SCTP)
+ * - Send a SUA primitive -> generate and send the msg to SCTP
+ * - Receive the sua "primitive"/msg data from SCTP
+ */
+
+#include "sua_debug.h"
+#include "sua_database.h"
+#include "sua_tcb.h"
+#include "sua_logging.h"
+#include "sua_syntax.h"
+#include "sua_cl.h"
+#include "sua_co.h"
+#include "sua_distribution.h"
+
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <map>
+#include <vector>
+
+using namespace std;
+
+#define BUFSIZE 2000
+
+// syntax definitions of the sua message
+Sua_container msg;
+
+// storage for received SUA messages
+vector<sua_save_str> rec_msg_pool;
+
+extern db_Sua_LocalList local_sua;
+extern db_Sua_RemoteList remote_sua;
+extern db_Sua_AssociationList Assoc_sua;
+extern tcb_Sua_TCB_arr tcb_pool;
+extern tcb_Sua_msgqueue_pool msg_store;
+
+/***********************************************************************/
+/* sctp_DataArriveNotif */
+/***********************************************************************/
+void sctp_DataArriveNotif( unsigned int sctp_assoc_id,
+ unsigned int stream_id,
+ unsigned int len,
+ unsigned int protocol_id,
+ unsigned int unordered_flag,
+ void * ulp_data_ptr
+ )
+{
+
+ unsigned short result;
+ unsigned int Sua_ConnId;
+ unsigned int sua_assoc_id;
+ unsigned int local_sua_id,remote_sua_id;
+ tcb_Sua_TCB_str *tcb_ptr;
+ Sua_syntax_error_struct error;
+ char databuf[BUFSIZE];
+ unsigned int flags = SCTP_MSG_DEFAULT;
+
+#ifdef DEBUG
+ cout << "Received a Data notification from SCTP for association " << sctp_assoc_id << " : handle and distribute\n";
+#endif
+
+
+
+ // receive data from SCTP
+ result = sctp_receive( sctp_assoc_id,
+ stream_id,
+ (unsigned char *) databuf,
+ &len,
+ flags
+ );
+
+ // display byte array
+#ifdef DEBUG
+ display_byte_array(databuf ,len);
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA message, just received from SCTP");
+ event_log("sua_distribution.c",logstring);
+ log_byte_array("sua_distribution.c", databuf,len);
+
+
+ // copy received data from databuf to msg object -> byte array
+ msg.sua_msg.insert(0, databuf, len);
+ // decode data to figure which SUA message we received
+ error = msg.sua_decode();
+
+ if (!error.no_error)
+ {
+ char logstring[100];
+ sprintf(logstring, "Decoding error in received SUA message : index = %d,", error.msg_index);
+ event_log("sua_distribution.c",logstring);
+ char *spare = new char[error.error_text.length()];
+ error.error_text.copy(spare, error.error_text.length());
+ sprintf(logstring, "Error string = %s,", spare);
+ event_log("sua_distribution.c",logstring);
+ cout << "Decoding error in received SUA message : "<< error.error_text << ", index = " << error.msg_index << "\n";
+ msg.sua_prim.hdr_msg_class = sua_max;
+ return;
+ }
+
+ // distribute the message based on some parameters
+ // Connectionless or connection-oriented
+ switch (msg.sua_prim.hdr_msg_class)
+ {
+ case (sua_cl):
+
+ // connectionless : strip of header and send to user
+ switch (msg.sua_prim.hdr_msg_type.cl)
+ {
+ case cl_data_transfer /*N_UNITDATA*/:
+ {
+#ifdef DEBUG
+ cout << "CL: Unitdata message handling\n";
+#endif
+ unsigned int local_sua_id,remote_sua_id;
+ sua_assoc_id = Assoc_sua.Find_association( sctp_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+ result = process_unitdata_msg ( local_sua_id,
+ sua_assoc_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received Unitdata msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case cl_data_response /*N_UNITDATA_SERVICE*/:
+ {
+#ifdef DEBUG
+ cout << "CL: Unitdata Service message handling\n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Received Unitdata Service msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ default:
+ {
+ cout << "Unknown connectionless message type !!\n";
+ char logstring[100];
+ sprintf(logstring, "Unknown connectionless message type");
+ event_log("sua_distribution.c",logstring);
+ break;
+ }
+ }
+
+ break;
+
+ case (sua_co):
+
+ // connectionoriented: get SCOC TCB, do state-event handling and send to use
+ switch (msg.sua_prim.hdr_msg_type.co)
+ {
+ case co_core /*N_CONNECT_IND */:
+ {
+#ifdef DEBUG
+ cout << "CO: Connect indication message handling\n";
+#endif
+ char logstring[100];
+ sprintf(logstring, "Received Connect Indication msg");
+ event_log("sua_distribution.c",logstring);
+
+
+ unsigned int local_sua_id,remote_sua_id;
+
+ sua_assoc_id = Assoc_sua.Find_association( sctp_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ tcb_ptr = tcb_pool.allocate_TCB(Sua_ConnId);
+
+ result = process_CORE_msg ( sua_assoc_id,
+ tcb_ptr,
+ Sua_ConnId,
+ msg
+ );
+ break;
+ }
+ case co_coak /*connect confirm */:
+ {
+#ifdef DEBUG
+ cout << "CO: Connection request acknowledge message handling\n";
+#endif
+ Sua_ConnId = msg.sua_prim.dest_ref;
+ tcb_ptr = tcb_pool.get_tcb(Sua_ConnId);
+ if (( msg.sua_prim.dest_ref_pres))
+ {
+ char logstring[100];
+ sprintf(logstring, "Received Connect Confirm Indication msg");
+ event_log("sua_distribution.c",logstring);
+
+ // call connection request acknowledge message handling
+ result = process_COAK_msg ( sctp_assoc_id,
+ tcb_ptr,
+ Sua_ConnId,
+ msg
+ );
+ }
+ else
+ cout << "ERROR: TCB " << Sua_ConnId << " was not retrieved?!!\n";
+
+ }
+ case co_data /*data*/:
+ {
+#ifdef DEBUG
+ cout << "CO: Data message handling\n";
+#endif
+ Sua_ConnId = msg.sua_prim.dest_ref;
+ tcb_ptr = tcb_pool.get_tcb(Sua_ConnId);
+ if (( msg.sua_prim.dest_ref_pres)/* &&
+ ( tcb_ptr /= NULL)*/)
+ {
+ char logstring[100];
+ sprintf(logstring, "Received Data Indication msg");
+ event_log("sua_distribution.c",logstring);
+
+ // call data message handling function
+ result = process_CODATA_msg ( sctp_assoc_id,
+ tcb_ptr,
+ Sua_ConnId,
+ msg
+ );
+ }
+ else
+ cout << "ERROR: TCB " << Sua_ConnId << " was not retrieved?!!\n";
+
+ break;
+ }
+ case co_relre /*release request*/:
+ {
+#ifdef DEBUG
+ cout << "CO: Release Request message handling\n";
+#endif
+ Sua_ConnId = msg.sua_prim.dest_ref;
+ tcb_ptr = tcb_pool.get_tcb(Sua_ConnId);
+ if (( msg.sua_prim.dest_ref_pres))
+ {
+ char logstring[100];
+ sprintf(logstring, "Received Release Request Indication msg");
+ event_log("sua_distribution.c",logstring);
+
+ // call release request message handling function
+ result = process_CORELRQ_msg ( sctp_assoc_id,
+ tcb_ptr,
+ Sua_ConnId,
+ msg
+ );
+ }
+ else
+ cout << "ERROR: TCB " << Sua_ConnId << " was not retrieved?!!\n";
+
+
+ break;
+ }
+ case co_relco /*release completed */:
+ {
+#ifdef DEBUG
+ cout << "CO: Release Complete message handling\n";
+#endif
+ Sua_ConnId = msg.sua_prim.dest_ref;
+ tcb_ptr = tcb_pool.get_tcb(Sua_ConnId);
+ if (( msg.sua_prim.dest_ref_pres))
+ {
+ char logstring[100];
+ sprintf(logstring, "Received Release Confirm Indication msg");
+ event_log("sua_distribution.c",logstring);
+
+ // call release complete message handling function
+ result = process_CORELCO_msg ( sctp_assoc_id,
+ tcb_ptr,
+ Sua_ConnId,
+ msg
+ );
+ }
+ else
+ cout << "ERROR: TCB " << Sua_ConnId << " was not retrieved?!!\n";
+
+
+ break;
+ }
+ case co_coref /*connection refused */:
+ {
+#ifdef DEBUG
+ cout << "CO: Connection refused message handling\n";
+#endif
+ Sua_ConnId = msg.sua_prim.dest_ref;
+ tcb_ptr = tcb_pool.get_tcb(Sua_ConnId);
+ if (( msg.sua_prim.dest_ref_pres))
+ {
+ char logstring[100];
+ sprintf(logstring, "Received Connect Confirm Indication msg");
+ event_log("sua_distribution.c",logstring);
+
+ // call connection request acknowledge message handling
+ result = process_COREF_msg ( sctp_assoc_id,
+ tcb_ptr,
+ Sua_ConnId,
+ msg
+ );
+ }
+ else
+ cout << "ERROR: TCB " << Sua_ConnId << " was not retrieved?!!\n";
+
+ }
+ default:
+ {
+ char logstring[100];
+ sprintf(logstring, "Unknown connectionoriented message type");
+ event_log("sua_distribution.c",logstring);
+ cout << "Unknown connectionoriented message type !!\n";
+ break;
+ }
+ }
+
+ break;
+
+ case (sua_mngt):
+ // SUA management msg
+ sua_assoc_id = Assoc_sua.Find_association( sctp_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ switch (msg.sua_prim.hdr_msg_type.mngt)
+ {
+ case mngt_error :
+ {
+#ifdef DEBUG
+ cout << "SUA Management: ERROR message handling\n";
+#endif
+
+
+ char logstring[100];
+ sprintf(logstring, "Received ERROR msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case mngt_notify :
+ {
+#ifdef DEBUG
+ cout << "SUA Management: NOTIFY message handling\n";
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "Received NOTIFY msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ default:
+ {
+ cout << "Unknown SUA managment message type !!\n";
+ char logstring[100];
+ sprintf(logstring, "Unknown SUA Management message type");
+ event_log("sua_distribution.c",logstring);
+ break;
+ }
+ }
+
+ break;
+
+
+
+ case (sua_ssnm):
+ // Signalling Network Management(SNM) msg
+ sua_assoc_id = Assoc_sua.Find_association( sctp_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ switch (msg.sua_prim.hdr_msg_type.ssnm)
+ {
+ case ssnm_duna :
+ {
+#ifdef DEBUG
+ cout << "SNM: Destination unavialable\n";
+#endif
+
+
+ char logstring[100];
+ sprintf(logstring, "Received DUNA msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case ssnm_dava :
+ {
+#ifdef DEBUG
+ cout << "SNM: Destination avialable message handling\n";
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "Received DAVA msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case ssnm_daud :
+ {
+#ifdef DEBUG
+ cout << "SNM: Destination state audit message handling\n";
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "Received DAUD msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case ssnm_scon :
+ {
+#ifdef DEBUG
+ cout << "SNM: Network congestion message handling\n";
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "Received SCON msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case ssnm_dupu :
+ {
+#ifdef DEBUG
+ cout << "SNM: Destination User Part Unavialable message handling\n";
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "Received DUPU msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case ssnm_drst :
+ {
+#ifdef DEBUG
+ cout << "SNM: Destination restricted message handling\n";
+#endif
+
+ char logstring[100];
+ sprintf(logstring, "Received DRST msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ default:
+ {
+ cout << "Unknown SUA managment message type !!\n";
+ char logstring[100];
+ sprintf(logstring, "Unknown SUA Management message type");
+ event_log("sua_distribution.c",logstring);
+ break;
+ }
+ }
+
+ break;
+
+ case (sua_aspsm):
+ // ASP State maintenance msg
+
+ sua_assoc_id = Assoc_sua.Find_association( sctp_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ switch (msg.sua_prim.hdr_msg_type.aspsm)
+ {
+ case aspsm_up :
+ {
+#ifdef DEBUG
+ cout << "ASPSM: ASP_UP message handling\n";
+#endif
+ result = process_ASPUP_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received ASPUP msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case aspsm_up_ack :
+ {
+#ifdef DEBUG
+ cout << "ASPSM: ASP_UP_ACK message handling\n";
+#endif
+ result = process_ASPUP_ACK_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received ASPUP ACK msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case aspsm_down :
+ {
+#ifdef DEBUG
+ cout << "ASPSM: ASP_DOWN message handling\n";
+#endif
+ result = process_ASPDOWN_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received ASPDO msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case aspsm_down_ack :
+ {
+#ifdef DEBUG
+ cout << "ASPSM: ASP_DOWN_ACK message handling\n";
+#endif
+ result = process_ASPDOWN_ACK_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received ASPDOWN ACK msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case aspsm_beat :
+ {
+#ifdef DEBUG
+ cout << "ASPSM: HEARTBEAT message handling\n";
+#endif
+ result = process_BEAT_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received HEARTBEAT msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case aspsm_beat_ack :
+ {
+#ifdef DEBUG
+ cout << "ASPSM: HEARTBEAT_ACK message handling\n";
+#endif
+ result = process_BEAT_ACK_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received HEARTBEAT ACK msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ default:
+ {
+ cout << "Unknown ASP State Maintenance message type !!\n";
+ char logstring[100];
+ sprintf(logstring, "Unknown ASP State Maintenance message type");
+ event_log("sua_distribution.c",logstring);
+ break;
+ }
+ }
+
+ break;
+
+ case (sua_asptm):
+ // ASP Traffic maintenance msg
+
+ sua_assoc_id = Assoc_sua.Find_association( sctp_assoc_id,
+ local_sua_id,
+ remote_sua_id
+ );
+
+ switch (msg.sua_prim.hdr_msg_type.asptm)
+ {
+ case asptm_act :
+ {
+#ifdef DEBUG
+ cout << "ASPTM: ASPAC message handling\n";
+#endif
+ result = process_ASPAC_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received ASPAC msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case asptm_act_ack :
+ {
+#ifdef DEBUG
+ cout << "ASPSM: ASPAC_ACK message handling\n";
+#endif
+ result = process_ASPAC_ACK_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received ASPAC ACK msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case asptm_inact :
+ {
+#ifdef DEBUG
+ cout << "ASPTM: ASPINAC message handling\n";
+#endif
+ result = process_ASPINAC_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received ASPINAC msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ case asptm_inact_ack :
+ {
+#ifdef DEBUG
+ cout << "ASPSM: ASPINAC_ACK message handling\n";
+#endif
+ result = process_ASPINAC_ACK_msg ( sua_assoc_id,
+ local_sua_id,
+ remote_sua_id,
+ msg
+ );
+
+ char logstring[100];
+ sprintf(logstring, "Received ASPINAC ACK msg");
+ event_log("sua_distribution.c",logstring);
+
+ break;
+ }
+ default:
+ {
+ cout << "Unknown ASP Traffic Maintenance message type !!\n";
+ char logstring[100];
+ sprintf(logstring, "Unknown ASP Traffic Maintenance message type");
+ event_log("sua_distribution.c",logstring);
+ break;
+ }
+ }
+
+ break;
+
+ default:
+ {
+ char logstring[100];
+ sprintf(logstring, "Unknown message type");
+ event_log("sua_distribution.c",logstring);
+ break;
+ }
+ }
+ // return
+#ifdef DEBUG
+ cout << "Received message processed\n";
+#endif
+}
+
+/***********************************************************************/
+/* sctp_NetworkStatusChangeNotif */
+/***********************************************************************/
+void sctp_NetworkStatusChangeNotif( unsigned int assoc_id,
+ short dest_addr_index,
+ unsigned short new_path_state,
+ void * ulp_data_ptr
+ )
+{
+#ifdef DEBUG
+ cout << "Received a Network status change notification from SCTP for association " << assoc_id << "\n";
+#endif
+}
+
+/***********************************************************************/
+/* sctp_SentFailureNotif */
+/***********************************************************************/
+void sctp_SentFailureNotif( unsigned int assoc_id,
+ unsigned char * unsent_data_sent_ptr,
+ unsigned int len,
+ unsigned int * sctp_send_context_ptr,
+ void * ulp_data_ptr
+ )
+{
+#ifdef DEBUG
+ cout << "Received a send failure notification from SCTP for association " << assoc_id << " Ignore it, not supported.\n";
+#endif
+}
+
+/***********************************************************************/
+/* sctp_communicationLostNotif */
+/***********************************************************************/
+void sctp_CommunicationLostNotif( unsigned int sctp_assoc_id,
+ unsigned short status_event,
+ void * ulp_data_ptr
+ )
+{
+ unsigned int sua_assoc_id,local_sua_id, remote_sua_id;
+
+#ifdef DEBUG
+ cout << "Received indication that communication with remote peer was lost for association " << sctp_assoc_id << "\n";
+ cout << "Status CommunicationLostNotif = " << status_event << "\n";
+#endif
+ /* Put in debugging file */
+ char logstring[100];
+ sprintf(logstring, "CommunicationLostNotif received from SCTP");
+ event_log("sua_distribution.c",logstring);
+ sprintf(logstring,"assoc_id = %d, status = %d ",sctp_assoc_id,status_event);
+ event_log("sua_distribution.c",logstring);
+
+#ifdef SUA_MANAGEMENT
+ if ((sua_assoc_id = Assoc_sua.Find_association(sctp_assoc_id, local_sua_id,remote_sua_id)) != 0)
+ {
+ /* if we found the sua assoc then the SUA ASP is marked down, */
+ /* as the sctp association has failed */
+ Assoc_sua.down(sua_assoc_id, 0);
+#ifdef DEBUG
+ cout << "ASP down for SUA association " << sua_assoc_id << "\n";
+#endif
+
+ }
+#endif
+
+}
+
+/***********************************************************************/
+/* sctp_CommunicationUpNotif */
+/***********************************************************************/
+void *sctp_CommunicationUpNotif( unsigned int sctp_assoc_id,
+ unsigned short status_event,
+ int nr_of_dest_addr,
+ unsigned short nr_of_input_streams,
+ unsigned short nr_of_output_streams,
+ void * ulp_data_ptr
+ )
+{
+
+ unsigned int sua_assoc_id,local_sua_id, remote_sua_id;
+ char logstring[100];
+ int result;
+ tcb_Sua_msg_elem sua_msg;
+
+#ifdef DEBUG
+ cout << "Received Communication Up indication for association " << sctp_assoc_id <<"\n";
+ cout << "Status CommunicationUpNotif = " << status_event << ", number of addresses used = " << nr_of_dest_addr << "\n";
+ cout << "Number of input streams = " << nr_of_input_streams << ", number of output streams = " << nr_of_output_streams << "\n";
+#endif
+
+ /* Put in debugging file */
+ sprintf(logstring, "CommunicationUpNotif received from SCTP");
+ event_log("sua_distribution.c",logstring);
+ sprintf(logstring,"assoc_id = %d, status = %d , number of dest addr = %d",sctp_assoc_id,status_event, nr_of_dest_addr);
+ event_log("sua_distribution.c",logstring);
+ sprintf(logstring,"Number of input streams = %d, number of output streams = %d", nr_of_input_streams,nr_of_output_streams);
+ event_log("sua_distribution.c",logstring);
+
+
+
+ if ((sua_assoc_id = Assoc_sua.Find_association(sctp_assoc_id, local_sua_id,remote_sua_id)) == 0) {
+#ifdef DEBUG
+ cout << "association " << sctp_assoc_id << " is not present\n";
+#endif
+ sua_assoc_id = Assoc_sua.passive_associate( sctp_assoc_id,
+ local_sua,
+ remote_sua,
+ nr_of_dest_addr,
+ nr_of_input_streams,
+ nr_of_output_streams
+ );
+ }
+
+ /* code include if SUA management is NOT used */
+#ifndef SUA_MANAGEMENT
+ if ( Assoc_sua.instance[sua_assoc_id].status == asp_down_traf_hold)
+ {
+ /* - get the saved msg ansd send it on the association that is setup */
+ sua_msg = msg_store.get_msg ( sua_assoc_id );
+
+ while ( sua_msg.valid)
+ {
+ char* databuf = new char[sua_msg.byte.length()];
+ sua_msg.byte.copy(databuf, sua_msg.byte.length());
+ datalen = sua_msg.byte.length();
+
+ /* msg retrieved and copied, may now remove it from queue */
+ msg_store.delete_msg ( sua_assoc_id );
+
+#ifdef DEBUG
+ display_byte_array(databuf , sua_msg.byte.length());
+#endif
+ char logstring[100];
+ sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", sctp_assoc_id);
+ event_log("sua_distribution.c",logstring);
+ log_byte_array("sua_distribution.c", databuf,sua_msg.byte.length());
+
+ result = sctp_send ( sctp_assoc_id,
+ sua_msg.stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY,
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ sua_msg.delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+ delete databuf;
+#ifdef DEBUG
+ cout << "sua_distribution.c:result sctp send = "<< result << "\n";
+#endif
+ /* get the next saved msg ansd send if any ? */
+ sua_msg = msg_store.get_msg ( sua_assoc_id );
+
+ }
+ /* SUA ASP is marked down */
+ Assoc_sua.down(sua_assoc_id,0);
+ }
+
+#endif
+
+ /* code include if SUA management IS used */
+#ifdef SUA_MANAGEMENT
+#ifdef DEBUG
+ cout << "sua_distribution.c:should send ASPUP\n";
+#endif
+ /* send ASP-UP to remote to start activating local & remote ASP */
+ result = sua_send_ASPUP( sua_assoc_id
+ );
+#endif
+
+ return NULL;
+}
+
+/***********************************************************************/
+/* sctp_CommunicationErrorNotif */
+/***********************************************************************/
+void sctp_CommunicationErrorNotif( unsigned int assoc_id,
+ unsigned short error_status,
+ void * ulp_data_ptr
+ )
+{
+#ifdef DEBUG
+ cout << "Received Error indication for association " << assoc_id << " with error status " << error_status << "\n";
+ cout << "Aborting association \n";
+#endif
+ sctp_deleteAssociation(assoc_id);
+}
+
+
+/***********************************************************************/
+/* sctp_RestartNotif */
+/***********************************************************************/
+void sctp_RestartNotif( unsigned int sctp_assoc_id,
+ void * ulp_data_ptr
+ )
+{
+ unsigned int sua_assoc_id,local_sua_id, remote_sua_id;
+ int result;
+
+#ifdef DEBUG
+ cout << "Received Restart indication for association " << sctp_assoc_id << "\n";
+#endif
+
+#ifdef SUA_MANAGEMENT
+ if ((sua_assoc_id = Assoc_sua.Find_association(sctp_assoc_id, local_sua_id,remote_sua_id)) == 0)
+ {
+#ifdef DEBUG
+ cout << "ASP status = " << Assoc_sua.instance[sua_assoc_id].asp.status <<" for SUA association " << sua_assoc_id << "\n";
+#endif
+
+ /* restart association: ASP state should be set to down */
+ Assoc_sua.down(sua_assoc_id,0);
+
+ /* if we found the sua assoc then we restart the ASP bringup sequence */
+ /* as the sctp association has come back online */
+ /* send ASP-UP to remote to start activating local & remote ASP */
+ result = sua_send_ASPUP( sua_assoc_id
+ );
+ }
+#endif
+
+}
+
+/***********************************************************************/
+/* sctp_ShutDownCompleteNotif */
+/***********************************************************************/
+void sctp_ShutDownCompleteNotif( unsigned int assoc_id,
+ void * ulp_data_ptr
+ )
+{
+#ifdef DEBUG
+ cout << "Received shutdown indication for association " << assoc_id << "\n";
+#endif
+}
+
+
+
+/***********************************************************************/
+/* Send_sua_primitive */
+/***********************************************************************/
+unsigned int Send_sua_primitive( unsigned int primitive,
+ unsigned int &sua_ConnId,
+ sccp_QOS_str &QOS,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address,
+ char *buffer,
+ unsigned int len
+ )
+{
+ int error;
+ char logstring[100];
+ tcb_Sua_TCB_str *tcb_ptr;
+#ifdef DEBUG
+ cout << "Send SUA primitive to local SUA instance\n";
+ cout << "ConnId = " << sua_ConnId << "\n";
+#endif
+
+ // search for the required local_ref
+ if (sua_ConnId != 0)
+ {
+ //handle connection oriented primitves which have already a TCB
+ tcb_ptr = tcb_pool.get_tcb(sua_ConnId);
+
+ switch (primitive)
+ {
+ case N_CONNECT_RESP:
+ //send back response on received CORE of connection
+ sprintf(logstring, "CO N-CONNECT RESPONSE primitive req");
+ event_log("sua_distribution.c",logstring);
+
+ error = sua_send_CORESP( QOS,
+ buffer,
+ len,
+ sua_ConnId,
+ tcb_ptr
+ );
+
+ break;
+ case N_DATA_REQ:
+ //send data on existing connection
+ sprintf(logstring, "CO N-DATA REQ primitive req");
+ event_log("sua_distribution.c",logstring);
+ error = sua_send_CODATA( QOS,
+ buffer,
+ len,
+ sua_ConnId,
+ tcb_ptr
+ );
+
+ break;
+ case N_RELEASE_REQ:
+ //Disconnect request on existing connection
+ sprintf(logstring, "CO N-RELEASE REQ primitive req");
+ event_log("sua_distribution.c",logstring);
+ error = sua_send_CORELRQ( QOS,
+ buffer,
+ len,
+ sua_ConnId,
+ tcb_ptr
+ );
+
+ break;
+ case N_RELEASE_CONF:
+ //Disconnect confirm request on existing connection
+ sprintf(logstring, "CO N-RELEASE CONFIRM primitive req");
+ event_log("sua_distribution.c",logstring);
+ error = sua_send_CORELCO( QOS,
+ buffer,
+ len,
+ sua_ConnId,
+ tcb_ptr
+ );
+
+ break;
+ case N_CONNECT_REFUSED:
+ //send a connect refused on connection
+ sprintf(logstring, "CO N-CONNECT REFUSED primitive req");
+ event_log("sua_distribution.c",logstring);
+
+ error = sua_send_COREF( QOS,
+ buffer,
+ len,
+ sua_ConnId,
+ tcb_ptr
+ );
+
+ break;
+ default:
+ sua_ConnId = 0;
+ error = 1;
+ break;
+ }
+ }
+ else
+ {
+ //handle connectionless primitives
+ //handle connection oriented primitives for which no TCB was yet alllocated
+ // figured out connectionless/connection-oriented primitived
+ switch (primitive)
+ {
+ case N_UNITDATA:
+ sprintf(logstring, "Unitdata primitive req");
+ event_log("sua_distribution.c",logstring);
+ sua_ConnId = 0;
+ error = sua_send_Unitdata(QOS,
+ called_pty_address,
+ calling_pty_address,
+ buffer,
+ len
+ );
+ break;
+ case N_CONNECT_REQ:
+ sprintf(logstring, "CO N-CONNECT REQ primitive req");
+ event_log("sua_distribution.c",logstring);
+
+ tcb_ptr = tcb_pool.allocate_TCB(sua_ConnId);
+
+ error = sua_send_CORE( QOS,
+ called_pty_address,
+ calling_pty_address,
+ buffer,
+ len,
+ sua_ConnId,
+ tcb_ptr
+ );
+ break;
+ default:
+ sua_ConnId = 0;
+ error = 1;
+ break;
+ }
+ }
+
+ return(error);
+
+}
+
+/***********************************************************************/
+/* receive_sua_primitive */
+/***********************************************************************/
+unsigned int Receive_sua_primitive( unsigned int &primitive,
+ unsigned int &Sua_ConnId,
+ sccp_QOS_str &QOS,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address,
+ char* buffer,
+ unsigned int len
+ )
+{
+
+
+ // retrieve the stored user data from the received msg list
+ sua_save_str temp=rec_msg_pool.front();
+ // delete the user data in the received msg list
+ rec_msg_pool.erase(rec_msg_pool.begin());
+
+ // primitive and address parameters
+ primitive = temp.primitive;
+ Sua_ConnId = temp.user_ref;
+ QOS = temp.QOS;
+ called_pty_address = temp.called_pty_address;
+ calling_pty_address = temp.calling_pty_address;
+ // put in supplied byte array(space is allocated beforehand by application)
+ temp.userdata.copy(buffer, temp.userdata.length());
+ len = temp.userdata.length();
+
+ return(len);
+}
+
+// end of module sua_distribution.c
diff --git a/sualibrary/sua/sua_distribution.h b/sualibrary/sua/sua_distribution.h
new file mode 100644
index 0000000..f384f29
--- /dev/null
+++ b/sualibrary/sua/sua_distribution.h
@@ -0,0 +1,170 @@
+/***************************************************************************
+ sua_distribution.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_distribution.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Dorine
+ * "When B.B. releases one of his pearls of wisedom and "
+ * "starts one of his walks around the block, then this designer says:"
+ * "I am getting tired of running in circles even if it is "
+ * "a nice block in a nice neighbourhood(maybe his walks are recursive)"
+ *
+ * Purpose: This header-file defines the SUA distributor functions for:
+ * - Data arrive notification(from SCTP) -> receive the msg data
+ * from SCTP(use receive_sua_primitive function below), process it
+ * and call the aproriate SUA msg handling function
+ * - Network status change Notification(from SCTP)
+ * - Sent Failure Notification(from SCTP)
+ * - Communication Lost Notification(from SCTP)
+ * - Communication Up Notification(from SCTP)
+ * - Communication Error Notification(from SCTP)
+ * - Restart Notification(from SCTP)
+ * - Shutdown Notification(from SCTP)
+ * - Send a SUA primitive -> generate and send the msg to SCTP
+ * - Receive the sua "primitive"/msg data from SCTP
+ */
+
+
+#ifndef SUA_DISTRIBUTION_H
+#define SUA_DISTRIBUTION_H
+
+
+#include "sua.h"
+#include <string>
+
+
+using namespace std;
+
+typedef struct {
+ unsigned int primitive;
+ unsigned int user_ref;
+ sccp_QOS_str QOS;
+ sccp_addr_str called_pty_address;
+ sccp_addr_str calling_pty_address;
+ string userdata;
+} sua_save_str;
+
+/***********************************************************************/
+/* sctp_DataArriveNotif */
+/***********************************************************************/
+void sctp_DataArriveNotif( unsigned int assoc_id,
+ unsigned int stream_id,
+ unsigned int len,
+ unsigned int protocol_id,
+ unsigned int unordered_flag,
+ void * ulp_data_ptr
+ );
+
+
+/***********************************************************************/
+/* sctp_NetworkStatusChangeNotif */
+/***********************************************************************/
+void sctp_NetworkStatusChangeNotif( unsigned int assoc_id,
+ short dest_addr_index,
+ unsigned short new_path_state,
+ void * ulp_data_ptr
+ );
+
+
+/***********************************************************************/
+/* sctp_SentFailureNotif */
+/***********************************************************************/
+void sctp_SentFailureNotif( unsigned int assoc_id,
+ unsigned char * unsent_data_sent_ptr,
+ unsigned int len,
+ unsigned int * sctp_send_context_ptr,
+ void * ulp_data_ptr
+ );
+
+
+/***********************************************************************/
+/* sctp_communicationLostNotif */
+/***********************************************************************/
+void sctp_CommunicationLostNotif( unsigned int assoc_id,
+ unsigned short status_event,
+ void * ulp_data_ptr
+ );
+
+/***********************************************************************/
+/* sctp_CommunicationUpNotif */
+/***********************************************************************/
+void* sctp_CommunicationUpNotif( unsigned int assoc_id,
+ unsigned short status_event,
+ int nr_of_dest_addr,
+ unsigned short nr_of_input_streams,
+ unsigned short nr_of_output_streams,
+ void * ulp_data_ptr
+ );
+
+
+/***********************************************************************/
+/* sctp_CommunicationErrorNotif */
+/***********************************************************************/
+void sctp_CommunicationErrorNotif( unsigned int assoc_id,
+ unsigned short error_status,
+ void * ulp_data_ptr
+ );
+
+
+/***********************************************************************/
+/* sctp_RestartNotif */
+/***********************************************************************/
+void sctp_RestartNotif( unsigned int assoc_id,
+ void * ulp_data_ptr
+ );
+
+
+/***********************************************************************/
+/* sctp_ShutDownCompleteNotif */
+/***********************************************************************/
+void sctp_ShutDownCompleteNotif( unsigned int assoc_id,
+ void * ulp_data_ptr
+ );
+
+#endif // SUA_DISTRIBUTION_H
+
+// end of module sua_distribution.h
+
+
diff --git a/sualibrary/sua/sua_file.cpp b/sualibrary/sua/sua_file.cpp
new file mode 100644
index 0000000..c5ad667
--- /dev/null
+++ b/sualibrary/sua/sua_file.cpp
@@ -0,0 +1,401 @@
+/***************************************************************************
+ sua_file.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_file.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Martine
+ * "This is the module of the fallen function with the big files by
+ * "Von Craenendonck!"
+ * "This module contains some real schoftware"
+ *
+ * Purpose: This code-file defines the SUA file access functions for:
+ * - get a argument in the line(delimited by a space)
+ * - read the sua file(containing arguments for the SUA database)
+ */
+
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+#include "sua_debug.h"
+#include "sua_database.h"
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <fstream>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h> /* includes <netinet/in.h> also ! */
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#define SUA_PORT 14001
+#define SUA_PPI 4
+
+using namespace std;
+
+
+string get_argument(string line,
+ int& begin,
+ int& end,
+ unsigned int& num_of_char_in_line)
+{
+ int len = 0;
+ bool cont = true;
+ while ((num_of_char_in_line <= line.length()) && (cont))
+ {
+
+ if ((line[num_of_char_in_line] == ' ') ||
+ (num_of_char_in_line >= line.length()))
+ {
+ end = num_of_char_in_line - 1;
+ len = num_of_char_in_line - begin;
+ cont = false;
+ }
+ num_of_char_in_line++;
+
+ }
+
+ char *temp = new char[len];
+
+ // convert to lowercase characters for easier processing
+ int i=0;
+ for(i = 0; i < len ; i++)
+ temp[i] = tolower(line[begin+i]);
+ string sua_arg(temp, len);
+
+#ifdef DEBUGFILE
+ cout << "indexes = "<< begin << " , " << end << " , " << len << "\n";
+ cout << temp << "\n";
+ cout << "got argument = " << sua_arg << " \n";
+ char v;
+ cin >> v;
+#endif
+
+ begin = end + 2;
+ end = 0;
+ delete temp;
+
+ return(sua_arg);
+}
+
+
+int read_sua_file(string filename,
+ db_Sua_LocalList& local_sua,
+ db_Sua_RemoteList& remote_sua,
+ db_Sua_AssociationList& Assoc_sua,
+ db_Sua_NameList& NameDB_sua,
+ db_Sua_ASList& ApplicServ_sua
+ )
+{
+ string sua_filename;
+ string sua_arg;
+ string address_str,ip_addr_str;
+ char ch1, ch2;
+ string sua_line;
+ int num_of_char = 0;
+ int num_of_arg = 0;
+ int num_of_lines = 0;
+ int present_local_instance = 0;
+ int present_remote_instance = 0;
+
+#ifdef DEBUG
+ cout << "file to read = " << filename << " \n";
+#endif
+ cout << "SUA local sua instantation parameters(mandatory) \n";
+ cout << "-s x.x.x.x -l yyy [-u] \n";
+ cout << "-s : source address \n";
+ cout << "-l : source local sua portnumber \n";
+ cout << "-u : listen on local port number \n";
+ cout << "SUA parameters of the sua tester (optional)\n";
+ cout << "Not supported yet (-b 1000 -o -v) \n";
+ cout << "SUA parameters of the SUA remote instantation(s) (optional)\n";
+ cout << "-d x.x.x.x -r yyy [-g tt-nat-np-digits] [-a ASnumber] \n";
+ cout << "-d : destination address \n";
+ cout << "-r : destination sua portnumber \n";
+ cout << "-g : global title(TTID-NAT-NUMPLAN-Digits) linked to destination address \n";
+ cout << "-a : Application Server(AS) this address belongs to \n";
+
+ ifstream infile(filename.c_str());
+ while (getline(infile, sua_line))
+ {
+ num_of_lines++;
+ // analyse input line and split up in arguments according to
+ // the spaces in the line: each argument is then processed
+ unsigned int num_of_char_in_line = 0;
+ int b=0, e=0;
+ bool next_arg;
+
+ sua_arg = get_argument(sua_line,b,e,num_of_char_in_line);
+ next_arg = false;
+
+ // make selection on cmd argument
+ while (num_of_char_in_line < sua_line.length())
+ {
+ ch2 = ' ';
+ if (sua_arg[0] == '-')
+ {
+ ch1 = sua_arg[1];
+ ch2 = sua_arg[2];
+ }
+ else if (sua_arg[0] == '/')
+ ch1 = sua_arg[0];
+ else
+ {
+ cout << "weird option \n";
+ ch1 = ' ';
+ }
+
+ switch (ch1)
+ {
+ case 's': // read source addresses for sua
+ {
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+ if (present_local_instance > 0) {
+ present_local_instance= 0;
+ }
+ local_sua.increase_instance();
+ Assoc_sua.increase_instance();
+ present_remote_instance = 0;
+ Assoc_sua.instance[Assoc_sua.num_of_instance].local_sua_id = local_sua.num_of_instance;
+ Assoc_sua.instance[Assoc_sua.num_of_instance].nr_of_inbound_streams = 1;
+ Assoc_sua.instance[Assoc_sua.num_of_instance].nr_of_outbound_streams = 1;
+
+ if (ch2 == 'n') {
+ ip_addr_str = NameDB_sua.read_host_name(address_str);
+ Assoc_sua.read_Source_addr(ip_addr_str);
+ }
+ else {
+ Assoc_sua.read_Source_addr(address_str);
+ }
+
+ present_local_instance++;
+ break;
+ }
+ case 'd':
+ { // read destination addresses for sua
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+ remote_sua.increase_instance();
+ if (present_remote_instance > 0) {
+ Assoc_sua.increase_instance();
+ Assoc_sua.instance[Assoc_sua.num_of_instance].Source =
+ Assoc_sua.instance[Assoc_sua.num_of_instance-1].Source;
+ Assoc_sua.instance[Assoc_sua.num_of_instance].local_sua_id =
+ Assoc_sua.instance[Assoc_sua.num_of_instance-1].local_sua_id;
+ Assoc_sua.instance[Assoc_sua.num_of_instance].nr_of_inbound_streams = 1;
+ Assoc_sua.instance[Assoc_sua.num_of_instance].nr_of_outbound_streams = 1;
+ present_remote_instance = 0;
+ }
+ if (ch2 == 'n') {
+ ip_addr_str = NameDB_sua.read_host_name(address_str);
+ Assoc_sua.read_Dest_addr(ip_addr_str);
+ }
+ else {
+ Assoc_sua.read_Dest_addr(address_str);
+ }
+ Assoc_sua.instance[Assoc_sua.num_of_instance].remote_sua_id = remote_sua.num_of_instance;
+
+ present_remote_instance++;
+
+ break;
+ }
+ case 'l':
+ { // read local portnumber for sua
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+ Assoc_sua.read_Source_port(address_str);
+
+ break;
+ }
+ case 'r':
+ { // read remote portnumber for sua
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+ Assoc_sua.read_Dest_port(address_str);
+
+ break;
+ }
+ case 'a':
+ { // read Application Server number this remote ASP belongs to
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+
+ Assoc_sua.instance[Assoc_sua.num_of_instance].asp.linked_to_AS[0] = ApplicServ_sua.read_AS(address_str, Assoc_sua.num_of_instance );
+
+ break;
+ }
+ case 'b':
+ {
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+#ifdef DEBUG
+ cout << "discard option b \n";
+#endif
+
+
+ }
+ case 'n':
+ { // read sybsytem number = SSN (valid for both local and remote)
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+ remote_sua.read_ssn(address_str);
+ local_sua.read_ssn(address_str);
+
+ break;
+ }
+ case 'q': // read QOS fields for sua
+ {
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+
+
+ break;
+ }
+ case 'u':
+ { //
+ break;
+ }
+ case 'm':
+ { //
+ break;
+ }
+ case 'o':
+ { //
+ break;
+ }
+ case 't':
+ { // number of streams incoming AND outgoing
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+ Assoc_sua.read_stream_number(address_str);
+ break;
+ }
+ case 'v':
+ { //
+ break;
+ }
+ case 'f':
+ { // file option: we are in file mode could later be used for
+ // recursive filereading. Ignore for the moment
+ num_of_arg++;
+ break;
+ }
+ case 'i':
+ {
+ // ignore character, is not a error, go to next argument
+ break;
+ }
+ case '7':
+ { /* read SS7 pointcodes */
+ switch (ch2)
+ {
+ case 's': // read source pointcode for sua
+ {
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+
+ Assoc_sua.read_Source_pointcode(address_str);
+
+ break;
+ }
+ case 'd':
+ { // read destination pointcode for sua
+ num_of_arg++;
+ address_str = get_argument(sua_line,b,e,num_of_char_in_line);
+
+ Assoc_sua.read_Dest_pointcode(address_str);
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ break;
+ }
+ case '/':
+ {
+ // comment: skip this line
+ num_of_char_in_line = num_of_char_in_line + sua_line.length();
+ b=0;
+ e=0;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ sua_arg = get_argument(sua_line,b,e,num_of_char_in_line);
+ num_of_arg++;
+ }
+ // finished reading the whole line
+ num_of_char = num_of_char + num_of_char_in_line;
+ cout << "Line " << num_of_lines << " : " << sua_line << "\n";
+ }
+
+#ifdef DEBUG
+ cout << "End of file: statistics \n";
+ cout << "Number of lines = " << num_of_lines <<"\n";
+ cout << "Number of characters in file = " << num_of_char << "\n";
+
+#endif
+
+ return (0);
+
+} /* end of read_sua_file */
+
+
+// end of module sua_file.c
+
+
+
diff --git a/sualibrary/sua/sua_file.h b/sualibrary/sua/sua_file.h
new file mode 100644
index 0000000..df7c3d5
--- /dev/null
+++ b/sualibrary/sua/sua_file.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ sua_file.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_file.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Annemie
+ * ""
+ *
+ * Purpose: This header-file defines the SUA file access functions for:
+ * - get a argument in the line(delimited by a space)
+ * - read the sua file(containing arguments for the SUA database)
+ */
+
+#ifndef SUA_FILE_H
+#define SUA_FILE_H
+
+
+#include <string>
+
+using namespace std;
+
+int read_sua_file(string filename,
+ db_Sua_LocalList& local_sua,
+ db_Sua_RemoteList& remote_sua,
+ db_Sua_AssociationList& Assoc_sua,
+ db_Sua_NameList& NameDB_sua,
+ db_Sua_ASList& ApplicServ_sua
+ );
+
+#endif // SUA_FILE_H
+
+// end of module sua_file.h
diff --git a/sualibrary/sua/sua_logging.cpp b/sualibrary/sua/sua_logging.cpp
new file mode 100644
index 0000000..8bc9757
--- /dev/null
+++ b/sualibrary/sua/sua_logging.cpp
@@ -0,0 +1,268 @@
+/***************************************************************************
+ sua_logging.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_logging.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Cindy
+ * "KISS (ME * ) methodology applies"
+ * " * The extended KISS method only applies to beautifull girls."
+ *
+ * Purpose: This code-file defines the SUA logging(error or normal stuff)
+ * functions for:
+ * - initialise the logging file
+ * - log events to logging file
+ * - log byte arrya to logging file
+ * - Display byte array to screen
+ * - close logging file
+ */
+
+
+#include "sua_debug.h"
+#include "sua.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <string>
+#include <iostream>
+#include <iomanip>
+#include <fstream.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+
+#define MAX_BYTES_IN_LINE 20
+
+ofstream logfile;
+char log_filename[100];
+
+typedef enum { min = -127,
+ max = 128
+} sua_byte_str;
+
+/***********************************************************************/
+/* init_logging_file */
+/***********************************************************************/
+void init_logging_file()
+{
+ struct timeval tv;
+ struct timezone tz;
+ struct tm *the_time;
+ // random temporary logfile
+ //sprintf(log_filename, "./tmp%d.log",(int)getpid());
+ sprintf(log_filename, "./tmp2603.log");
+ cout << "Logging all errors and events to file " << log_filename <<"\n";
+ // creation of random logfile: overwrite file if already exists
+ logfile.open(log_filename);
+ if (!logfile)
+ {
+ cout << "Logging file " << log_filename << " could not be created\n";
+ exit(0);
+ }
+ gettimeofday(&tv, &tz);
+ the_time = localtime((time_t *) & (tv.tv_sec));
+ logfile << the_time->tm_hour << ":" << the_time->tm_min << ":" << the_time->tm_sec << ":" << (int) (tv.tv_usec / 1000) << " >> Logfile " << log_filename << " created \n" << flush;
+
+}
+
+
+
+/* This function logs events.
+ Parameters:
+ @param event_log_level : INTERNAL_EVENT_0 INTERNAL_EVENT_1 EXTERNAL_EVENT_X EXTERNAL_EVENT
+ @param module_name : the name of the module that received the event.
+ @param log_info : the info that is printed with the modulename.
+ @param anyno : optional pointer to unsigned int, which is printed along with log_info.
+ The conversion specification must be contained in log_info.
+ @author Hölzlwimmer
+*/
+
+/***********************************************************************/
+/* event_log */
+/***********************************************************************/
+void event_log( char *module_name, char *log_info, ...)
+{
+
+#ifdef FILE_DEBUG
+ struct timeval tv;
+ struct timezone tz;
+ struct tm *the_time;
+
+ gettimeofday(&tv, &tz);
+ the_time = localtime((time_t *) & (tv.tv_sec));
+ logfile << the_time->tm_hour << ":" << the_time->tm_min << ":" << the_time->tm_sec << ":" << (int) (tv.tv_usec / 1000) << " >> " << module_name << " >> " << log_info << " \n" << flush;
+#endif
+
+ return;
+}
+
+/***********************************************************************/
+/* event_log_byte_array */
+/***********************************************************************/
+void log_byte_array( char *module_name, char *log_info, int len)
+{
+#ifdef FILE_DEBUG
+ int i,space;
+ int li;
+ int lines;
+ int index;
+ struct timeval tv;
+ struct timezone tz;
+ struct tm *the_time;
+
+
+ gettimeofday(&tv, &tz);
+ the_time = localtime((time_t *) & (tv.tv_sec));
+ logfile << the_time->tm_hour << ":" << the_time->tm_min << ":" << the_time->tm_sec << ":" << (int) (tv.tv_usec / 1000) << " >> " << module_name << " >> " ;
+ logfile << "Display byte array(in Hex), length " << len << "(hex " << hex << len << ")\n";
+
+ lines = (len / MAX_BYTES_IN_LINE) + 1;
+ li = 0;
+ index = 0;
+ logfile.setf(ios::hex);
+ while ( li < lines){
+ i = 0;
+ space = 0;
+ while (( i < MAX_BYTES_IN_LINE) && (index < len)) {
+ /* what is needed to display a single byte in hex */
+ /* convert the char element to a unsigned character : weird??? */
+ /* then convert the unsigned char to a unsigned short */
+ /* do the display of the unsigned short */
+ unsigned char usc = (log_info[index]);
+ unsigned short c = usc;
+ logfile << hex << setfill('0') << setw(2) << c;
+ space++;
+ if (space >= 4) {
+ logfile << " ";
+ space = 0;
+ }
+ index++;
+ i++;
+ }
+ logfile << "\n";
+ li++;
+ }
+ logfile.setf(ios::dec);
+ logfile << flush;
+#endif
+
+ return;
+}
+
+
+/***********************************************************************/
+/* display_byte_array */
+/***********************************************************************/
+void display_byte_array( char *log_info, int len)
+{
+ int i,li, lines,index, space;
+
+ lines = (len / MAX_BYTES_IN_LINE) + 1;
+ li = 0;
+ index = 0;
+
+
+ //cout << "lines = " << lines << " , len = " << len << "\n";
+ cout.setf(ios::hex);
+ while ( li < lines){
+ i = 0;
+ space = 0;
+ while (( i < MAX_BYTES_IN_LINE) && (index < len)) {
+ /* what is needed to display a single byte in hex */
+ /* convert the char element to a unsigned character : weird??? */
+ /* then convert the unsigned char to a unsigned short */
+ /* do the display of the unsigned short */
+ unsigned char usc = (log_info[index]);
+ unsigned short c = usc;
+ cout << hex << setfill('0') << setw(2) << c;
+ space++;
+ if (space >= 4) {
+ cout << " ";
+ space = 0;
+ }
+ index++;
+ i++;
+ }
+ cout << "\n";
+ // cout << dec << "i = " << i << " , li = " << li << " , index = " << index << "\n";
+ li++;
+ }
+ cout.setf(ios::dec);
+ cout << "SUA message size = " << len << "\n";
+
+}
+
+
+/***********************************************************************/
+/* close_logging_file */
+/***********************************************************************/
+void close_logging_file()
+{
+ struct timeval tv;
+ struct timezone tz;
+ struct tm *the_time;
+
+ gettimeofday(&tv, &tz);
+ the_time = localtime((time_t *) & (tv.tv_sec));
+ logfile << the_time->tm_hour << ":" << the_time->tm_min << ":" << the_time->tm_sec << ":" << (int) (tv.tv_usec / 1000) << " >> Logfile " << log_filename << " closed \n" << flush;
+
+ // closing of random logfile
+ logfile.close();
+
+}
+
+
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_logging.h b/sualibrary/sua/sua_logging.h
new file mode 100644
index 0000000..850be1e
--- /dev/null
+++ b/sualibrary/sua/sua_logging.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ sua_logging.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_logging.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Annick
+ * ""
+ *
+ * Purpose: This header-file defines the SUA logging(error or normal stuff)
+ * functions for:
+ * - initialise the logging file
+ * - log events to logging file
+ * - log byte arrya to logging file
+ * - Display byte array to screen
+ * - close logging file
+ */
+
+#ifndef SUA_LOGGING_H
+#define SUA_LOGGING_H
+
+void init_logging_file();
+void event_log( char *module_name, char *log_info, ...);
+void log_byte_array( char *module_name, char *log_info, int len);
+void display_byte_array( char *log_info, int len);
+void close_logging_file();
+
+#endif // SUA_LOGGING_H
+
+
+
diff --git a/sualibrary/sua/sua_sual.cpp b/sualibrary/sua/sua_sual.cpp
new file mode 100644
index 0000000..1b23cc0
--- /dev/null
+++ b/sualibrary/sua/sua_sual.cpp
@@ -0,0 +1,686 @@
+/***************************************************************************
+ sua_sual.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_sual.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Patricia
+ * "a straight line version of SUA, really "
+ * "without the handpainted perrywinkels according to Hyacinth Bucket"
+ *
+ * Purpose: This code-file defines the SUA light interface:
+ * - SUAL Callback function
+ * and SUA light functions for:
+ * - SUAL initialisation
+ * - SUAL Connectionless data Notification
+ * - SUAL CO Connect Notification
+ * - SUAL CO Connect Confirm Notification
+ * - SUAL CO Data Notification
+ * - SUAL CO DisConnect Notification
+ * - SUAL Register Instance
+ * - SUAL Connectionless Data Request to SUA
+ * - SUAL CO Connect Request to SUA
+ * - SUAL CO Connect Confirm Request to SUA
+ * - SUAL CO Data Request to SUA
+ * - SUAL CO DisConnect Request to SUA
+ * - SUAL CO Data read from SUA
+ * - SUAL Connectionless Data read from SUA
+ */
+
+#include "sua_sual.h"
+#include "sua_database.h"
+#include "sua_file.h"
+#include "sua_distribution.h"
+#include "sua_logging.h"
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+#include <map>
+#include <vector>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h> /* includes <netinet/in.h> also ! */
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#define MAX_DATA_LENGTH 2000
+
+using namespace std;
+/* definition of SUA local object and of remote object */
+extern db_Sua_LocalList local_sua;
+extern db_Sua_RemoteList remote_sua;
+extern db_Sua_AssociationList Assoc_sua;
+
+typedef struct {
+ unsigned int local_sua_id;
+ unsigned int user_ref;
+ string userdata;
+} sual_save_str;
+
+vector <sual_save_str> sual_rec_msg;
+
+SUAL_ULP_CallBacks sual_callback;
+
+/***********************************************************************/
+/* SUA light clone interface functions and structs with SUA */
+/***********************************************************************/
+/***********************************************************************/
+/* sual_init */
+/***********************************************************************/
+
+int sual_init(unsigned char *pConfFile)
+{
+
+ cout << "Initialising SUA datastructures\n ";
+ init_logging_file();
+ local_sua.initialize();
+ remote_sua.initialize();
+ Assoc_sua.initialize();
+ cout << "Finished initialising SUAL data\n ";
+ return (0);
+} /* end of sua_initialisation */
+
+/***********************************************************************/
+/* SUAL_ClDataIndNotif */
+/***********************************************************************/
+void SUAL_ClDataIndNotif ( unsigned int local_sua_id,
+ unsigned int primitive,
+ unsigned int datalen
+ )
+{
+ unsigned int ControlNumber;
+ unsigned int length = 0;
+ sual_PeerAddr PeerAddr;
+ sual_PeerAddr *pPeerAddr;
+ unsigned int Sua_ConnId = 0;
+ char databuffer[MAX_DATA_LENGTH];
+ sccp_QOS_str QOS;
+ sccp_addr_str clg,cld;
+ sual_save_str temp;
+
+ Receive_sua_primitive ( primitive,
+ Sua_ConnId,
+ QOS,
+ cld,
+ clg,
+ databuffer,
+ length
+ );
+
+ // fill in the source address (=local sua address/CLG)
+ switch (clg.routing_ind)
+ {
+ case (route_on_ssn):
+
+ if (clg.address_fields_present.pc == ipvx_pc_present)
+ {
+ if (clg.pc.ipvx.sa.sa_family == AF_INET)
+ {
+ PeerAddr.AddrType = SUAL_ADDRTYPE_IPV4;
+ PeerAddr.uPeerAddr.ip4 = clg.pc.ipvx.sin.sin_addr;
+ }
+ else if (clg.pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ PeerAddr.AddrType = SUAL_ADDRTYPE_IPV6;
+ PeerAddr.uPeerAddr.ip6 = clg.pc.ipvx.sin6.sin6_addr;
+ }
+ else
+ cout << "error filling in CLG IP address \n";
+ }
+ else
+ cout << "unsupported CLG address option\n";
+
+ break;
+ default:
+ cout << "Invalid CLG address option\n";
+ break;
+ }
+
+ ControlNumber = QOS.sequence_number;
+ pPeerAddr = &PeerAddr;
+
+ temp.user_ref = Sua_ConnId;
+ temp.local_sua_id = local_sua_id;
+ // copy character array to temp string
+ temp.userdata.insert(0,databuffer,length);
+
+ sual_rec_msg.push_back(temp);
+
+ sual_callback.ClDataIndNotif ( local_sua_id,
+ ControlNumber,
+ pPeerAddr,
+ datalen
+ );
+
+
+}
+
+/***********************************************************************/
+/* SUAL_ConnIndNotif */
+/***********************************************************************/
+void SUAL_ConnIndNotif ( unsigned int local_sua_id,
+ unsigned int local_sua_ref,
+ unsigned int datalen
+ )
+{
+ unsigned int primitive;
+ unsigned int length = 0;
+ sual_PeerAddr PeerAddr;
+ sual_PeerAddr *pPeerAddr;
+ unsigned int Sua_ConnId = 0;
+ char databuffer[MAX_DATA_LENGTH];
+ sccp_QOS_str QOS;
+ sccp_addr_str clg,cld;
+ sual_save_str temp;
+
+ Receive_sua_primitive ( primitive,
+ Sua_ConnId,
+ QOS,
+ cld,
+ clg,
+ databuffer,
+ length
+ );
+
+ // fill in the source address (=local sua address/CLG)
+ switch (clg.routing_ind)
+ {
+ case (route_on_ssn):
+
+ if (clg.address_fields_present.pc == ipvx_pc_present)
+ {
+ if (clg.pc.ipvx.sa.sa_family == AF_INET)
+ {
+ PeerAddr.AddrType = SUAL_ADDRTYPE_IPV4;
+ PeerAddr.uPeerAddr.ip4 = clg.pc.ipvx.sin.sin_addr;
+ }
+ else if (clg.pc.ipvx.sa.sa_family == AF_INET6)
+ {
+ PeerAddr.AddrType = SUAL_ADDRTYPE_IPV6;
+ PeerAddr.uPeerAddr.ip6 = clg.pc.ipvx.sin6.sin6_addr;
+ }
+ else
+ cout << "error filling in CLG IP address \n";
+ }
+ else
+ cout << "unsupported CLG address option\n";
+
+ break;
+ default:
+ cout << "Invalid CLG address option\n";
+ break;
+ }
+
+ pPeerAddr = &PeerAddr;
+
+ temp.user_ref = Sua_ConnId;
+ temp.local_sua_id = local_sua_id;
+ // copy character array to temp string
+ temp.userdata.insert(0,databuffer,length);
+
+ sual_rec_msg.push_back(temp);
+
+ sual_callback.ConnIndNotif ( Sua_ConnId,
+ pPeerAddr,
+ datalen
+ );
+
+
+}
+
+/***********************************************************************/
+/* SUAL_ConnConfIndNotif */
+/***********************************************************************/
+void SUAL_ConnConfIndNotif ( unsigned int local_sua_id,
+ unsigned int local_sua_ref,
+ unsigned int datalen
+ )
+{
+ unsigned int primitive;
+ unsigned int length = 0;
+ unsigned int Sua_ConnId = 0;
+ char databuffer[MAX_DATA_LENGTH];
+ sccp_QOS_str QOS;
+ sccp_addr_str clg,cld;
+ sual_save_str temp;
+
+ Receive_sua_primitive ( primitive,
+ Sua_ConnId,
+ QOS,
+ cld,
+ clg,
+ databuffer,
+ length
+ );
+
+
+ temp.user_ref = Sua_ConnId;
+ temp.local_sua_id = local_sua_id;
+ // copy character array to temp string
+ temp.userdata.insert(0,databuffer,length);
+
+ sual_rec_msg.push_back(temp);
+
+ sual_callback.ConnConfNotif ( Sua_ConnId,
+ datalen
+ );
+
+
+}
+
+/***********************************************************************/
+/* SUAL_CoDataIndNotif */
+/***********************************************************************/
+void SUAL_CoDataIndNotif ( unsigned int local_sua_id,
+ unsigned int local_sua_ref,
+ unsigned int datalen
+ )
+{
+ unsigned int primitive;
+ unsigned int length = 0;
+ unsigned int Sua_ConnId = 0;
+ char databuffer[MAX_DATA_LENGTH];
+ sccp_QOS_str QOS;
+ sccp_addr_str clg,cld;
+ sual_save_str temp;
+
+ Receive_sua_primitive ( primitive,
+ Sua_ConnId,
+ QOS,
+ cld,
+ clg,
+ databuffer,
+ length
+ );
+
+
+ temp.user_ref = Sua_ConnId;
+ temp.local_sua_id = local_sua_id;
+ // copy character array to temp string
+ temp.userdata.insert(0,databuffer,length);
+
+ sual_rec_msg.push_back(temp);
+
+ sual_callback.CoDataIndNotif ( Sua_ConnId,
+ datalen
+ );
+
+
+}
+
+/***********************************************************************/
+/* SUAL_DisConnIndNotif */
+/***********************************************************************/
+void SUAL_DisConnIndNotif ( unsigned int local_sua_id,
+ unsigned int local_sua_ref,
+ unsigned int reason,
+ unsigned int datalen
+ )
+{
+ unsigned int primitive;
+ unsigned int length = 0;
+ unsigned int Sua_ConnId = 0;
+ char databuffer[MAX_DATA_LENGTH];
+ sccp_QOS_str QOS;
+ sccp_addr_str clg,cld;
+ sual_save_str temp;
+
+ Receive_sua_primitive ( primitive,
+ Sua_ConnId,
+ QOS,
+ cld,
+ clg,
+ databuffer,
+ length
+ );
+
+
+ temp.user_ref = Sua_ConnId;
+ temp.local_sua_id = local_sua_id;
+ // copy character array to temp string
+ temp.userdata.insert(0,databuffer,length);
+
+ sual_rec_msg.push_back(temp);
+
+ sual_callback.DisconnIndNotif ( Sua_ConnId,
+ reason,
+ datalen
+ );
+
+
+}
+
+/***********************************************************************/
+/* sual_RegisterSUAL_instance */
+/***********************************************************************/
+extern sual_InstId_t sual_RegisterSUAL_instance ( sual_port_t local_ssn,
+ SUAL_ULP_CallBacks *callback
+ )
+{
+ Sua_ULP_CallBacks ULP_CallbackFunctions;
+ int res;
+
+ sual_callback.ClDataIndNotif = callback->ClDataIndNotif;
+ sual_callback.ConnIndNotif = callback->ConnIndNotif;
+ sual_callback.ConnConfNotif = callback->ConnConfNotif;
+ sual_callback.CoDataIndNotif = callback->CoDataIndNotif;
+ sual_callback.DisconnIndNotif = callback->DisconnIndNotif;
+
+
+ ULP_CallbackFunctions.ulp_ClDataIndNotif = &SUAL_ClDataIndNotif;
+ ULP_CallbackFunctions.ulp_ConnIndNotif = &SUAL_ConnIndNotif;
+ ULP_CallbackFunctions.ulp_ConnConfIndNotif = &SUAL_ConnConfIndNotif;
+ ULP_CallbackFunctions.ulp_ConnDataIndNotif = &SUAL_CoDataIndNotif;
+ ULP_CallbackFunctions.ulp_DisConnIndNotif = &SUAL_DisConnIndNotif;
+
+ // register all the local SUA together with their SCTP instances
+ res = sua_registerInstance( local_ssn,
+ ULP_CallbackFunctions
+ );
+
+ return(0);
+}
+
+/***********************************************************************/
+/* sual_ClDataReq : send Connectionless UnitData request to SUAL/SUA */
+/***********************************************************************/
+int sual_ClDataReq( sual_id_t InstId,
+ sual_PeerAddr_t *pPeerAddr,
+ uint ControlNumber,
+ unsigned char *pUserData,
+ uint UserDataLen
+ )
+{
+
+ unsigned int Sua_ConnId = 0;
+ sccp_addr_str cl_clg, cl_cld;
+ sccp_QOS_str cl_QOS;
+ unsigned int xsxx;
+
+ cl_QOS.prot_class = class0;
+ cl_QOS.in_sequence = false;
+ cl_QOS.sequence_number = ControlNumber;
+ cl_QOS.return_msg_on_error = 0;
+ cl_QOS.importance = 0;
+
+ /* indicate to SUA to get own(=source) address from the sua database */
+ cl_clg.address_fields_present.pc = no_pc_present;
+ cl_clg.address_fields_present.name_gt = no_name_present;
+ cl_clg.address_fields_present.ssn_port = no_sap_present;
+ cl_clg.address_fields_present.field_in_header = include_nothing;
+
+ /* convert destination address (only pointcodes supported) */
+ cl_cld.address_fields_present.pc = ipvx_pc_present;
+ cl_cld.address_fields_present.name_gt = no_name_present;
+ cl_cld.address_fields_present.ssn_port = no_sap_present;
+ cl_cld.address_fields_present.field_in_header = include_nothing;
+ cl_cld.routing_ind = route_on_ssn;
+
+ if (pPeerAddr->AddrType == SUAL_ADDRTYPE_IPV4)
+ {
+ cl_cld.pc.ipvx.sa.sa_family = AF_INET;
+ cl_cld.pc.ipvx.sin.sin_addr = pPeerAddr->uPeerAddr.ip4;
+ cl_cld.pc.ipvx.sin.sin_port = SUAL_DEF_PORTNUMBER;
+ }
+ else if (pPeerAddr->AddrType == SUAL_ADDRTYPE_IPV6)
+ {
+ cl_cld.pc.ipvx.sa.sa_family = AF_INET6;
+ cl_cld.pc.ipvx.sin6.sin6_addr = pPeerAddr->uPeerAddr.ip6;
+ cl_cld.pc.ipvx.sin6.sin6_port = SUAL_DEF_PORTNUMBER;
+ }
+ else
+ {
+ cout << "Invalid Destination address option\n";
+ }
+
+ char *databuffer = (char *) pUserData;
+
+ xsxx = Send_sua_primitive(N_UNITDATA,
+ Sua_ConnId,
+ cl_QOS,
+ cl_cld,
+ cl_clg,
+ databuffer,
+ UserDataLen
+ );
+ return(xsxx);
+}
+
+/***********************************************************************/
+/* sual_ConnReq : send connect request to SUAL/SUA */
+/***********************************************************************/
+sual_id_t sual_ConnReq( sual_id_t InstId,
+ sual_PeerAddr_t *pPeerAddr,
+ unsigned char *pUserData,
+ uint UserDataLen
+ )
+{
+
+ unsigned int Sua_ConnId = 0;
+ sccp_addr_str clg, cld;
+ sccp_QOS_str QOS;
+ unsigned int xsxx;
+
+ QOS.prot_class = class2;
+ QOS.in_sequence = false;
+ QOS.sequence_number = 0;
+ QOS.return_msg_on_error = 0;
+ QOS.importance = 0;
+
+ /* indicate to SUA to get own(=source) address from the sua database */
+ clg.address_fields_present.pc = no_pc_present;
+ clg.address_fields_present.name_gt = no_name_present;
+ clg.address_fields_present.ssn_port = no_sap_present;
+ clg.address_fields_present.field_in_header = include_nothing;
+
+ /* convert destination address (only pointcodes supported) */
+ cld.address_fields_present.pc = ipvx_pc_present;
+ cld.address_fields_present.name_gt = no_name_present;
+ cld.address_fields_present.ssn_port = no_sap_present;
+ cld.address_fields_present.field_in_header = include_nothing;
+ cld.routing_ind = route_on_ssn;
+
+ if (pPeerAddr->AddrType == SUAL_ADDRTYPE_IPV4)
+ {
+ cld.pc.ipvx.sa.sa_family = AF_INET;
+ cld.pc.ipvx.sin.sin_addr = pPeerAddr->uPeerAddr.ip4;
+ cld.pc.ipvx.sin.sin_port = SUAL_DEF_PORTNUMBER;
+ }
+ else if (pPeerAddr->AddrType == SUAL_ADDRTYPE_IPV6)
+ {
+ cld.pc.ipvx.sa.sa_family = AF_INET6;
+ cld.pc.ipvx.sin6.sin6_addr = pPeerAddr->uPeerAddr.ip6;
+ cld.pc.ipvx.sin6.sin6_port = SUAL_DEF_PORTNUMBER;
+ }
+ else
+ {
+ cout << "Invalid Destination address option\n";
+ }
+
+ char *databuffer = (char *) pUserData;
+
+ xsxx = Send_sua_primitive(N_UNITDATA,
+ Sua_ConnId,
+ QOS,
+ cld,
+ clg,
+ databuffer,
+ UserDataLen
+ );
+ return(xsxx);
+
+}
+
+/***********************************************************************/
+/* sual_ConnResp : send connect response to SUAL/SUA */
+/***********************************************************************/
+int sual_ConnResp( sual_id_t InstId,
+ sual_id_t sual_ConnId,
+ unsigned char *pUserData,
+ uint UserDataLen
+ )
+{
+ return(0);
+}
+
+/***********************************************************************/
+/* sual_CoDataReq : send Connection-oriented Data request to SUAL/SUA */
+/***********************************************************************/
+int sual_CoDataReq( sual_id_t InstId,
+ sual_id_t sual_ConnId,
+ unsigned char *pUserData,
+ uint UserDataLen
+ )
+{
+
+ unsigned int Sua_ConnId = sual_ConnId;
+ sccp_addr_str clg, cld;
+ sccp_QOS_str QOS;
+ unsigned int xsxx;
+
+ QOS.prot_class = class2;
+ QOS.in_sequence = false;
+ QOS.sequence_number = 0;
+ QOS.return_msg_on_error = 0;
+ QOS.importance = 0;
+
+ /* no source address needed */
+ clg.address_fields_present.pc = no_pc_present;
+ clg.address_fields_present.name_gt = no_name_present;
+ clg.address_fields_present.ssn_port = no_sap_present;
+ clg.address_fields_present.field_in_header = include_nothing;
+
+ /* no destinationaddres needed */
+ cld.address_fields_present.pc = no_pc_present;
+ cld.address_fields_present.name_gt = no_name_present;
+ cld.address_fields_present.ssn_port = no_sap_present;
+ cld.address_fields_present.field_in_header = include_nothing;
+
+ char *databuffer = (char *) pUserData;
+
+ xsxx = Send_sua_primitive(N_DATA_REQ,
+ Sua_ConnId,
+ QOS,
+ cld,
+ clg,
+ databuffer,
+ UserDataLen
+ );
+ return(xsxx);
+}
+
+
+/***********************************************************************/
+/* sual_DisconnReq : send Disconnect request to SUAL/SUA */
+/***********************************************************************/
+int sual_DisconnReq( sual_id_t InstId,
+ sual_id_t sual_ConnId,
+ unsigned char *pUserData,
+ uint UserDataLen
+ )
+{
+ return(0);
+}
+
+/***********************************************************************/
+/* sual_CoDataRead : read Connection-oriented Data from SUA/SUAL */
+/***********************************************************************/
+int sual_CoDataRead( sual_id_t InstId,
+ sual_id_t sual_ConnId,
+ unsigned char *pBuff,
+ uint BuffLen
+ )
+{
+ sual_save_str temp = sual_rec_msg.front();
+ sual_rec_msg.erase( sual_rec_msg.begin());
+
+ sual_ConnId = temp.user_ref;
+ InstId = temp.local_sua_id;
+ // put in supplied byte array(space is allocated beforehand by application)
+ temp.userdata.copy((char *)pBuff, temp.userdata.length(),0);
+ BuffLen = temp.userdata.length();
+ return(SUAL_OK);
+}
+
+/***********************************************************************/
+/* sual_ClDataRead : read Connectionless Data from SUA/SUAL */
+/***********************************************************************/
+int sual_ClDataRead( sual_id_t InstId,
+ sual_DataId_t DataId,
+ unsigned char *pBuff,
+ uint BuffLen
+ )
+{
+ sual_save_str temp = sual_rec_msg.front();
+ sual_rec_msg.erase( sual_rec_msg.begin());
+
+ DataId = temp.user_ref;
+ InstId = temp.local_sua_id;
+ // put in supplied byte array(space is allocated beforehand by application)
+ temp.userdata.copy((char *)pBuff, temp.userdata.length(),0);
+ BuffLen = temp.userdata.length();
+ return(SUAL_OK);
+}
+
+
+/***********************************************************************/
+/* sual_snapshot : get snapshot of sua data */
+/***********************************************************************/
+extern int sual_snapshot( unsigned char *pSnapshotFile /* if NULL: stdout */
+ )
+
+{
+ return(0);
+}
+
+// end of module sua_sual.c++
+
diff --git a/sualibrary/sua/sua_sual.h b/sualibrary/sua/sua_sual.h
new file mode 100644
index 0000000..dd92084
--- /dev/null
+++ b/sualibrary/sua/sua_sual.h
@@ -0,0 +1,459 @@
+/***************************************************************************
+ sua_sual.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_sual.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Marie-Ange
+ * "A ligth weigth version of SUA, just what the doctor ordered"
+ *
+ * Purpose: This header-file defines the SUA light interface:
+ * - SUAL address structure
+ * - SUAL Callback function
+ * - SUAL function return values
+ * and SUA light functions for:
+ * - SUAL initialisation
+ * - SUAL Connectionless data Notification
+ * - SUAL CO Connect Notification
+ * - SUAL CO Connect Confirm Notification
+ * - SUAL CO Data Notification
+ * - SUAL CO DisConnect Notification
+ * - SUAL Register Instance
+ * - SUAL Connectionless Data Request to SUA
+ * - SUAL CO Connect Request to SUA
+ * - SUAL CO Connect Confirm Request to SUA
+ * - SUAL CO Data Request to SUA
+ * - SUAL CO DisConnect Request to SUA
+ * - SUAL CO Data read from SUA
+ * - SUAL Connectionless Data read from SUA
+ */
+
+#ifndef SUA_SUAL_H
+#define SUA_SUAL_H
+
+/*
+ ***************************************************************************
+ *
+ * Module: sua_sual.h
+ *
+ * Purpose: definition of SUALight API
+ *
+ ***************************************************************************
+ */
+
+#ifdef LINUX
+ #include <unistd.h>
+#endif
+
+//#include <cdefs.h>
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#define SUAL_SUALSERVICE_NAME "sual"
+#define SUAL_SUALSERVICE_TRANSPORTPCOL "sctp"
+#define SUAL_DEF_PORTNUMBER 14002
+
+#define SUA_SCTP_PAYLOAD_PCOL_ID 0x04
+
+
+/* structures for API functions */
+typedef int sual_id_t;
+typedef unsigned short sual_port_t;
+typedef sual_id_t sual_InstId_t;
+typedef sual_id_t sual_ConnId_t;
+typedef sual_id_t sual_DataId_t;
+typedef int reason_t;
+
+#define SUAL_DEF_NOSTREAMS 127
+
+
+extern int sual_errno;
+
+
+typedef struct sual_PeerAddr {
+ int AddrType; /* predefined values for AddrType to indicate which
+ type is used in uPeerAddr: SUAL_ADDRTYPE_IPV4,
+ SUAL_ADDRTYPE_IPV6 */
+ union uPeerAddr {
+ struct in_addr ip4;
+ struct in6_addr ip6;
+ } uPeerAddr;
+} sual_PeerAddr_t;
+
+/* SUAL_ULP_CallBacks definitions */
+typedef struct sual_ULPcallbackFunctions {
+
+ void (*ConnIndNotif)( sual_id_t sual_ConnId,
+ sual_PeerAddr_t *pPeerAddr,
+ uint UserDataLen
+ );
+ void (*ConnConfNotif)( sual_id_t sual_ConnId,
+ uint UserDataLen
+ );
+ void (*CoDataIndNotif)( sual_id_t sual_ConnId,
+ uint UserDataLen
+ );
+ void (*DisconnIndNotif)( sual_id_t sual_ConnId,
+ reason_t reason,
+ uint UserDataLen
+ );
+ void (*ClDataIndNotif)( sual_id_t sual_DataId,
+ uint ControlNumer,
+ sual_PeerAddr_t *pPeerAddr,
+ uint UserDataLen
+ );
+} sual_ULPcallbackFunctions_t;
+
+
+typedef sual_ULPcallbackFunctions_t sualUif_Cbacks_t;
+
+typedef sual_ULPcallbackFunctions_t SUAL_ULP_CallBacks;
+
+typedef enum {
+ SUAL_ADDRTYPE_IPV4,
+ SUAL_ADDRTYPE_IPV6
+} sual_IpAddrType_t;
+
+
+/*
+ * API-functions
+ */
+extern int sual_init(
+ unsigned char *pConfFile
+);
+
+extern sual_InstId_t sual_RegisterSUAL_Instance(
+ sual_port_t LocalPort,
+ sual_ULPcallbackFunctions_t *pULPcallbackFunctions
+);
+
+
+sual_id_t
+sual_ConnReq(
+ sual_id_t InstId,
+ sual_PeerAddr_t *pPeerAddr,
+ unsigned char *pUserData,
+ uint UserDataLen
+);
+
+int
+sual_ConnResp(
+ sual_id_t InstId,
+ sual_id_t sual_ConnId,
+ unsigned char *pUserData,
+ uint UserDataLen
+);
+
+int
+sual_DisconnReq(
+ sual_id_t InstId,
+ sual_id_t sual_ConnId,
+ unsigned char *pUserData,
+ uint UserDataLen
+);
+
+int
+sual_CoDataRead(
+ sual_id_t InstId,
+ sual_id_t sual_ConnId,
+ unsigned char *pBuff,
+ uint BuffLen
+);
+
+int
+sual_ClDataRead(
+ sual_id_t InstId,
+ sual_DataId_t DataId,
+ unsigned char *pBuff,
+ uint BuffLen
+);
+
+
+int
+sual_CoDataReq(
+ sual_id_t InstId,
+ sual_id_t sual_ConnId,
+ unsigned char *pUserData,
+ uint UserDataLen
+);
+
+int
+sual_ClDataReq(
+ sual_id_t InstId,
+ sual_PeerAddr_t *pPeerAddr,
+ uint ControlNumber,
+ unsigned char *pUserData,
+ uint UserDataLen
+);
+
+extern int
+sual_snapshot(
+ unsigned char *pSnapshotFile /* if NULL: stdout */
+);
+
+/*====================== reasons of ulp_DisconnIndNotif: ======================*/
+
+typedef enum {
+ SUAL_DISCONN_NOMORE_STREAMS=100,
+ SUAL_DISCONN_SCTP_ASSOCIATION_LOST,
+ SUAL_DISCONN_USERDATA_NOTREAD,
+ SUAL_DISCONN_READUSERDATA_ILLPARAM,
+ SUAL_DISCONN_CO_DATAREQ_WITHOUT_PAYLOAD,
+ SUAL_DISCONN_WRONGEVENT_FROM_OTHER_PEER,
+ SUAL_DISCONN_BY_COMMUNICATION_LOST,
+ SUAL_DISCONN_BY_NETWORKSTATUSCHANGE,
+ SUAL_DISCONN_COAC_CC_NOT_IN_CONNREQ_SENT, /* new */
+ SUAL_DISCONN_BY_COAK_REF, /*new*/
+ SUAL_DISCONN_NOMEM,
+
+ SUAL_DISCONN_NOTABLE2SEND_SCTP_RELEASEREQUEST_MSG,
+
+ SUAL_DISCONN_NOTABLE2SEND_SCTP_CONNECTREQUEST_MSG,
+ SUAL_DISCONN_NOTABLE2SEND_SCTP_MSG,
+ SUAL_DISCONN_NOTABLE2SEND_SCTP_COAK_REF_MSG,
+
+ SUAL_DISCONN_SENDFAILURENOTIF, /* new */
+
+ SUAL_DISCONN_LAST
+} sual_disconnReason_t;
+
+/*====================== returns of sual-API-functions: ======================*/
+
+#define SUAL_OK 0
+
+
+typedef enum {
+ SUAL_API_RETURNS_FIRST=-1999, /* is no return */
+
+
+/*
+ * Returns of all function exept sual_init()
+ */
+ SUAL_EERR_ENTITYSTATE, /* entity error */
+ SUAL_UERR_WRONG_INSTID, /* ULP error */
+ SUAL_ERR_NOMEM, /* no more memory */
+
+/*
+ * Returns of all connection oriented api-functions
+ */
+ SUAL_UERR_NOSUCH_CONN, /* obsolete */
+ SUAL_UERR_CONNSTATE,
+ SUAL_UERR_ILLPARAM_USERDATA,/* concerning UserDataLen, pUserData */
+ SUAL_UERR_USERDATA_NOTREAD, /* new */
+
+/*
+ * sual_init()
+ */
+ SUAL_EERR_ILLPARAM, /* e.g. Null-pointer */
+ SUAL_CFG_ENOFILENAME,
+ SUAL_CFG_EOPENFILE,
+ SUAL_CFG_ENOPARAM,
+ SUAL_CFG_EPARAMVALUE,
+ SUAL_CFG_EPARAMFORMAT,
+ SUAL_CFG_EBUFFERLNG,
+ SUAL_CERR_NOLOCAL_ADDRS_IN_CONFFILE,
+ SUAL_SERR_SCTP_REGISTER, /* sctp error */
+/* new */
+ SUAL_WARN_LOCKED_REINIT,
+
+/*
+ * Returns of sual_RegisterSUAL_Instance()
+ */
+ SUAL_UERR_NULLPOINTER_CALLBACK,
+ SUAL_UERR_CBMISSING_CONCONFNOTIF,
+ SUAL_UERR_CBMISSING_CONINDNOTIF,
+ SUAL_UERR_CBMISSING_DISCONNINDNOTIF,
+ SUAL_UERR_CBMISSING_CODATAINDNOTIF,
+ SUAL_UERR_CBMISSING_CLDATAINDNOTIF,
+
+ SUAL_UERR_LOCALPORT_NOTUNIQUE,
+
+/*
+ * Returns of sual_ConnReq()
+ */
+ SUAL_UERR_NO_PEERADDR,
+ SUAL_UERR_IPV4_NOTYET,
+ SUAL_UERR_WRONG_ADDRTYPE,
+ SUAL_WARN_SHORTAGE_OF_STREAMS,
+
+/*
+ * Returns of sual_ConnResp()
+ * see common returns:
+ - SUAL_UERR_ILLPARAM_USERDATA
+ - SUAL_UERR_CONNSTATE
+ */
+
+
+/*
+ * Returns of sual_DisconnReq()
+ * see common returns:
+ - SUAL_UERR_ILLPARAM_USERDATA
+ - SUAL_UERR_CONNSTATE
+ */
+
+
+/*
+ * Returns of sual_CoDataRead() and sual_ClDataRead()
+ */
+ SUAL_UERR_MISSING_DATABUFFER,
+ SUAL_UERR_MISSING_USERDATALEN,
+ SUAL_UERR_BUFFLEN_TOOLESS,
+ /*
+ * Returns of sual_CoDataRead()
+ */
+ SUAL_UERR_WRONG_CONNID,
+ SUAL_UERR_CO_NODATA2READ,
+ /*
+ * Returns of sual_ClDataRead()
+ */
+ SUAL_UERR_WRONG_DATAID,
+ SUAL_UERR_CL_NODATA2READ, /* e.g. already read */
+
+/*
+ * Returns of sual_CoDataReq() and sual_ClDataReq()
+ */
+ SUAL_UERR_DATAREQ_MISSING_DATABUFFER, /* obsolete */
+ SUAL_UERR_DATAREQ_MISSING_USERDATALEN,/* obsolete */
+
+/*
+ * Returns of sual_ClDataReq()
+ - SUAL_UERR_NO_PEERADDR
+ - SUAL_UERR_IPV4_NOTYET
+ - SUAL_UERR_WRONG_ADDRTYPE
+ */
+ SUAL_UERR_CONTROLNUMBER_OUT_OF_RANGE,
+
+/*==============================================*/
+
+
+/*
+ * errors on LIF
+ */
+
+ SUAL_RCVCLDATATRANSFER_USERDATA_NOTREAD, /* new */
+
+ SUAL_ERR_NOSUCH_SCTP_ASSOCIATION,
+ SUAL_ERR_ULP_SSN_NOTREGISTERED,
+ SUAL_ERR_STREAMID_TOOBIG,
+ SUAL_ERR_NOMEM_TO_RECEIVE_SCTPCHUNK,
+ SUAL_ERR_FAILURE_SCTP_ASSOCIATE,
+ SUAL_ERR_WRONG_AF_INET_TYPE,
+ SUAL_ERR_SUAL_RELRE_MSG_ON_FREE_STREAM,
+ SUAL_ERR_SUAL_COAK_CC_MSG_ON_FREE_STREAM,
+ SUAL_ERR_SUAL_RELCO_MSG_ON_FREE_STREAM,
+ SUAL_ERR_SUAL_CODT_MSG_ON_FREE_STREAM,
+ SUAL_ERR_COAC_CC_NOT_IN_CONNREQ_SENT,
+ SUAL_ERR_RCV_RELCO_BUTNOTWAITING_FOR,
+
+ SUAL_SERR_NOTEXIST_DESTADDR,
+ SUAL_SERR_NOTSUPPORTED_ADDRFORMAT,
+ SUAL_SERR_WRONG_MSGTYP_ONSTREAM,
+ SUAL_SERR_WRONG_MSGLEN,
+ SUAL_SERR_WRONGEVENT_FROM_OTHER_PEER,
+ SUAL_SERR_NOMORE_STREAMS,
+ SUAL_SERR_NOTABLE2SEND_SCTP_MSG,
+
+
+
+/*
+ * Errors concerning the SUAL-message
+ */
+ SUAL_MSGERR_WRONG_PCOL_VERS=-600,
+ SUAL_MSGERR_WRONG_MSGLEN, /* new */
+ SUAL_MSGERR_LEN_TOOLESS_MSGHDR,
+ SUAL_MSGERR_UNKNOWN_MSGTYPE,
+ SUAL_MSGERR_WRONG_VALUES4SPARE,
+
+/*
+ * Errors in syslog
+ */
+ SUAL_SSN_NOTREGISTERED,
+
+/*
+ * Program errors, which should newer occur
+ */
+ SUAL_PERR_NO_SNAPSHOT_FD=-580,
+ SUAL_PERR_ASS_NOTESTABL,
+ SUAL_PERR_ASS_STATE_UNKNOWN,
+ SUAL_PERR_WRONG_STATE,
+ SUAL_PERR_ALREADY_REGISTERED,
+
+ SUAL_PERR_NULLPOINTER,
+ SUAL_PERR_PARAM_NULLPOINTER,
+
+ SUAL_PERR_NULLPOINTER_PEERADDR,
+ SUAL_PERR_NULLPOINTER_SOCKUNION,
+
+ SUAL_PERR_NULLPOINTER_INSTEL,
+ SUAL_PERR_NULLPOINTER_ASSEL,
+ SUAL_PERR_NULLPOINTER_CONNEL,
+ SUAL_PERR_NULLPOINTER_STREAMEL,
+
+ SUAL_PERR_NULLPOINTER_RCVMSG,
+ SUAL_PERR_NULLPOINTER_POIPOIRCVMSG,
+ SUAL_PERR_NULLPOINTER_USERDATA,
+
+ SUAL_PERR_WRONG_CONNID_INREAD,
+ SUAL_PERR_CONNSTATE,
+ SUAL_PERR_INCONSISTENT_LEN,
+ SUAL_PERR_NOASS_IN_CONNEL,
+ SUAL_PERR_ARG_IS_NULL_POINTER,
+
+ SUAL_PERR_WRONG_ASS_STATE,
+ SUAL_PERR_WRONG_EVENT_ONFREESTREAM,
+ SUAL_PERR_NOSUCH_SCTPASSOC,
+
+ /* 19.06.2001: additional errors: */
+ /* sual_init(): */
+ SUAL_SERR_SYSTEMFUNCTION,
+ SUAL_PERR_ERROR,
+ SUAL_CFG_ERROR,
+
+ SUAL_LAST_RET_VALUE
+} sual_api_returns_t;
+
+#endif // SUA_SUAL_H
+
+// end of module sua_sual.h
diff --git a/sualibrary/sua/sua_syntax.cpp b/sualibrary/sua/sua_syntax.cpp
new file mode 100644
index 0000000..f7d67f4
--- /dev/null
+++ b/sualibrary/sua/sua_syntax.cpp
@@ -0,0 +1,4733 @@
+/***************************************************************************
+ sua_syntax.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_syntax.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 8.
+ *
+ * Author(s): Gery Verwimp
+ * Lode Coene
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Dorine
+ * "route some msg and get a hug from the Easter bunny."
+ * "question: which bunny, the right one , the left one or both "
+ * "(and don't forget to apply the KISS (ME *) methodology)"
+ *
+ * Purpose: This header-file defines the SUA syntax class for SUA
+ * primitives and messages, including the en/decoding routines.
+ */
+
+#include "sua_syntax.h"
+#include <iostream>
+#include <iomanip>
+using namespace std;
+
+/********************************************************************/
+/* General error structure, returned by main en/decoder */
+/********************************************************************/
+
+Sua_syntax_error_struct SYNTAX_ERR;
+
+/********************************************************************/
+/* General purpose overlay structure, used everywhere */
+/********************************************************************/
+
+union Four_bytes_overlay {
+ uint32_t dq;
+ uint16_t dw[2];
+ uint8_t db[4];
+};
+
+Four_bytes_overlay OVERLAY;
+
+/********************************************************************/
+/* Sua_container method sua_init : Initialize SUA container element */
+/********************************************************************/
+
+void Sua_container::sua_init () {
+ /* Initialize primitive */
+ /* Initialize SUA header */
+ sua_prim.hdr_version = Sua_unknown;
+ sua_prim.hdr_msg_class = sua_mngt;
+ sua_prim.hdr_msg_type.mngt = mngt_error;
+ /* Initialize every boolean parameter to FALSE */
+ sua_prim.data_pres = FALSE;
+ sua_prim.info_pres = FALSE;
+ sua_prim.rout_con_pres = FALSE;
+ sua_prim.diag_info_pres = FALSE;
+ sua_prim.hb_data_pres = FALSE;
+ sua_prim.traf_mode_pres = FALSE;
+ sua_prim.err_code_pres = FALSE;
+ sua_prim.status_pres = FALSE;
+ sua_prim.cong_lvl_pres = FALSE;
+ sua_prim.ASP_id_pres = FALSE;
+ sua_prim.aff_pc_pres = FALSE;
+ sua_prim.hop_count_pres = FALSE;
+ sua_prim.source_addr_pres = FALSE;
+ sua_prim.dest_addr_pres = FALSE;
+ sua_prim.source_ref_pres = FALSE;
+ sua_prim.dest_ref_pres = FALSE;
+ sua_prim.SCCP_cause_pres = FALSE;
+ sua_prim.seq_nr_pres = FALSE;
+ sua_prim.rec_seq_nr_pres = FALSE;
+ sua_prim.asp_cap_pres = FALSE;
+ sua_prim.credit_pres = FALSE;
+ sua_prim.importance_pres = FALSE;
+ sua_prim.prot_class_pres = FALSE;
+ sua_prim.seq_control_pres = FALSE;
+ sua_prim.segm_pres = FALSE;
+ sua_prim.TID_label_pres = FALSE;
+ sua_prim.DRN_label_pres = FALSE;
+ sua_prim.dest_addr.ssn_incl = FALSE;
+ sua_prim.dest_addr.gt_incl = FALSE;
+ sua_prim.dest_addr.pc_incl = FALSE;
+ sua_prim.dest_addr.pc_pres = FALSE;
+ sua_prim.dest_addr.ip_addr_pres = FALSE;
+ sua_prim.dest_addr.gt_pres = FALSE;
+ sua_prim.dest_addr.hostname_pres = FALSE;
+ sua_prim.source_addr.ssn_incl = FALSE;
+ sua_prim.source_addr.gt_incl = FALSE;
+ sua_prim.source_addr.pc_incl = FALSE;
+ sua_prim.source_addr.pc_pres = FALSE;
+ sua_prim.source_addr.ip_addr_pres = FALSE;
+ sua_prim.source_addr.gt_pres = FALSE;
+ sua_prim.source_addr.hostname_pres = FALSE;
+ /* The message string is NOT explicitly initialized !! */
+}
+
+/********************************************************************/
+/* Sua_container method sua_encode : Encode primitive */
+/********************************************************************/
+
+/* The encoder function expects a valid local syntax (sua_prim)
+ and returns the transfer syntax (message) in the sua_msg string field.
+ A number of plausibility checks are done :
+ - mandatory parameters (depending on msg type and class) must be present
+ - parameters which are not applicable are ignored, even when present
+ - parameters are checked on validity (range, compatibility with other parameters)
+*/
+
+/* 1. Definition of encoding procedures */
+/* 1.1 Parameter encoding procedures */
+
+/* 1.1.1 Common parameters */
+
+boolean encode_netw_app (string& msg, uint32_t netw_app) {
+ /* Kept for RK syntax */
+ /* Reserve 8 bytes */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x010D);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ OVERLAY.dq = htonl(netw_app);
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_data (string& msg, string& data) {
+ /* Reserve 4 bytes for tag and length */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 4);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0003);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length */
+ OVERLAY.dw[1] = htons(data.size() + 4);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ /* Encode data */
+ if (data.size() > 0) {
+ msg += data;
+ /* Encode possible padding bytes */
+ if ((data.size() % 4) != 0) {
+ OVERLAY.db[0] = 0; // padding byte is zero
+ int nr_of_pad = 4 - (data.size() % 4);
+ for (int i = 0; i < nr_of_pad; i++)
+ msg += OVERLAY.db[0];
+ }
+ return TRUE;
+ }
+ else {
+ /* Signal error : empty parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Empty Data parameter";
+ return FALSE;
+ }
+}
+
+boolean encode_ASP_id (string& msg, uint32_t asp_id) {
+ /* Reserve 4 bytes for tag and length */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0011);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode data */
+ OVERLAY.dq = htonl(asp_id);
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+
+ return TRUE;
+
+}
+
+boolean encode_info (string& msg, string& info) {
+ /* Reserve 4 bytes for tag and length */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 4);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0004);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length */
+ OVERLAY.dw[1] = htons(info.size() + 4);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ /* Encode data */
+ if (info.size() > 0) {
+ msg += info;
+ /* Encode possible padding bytes */
+ if ((info.size() % 4) != 0) {
+ OVERLAY.db[0] = 0; // padding byte is zero
+ int nr_of_pad = 4 - (info.size() % 4);
+ for (int i = 0; i < nr_of_pad; i++)
+ msg += OVERLAY.db[0];
+ }
+ return TRUE;
+ }
+ else {
+ /* Signal error : empty parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Empty Info parameter";
+ return FALSE;
+ }
+}
+
+boolean encode_rout_con (string& msg, uint32_t routing_ctxt) {
+ /* Reserve 8 bytes for routing context */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0006);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ OVERLAY.dq = htonl(routing_ctxt);
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_diag_info (string& msg, string& diag_info) {
+ /* Reserve 4 bytes for tag and length */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 4);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0007);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length */
+ OVERLAY.dw[1] = htons(diag_info.size() + 4);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ /* Encode data */
+ if (diag_info.size() > 0) {
+ msg += diag_info;
+ /* Encode possible padding bytes */
+ if ((diag_info.size() % 4) != 0) {
+ OVERLAY.db[0] = 0; // padding byte is zero
+ int nr_of_pad = 4 - (diag_info.size() % 4);
+ for (int i = 0; i < nr_of_pad; i++)
+ msg += OVERLAY.db[0];
+ }
+ return TRUE;
+ }
+ else {
+ /* Signal error : empty parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Empty Diagnostics Info parameter";
+ return FALSE;
+ }
+}
+
+boolean encode_hb_data (string& msg, string& hb_data) {
+ /* Reserve 4 bytes for tag and length */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 4);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0009);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length */
+ OVERLAY.dw[1] = htons(hb_data.size() + 4);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ /* Encode data */
+ if (hb_data.size() > 0) {
+ msg += hb_data;
+ /* Encode possible padding bytes */
+ if ((hb_data.size() % 4) != 0) {
+ OVERLAY.db[0] = 0; // padding byte is zero
+ int nr_of_pad = 4 - (hb_data.size() % 4);
+ for (int i = 0; i < nr_of_pad; i++)
+ msg += OVERLAY.db[0];
+ }
+ return TRUE;
+ }
+ else {
+ /* Signal error : empty parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Empty Heartbeat data parameter";
+ return FALSE;
+ }
+}
+
+boolean encode_traf_mode (string& msg, Sua_traffic_mode_type traffic_mt) {
+ /* Reserve 8 bytes for traffic mode type */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x000B);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ /* Check traffic mode type */
+ if (traffic_mt < tmt_max) {
+ OVERLAY.dq = htonl(uint32_t(traffic_mt));
+ for (int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid Traffic Mode";
+ return FALSE;
+ }
+}
+
+boolean encode_error_code (string& msg, Sua_error_code_type err_code) {
+ /* Reserve 8 bytes for error code type */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x000C);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ /* Check error code type */
+ if (err_code < ect_max) {
+ OVERLAY.dq = htonl(uint32_t(err_code));
+ for (int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid Error Code";
+ return FALSE;
+ }
+}
+
+/* 1.1.2 SUA specific parameters */
+
+boolean encode_hop_count (string& msg, uint8_t hop_count) {
+ /* Reserve 8 bytes for hop count */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0101);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ for(int i = 0; i < 3; i++)
+ msg[pdu_index + i] = 0; // spare bytes
+ pdu_index += 3; // value
+ if (hop_count < 16)
+ msg[pdu_index] = hop_count;
+ else {
+ /* Signal error : parameter out of range */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Hop counter too high";
+ return FALSE;
+ }
+ return TRUE;
+}
+
+boolean encode_addr (string& msg, Sua_address_struct& address) {
+ /* Encode address parameters */
+ /* Reserve 4 bytes for routing and address indicator */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 4);
+ /* Routing indicator : in this version only route on IP, hostname and SSN is allowed */
+ if ((address.rout_ind != ri_route_IP_SSN) &&
+ (address.rout_ind != ri_route_PC_SSN) &&
+ (address.rout_ind != ri_route_hostname)) {
+ /* Signal error : invalid routing indicator used */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid routing indicator";
+ return FALSE;
+ }
+ OVERLAY.dw[0] = htons(address.rout_ind);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Address indicator : depending on routing indicator, we set the appropriate flags */
+ OVERLAY.dw[0] = 0; // Include nothing
+ if ((address.rout_ind == ri_route_PC_SSN) || (address.rout_ind == ri_route_IP_SSN) || (address.ssn_incl))
+ OVERLAY.db[0] |= 0x01;
+ if (address.pc_incl)
+ OVERLAY.db[0] |= 0x02;
+ if ((address.rout_ind == ri_route_GT) || (address.gt_incl))
+ OVERLAY.db[0] |= 0x04;
+ OVERLAY.dw[0] = htons(OVERLAY.dw[0]);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Address element checks : when routing on
+ - GT, a GT must be present
+ - SSN, either an IP address or PC must be present; these may never appear together
+ - hostname, a hostname must be present
+ Currently, we only allow SSN + IP address or hostname
+ */
+ /* Reserve 8 bytes for SSN address parameter */
+ msg.resize(pdu_index + 8);
+ /* Encode SSN tag */
+ OVERLAY.dw[0] = htons(0x8003);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode SSN length : always 8 bytes, no padding */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode SSN value */
+ for(int i = 0; i < 3; i++)
+ msg[pdu_index + i] = 0; // spare bytes
+ pdu_index += 3; // value
+ msg[pdu_index] = address.ssn;
+ pdu_index++; // next tag
+ /* Encode IP address or hostname */
+ char* pdu_c;
+ if (address.ip_addr_pres) {
+ /* Check type */
+ switch (address.ip_addr_type) {
+ case short(ip_v4) :
+ /* An IPv4 address is 4 bytes long (NBO), so reserve 8 bytes */
+ msg.resize(pdu_index + 8);
+ OVERLAY.dw[0] = htons(0x8004);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ OVERLAY.dq = address.ip_addr.ipv4.sin_addr.s_addr;
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ break;
+ case short(ip_v6) :
+ /* An IPv6 address is 16 bytes long (NBO), so reserve 20 bytes */
+ msg.resize(pdu_index + 20);
+ OVERLAY.dw[0] = htons(0x8006);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ OVERLAY.dw[1] = htons(20);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ pdu_c = (char*) &address.ip_addr.ipv6.sin6_addr.s6_addr;
+ for(int i = 0; i < 16; i++) {
+ msg[pdu_index + i] = *pdu_c;
+ pdu_c++;
+ }
+ pdu_index += 16; // next tag
+ break;
+ default : {
+ /* Signal error : invalid IP address type */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid IP address type";
+ return FALSE;
+ }
+ } // End switch IP type
+ } // Endif
+ else if (address.pc_pres) {
+ /* An point code address is 4 bytes long (NBO), so reserve 8 bytes */
+ msg.resize(pdu_index + 8);
+ OVERLAY.dw[0] = htons(0x8002);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ OVERLAY.dq = address.pc;
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[3-i];
+
+ } // Endif
+ else if (address.hostname_pres){
+ msg.resize(pdu_index + address.hostname.length() + 2 + 4);
+ OVERLAY.dw[0] = htons(0x8005);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ OVERLAY.dw[1] = htons(address.hostname.length() + 6);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+
+ string name_str;
+ int numchar = 0;
+ int i,first= 0; /* start of name array */
+ int last= address.hostname.size();
+ unsigned int current = address.hostname.find('.');
+ while(current != string::npos)
+ {
+ /* determine the length of each label(except the last)*/
+ numchar = current - first;
+ /* copy length of label into PDU */
+ OVERLAY.dw[0] = numchar;
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ /* copy the label in the PDU */
+ for (i=0; i < numchar; i++) {
+ OVERLAY.dw[0] = address.hostname[first + i];
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ }
+ first= current + 1;
+ current = address.hostname.find('.', first);
+ }
+ /* determine lenght of last label */
+ numchar = last - first;
+ OVERLAY.dw[0] = numchar;
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ for (i=0; i < numchar; i++) {
+ OVERLAY.dw[0] = address.hostname[first + i];
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ }
+ /* end of hostname */
+ msg[pdu_index] = htons(0x00);
+ pdu_index++;
+ /* padding out up a 32 bit boundary */
+ int mod_nr = 0;
+ if ((mod_nr = pdu_index % 4) != 0)
+ {
+ for (i=0; i < (4 - mod_nr); i++) {
+ OVERLAY.dw[0] = htons(0x0000);;
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ }
+ }
+ }
+ else {
+ /* Signal error : IP address missing */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Address parameter missing";
+ return FALSE;
+ }
+ return TRUE;
+}
+
+boolean encode_src_addr (string& msg, Sua_address_struct& address) {
+ boolean no_error = TRUE;
+ /* Reserve extra 4 bytes for tag, length */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 4);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0102);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Lenght is encoded when known, at the end */
+ /* Encode value */
+ no_error = encode_addr (msg, address);
+ if (no_error) {
+ /* Encode length : calculate as current size - pdu_index + 2 (tag) */
+ OVERLAY.dw[1] = htons(msg.size() - pdu_index + 2);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ }
+ return no_error;
+}
+
+boolean encode_dest_addr (string& msg, Sua_address_struct& address) {
+ boolean no_error = TRUE;
+ /* Reserve extra 4 bytes for tag, length */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 4);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0103);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Lenght is encoded when known, at the end */
+ /* Encode value */
+ no_error = encode_addr (msg, address);
+ if (no_error) {
+ /* Encode length : calculate as current size - pdu_index + 2 (tag) */
+ OVERLAY.dw[1] = htons(msg.size() - pdu_index + 2);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ }
+ return no_error;
+}
+
+boolean encode_source_ref (string& msg, uint32_t src_ref) {
+ /* Reserve 8 bytes for source reference */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0104);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ OVERLAY.dq = htonl(src_ref);
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_dest_ref (string& msg, uint32_t dest_ref) {
+ /* Reserve 8 bytes for destination reference */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0105);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ OVERLAY.dq = htonl(dest_ref);
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_SCCP_cause (string& msg, SCCP_cause_struct cause) {
+ /* Reserve 8 bytes */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0106);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value : 2 spare bytes, then cause type and value */
+ OVERLAY.dw[0] = 0;
+ OVERLAY.db[2] = uint8_t(cause.cause_type);
+ OVERLAY.db[3] = cause.cause_value;
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_seq_nr (string& msg, Sua_seq_nr_struct seq_nr) {
+ /* Reserve 8 bytes for sequence number */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0107);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value : 2 spare bytes, then received seq nr, more data flag and sent seq nr */
+ OVERLAY.dw[0] = 0;
+ OVERLAY.db[2] = 0; // No rcvd seq nr, only more data flag will be set
+ OVERLAY.db[3] = 0; // No sent seq nr for protocol class 2
+ if (seq_nr.more_data)
+ OVERLAY.db[2] |= 0x01;
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_asp_cap (string& msg, Sua_asp_cap_struct asp_cap) {
+ /* Reserve 8 bytes for ASP capabilities */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0109);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ msg[pdu_index] = 0; // spare byte
+ pdu_index++;
+ msg[pdu_index] = 0; // spare byte
+ pdu_index++;
+ OVERLAY.db[0] = 0; // clear byte
+ /* Protocol class 0 is always supported */
+ OVERLAY.db[0] |= 0x01;
+ if (asp_cap.cl1_supp)
+ OVERLAY.db[0] |= 0x02;
+ if (asp_cap.cl2_supp)
+ OVERLAY.db[0] |= 0x04;
+ if (asp_cap.cl3_supp)
+ OVERLAY.db[0] |= 0x08;
+ msg[pdu_index] = OVERLAY.db[0]; // Supported protocol classes
+ pdu_index++;
+ /* Check interworking type */
+ if (asp_cap.interworking < iw_max) {
+ msg[pdu_index] = uint8_t(asp_cap.interworking);
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid Interworking type";
+ return FALSE;
+ }
+}
+
+boolean encode_seq_ctrl (string& msg, uint32_t seq_ctrl) {
+ /* Reserve 8 bytes for sequence control */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0116);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ OVERLAY.dq = htonl(seq_ctrl);
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_importance (string& msg, uint8_t importance) {
+ /* Reserve 8 bytes for importance */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0113);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ for(int i = 0; i < 3; i++)
+ msg[pdu_index + i] = 0; // spare bytes
+ pdu_index += 3; // value
+ if (importance < 8)
+ msg[pdu_index] = importance;
+ else {
+ /* Signal error : parameter out of range */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Importance too high";
+ return FALSE;
+ }
+ return TRUE;
+}
+
+boolean encode_prot_class (string& msg, Sua_protocol_class_struct pr_cl) {
+ /* Reserve 8 bytes for protocol class */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0115);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ for(int i = 0; i < 3; i++)
+ msg[pdu_index + i] = 0; // spare bytes
+ pdu_index += 3; // value
+ /* Encode protocol class and special options */
+ if (pr_cl.pcl < prot_max) {
+ OVERLAY.db[0] = uint8_t(pr_cl.pcl);
+ if ((pr_cl.return_option) && ((pr_cl.pcl == prot_class_0) || (pr_cl.pcl == prot_class_1)))
+ OVERLAY.db[0] |= 0x80; // Set return on error flag
+ }
+ else {
+ /* Signal error : invalid parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid Protocol Class";
+ return FALSE;
+ }
+ msg[pdu_index] = OVERLAY.db[0];
+ return TRUE;
+}
+
+boolean encode_segmentation (string& msg, Sua_segm_struct segments) {
+ /* Reserve 8 bytes for segmentation parameter */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0117);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ OVERLAY.dq = htonl(segments.segm_ref);
+ if (OVERLAY.db[0] == 0) {
+ if (segments.remain < 16) {
+ OVERLAY.db[0] = segments.remain;
+ if (segments.first)
+ OVERLAY.db[0] |= 0x80; // Set first segment flag
+ }
+ else {
+ /* Signal error : parameter out of range */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Remaining segments too high";
+ return FALSE;
+ }
+ }
+ else {
+ /* Signal error : parameter out of range */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Segmentation reference out of range";
+ return FALSE;
+ }
+ /* Copy into message */
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_TID_label (string& msg, Sua_label_struct TID_label) {
+ /* Reserve 8 bytes for TID label */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x0119);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ int max_label = 2;
+ if ((TID_label.start < 32) && (TID_label.start >= TID_label.end) && ((TID_label.start - TID_label.end) < 16)) {
+ for (int i = 0; i < (TID_label.start - TID_label.end); i++)
+ max_label = max_label * 2;
+ if (TID_label.label_value < max_label) {
+ OVERLAY.db[0] = TID_label.start;
+ OVERLAY.db[1] = TID_label.end;
+ OVERLAY.dw[1] = htons(TID_label.label_value);
+ }
+ else {
+ /* Signal error : paramater syntax error */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid TID label";
+ return FALSE;
+ }
+ }
+ else {
+ /* Signal error : parameter syntax error */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid TID label position or length";
+ return FALSE;
+ }
+ /* Copy into message */
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+boolean encode_DRN_label (string& msg, Sua_label_struct DRN_label) {
+ /* Reserve 8 bytes for DRN label */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x011A);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value */
+ int max_label = 2;
+ if ((DRN_label.start < 32) && (DRN_label.start >= DRN_label.end) && ((DRN_label.start - DRN_label.end) < 16)) {
+ for (int i = 0; i < (DRN_label.start - DRN_label.end); i++)
+ max_label = max_label * 2;
+ if (DRN_label.label_value < max_label) {
+ OVERLAY.db[0] = DRN_label.start;
+ OVERLAY.db[1] = DRN_label.end;
+ OVERLAY.dw[1] = htons(DRN_label.label_value);
+ }
+ else {
+ /* Signal error : paramater syntax error */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid DRN label";
+ return FALSE;
+ }
+ }
+ else {
+ /* Signal error : parameter syntax error */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Encoding : Invalid DRN label position or length";
+ return FALSE;
+ }
+ /* Copy into message */
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = OVERLAY.db[i];
+ return TRUE;
+}
+
+/* 1.2 Message encoding procedures */
+
+/* 1.2.3 ASP Server Management messages */
+
+boolean encode_ASP_up_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - ASP Identifier (dynamic assignment not supported)
+ - Info string
+ */
+ boolean no_error = TRUE;
+ if (prim.ASP_id_pres)
+ no_error = encode_ASP_id (msg, prim.ASP_id);
+ if (prim.info_pres)
+ no_error = encode_info (msg, prim.info_string);
+ return no_error;
+}
+
+boolean encode_ASP_down_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - Info string
+ */
+ boolean no_error = TRUE;
+ if (prim.info_pres)
+ no_error = encode_info (msg, prim.info_string);
+ return no_error;
+}
+
+boolean encode_ASP_beat_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - Heartbeat data
+ */
+ boolean no_error = TRUE;
+ if (prim.hb_data_pres)
+ no_error = encode_hb_data (msg, prim.hb_data);
+ return no_error;
+}
+
+boolean encode_ASP_up_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - ASP Identifier (dynamic assignment not supported)
+ - Info string
+ */
+ boolean no_error = TRUE;
+ if (prim.info_pres)
+ no_error = encode_info (msg, prim.info_string);
+ return no_error;
+}
+
+boolean encode_ASP_down_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - Info string
+ */
+ boolean no_error = TRUE;
+ if (prim.info_pres)
+ no_error = encode_info (msg, prim.info_string);
+ return no_error;
+}
+
+boolean encode_ASP_beat_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - Heartbeat data
+ */
+ boolean no_error = TRUE;
+ if (prim.hb_data_pres)
+ no_error = encode_hb_data (msg, prim.hb_data);
+ return no_error;
+}
+
+/* 1.2.4 ASP Traffic Management messages */
+
+boolean encode_ASP_act_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - Traffic mode type
+ - Routing context
+ - TID label
+ - DRN label
+ - Info string
+ */
+ boolean no_error = TRUE;
+ if (prim.traf_mode_pres)
+ no_error = encode_traf_mode (msg, prim.traf_mode);
+ if (prim.rout_con_pres && no_error)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.TID_label_pres && no_error)
+ no_error = encode_TID_label (msg, prim.TID_label);
+ if (prim.DRN_label_pres && no_error)
+ no_error = encode_DRN_label (msg, prim.DRN_label);
+ if (prim.info_pres && no_error)
+ no_error = encode_info (msg, prim.info_string);
+ return no_error;
+}
+
+boolean encode_ASP_inact_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - Routing context
+ - Info string
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.info_pres && no_error)
+ no_error = encode_info (msg, prim.info_string);
+ return no_error;
+}
+
+boolean encode_ASP_act_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - Traffic mode type
+ - Routing context
+ - Info string
+ */
+ boolean no_error = TRUE;
+ if (prim.traf_mode_pres)
+ no_error = encode_traf_mode (msg, prim.traf_mode);
+ if (prim.rout_con_pres && no_error)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.info_pres && no_error)
+ no_error = encode_info (msg, prim.info_string);
+ return no_error;
+}
+
+boolean encode_ASP_inact_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters are optional :
+ - Routing context
+ - Info string
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.info_pres && no_error)
+ no_error = encode_info (msg, prim.info_string);
+ return no_error;
+}
+
+/* 1.2.7 Connectionless messages */
+
+boolean encode_cl_data_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Protocol class
+ - Source address
+ - Destination address
+ - Sequence control
+ - Data
+ Following parameters are optional :
+ - Routing context
+ - Hop count
+ - Importance
+ - Message priority (we don't use it)
+ - Correlation ID (we don't use Broadcast mode)
+ - Segmentation
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.prot_class_pres && no_error) {
+ /* Protocol class must be 0 or 1 */
+ if ((prim.prot_class.pcl == prot_class_0) || (prim.prot_class.pcl == prot_class_1))
+ no_error = encode_prot_class (msg, prim.prot_class);
+ else {
+ /* Signal error : invalid parameter */
+ SYNTAX_ERR.msg_index = msg.size();
+ SYNTAX_ERR.error_text = "Encoding : Invalid protocol class for connectionless msg";
+ return FALSE;
+ }
+ }
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Protocol class parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.source_addr_pres && no_error)
+ no_error = encode_src_addr (msg, prim.source_addr);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Source address parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.dest_addr_pres && no_error)
+ no_error = encode_dest_addr (msg, prim.dest_addr);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination address parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.seq_control_pres && no_error)
+ no_error = encode_seq_ctrl (msg, prim.seq_control);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Sequence control parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.hop_count_pres && no_error)
+ no_error = encode_hop_count (msg, prim.hop_count);
+ if (prim.importance_pres && no_error)
+ no_error = encode_importance (msg, prim.importance);
+ if (prim.segm_pres && no_error)
+ no_error = encode_segmentation (msg, prim.segm);
+ if (prim.data_pres && no_error)
+ no_error = encode_data (msg, prim.data_string);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Data parameter missing";
+ return FALSE;
+ }
+ }
+ return no_error;
+}
+
+boolean encode_cl_data_resp_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - SCCP Cause
+ - Source address
+ - Destination address
+ Following parameters are optional :
+ - Routing context
+ - Hop count
+ - Importance
+ - Message priority (we don't use it)
+ - Correlation ID (we don't use Broadcast mode)
+ - Data
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.SCCP_cause_pres && no_error) {
+ /* Cause type must be return cause */
+ prim.SCCP_cause.cause_type = ctp_return_cause;
+ no_error = encode_SCCP_cause (msg, prim.SCCP_cause);
+ }
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : SCCP cause parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.source_addr_pres && no_error)
+ no_error = encode_src_addr (msg, prim.source_addr);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Source address parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.dest_addr_pres && no_error)
+ no_error = encode_dest_addr (msg, prim.dest_addr);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination address parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.hop_count_pres && no_error)
+ no_error = encode_hop_count (msg, prim.hop_count);
+ if (prim.importance_pres && no_error)
+ no_error = encode_importance (msg, prim.importance);
+ if (prim.data_pres && no_error)
+ no_error = encode_data (msg, prim.data_string);
+ return no_error;
+}
+
+/* 1.2.8 Connection-oriented messages */
+/* Only protocol class 2 messages are supported */
+
+boolean encode_co_conn_req_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Protocol class
+ - Source reference
+ - Destination address
+ - Sequence control
+ Following parameters are optional :
+ - Routing context
+ - Source address
+ - Hop count
+ - Importance
+ - Message priority (we don't use it)
+ - Credit (no support for protocol class 3)
+ - Data
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.prot_class_pres && no_error) {
+ /* Return option not applicable */
+ prim.prot_class.return_option = FALSE;
+ /* Protocol class must be 2 or 3 */
+ if ((prim.prot_class.pcl == prot_class_2) || (prim.prot_class.pcl == prot_class_3))
+ no_error = encode_prot_class (msg, prim.prot_class);
+ else {
+ /* Signal error : invalid parameter */
+ SYNTAX_ERR.msg_index = msg.size();
+ SYNTAX_ERR.error_text = "Encoding : Invalid protocol class for connection-oriented msg";
+ return FALSE;
+ }
+ }
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Protocol class parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.source_ref_pres && no_error)
+ no_error = encode_source_ref (msg, prim.source_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Source Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.dest_addr_pres && no_error)
+ no_error = encode_dest_addr (msg, prim.dest_addr);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination address parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.seq_control_pres && no_error)
+ no_error = encode_seq_ctrl (msg, prim.seq_control);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Sequence control parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.source_addr_pres && no_error)
+ no_error = encode_src_addr (msg, prim.source_addr);
+ if (prim.hop_count_pres && no_error)
+ no_error = encode_hop_count (msg, prim.hop_count);
+ if (prim.importance_pres && no_error)
+ no_error = encode_importance (msg, prim.importance);
+ if (prim.data_pres && no_error)
+ no_error = encode_data (msg, prim.data_string);
+ return no_error;
+}
+
+boolean encode_co_conn_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Protocol class
+ - Destination reference
+ - Source reference
+ Following parameters are optional :
+ - Routing context
+ - Destination address
+ - Importance
+ - Message priority (we don't use it)
+ - Credit (no support for protocol class 3)
+ - Data
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.prot_class_pres && no_error) {
+ /* Return option not applicable */
+ prim.prot_class.return_option = FALSE;
+ /* Protocol class must be 2 or 3 */
+ if ((prim.prot_class.pcl == prot_class_2) || (prim.prot_class.pcl == prot_class_3))
+ no_error = encode_prot_class (msg, prim.prot_class);
+ else {
+ /* Signal error : invalid parameter */
+ SYNTAX_ERR.msg_index = msg.size();
+ SYNTAX_ERR.error_text = "Encoding : Invalid protocol class for connection-oriented msg";
+ return FALSE;
+ }
+ }
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Protocol class parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.dest_ref_pres && no_error)
+ no_error = encode_dest_ref (msg, prim.dest_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.source_ref_pres && no_error)
+ no_error = encode_source_ref (msg, prim.source_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Source Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.dest_addr_pres && no_error)
+ no_error = encode_dest_addr (msg, prim.dest_addr);
+ if (prim.importance_pres && no_error)
+ no_error = encode_importance (msg, prim.importance);
+ if (prim.data_pres && no_error)
+ no_error = encode_data (msg, prim.data_string);
+ return no_error;
+}
+
+boolean encode_co_conn_ref_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Destination reference
+ - SCCP cause
+ Following parameters are optional :
+ - Routing context
+ - Destination address
+ - Importance
+ - Data
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.dest_ref_pres && no_error)
+ no_error = encode_dest_ref (msg, prim.dest_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.SCCP_cause_pres && no_error) {
+ /* Cause type must be refusal cause */
+ prim.SCCP_cause.cause_type = ctp_refusal_cause;
+ no_error = encode_SCCP_cause (msg, prim.SCCP_cause);
+ }
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : SCCP Cause parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.dest_addr_pres && no_error)
+ no_error = encode_dest_addr (msg, prim.dest_addr);
+ if (prim.importance_pres && no_error)
+ no_error = encode_importance (msg, prim.importance);
+ if (prim.data_pres && no_error)
+ no_error = encode_data (msg, prim.data_string);
+ return no_error;
+}
+
+boolean encode_co_rel_req_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Destination reference
+ - Source reference
+ - SCCP cause
+ Following parameters are optional :
+ - Routing context
+ - Importance
+ - Data
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.dest_ref_pres && no_error)
+ no_error = encode_dest_ref (msg, prim.dest_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.source_ref_pres && no_error)
+ no_error = encode_source_ref (msg, prim.source_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Source Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.SCCP_cause_pres && no_error) {
+ /* Cause type must be release cause */
+ prim.SCCP_cause.cause_type = ctp_release_cause;
+ no_error = encode_SCCP_cause (msg, prim.SCCP_cause);
+ }
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : SCCP Cause parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.importance_pres && no_error)
+ no_error = encode_importance (msg, prim.importance);
+ if (prim.data_pres && no_error)
+ no_error = encode_data (msg, prim.data_string);
+ return no_error;
+}
+
+boolean encode_co_rel_conf_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Destination reference
+ - Source reference
+ Following parameters are optional :
+ - Routing context
+ - Importance
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.dest_ref_pres && no_error)
+ no_error = encode_dest_ref (msg, prim.dest_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.source_ref_pres && no_error)
+ no_error = encode_source_ref (msg, prim.source_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Source Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.importance_pres && no_error)
+ no_error = encode_importance (msg, prim.importance);
+ return no_error;
+}
+
+boolean encode_co_data_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Sequence number
+ - Destination reference
+ - Data
+ Following parameters are optional :
+ - Routing context
+ - Message priority (we don't use it)
+ - Correlation ID (we don't support Broadcast mode)
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.seq_nr_pres && no_error) {
+ /* Sent and received sequence number don't apply */
+ prim.seq_nr.sent_seq_nr = 0;
+ prim.seq_nr.rcvd_seq_nr = 0;
+ no_error = encode_seq_nr (msg, prim.seq_nr);
+ }
+ else {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Sequence number parameter missing";
+ return FALSE;
+ }
+ if (prim.dest_ref_pres && no_error)
+ no_error = encode_dest_ref (msg, prim.dest_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.data_pres && no_error)
+ no_error = encode_data (msg, prim.data_string);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Data parameter missing";
+ return FALSE;
+ }
+ }
+ return no_error;
+}
+
+boolean encode_co_err_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Destination reference
+ - SCCP cause
+ Following parameters are optional :
+ - Routing context
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.dest_ref_pres && no_error)
+ no_error = encode_dest_ref (msg, prim.dest_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.SCCP_cause_pres && no_error) {
+ /* Cause type must be error cause */
+ prim.SCCP_cause.cause_type = ctp_error_cause;
+ no_error = encode_SCCP_cause (msg, prim.SCCP_cause);
+ }
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : SCCP Cause parameter missing";
+ return FALSE;
+ }
+ }
+ return no_error;
+}
+
+boolean encode_co_it_msg (Sua_primitive_struct& prim, string& msg) {
+ /* Following parameters MUST be present :
+ - Protocol class
+ - Destination reference
+ - Source reference
+ - Sequence number (coded zero for protocol class 2)
+ - Credit (coded zero for protocol class 2)
+ Following parameters are optional :
+ - Routing context
+ */
+ boolean no_error = TRUE;
+ if (prim.rout_con_pres)
+ no_error = encode_rout_con (msg, prim.rout_con);
+ if (prim.prot_class_pres && no_error) {
+ /* Return option not applicable */
+ prim.prot_class.return_option = FALSE;
+ /* Protocol class is set to 2 */
+ prim.prot_class.pcl = prot_class_2;
+ no_error = encode_prot_class (msg, prim.prot_class);
+ }
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Protocol class parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.dest_ref_pres)
+ no_error = encode_dest_ref (msg, prim.dest_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Destination Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (prim.source_ref_pres && no_error)
+ no_error = encode_source_ref (msg, prim.source_ref);
+ else {
+ if (no_error) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Encoding : Source Reference parameter missing";
+ return FALSE;
+ }
+ }
+ if (no_error) {
+ prim.seq_nr.sent_seq_nr = 0;
+ prim.seq_nr.rcvd_seq_nr = 0;
+ prim.seq_nr.more_data = FALSE;
+ no_error = encode_seq_nr (msg, prim.seq_nr);
+ }
+ if (no_error) {
+ prim.credit = 0;
+ /* Reserve 8 bytes */
+ int pdu_index = msg.size();
+ msg.resize(pdu_index + 8);
+ /* Encode tag */
+ OVERLAY.dw[0] = htons(0x010A);
+ msg[pdu_index] = OVERLAY.db[0];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[1];
+ pdu_index++;
+ /* Encode length, always 8 bytes */
+ OVERLAY.dw[1] = htons(8);
+ msg[pdu_index] = OVERLAY.db[2];
+ pdu_index++;
+ msg[pdu_index] = OVERLAY.db[3];
+ pdu_index++;
+ /* Encode value : completely zero */
+ for(int i = 0; i < 4; i++)
+ msg[pdu_index + i] = 0;
+ }
+ return no_error;
+}
+
+/* 1.3 Sua encoding method */
+Sua_syntax_error_struct Sua_container::sua_encode () {
+
+ /* Syntax Error struct initialization */
+ SYNTAX_ERR.msg_index = 0;
+ SYNTAX_ERR.no_error = TRUE;
+ SYNTAX_ERR.error_text = "Encoding : no error";
+
+ /* Encoding variables */
+ int pdu_index = 0;
+ boolean no_error = TRUE;
+ string strBlank;
+
+ /* Initialize message string to clean up old mess */
+ sua_msg = strBlank;
+
+ /* Reserve 8 bytes for msg header */
+ sua_msg.resize(8);
+
+ /* Only version 1 is supported */
+ sua_prim.hdr_version = Sua_version1;
+ sua_msg[pdu_index] = uint8_t(Sua_version1);
+ pdu_index++;
+ /* Reserved byte coded 0 */
+ sua_msg[pdu_index] = 0;
+ pdu_index++;
+ /* Encode message class */
+ sua_msg[pdu_index] = uint8_t(sua_prim.hdr_msg_class);
+ pdu_index++;
+
+ /* Encode message type according to class */
+ switch (sua_prim.hdr_msg_class) {
+ case sua_aspsm :
+ sua_msg[pdu_index] = uint8_t(sua_prim.hdr_msg_type.aspsm);
+ pdu_index++;
+ break;
+ case sua_asptm :
+ sua_msg[pdu_index] = uint8_t(sua_prim.hdr_msg_type.asptm);
+ pdu_index++;
+ break;
+ case sua_cl :
+ sua_msg[pdu_index] = uint8_t(sua_prim.hdr_msg_type.cl);
+ pdu_index++;
+ break;
+ case sua_co :
+ sua_msg[pdu_index] = uint8_t(sua_prim.hdr_msg_type.co);
+ pdu_index++;
+ break;
+ default : {
+ /* Signal error : invalid message class */
+ SYNTAX_ERR.msg_index = 2;
+ SYNTAX_ERR.error_text = "Encoding : Invalid message class";
+ no_error = FALSE;
+ }
+ } // End switch message class
+
+ if (no_error) {
+ /* The message length field is encoded at the end, pdu_index is kept at this position */
+ /* Start encoding of message parameters : double switch ! */
+ switch (sua_prim.hdr_msg_class) {
+ case sua_aspsm :
+ switch (sua_prim.hdr_msg_type.aspsm) {
+ case aspsm_up :
+ no_error = encode_ASP_up_msg (sua_prim, sua_msg);
+ break;
+ case aspsm_down :
+ no_error = encode_ASP_down_msg (sua_prim, sua_msg);
+ break;
+ case aspsm_beat :
+ no_error = encode_ASP_beat_msg (sua_prim, sua_msg);
+ break;
+ case aspsm_up_ack :
+ no_error = encode_ASP_up_ack_msg (sua_prim, sua_msg);
+ break;
+ case aspsm_down_ack :
+ no_error = encode_ASP_down_ack_msg (sua_prim, sua_msg);
+ break;
+ case aspsm_beat_ack :
+ no_error = encode_ASP_beat_ack_msg (sua_prim, sua_msg);
+ break;
+ default : {
+ /* Signal error : invalid message type */
+ SYNTAX_ERR.msg_index = 3;
+ SYNTAX_ERR.error_text = "Encoding : Invalid sua_aspsm message type";
+ no_error = FALSE;
+ }
+ } // End switch aspsm msg type
+ break;
+ case sua_asptm :
+ switch (sua_prim.hdr_msg_type.asptm) {
+ case asptm_act :
+ no_error = encode_ASP_act_msg (sua_prim, sua_msg);
+ break;
+ case asptm_inact :
+ no_error = encode_ASP_inact_msg (sua_prim, sua_msg);
+ break;
+ case asptm_act_ack :
+ no_error = encode_ASP_act_ack_msg (sua_prim, sua_msg);
+ break;
+ case asptm_inact_ack :
+ no_error = encode_ASP_inact_ack_msg (sua_prim, sua_msg);
+ break;
+ default : {
+ /* Signal error : invalid message type */
+ SYNTAX_ERR.msg_index = 3;
+ SYNTAX_ERR.error_text = "Encoding : Invalid sua_asptm message type";
+ no_error = FALSE;
+ }
+ } // End switch asptm msg type
+ break;
+ case sua_cl :
+ switch (sua_prim.hdr_msg_type.cl) {
+ case cl_data_transfer :
+ no_error = encode_cl_data_msg (sua_prim, sua_msg);
+ break;
+ case cl_data_response :
+ no_error = encode_cl_data_resp_msg (sua_prim, sua_msg);
+ break;
+ default : {
+ /* Signal error : invalid message type */
+ SYNTAX_ERR.msg_index = 3;
+ SYNTAX_ERR.error_text = "Encoding : Invalid sua_cl message type";
+ no_error = FALSE;
+ }
+ } // End switch cl msg type
+ break;
+ case sua_co :
+ switch (sua_prim.hdr_msg_type.co) {
+ case co_core :
+ no_error = encode_co_conn_req_msg (sua_prim, sua_msg);
+ break;
+ case co_coak :
+ no_error = encode_co_conn_ack_msg (sua_prim, sua_msg);
+ break;
+ case co_coref :
+ no_error = encode_co_conn_ref_msg (sua_prim, sua_msg);
+ break;
+ case co_relre :
+ no_error = encode_co_rel_req_msg (sua_prim, sua_msg);
+ break;
+ case co_relco :
+ no_error = encode_co_rel_conf_msg (sua_prim, sua_msg);
+ break;
+ case co_data :
+ no_error = encode_co_data_msg (sua_prim, sua_msg);
+ break;
+ case co_err :
+ no_error = encode_co_err_msg (sua_prim, sua_msg);
+ break;
+ case co_it :
+ no_error = encode_co_it_msg (sua_prim, sua_msg);
+ break;
+ default : {
+ /* Signal error : invalid message type */
+ SYNTAX_ERR.msg_index = 3;
+ SYNTAX_ERR.error_text = "Encoding : Invalid sua_co message type";
+ no_error = FALSE;
+ }
+ } // End switch co msg type
+ break;
+ default : {
+ /* Signal error : invalid message class */
+ SYNTAX_ERR.msg_index = 2;
+ SYNTAX_ERR.error_text = "Encoding : Invalid message class";
+ no_error = FALSE;
+ }
+ } // End switch message class
+ } // End message encoding
+
+ if (no_error) {
+ // Also padding bytes of final parameter are included in the total message length
+ OVERLAY.dq = htonl(sua_msg.size());
+ for (int i = 0; i < 4; i++)
+ sua_msg[pdu_index + i] = OVERLAY.db[i];
+ pdu_index += 4; // next tag
+ }
+ else {
+ /* Printout error text */
+ SYNTAX_ERR.no_error = FALSE;
+ cout << "Error position = " << SYNTAX_ERR.msg_index << endl;
+ cout << SYNTAX_ERR.error_text << endl;
+ }
+ return SYNTAX_ERR;
+}
+
+/********************************************************************/
+/* Sua_container method sua_decode : Decode SUA container element */
+/********************************************************************/
+
+/* The decoder function expects a valid transfer syntax (sua_msg)
+ and returns the local syntax (primitive) in the sua_prim field.
+ A number of plausibility checks are done :
+ - the message and parameter length fields must be consistent
+ - mandatory parameters (depending on msg type and class) must be present
+ - unrecognized parameters or parameters that are not applicable, are ignored
+ - parameters are checked on validity (range, compatibility with other parameters)
+ - duplicate parameters are not allowed
+*/
+
+/* 2. Definition of decoding procedures */
+/* 2.1 Parameter decoding procedures */
+
+/* Input pdu_index always points to the tag field of the parameter in the message */
+/* Output pdu_index always points to the tag field of the next parameter in the message */
+
+/* 2.1.1 Common parameters */
+
+boolean decode_netw_app (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* Kept for RK syntax */
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode network appearance */
+ prim.netw_app_pres = TRUE;
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++) {
+ OVERLAY.db[i] = msg[pdu_index + i];
+ }
+ prim.netw_app = ntohl(OVERLAY.dq);
+ pdu_index += 4; // Next tag
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Network Appearance length";
+ return FALSE;
+ }
+}
+
+boolean decode_data (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* Get the parameter length */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ /* There should be at least 1 byte of data */
+ if (par_len > 4) {
+ /* Copy to the data string */
+ prim.data_pres = TRUE;
+ prim.data_string = msg.substr(pdu_index + 4, par_len - 4);
+ /* Set pdu_index to next tag */
+ pdu_index += par_len;
+ pdu_index += (4 - (par_len % 4)) % 4; // don't forget padding bytes
+ return TRUE;
+ }
+ else {
+ /* Signal error : empty parameter */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Empty Data parameter";
+ return FALSE;
+ }
+}
+
+boolean decode_info (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* Get the parameter length */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ /* There should be at least 1 byte of info */
+ if (par_len > 4) {
+ /* Copy to the info string */
+ prim.info_pres = TRUE;
+ prim.info_string = msg.substr(pdu_index + 4, par_len - 4);
+ /* Set pdu_index to next tag */
+ pdu_index += par_len;
+ pdu_index += (4 - (par_len % 4)) % 4; // don't forget padding bytes
+ return TRUE;
+ }
+ else {
+ /* Signal error : empty parameter */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Empty Info parameter";
+ return FALSE;
+ }
+}
+
+boolean decode_rout_con (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode routing context */
+ prim.rout_con_pres = TRUE;
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++) {
+ OVERLAY.db[i] = msg[pdu_index + i];
+ }
+ prim.rout_con = ntohl(OVERLAY.dq);
+ pdu_index += 4; // Next tag
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Routing Context length";
+ return FALSE;
+ }
+}
+
+boolean decode_hb_data (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* Get the parameter length */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ /* There should be at least 1 byte of data */
+ if (par_len > 4) {
+ /* Copy to the hb_data string */
+ prim.hb_data_pres = TRUE;
+ prim.hb_data = msg.substr(pdu_index + 4, par_len - 4);
+ /* Set pdu_index to next tag */
+ pdu_index += par_len;
+ pdu_index += (4 - (par_len % 4)) % 4; // don't forget padding bytes
+ return TRUE;
+ }
+ else {
+ /* Signal error : empty parameter */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Empty Heartbeat data parameter";
+ return FALSE;
+ }
+}
+
+boolean decode_traf_mode (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode traffic mode type */
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++) {
+ OVERLAY.db[i] = msg[pdu_index + i];
+ }
+ OVERLAY.dq = ntohl(OVERLAY.dq);
+ /* Check traffic mode type value */
+ if (OVERLAY.dq < tmt_max) {
+ pdu_index += 4; // Next tag
+ prim.traf_mode_pres = TRUE;
+ prim.traf_mode = Sua_traffic_mode_type(OVERLAY.dq);
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Traffic Mode Type value";
+ return FALSE;
+ }
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Traffic Mode Type length";
+ return FALSE;
+ }
+}
+
+boolean decode_error_code (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode error code */
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++) {
+ OVERLAY.db[i] = msg[pdu_index + i];
+ }
+ OVERLAY.dq = ntohl(OVERLAY.dq);
+ /* Check error code value */
+ if (OVERLAY.dq < ect_max) {
+ pdu_index += 4; // Next tag
+ prim.err_code_pres = TRUE;
+ prim.err_code = Sua_error_code_type(OVERLAY.dq);
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Error Code value";
+ return FALSE;
+ }
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Error Code length";
+ return FALSE;
+ }
+}
+
+/* 2.1.2 SUA specific parameters */
+
+boolean decode_hop_count (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode hop counter */
+ prim.hop_count = uint8_t(msg[pdu_index + 7]);
+ /* Check whether hop counter within range */
+ if (prim.hop_count > 15) {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index + 7;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Hop Counter value";
+ return FALSE;
+ }
+ pdu_index += 8; // next tag
+ prim.hop_count_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Hop Counter length";
+ return FALSE;
+ }
+}
+
+boolean decode_addr (Sua_address_struct& addr, string& msg, unsigned int& pdu_index) {
+ unsigned int next_tag_pdu_idx = 0;
+ int j = 0;
+ unsigned int numchar = 0;
+ bool look_for_next_label = FALSE;
+ /* Get the parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[1]);
+ /* There must be at least a routing and address indicator, plus 1 parameter */
+ if (par_len > 12) {
+ /* Evaluate address parameters, the address structure has been cleaned up */
+ /* Routing indicator */
+ pdu_index += 4;
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ uint16_t pdu_word = ntohs(OVERLAY.dw[0]);
+ /* Check validity of routing indicator, only route on IP and SSN is supported */
+ if ((pdu_word != uint16_t(ri_route_IP_SSN)) &&
+ (pdu_word != uint16_t(ri_route_PC_SSN)) &&
+ (pdu_word != uint16_t(ri_route_hostname))){
+ /* Signal error : routing indicator not supported */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Routing Indicator not supported";
+ return FALSE;
+ }
+ addr.rout_ind = Sua_rout_ind(pdu_word);
+ /* Address indicator */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ pdu_word = ntohs(OVERLAY.dw[1]);
+ if ((pdu_word & 0x01) != 0)
+ addr.ssn_incl = TRUE;
+ if ((pdu_word & 0x02) != 0)
+ addr.pc_incl = TRUE;
+ if ((pdu_word & 0x04) != 0)
+ addr.gt_incl = TRUE;
+ /* Address parameters */
+ pdu_index += 4; // pdu_index points to first address parameter tag
+ par_len -= 8; // remaining address length
+ uint16_t addr_par_len, addr_par_tag;
+ uint32_t addr_par_val;
+ char* pdu_c;
+ while (par_len > 4) {
+ /* Evaluate address parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ addr_par_len = ntohs(OVERLAY.dw[1]);
+ /* Check for length overflow */
+ if (addr_par_len <= par_len) {
+ /* Evaluate address parameter tag and decode or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ addr_par_tag = ntohs(OVERLAY.dw[0]);
+ switch (addr_par_tag) {
+ case 0x8001 :
+ /* Global Title not supported, so we jump over it */
+ addr_par_len += (4 - (addr_par_len % 4)) % 4; // don't forget padding bytes
+ pdu_index += addr_par_len; // next tag
+ if (par_len >= addr_par_len)
+ par_len -= addr_par_len; // adjust remaining parameter length
+ else
+ par_len = 0;
+ break;
+ case 0x8002 :
+ /* SS7 Point code , length 8 bytes */
+ if (addr_par_len == 8) {
+ /* Fill in point code address parameters */
+ addr.pc_pres = TRUE;
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++)
+ OVERLAY.db[3-i] = msg[pdu_index + i];
+ addr.pc = OVERLAY.dq;
+ pdu_index += 4; // next tag
+ par_len -= 8; // adjust remaining parameter length
+ }
+ else {
+ /* Signal error : invalid point code parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid point code length";
+ return FALSE;
+ }
+ break;
+ case 0x8003 :
+ /* SSN parameter, length 8 bytes */
+ if (addr_par_len == 8) {
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++)
+ OVERLAY.db[i] = msg[pdu_index + i];
+ addr_par_val = ntohl(OVERLAY.dq);
+ if (addr_par_val <= 255)
+ addr.ssn = addr_par_val;
+ else
+ addr.ssn = 0;
+ pdu_index += 4; // next tag
+ par_len -= 8; // adjust remaining parameter length
+ }
+ else {
+ /* Signal error : invalid address parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid SSN length";
+ return FALSE;
+ }
+ break;
+ case 0x8004 :
+ /* IPv4 address, length 8 bytes */
+ if (addr_par_len == 8) {
+ /* Fill in IP address parameters */
+ addr.ip_addr_pres = TRUE;
+ addr.ip_addr_type = ip_v4;
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++)
+ OVERLAY.db[i] = msg[pdu_index + i];
+ addr.ip_addr.ipv4.sin_addr.s_addr = OVERLAY.dq;
+ pdu_index += 4; // next tag
+ par_len -= 8; // adjust remaining parameter length
+ }
+ else {
+ /* Signal error : invalid address parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid IPv4 address length";
+ return FALSE;
+ }
+ break;
+ case 0x8005 :
+ /* Hostname, variable length */
+ addr_par_len += (4 - (addr_par_len % 4)) % 4; // don't forget padding bytes
+ addr.hostname_pres = TRUE;
+ next_tag_pdu_idx = pdu_index + addr_par_len; // next tag
+ j = 0;
+ numchar = 0;
+ // resize the string to receive the hostname in
+ addr.hostname.resize(addr_par_len - 6);
+ // get length of first label
+ pdu_index += 4;
+ OVERLAY.dq = 0;
+ OVERLAY.db[0] = msg[pdu_index];
+ numchar = uint8_t(OVERLAY.db[0]);
+ //cout << "numchar = " << numchar << ", " << msg[pdu_index] << "\n";
+ pdu_index++; // go to first char of label
+ look_for_next_label = (numchar != 0) &&
+ ( pdu_index < next_tag_pdu_idx);
+ while (look_for_next_label) {
+ // copy contents of label into the string
+ for (unsigned int i = 0; i < numchar; i++){
+ OVERLAY.db[0] = msg[pdu_index + i];
+ addr.hostname[j] = OVERLAY.db[0];
+ j++;
+ }
+ pdu_index += (numchar); // next label length field ?
+ // get length of next label
+ OVERLAY.db[0] = msg[pdu_index];
+ numchar = uint8_t(OVERLAY.db[0]);
+ //cout << "numchar = " << numchar << ", j = " << j <<"\n";
+ if (numchar != 0){
+ addr.hostname[j]= '.';
+ pdu_index++; // go to first char of label
+ j++;
+ }
+ /* else end of name */
+
+ look_for_next_label = (numchar != 0) &&
+ ( pdu_index < next_tag_pdu_idx);
+ }
+ if (par_len >= addr_par_len)
+ par_len -= addr_par_len; // adjust remaining parameter length
+ else
+ par_len = 0;
+ /* set pdu_index onto next following tag of sua msg */
+ pdu_index = next_tag_pdu_idx;
+ break;
+ case 0x8006 :
+ /* IPv6 address, length 20 bytes */
+ if (addr_par_len == 20) {
+ /* Fill in IP address parameters */
+ addr.ip_addr_pres = TRUE;
+ addr.ip_addr_type = ip_v6;
+ pdu_index += 4;
+ pdu_c = (char*) &addr.ip_addr.ipv6.sin6_addr.s6_addr;
+ for (int i = 0; i < 16; i++) {
+ *pdu_c = msg[pdu_index + i];
+ pdu_c++;
+ }
+ pdu_index += 16; // next tag
+ par_len -= 20; // adjust remaining parameter length
+ }
+ else {
+ /* Signal error : invalid address parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid IPv6 address length";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this unknown address parameter */
+ addr_par_len += (4 - (addr_par_len % 4)) % 4; // don't forget padding bytes
+ pdu_index += addr_par_len; // next tag
+ if (par_len >= addr_par_len)
+ par_len -= addr_par_len; // adjust remaining parameter length
+ else
+ par_len = 0;
+ }
+ } // End switch address parameter tag
+ }
+ else {
+ /* Signal error : invalid address parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Address parameter length overflow";
+ return FALSE;
+ } // End check valid address parameter length
+ } //End while address parameters present
+ }
+ else {
+ /* Signal error : address parameters missing */
+ SYNTAX_ERR.msg_index = pdu_index + 4;
+ SYNTAX_ERR.error_text = "Decoding : Mandatory address parameters missing";
+ return FALSE;
+ }
+ /* Address parameter check */
+ /* An SSN different from "unknown" (0) and an IP address must be present */
+ if (addr.ssn == 0) {
+ /* Signal error : unknown SSN */
+ SYNTAX_ERR.error_text = "Decoding : SSN missing or unknown";
+ return FALSE;
+ }
+ if (!addr.ip_addr_pres) {
+ /* Signal error : missing IP address */
+ //SYNTAX_ERR.error_text = "Decoding : IP address missing";
+ //return FALSE;
+ }
+ return TRUE;
+}
+
+boolean decode_src_addr (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ boolean no_error = TRUE;
+ /* Clear source address */
+ prim.source_addr.rout_ind = ri_reserved0;
+ prim.source_addr.ssn_incl = FALSE;
+ prim.source_addr.gt_incl = FALSE;
+ prim.source_addr.pc_incl = FALSE;
+ prim.source_addr.pc_pres = FALSE;
+ prim.source_addr.ip_addr_pres = FALSE;
+ prim.source_addr.gt_pres = FALSE;
+ prim.source_addr.hostname_pres = FALSE;
+ /* Decode source address */
+ no_error = decode_addr (prim.source_addr, msg, pdu_index);
+ if (no_error)
+ prim.source_addr_pres = TRUE;
+ return no_error;
+}
+
+boolean decode_dest_addr (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ boolean no_error = TRUE;
+ /* Clear destination address */
+ prim.dest_addr.rout_ind = ri_reserved0;
+ prim.dest_addr.ssn_incl = FALSE;
+ prim.dest_addr.gt_incl = FALSE;
+ prim.dest_addr.pc_incl = FALSE;
+ prim.dest_addr.pc_pres = FALSE;
+ prim.dest_addr.ip_addr_pres = FALSE;
+ prim.dest_addr.gt_pres = FALSE;
+ prim.dest_addr.hostname_pres = FALSE;
+ /* Decode destination address */
+ no_error = decode_addr (prim.dest_addr, msg, pdu_index);
+ if (no_error)
+ prim.dest_addr_pres = TRUE;
+ return no_error;
+}
+
+boolean decode_source_ref (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode source reference */
+ prim.source_ref_pres = TRUE;
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++) {
+ OVERLAY.db[i] = msg[pdu_index + i];
+ }
+ prim.source_ref = ntohl(OVERLAY.dq);
+ pdu_index += 4; // Next tag
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Source Reference length";
+ return FALSE;
+ }
+}
+
+boolean decode_dest_ref (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode destination reference */
+ prim.dest_ref_pres = TRUE;
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++) {
+ OVERLAY.db[i] = msg[pdu_index + i];
+ }
+ prim.dest_ref = ntohl(OVERLAY.dq);
+ pdu_index += 4; // Next tag
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Destination Reference length";
+ return FALSE;
+ }
+}
+
+boolean decode_SCCP_cause (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode SCCP cause */
+ pdu_index += 6;
+ /* Check cause type within range */
+ OVERLAY.db[2] = msg[pdu_index];
+ if ((OVERLAY.db[2] > uint8_t(ctp_reserved0)) && (OVERLAY.db[2] < uint8_t(ctp_max))) {
+ prim.SCCP_cause.cause_type = SCCP_cause_type(OVERLAY.db[2]);
+ prim.SCCP_cause.cause_value = msg[pdu_index + 1];
+ pdu_index += 2; // Next tag
+ prim.SCCP_cause_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Invalid SCCP Cause type";
+ return FALSE;
+ }
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid SCCP Cause length";
+ return FALSE;
+ }
+}
+
+boolean decode_seq_nr (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode sequence number */
+ pdu_index += 6;
+ /* Clear sequence number, only interpret more data flag */
+ prim.seq_nr.sent_seq_nr = 0;
+ prim.seq_nr.rcvd_seq_nr = 0;
+ prim.seq_nr.more_data = ((msg[pdu_index] & 0x01) != 0);
+ pdu_index += 2; // Next tag
+ prim.seq_nr_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Sequence Number length";
+ return FALSE;
+ }
+}
+
+boolean decode_asp_cap (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode ASP capabilities */
+ pdu_index += 6;
+ /* Get supported protocol classes, at least protocol class 0 must be supported */
+ prim.asp_cap.cl0_supp = (msg[pdu_index] && 0x01);
+ prim.asp_cap.cl1_supp = (msg[pdu_index] && 0x02);
+ prim.asp_cap.cl2_supp = (msg[pdu_index] && 0x04);
+ prim.asp_cap.cl3_supp = (msg[pdu_index] && 0x08);
+ if (!prim.asp_cap.cl0_supp) {
+ /* Signal error : basic protocol class not supported */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : No support of protocol class 0";
+ return FALSE;
+ }
+ pdu_index++;
+ /* Check whether interworking type allowed */
+ if (uint8_t(msg[pdu_index]) < uint8_t(iw_max)) {
+ prim.asp_cap.interworking = Sua_interworking_type(msg[pdu_index]);
+ }
+ else {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Interworking type";
+ return FALSE;
+ }
+ pdu_index++; // next tag
+ prim.asp_cap_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid ASP capabilities length";
+ return FALSE;
+ }
+}
+
+boolean decode_seq_ctrl (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode sequence control */
+ prim.seq_control_pres = TRUE;
+ pdu_index += 4;
+ for (int i = 0; i < 4; i++) {
+ OVERLAY.db[i] = msg[pdu_index + i];
+ }
+ prim.seq_control = ntohl(OVERLAY.dq);
+ pdu_index += 4; // Next tag
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Sequence Control length";
+ return FALSE;
+ }
+}
+
+boolean decode_importance (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode importance */
+ prim.importance = uint8_t(msg[pdu_index + 7]);
+ /* Check whether importance within range */
+ if (prim.importance > 7) {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index + 7;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Importance value";
+ return FALSE;
+ }
+ pdu_index += 8; // next tag
+ prim.importance_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Importance length";
+ return FALSE;
+ }
+}
+
+boolean decode_prot_class (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode protocol class */
+ uint8_t prot_cl = uint8_t(msg[pdu_index + 7]);
+ prim.prot_class.return_option = ((prot_cl & 0x80) != 0);
+ prot_cl &= 0x03;
+ prim.prot_class.pcl = Sua_protocol_class(prot_cl);
+ pdu_index += 8; // next tag
+ prim.prot_class_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Protocol Class length";
+ return FALSE;
+ }
+}
+
+boolean decode_segmentation (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ if (par_len == 8) {
+ /* Decode segmentation */
+ uint8_t first_rem = uint8_t(msg[pdu_index + 4]);
+ prim.segm.first = ((first_rem & 0x80) != 0);
+ first_rem &= 0x0F;
+ prim.segm.remain = first_rem;
+ OVERLAY.db[0] = 0;
+ OVERLAY.db[1] = uint8_t(msg[pdu_index + 5]);
+ OVERLAY.db[2] = uint8_t(msg[pdu_index + 6]);
+ OVERLAY.db[3] = uint8_t(msg[pdu_index + 7]);
+ prim.segm.segm_ref = ntohl(OVERLAY.dq);
+ pdu_index += 8; // next tag
+ prim.segm_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Segmentation length";
+ return FALSE;
+ }
+}
+
+boolean decode_TID_label (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ uint16_t max_label = 2;
+ if (par_len == 8) {
+ /* Decode TID label */
+ prim.TID_label.start = uint8_t(msg[pdu_index + 4]);
+ prim.TID_label.end = uint8_t(msg[pdu_index + 5]);
+ OVERLAY.db[2] = uint8_t(msg[pdu_index + 6]);
+ OVERLAY.db[3] = uint8_t(msg[pdu_index + 7]);
+ prim.TID_label.label_value = ntohs(OVERLAY.dw[1]);
+ /* Check values */
+ if ((prim.TID_label.start < 32) && (prim.TID_label.start >= prim.TID_label.end)
+ && ((prim.TID_label.start - prim.TID_label.end) < 16)) {
+ for (int i = 0; i < (prim.TID_label.start - prim.TID_label.end); i++)
+ max_label = max_label * 2;
+ if (prim.TID_label.label_value >= max_label) {
+ /* Signal error : paramater syntax error */
+ SYNTAX_ERR.msg_index = pdu_index + 6;
+ SYNTAX_ERR.error_text = "Decoding : Invalid TID label";
+ return FALSE;
+ }
+ }
+ else {
+ /* Signal error : parameter syntax error */
+ SYNTAX_ERR.msg_index = pdu_index + 4;
+ SYNTAX_ERR.error_text = "Decoding : Invalid TID label position or length";
+ return FALSE;
+ }
+ pdu_index += 8; // next tag
+ prim.TID_label_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid TID label length";
+ return FALSE;
+ }
+}
+
+boolean decode_DRN_label (Sua_primitive_struct& prim, string& msg, unsigned int& pdu_index) {
+ /* The parameter length should be 8 bytes */
+ OVERLAY.db[0] = msg[pdu_index + 2];
+ OVERLAY.db[1] = msg[pdu_index + 3];
+ uint16_t par_len = ntohs(OVERLAY.dw[0]);
+ uint16_t max_label = 2;
+ if (par_len == 8) {
+ /* Decode DRN label */
+ prim.DRN_label.start = uint8_t(msg[pdu_index + 4]);
+ prim.DRN_label.end = uint8_t(msg[pdu_index + 5]);
+ OVERLAY.db[2] = uint8_t(msg[pdu_index + 6]);
+ OVERLAY.db[3] = uint8_t(msg[pdu_index + 7]);
+ prim.DRN_label.label_value = ntohs(OVERLAY.dw[1]);
+ /* Check values */
+ if ((prim.DRN_label.start < 32) && (prim.DRN_label.start >= prim.DRN_label.end)
+ && ((prim.DRN_label.start - prim.DRN_label.end) < 16)) {
+ for (int i = 0; i < (prim.DRN_label.start - prim.DRN_label.end); i++)
+ max_label = max_label * 2;
+ if (prim.DRN_label.label_value >= max_label) {
+ /* Signal error : paramater syntax error */
+ SYNTAX_ERR.msg_index = pdu_index + 6;
+ SYNTAX_ERR.error_text = "Decoding : Invalid DRN label";
+ return FALSE;
+ }
+ }
+ else {
+ /* Signal error : parameter syntax error */
+ SYNTAX_ERR.msg_index = pdu_index + 4;
+ SYNTAX_ERR.error_text = "Decoding : Invalid DRN label position or length";
+ return FALSE;
+ }
+ pdu_index += 8; // next tag
+ prim.DRN_label_pres = TRUE;
+ return TRUE;
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid DRN label length";
+ return FALSE;
+ }
+}
+
+/* 2.2 Message decoding procedures */
+
+/* 2.2.3 ASP Server Management messages */
+
+boolean decode_ASP_up_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0004 :
+ if (!prim.info_pres)
+ no_error = decode_info (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Info parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+boolean decode_ASP_down_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0004 :
+ if (!prim.info_pres)
+ no_error = decode_info (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Info parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+boolean decode_ASP_beat_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0009 :
+ if (!prim.hb_data_pres)
+ no_error = decode_hb_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Heartbeat data parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+boolean decode_ASP_up_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0004 :
+ if (!prim.info_pres)
+ no_error = decode_info (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Info parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+boolean decode_ASP_down_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0004 :
+ if (!prim.info_pres)
+ no_error = decode_info (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Info parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+boolean decode_ASP_beat_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0009 :
+ if (!prim.hb_data_pres)
+ no_error = decode_hb_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Heartbeat data parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+/* 2.2.4 ASP Traffic Management messages */
+
+boolean decode_ASP_act_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0004 :
+ if (!prim.info_pres)
+ no_error = decode_info (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Info parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x000B :
+ if (!prim.traf_mode_pres)
+ no_error = decode_traf_mode (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Traffic Mode type parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0119 :
+ if (!prim.TID_label_pres)
+ no_error = decode_TID_label (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate TID label parameter";
+ return FALSE;
+ }
+ break;
+ case 0x011A :
+ if (!prim.DRN_label_pres)
+ no_error = decode_DRN_label (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate DRN label parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+boolean decode_ASP_inact_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0004 :
+ if (!prim.info_pres)
+ no_error = decode_info (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Info parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+boolean decode_ASP_act_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0004 :
+ if (!prim.info_pres)
+ no_error = decode_info (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Info parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x000B :
+ if (!prim.traf_mode_pres)
+ no_error = decode_traf_mode (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Traffic Mode type parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+boolean decode_ASP_inact_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8;
+ /* Check whether further parameters are present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0004 :
+ if (!prim.info_pres)
+ no_error = decode_info (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Info parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End parameter length check
+ } // End while parameters present
+
+ /* No checks for mandatory parameters are needed */
+ return no_error;
+}
+
+/* 2.2.7 Connectionless messages */
+
+boolean decode_cl_data_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0003 :
+ if (!prim.data_pres)
+ no_error = decode_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Data parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0101 :
+ if (!prim.hop_count_pres)
+ no_error = decode_hop_count (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Hop Counter parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0102 :
+ if (!prim.source_addr_pres)
+ no_error = decode_src_addr (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Source Address parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0103 :
+ if (!prim.dest_addr_pres)
+ no_error = decode_dest_addr (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Address parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0116 : /* tag may change, see SUA v9 */
+ if (!prim.seq_control_pres)
+ no_error = decode_seq_ctrl (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Sequence Control parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0113 :
+ if (!prim.importance_pres)
+ no_error = decode_importance (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Importance parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0115 :
+ if (!prim.prot_class_pres)
+ no_error = decode_prot_class (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Protocol Class parameter";
+ return FALSE;
+ }
+ if (no_error && (prim.prot_class.pcl != prot_class_0) && (prim.prot_class.pcl != prot_class_1)) {
+ /* Signal error : invalid protocol class */
+ SYNTAX_ERR.msg_index = pdu_index - 1;
+ SYNTAX_ERR.error_text = "Decoding : Invalid protocol class for connectionless msg";
+ return FALSE;
+ }
+ break;
+ case 0x0117 :
+ if (!prim.segm_pres)
+ no_error = decode_segmentation (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Segmentation parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Protocol class
+ - Source address
+ - Destination address
+ - Sequence control
+ - Data
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.prot_class_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Protocol Class missing";
+ return FALSE;
+ }
+ if (no_error && !prim.source_addr_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Source Address missing";
+ return FALSE;
+ }
+ if (no_error && !prim.dest_addr_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Address missing";
+ return FALSE;
+ }
+ if (no_error && !prim.seq_control_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Sequence Control missing";
+ return FALSE;
+ }
+ if (no_error && !prim.data_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Data missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+boolean decode_cl_data_resp_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0003 :
+ if (!prim.data_pres)
+ no_error = decode_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Data parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0101 :
+ if (!prim.hop_count_pres)
+ no_error = decode_hop_count (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Hop Counter parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0102 :
+ if (!prim.source_addr_pres)
+ no_error = decode_src_addr(prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Source Address parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0103 :
+ if (!prim.dest_addr_pres)
+ no_error = decode_dest_addr (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Address parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0106 :
+ if (!prim.SCCP_cause_pres)
+ no_error = decode_SCCP_cause (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate SCCP Cause parameter";
+ return FALSE;
+ }
+ if (no_error && (prim.SCCP_cause.cause_type != ctp_return_cause)) {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index - 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid SCCP Cause type for connectionless msg";
+ return FALSE;
+ }
+ break;
+ case 0x0113 :
+ if (!prim.importance_pres)
+ no_error = decode_importance (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Importance parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - SCCP Cause
+ - Source address
+ - Destination address
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.SCCP_cause_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter SCCP Cause missing";
+ return FALSE;
+ }
+ if (no_error && !prim.source_addr_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Source Address missing";
+ return FALSE;
+ }
+ if (no_error && !prim.dest_addr_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Address missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+/* 2.2.8 Connection-oriented messages */
+/* Only protocol class 2 messages are supported */
+
+boolean decode_co_conn_req_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0003 :
+ if (!prim.data_pres)
+ no_error = decode_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Data parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0101 :
+ if (!prim.hop_count_pres)
+ no_error = decode_hop_count (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Hop Counter parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0102 :
+ if (!prim.source_addr_pres)
+ no_error = decode_src_addr (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Source Address parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0103 :
+ if (!prim.dest_addr_pres)
+ no_error = decode_dest_addr (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Address parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0104 :
+ if (!prim.source_ref_pres)
+ no_error = decode_source_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Source Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0113 :
+ if (!prim.importance_pres)
+ no_error = decode_importance (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Importance parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0115 :
+ if (!prim.prot_class_pres)
+ no_error = decode_prot_class (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Protocol Class parameter";
+ return FALSE;
+ }
+ prim.prot_class.return_option = FALSE;
+ if (no_error && (prim.prot_class.pcl != prot_class_2) && (prim.prot_class.pcl != prot_class_3)) {
+ /* Signal error : invalid protocol class */
+ SYNTAX_ERR.msg_index = pdu_index - 1;
+ SYNTAX_ERR.error_text = "Decoding : Invalid protocol class for connection-oriented msg";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Protocol class
+ - Source reference
+ - Destination address
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.prot_class_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Protocol Class missing";
+ return FALSE;
+ }
+ if (no_error && !prim.source_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Source Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.dest_addr_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Address missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+boolean decode_co_conn_ack_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0003 :
+ if (!prim.data_pres)
+ no_error = decode_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Data parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0103 :
+ if (!prim.dest_addr_pres)
+ no_error = decode_dest_addr (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Address parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0104 :
+ if (!prim.source_ref_pres)
+ no_error = decode_source_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Source Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0105 :
+ if (!prim.dest_ref_pres)
+ no_error = decode_dest_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0113 :
+ if (!prim.importance_pres)
+ no_error = decode_importance (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Importance parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0115 :
+ if (!prim.prot_class_pres)
+ no_error = decode_prot_class (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Protocol Class parameter";
+ return FALSE;
+ }
+ prim.prot_class.return_option = FALSE;
+ if (no_error && (prim.prot_class.pcl != prot_class_2) && (prim.prot_class.pcl != prot_class_3)) {
+ /* Signal error : invalid protocol class */
+ SYNTAX_ERR.msg_index = pdu_index - 1;
+ SYNTAX_ERR.error_text = "Decoding : Invalid protocol class for connection-oriented msg";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Protocol class
+ - Destination reference
+ - Source reference
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.prot_class_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Protocol Class missing";
+ return FALSE;
+ }
+ if (no_error && !prim.dest_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.source_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Source Reference missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+boolean decode_co_conn_ref_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0003 :
+ if (!prim.data_pres)
+ no_error = decode_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Data parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0103 :
+ if (!prim.dest_addr_pres)
+ no_error = decode_dest_addr (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Address parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0105 :
+ if (!prim.dest_ref_pres)
+ no_error = decode_dest_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0106 :
+ if (!prim.SCCP_cause_pres)
+ no_error = decode_SCCP_cause (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate SCCP Cause parameter";
+ return FALSE;
+ }
+ if (no_error && (prim.SCCP_cause.cause_type != ctp_refusal_cause)) {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index - 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid SCCP Cause type for connection refused msg";
+ return FALSE;
+ }
+ break;
+ case 0x0113 :
+ if (!prim.importance_pres)
+ no_error = decode_importance (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Importance parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Destination reference
+ - SCCP cause
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.dest_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.SCCP_cause_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter SCCP Cause missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+boolean decode_co_rel_req_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0003 :
+ if (!prim.data_pres)
+ no_error = decode_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Data parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0104 :
+ if (!prim.source_ref_pres)
+ no_error = decode_source_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Source Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0105 :
+ if (!prim.dest_ref_pres)
+ no_error = decode_dest_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0106 :
+ if (!prim.SCCP_cause_pres)
+ no_error = decode_SCCP_cause (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate SCCP Cause parameter";
+ return FALSE;
+ }
+ if (no_error && (prim.SCCP_cause.cause_type != ctp_release_cause)) {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index - 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid SCCP Cause type for release req msg";
+ return FALSE;
+ }
+ break;
+ case 0x0113 :
+ if (!prim.importance_pres)
+ no_error = decode_importance (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Importance parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Destination reference
+ - Source reference
+ - SCCP cause
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.dest_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.source_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Source Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.SCCP_cause_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter SCCP Cause missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+boolean decode_co_rel_conf_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0104 :
+ if (!prim.source_ref_pres)
+ no_error = decode_source_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Source Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0105 :
+ if (!prim.dest_ref_pres)
+ no_error = decode_dest_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0113 :
+ if (!prim.importance_pres)
+ no_error = decode_importance (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Importance parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Destination reference
+ - Source reference
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.dest_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.source_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Source Reference missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+boolean decode_co_data_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0003 :
+ if (!prim.data_pres)
+ no_error = decode_data (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Data parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0105 :
+ if (!prim.dest_ref_pres)
+ no_error = decode_dest_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0107 :
+ if (!prim.seq_nr_pres)
+ no_error = decode_seq_nr (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Sequence Number parameter";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Sequence number
+ - Destination reference
+ - Data
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.seq_nr_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Sequence Number missing";
+ return FALSE;
+ }
+ if (no_error && !prim.dest_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.data_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Data missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+boolean decode_co_err_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0105 :
+ if (!prim.dest_ref_pres)
+ no_error = decode_dest_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0106 :
+ if (!prim.SCCP_cause_pres)
+ no_error = decode_SCCP_cause (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate SCCP Cause parameter";
+ return FALSE;
+ }
+ if (no_error && (prim.SCCP_cause.cause_type != ctp_error_cause)) {
+ /* Signal error : invalid parameter value */
+ SYNTAX_ERR.msg_index = pdu_index - 2;
+ SYNTAX_ERR.error_text = "Decoding : Invalid SCCP Cause type for error msg";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Destination reference
+ - SCCP cause
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.dest_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.SCCP_cause_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter SCCP Cause missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+boolean decode_co_it_msg (Sua_primitive_struct& prim, string& msg) {
+ boolean no_error = TRUE;
+ uint32_t msg_len = ntohl(OVERLAY.dq);
+ unsigned int pdu_index = 8; // Start with first tag
+ /* Check whether a further parameter is present, at least tag & length fields must be there */
+ uint16_t par_tag, par_len;
+ while ((msg_len >= (pdu_index + 3)) && no_error) {
+ /* Evaluate parameter length */
+ OVERLAY.db[2] = msg[pdu_index + 2];
+ OVERLAY.db[3] = msg[pdu_index + 3];
+ par_len = ntohs(OVERLAY.dw[1]);
+ if ((pdu_index + par_len) <= msg_len) {
+ /* Evaluate parameter tag and call corresponding decoding routine or jump over it */
+ OVERLAY.db[0] = msg[pdu_index];
+ OVERLAY.db[1] = msg[pdu_index + 1];
+ par_tag = ntohs(OVERLAY.dw[0]);
+ switch (par_tag) {
+ case 0x0006 :
+ if (!prim.rout_con_pres)
+ no_error = decode_rout_con (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Routing Context parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0104 :
+ if (!prim.source_ref_pres)
+ no_error = decode_source_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Source Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0105 :
+ if (!prim.dest_ref_pres)
+ no_error = decode_dest_ref (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Destination Reference parameter";
+ return FALSE;
+ }
+ break;
+ case 0x0115 :
+ if (!prim.prot_class_pres)
+ no_error = decode_prot_class (prim, msg, pdu_index);
+ else {
+ /* Signal error : duplicate parameter */
+ SYNTAX_ERR.msg_index = pdu_index;
+ SYNTAX_ERR.error_text = "Decoding : Duplicate Protocol Class parameter";
+ return FALSE;
+ }
+ prim.prot_class.return_option = FALSE;
+ if (no_error && (prim.prot_class.pcl != prot_class_2) && (prim.prot_class.pcl != prot_class_3)) {
+ /* Signal error : invalid protocol class */
+ SYNTAX_ERR.msg_index = pdu_index - 1;
+ SYNTAX_ERR.error_text = "Decoding : Invalid protocol class for connection-oriented msg";
+ return FALSE;
+ }
+ break;
+ default : {
+ /* Jump over this totally uninteresting parameter to next double word position */
+ par_len += (4 - (par_len % 4)) % 4;
+ pdu_index += par_len;
+ }
+ } // End switch parameter tag
+ }
+ else {
+ /* Signal error : invalid parameter length */
+ SYNTAX_ERR.msg_index = pdu_index + 2;
+ SYNTAX_ERR.error_text = "Decoding : Parameter length overflow";
+ return FALSE;
+ } // End check valid parameter length
+ } // End while parameters present
+
+ /* Start checks for mandatory parameters :
+ - Protocol class
+ - Destination reference
+ - Source reference
+ The local syntax is filled out unless an error has occurred.
+ */
+ if (no_error && !prim.prot_class_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Protocol Class missing";
+ return FALSE;
+ }
+ if (no_error && !prim.dest_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Destination Reference missing";
+ return FALSE;
+ }
+ if (no_error && !prim.source_ref_pres) {
+ /* Signal error : mandatory parameter missing */
+ SYNTAX_ERR.error_text = "Decoding : Parameter Source Reference missing";
+ return FALSE;
+ }
+ return no_error;
+}
+
+/* 2.3 Sua decoding method */
+Sua_syntax_error_struct Sua_container::sua_decode () {
+
+ /* Syntax Error struct initialization */
+ SYNTAX_ERR.msg_index = 0;
+ SYNTAX_ERR.no_error = TRUE;
+ SYNTAX_ERR.error_text = "Decoding no error";
+
+ /* Decoding variables */
+ uint8_t pdu_byte;
+ boolean no_error = TRUE;
+
+ /* Initialize primitive container to clean up old mess */
+ this->sua_init ();
+
+ /* Start decoding message header, at least 8 bytes must be present */
+ uint32_t msg_len;
+ if (sua_msg.size() >= 8) {
+ for (int i = 0; i < 4; i++)
+ OVERLAY.db[i] = sua_msg[i + 4];
+ msg_len = ntohl(OVERLAY.dq);
+ }
+ else
+ msg_len = 0;
+ if ((msg_len >= 8) && (msg_len <= sua_msg.size())) {
+ /* Check Sua version, only version 1 is supported */
+ pdu_byte = uint8_t(sua_msg[0]);
+ if (pdu_byte == uint8_t(Sua_version1)) {
+ sua_prim.hdr_version = Sua_version1;
+ /* Check message class and type, with call to corresponding msg decoding procedure */
+ pdu_byte = uint8_t(sua_msg[2]);
+ switch (pdu_byte) {
+ case uint8_t(sua_aspsm) :
+ sua_prim.hdr_msg_class = sua_aspsm;
+ /* Check ASP server management msg type */
+ pdu_byte = uint8_t(sua_msg[3]);
+ switch (pdu_byte) {
+ case uint8_t(aspsm_up) :
+ sua_prim.hdr_msg_type.aspsm = aspsm_up;
+ no_error = decode_ASP_up_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(aspsm_down) :
+ sua_prim.hdr_msg_type.aspsm = aspsm_down;
+ no_error = decode_ASP_down_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(aspsm_beat) :
+ sua_prim.hdr_msg_type.aspsm = aspsm_beat;
+ no_error = decode_ASP_beat_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(aspsm_up_ack) :
+ sua_prim.hdr_msg_type.aspsm = aspsm_up_ack;
+ no_error = decode_ASP_up_ack_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(aspsm_down_ack) :
+ sua_prim.hdr_msg_type.aspsm = aspsm_down_ack;
+ no_error = decode_ASP_down_ack_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(aspsm_beat_ack) :
+ sua_prim.hdr_msg_type.aspsm = aspsm_beat_ack;
+ no_error = decode_ASP_beat_ack_msg (sua_prim, sua_msg);
+ break;
+ default : {
+ sua_prim.hdr_msg_type.aspsm = aspsm_reserved0;
+ /* Signal error : invalid message type */
+ SYNTAX_ERR.msg_index = 3;
+ SYNTAX_ERR.error_text = "Decoding : Invalid ASP server management message type";
+ no_error = FALSE;
+ }
+ } // End switch aspsm msg
+ break;
+ case uint8_t(sua_asptm) :
+ sua_prim.hdr_msg_class = sua_asptm;
+ /* Check ASP traffic management msg type */
+ pdu_byte = uint8_t(sua_msg[3]);
+ switch (pdu_byte) {
+ case uint8_t(asptm_act) :
+ sua_prim.hdr_msg_type.asptm = asptm_act;
+ no_error = decode_ASP_act_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(asptm_inact) :
+ sua_prim.hdr_msg_type.asptm = asptm_inact;
+ no_error = decode_ASP_inact_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(asptm_act_ack) :
+ sua_prim.hdr_msg_type.asptm = asptm_act_ack;
+ no_error = decode_ASP_act_ack_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(asptm_inact_ack) :
+ sua_prim.hdr_msg_type.asptm = asptm_inact_ack;
+ no_error = decode_ASP_inact_ack_msg (sua_prim, sua_msg);
+ break;
+ default : {
+ sua_prim.hdr_msg_type.asptm = asptm_reserved0;
+ /* Signal error : invalid message type */
+ SYNTAX_ERR.msg_index = 3;
+ SYNTAX_ERR.error_text = "Decoding : Invalid connectionless message type";
+ no_error = FALSE;
+ }
+ } // End switch asptm msg
+ break;
+ case uint8_t(sua_cl):
+ sua_prim.hdr_msg_class = sua_cl;
+ /* Check connectionless msg type */
+ pdu_byte = uint8_t(sua_msg[3]);
+ switch (pdu_byte) {
+ case uint8_t(cl_data_transfer) :
+ sua_prim.hdr_msg_type.cl = cl_data_transfer;
+ no_error = decode_cl_data_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(cl_data_response) :
+ sua_prim.hdr_msg_type.cl = cl_data_response;
+ no_error = decode_cl_data_resp_msg (sua_prim, sua_msg);
+ break;
+ default : {
+ sua_prim.hdr_msg_type.cl = cl_reserved0;
+ /* Signal error : invalid message type */
+ SYNTAX_ERR.msg_index = 3;
+ SYNTAX_ERR.error_text = "Decoding : Invalid connectionless message type";
+ no_error = FALSE;
+ }
+ } // End switch cl msg
+ break;
+ case uint8_t(sua_co) :
+ sua_prim.hdr_msg_class = sua_co;
+ /* Check connection-oriented msg type */
+ pdu_byte = uint8_t(sua_msg[3]);
+ switch (pdu_byte) {
+ case uint8_t(co_core) :
+ sua_prim.hdr_msg_type.co = co_core;
+ no_error = decode_co_conn_req_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(co_coak) :
+ sua_prim.hdr_msg_type.co = co_coak;
+ no_error = decode_co_conn_ack_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(co_coref) :
+ sua_prim.hdr_msg_type.co = co_coref;
+ no_error = decode_co_conn_ref_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(co_relre) :
+ sua_prim.hdr_msg_type.co = co_relre;
+ no_error = decode_co_rel_req_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(co_relco) :
+ sua_prim.hdr_msg_type.co = co_relco;
+ no_error = decode_co_rel_conf_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(co_data) :
+ sua_prim.hdr_msg_type.co = co_data;
+ no_error = decode_co_data_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(co_err) :
+ sua_prim.hdr_msg_type.co = co_err;
+ no_error = decode_co_err_msg (sua_prim, sua_msg);
+ break;
+ case uint8_t(co_it) :
+ sua_prim.hdr_msg_type.co = co_it;
+ no_error = decode_co_it_msg (sua_prim, sua_msg);
+ break;
+ default : {
+ sua_prim.hdr_msg_type.co = co_reserved0;
+ /* Signal error : invalid message type */
+ SYNTAX_ERR.msg_index = 3;
+ SYNTAX_ERR.error_text = "Decoding : Invalid connection-oriented message type";
+ no_error = FALSE;
+ }
+ } // End switch co msg
+ break;
+ default : {
+ /* Signal error : invalid message class */
+ SYNTAX_ERR.msg_index = 2;
+ SYNTAX_ERR.error_text = "Decoding : Unknown message class";
+ no_error = FALSE;
+ }
+ } // End msg class switch
+ }
+ else {
+ sua_prim.hdr_version = Sua_unknown;
+ /* Signal error : invalid Sua version */
+ SYNTAX_ERR.msg_index = 0;
+ SYNTAX_ERR.error_text = "Decoding : Invalid Sua version";
+ no_error = FALSE;
+ } // Endif version
+ }
+ else {
+ /* Signal error : invalid message length */
+ SYNTAX_ERR.msg_index = 4;
+ SYNTAX_ERR.error_text = "Decoding : Invalid message length";
+ no_error = FALSE;
+ } // Endif msg length
+
+ if (!no_error) {
+ /* Printout error text */
+ SYNTAX_ERR.no_error = FALSE;
+ cout << "Error position = " << SYNTAX_ERR.msg_index << endl;
+ cout << SYNTAX_ERR.error_text << endl;
+ }
+ return SYNTAX_ERR;
+}
+
+
+
+ ///:~
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_syntax.h b/sualibrary/sua/sua_syntax.h
new file mode 100644
index 0000000..0295a8f
--- /dev/null
+++ b/sualibrary/sua/sua_syntax.h
@@ -0,0 +1,447 @@
+/***************************************************************************
+ sua_syntax.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_syntax.h,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 5.
+ *
+ * Author(s): Gery Verwimp
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Kathleen
+ * "Computers/networks must be female, because if they were male, "
+ * "they would be perfectably predictable and computers/networks are "
+ * "never predictable. If you do not believe this, just ask any women."
+ *
+ * Purpose: This header-file defines the SUA syntax class for SUA
+ * primitives and messages, including the en/decoding routines.
+ */
+
+#ifndef SUA_SYNTAX_H
+#define SUA_SYNTAX_H
+
+#include "sua.h"
+#include <string>
+
+/********************************/
+/* 0. SUA message header syntax */
+/********************************/
+
+enum Sua_version {
+ Sua_unknown,
+ Sua_version1
+};
+
+enum Sua_msg_class {
+ sua_mngt,
+ sua_reserved1,
+ sua_ssnm,
+ sua_aspsm,
+ sua_asptm,
+ sua_reserved5,
+ sua_reserved6,
+ sua_cl,
+ sua_co,
+ sua_rkm,
+ sua_max
+};
+
+enum Sua_mngt_msg_type {
+ mngt_error,
+ mngt_notify,
+ mngt_max
+};
+
+enum Sua_ssnm_msg_type {
+ ssnm_reserved0,
+ ssnm_duna,
+ ssnm_dava,
+ ssnm_daud,
+ ssnm_scon,
+ ssnm_dupu,
+ ssnm_drst,
+ ssnm_max
+};
+
+enum Sua_aspsm_msg_type {
+ aspsm_reserved0,
+ aspsm_up,
+ aspsm_down,
+ aspsm_beat,
+ aspsm_up_ack,
+ aspsm_down_ack,
+ aspsm_beat_ack,
+ aspsm_max
+};
+
+enum Sua_asptm_msg_type {
+ asptm_reserved0,
+ asptm_act,
+ asptm_inact,
+ asptm_act_ack,
+ asptm_inact_ack,
+ asptm_max
+};
+
+enum Sua_cl_msg_type {
+ cl_reserved0,
+ cl_data_transfer, /* unitdata */
+ cl_data_response, /* unitdata service */
+ cl_max
+};
+
+enum Sua_co_msg_type {
+ co_reserved0,
+ co_core, /* connection request */
+ co_coak, /* connection confirm */
+ co_coref, /* connection refused */
+ co_relre, /* release request */
+ co_relco, /* release confirm */
+ co_resco, /* reset confirm */
+ co_resre, /* reset request */
+ co_data, /* data transfer, expedited data */
+ co_data_ack, /* (expedited) data acknowledge */
+ co_err, /* PDU error */
+ co_it, /* inactivity test */
+ co_max
+};
+
+enum Sua_rkm_msg_type {
+ rkm_reserved0,
+ rkm_reg_req, /* registration request */
+ rkm_reg_resp, /* registration response */
+ rkm_dereg_req, /* deregistration request */
+ rkm_dereg_resp, /* deregistration response */
+ rkm_max
+};
+
+union Sua_msg_type {
+ Sua_mngt_msg_type mngt;
+ Sua_ssnm_msg_type ssnm;
+ Sua_aspsm_msg_type aspsm;
+ Sua_asptm_msg_type asptm;
+ Sua_cl_msg_type cl;
+ Sua_co_msg_type co;
+ Sua_rkm_msg_type rkm;
+};
+
+/***********************************/
+/* 1. SUA management message modes */
+/***********************************/
+
+enum Sua_traffic_mode_type {
+ tmt_unknown,
+ tmt_override,
+ tmt_loadshare,
+ tmt_broadcast,
+ tmt_max
+};
+
+enum Sua_error_code_type {
+ ect_unknown,
+ ect_invalid_version,
+ ect_invalid_interface_id,
+ ect_unsupported_msg_class,
+ ect_unsupported_msg_type,
+ ect_unsupported_traffic_handling_mode,
+ ect_unexpected_msg,
+ ect_protocol_error,
+ ect_unsupported_interface_id_type, /* not used in SUA */
+ ect_invalid_stream_id,
+ ect_unassigned_TEI, /* not used in SUA */
+ ect_unrecognized_SAPI, /* not used in SUA */
+ ect_invalid_TEI_SAPI_comb, /* not used in SUA */
+ ect_refused_mngt_blocking,
+ ect_ASP_id_required,
+ ect_invalid_ASP_id,
+ ect_invalid_routing_context,
+ ect_invalid_parameter_value,
+ ect_parameter_field_error,
+ ect_unexpected_parameter,
+ ect_destination_status_unknown,
+ ect_invalid_network_appearance,
+ ect_missing_parameter,
+ ect_routing_key_change_refused,
+ ect_invalid_loadsharing_label,
+ ect_max
+};
+
+typedef struct {
+ uint8_t status_type;
+ uint8_t status_ID;
+} Sua_status_struct;
+
+/* ASP capabilities */
+
+enum Sua_interworking_type {
+ iw_none, /* no interworking with SS7 */
+ iw_asp, /* IP endpoint ASP */
+ iw_sg, /* Signalling Gateway */
+ iw_relay, /* IP relay point */
+ iw_max
+};
+
+typedef struct {
+ boolean cl0_supp;
+ boolean cl1_supp;
+ boolean cl2_supp;
+ boolean cl3_supp;
+ uint8_t interworking;
+} Sua_asp_cap_struct;
+
+/*********************************/
+/* 2. SUA protocol message modes */
+/*********************************/
+
+enum Sua_protocol_class {
+ prot_class_0,
+ prot_class_1,
+ prot_class_2,
+ prot_class_3,
+ prot_max
+};
+
+typedef struct {
+ Sua_protocol_class pcl;
+ boolean return_option;
+} Sua_protocol_class_struct;
+
+/* The SUA address parameter contains following fields :
+ - routing indicator : see below
+ - address indicator : for SS7 interworking, defines inclusion of SSN, PC or GT in SS7 address
+ - address parameters : combination of GT, hostname, IPaddress, SSN, PC
+*/
+
+enum Sua_rout_ind {
+ ri_reserved0,
+ ri_route_GT,
+ ri_route_PC_SSN,
+ ri_route_hostname,
+ ri_route_IP_SSN,
+ ri_max
+};
+
+typedef struct {
+ uint8_t translation_type;
+ uint8_t num_plan;
+ uint8_t nat_addr;
+ uint8_t nr_of_digits;
+ uint8_t digits[24];
+} SCCP_GT_struct;
+
+enum Sua_ip_addr_type {
+ ip_reserved0,
+ ip_v4,
+ ip_v6,
+ ip_max
+};
+
+union Ip_address {
+ sockaddr_in ipv4;
+ sockaddr_in6 ipv6;
+};
+
+typedef struct {
+ Sua_rout_ind rout_ind;
+ /* Flags for address indicator */
+ boolean ssn_incl;
+ boolean gt_incl;
+ boolean pc_incl;
+ /* Indication of elements present */
+ boolean pc_pres;
+ boolean ip_addr_pres;
+ boolean gt_pres;
+ boolean hostname_pres;
+ /* An SSN must always be present on the primitive interface, even if unknown (=0) */
+ uint8_t ssn;
+ int pc;
+ Sua_ip_addr_type ip_addr_type;
+ Ip_address ip_addr;
+ SCCP_GT_struct gt;
+ string hostname;
+} Sua_address_struct;
+
+/* The SCCP Cause parameter can contain the following :
+ - return cause (in CLDR messages)
+ - refusal cause (in COREF messages)
+ - release cause (in RELRE messages)
+ - reset cause (in RESRE messages)
+ - error cause (in COERR messages)
+*/
+enum SCCP_cause_type {
+ ctp_reserved0,
+ ctp_return_cause,
+ ctp_refusal_cause,
+ ctp_release_cause,
+ ctp_reset_cause,
+ ctp_error_cause,
+ ctp_max
+};
+
+typedef struct {
+ SCCP_cause_type cause_type;
+ uint16_t cause_value;
+} SCCP_cause_struct;
+
+/* The sequence number parameter contains :
+ - the sent and received seq numbers (0..127) for protocol class 3
+ - the more data indicator for protocol classes 2 and 3
+*/
+
+typedef struct {
+ uint8_t sent_seq_nr;
+ uint8_t rcvd_seq_nr;
+ boolean more_data;
+} Sua_seq_nr_struct;
+
+/* The segmentation parameter contains :
+ - first segment indication
+ - number of remaining segments (0..15)
+ - segmentation reference (0..2~24-1)
+*/
+
+typedef struct {
+ boolean first;
+ uint8_t remain;
+ uint32_t segm_ref;
+} Sua_segm_struct;
+
+/* The label parameter contains :
+ - start of the label bits (0..31)
+ - end of the label bits (0..31)
+ - label value (0..2~16-1)
+*/
+
+typedef struct {
+ uint8_t start;
+ uint8_t end;
+ uint16_t label_value;
+} Sua_label_struct;
+
+/* And now, we present to you the SUA container, mother of all interfaces */
+
+typedef struct {
+ /* 0. Mandatory header */
+ Sua_version hdr_version;
+ Sua_msg_class hdr_msg_class;
+ Sua_msg_type hdr_msg_type;
+ /* 1. Common parameter part presence */
+ boolean data_pres;
+ boolean info_pres;
+ boolean rout_con_pres;
+ boolean diag_info_pres;
+ boolean hb_data_pres;
+ boolean traf_mode_pres;
+ boolean err_code_pres;
+ boolean status_pres;
+ boolean cong_lvl_pres;
+ boolean ASP_id_pres;
+ boolean aff_pc_pres;
+ /* 1. Common parameter part */
+ string data_string;
+ string info_string;
+ uint32_t rout_con;
+ string diag_info;
+ string hb_data;
+ Sua_traffic_mode_type traf_mode;
+ Sua_error_code_type err_code;
+ Sua_status_struct status;
+ uint8_t cong_lvl;
+ uint32_t ASP_id;
+ uint32_t aff_pc;
+ /* 2. SUA specific parameter part presence */
+ boolean netw_app_pres;
+ boolean hop_count_pres;
+ boolean source_addr_pres;
+ boolean dest_addr_pres;
+ boolean source_ref_pres;
+ boolean dest_ref_pres;
+ boolean SCCP_cause_pres;
+ boolean seq_nr_pres;
+ boolean rec_seq_nr_pres;
+ boolean asp_cap_pres;
+ boolean credit_pres;
+ boolean importance_pres;
+ boolean prot_class_pres;
+ boolean seq_control_pres;
+ boolean segm_pres;
+ boolean TID_label_pres;
+ boolean DRN_label_pres;
+ /* 2. SUA specific parameter part */
+ uint32_t netw_app;
+ Sua_address_struct source_addr;
+ Sua_address_struct dest_addr;
+ uint32_t source_ref;
+ uint32_t dest_ref;
+ SCCP_cause_struct SCCP_cause;
+ Sua_seq_nr_struct seq_nr;
+ Sua_asp_cap_struct asp_cap;
+ Sua_protocol_class_struct prot_class;
+ uint8_t hop_count;
+ uint8_t rec_seq_nr;
+ uint8_t credit;
+ uint8_t importance;
+ uint32_t seq_control;
+ Sua_segm_struct segm;
+ Sua_label_struct TID_label;
+ Sua_label_struct DRN_label;
+} Sua_primitive_struct;
+
+typedef struct {
+ int msg_index; // position in transfer syntax
+ boolean no_error;
+ string error_text; // error text, specifying details
+} Sua_syntax_error_struct;
+
+class Sua_container {
+ public:
+ Sua_primitive_struct sua_prim;
+ string sua_msg;
+ void sua_init ();
+ Sua_syntax_error_struct sua_encode ();
+ Sua_syntax_error_struct sua_decode ();
+};
+
+#endif // SUA_SYNTAX_H
+
+
+
+
+
+
diff --git a/sualibrary/sua/sua_tcb.cpp b/sualibrary/sua/sua_tcb.cpp
new file mode 100644
index 0000000..e896cb1
--- /dev/null
+++ b/sualibrary/sua/sua_tcb.cpp
@@ -0,0 +1,218 @@
+/***************************************************************************
+ sua_tcb.cpp - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_tcb.cpp,v 1.1.1.1 2002/02/04 14:30:42 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Daphne
+ * "Listen very carefully, I shall say this only once:"
+ * "a TCB, a TCB, my kingdom for a TCB"
+ *
+ * Purpose: This code-file defines the SUA Transaction Control Block(TCB) pool
+ * functions for(needed for SUA connection oriented):
+ * - initialising a single TCB
+ * - initialising the TCB pool
+ * - allocate a TCB
+ * - get a TCB
+ * - release a TCB
+ * And for the Saved SUA msg queue pool
+ * - add SUA msg to queue
+ * - get sua msg from queue
+ * - release the SUA msg from the queue
+ */
+
+#include "sua_debug.h"
+#include "sua_tcb.h"
+#include "sua_database.h"
+#include "sua_logging.h"
+#include "sua.h"
+
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include <string>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h> /* includes <netinet/in.h> also ! */
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+using namespace std;
+
+/* sua SCOC tcb pool */
+tcb_Sua_TCB_arr tcb_pool;
+
+/* sua temporary message store */
+tcb_Sua_msgqueue_pool msg_store;
+
+/***********************************************************************/
+/* Sua SCOC TCB: initialise TCB element */
+/***********************************************************************/
+void tcb_Sua_TCB_str::init_TCB_elem()
+{
+ state = scoc_idle;
+ Dest_LR = 0;
+ Source_LR = 0;
+ User_ref_id = 0;
+ sctp_Association_id = 0;
+ prcl_class = class0 ;
+ return_option = FALSE;
+}
+
+/***********************************************************************/
+/* Sua SCOC TCB arr: initialise TCB pool */
+/***********************************************************************/
+void tcb_Sua_TCB_arr::init_TCB_pool()
+{
+ cout << "Initialising ?? \n";
+ last_allocated_tcb = 0;
+}
+
+
+/***********************************************************************/
+/* Sua SCOC TCB arr: allocate a TCB */
+/***********************************************************************/
+tcb_Sua_TCB_str *tcb_Sua_TCB_arr:: allocate_TCB(unsigned int &local_ref){
+
+ last_allocated_tcb++;
+ // allocate the TCB
+ tcb_Sua_TCB_str new_tcb;
+ new_tcb.init_TCB_elem();
+ tcb_sua_pair_str tcb_ref_pair(last_allocated_tcb,new_tcb);
+
+ tcb_sua_map_iterator_str p = tcb.insert(tcb_ref_pair);
+
+ if (p.second)
+ {
+ char logstring[100];
+ sprintf(logstring, "TCB %d allocated",last_allocated_tcb);
+ event_log("sua_tcb.c",logstring);
+ }
+ else
+ {
+ char logstring[100];
+ sprintf(logstring, "No TCB allocated, damm");
+ event_log("sua_tcb.c",logstring);
+ }
+
+ local_ref = last_allocated_tcb;
+ cout << "tcb local ref = " << local_ref << "\n";
+ return(&tcb[last_allocated_tcb]);
+}
+
+/***********************************************************************/
+/* Sua SCOC TCB arr: get address of TCB */
+/***********************************************************************/
+tcb_Sua_TCB_str *tcb_Sua_TCB_arr:: get_tcb(unsigned int local_ref) {
+
+ return(&tcb[local_ref]);
+}
+
+/***********************************************************************/
+/* Sua SCOC TCB arr: release the TCB */
+/***********************************************************************/
+void tcb_Sua_TCB_arr:: release_TCB(unsigned int local_reference){
+
+ int count = tcb.erase(local_reference);
+
+ if (count != 0)
+ {
+ char logstring[100];
+ sprintf(logstring, "TCB instances %d of LR %d Released : ",count,local_reference);
+ event_log("sua_tcb.c",logstring);
+ }
+ else
+ {
+ char logstring[100];
+ sprintf(logstring, "TCB instance not released");
+ event_log("sua_tcb.c",logstring);
+ }
+
+}
+
+/***********************************************************************/
+/* Sua_msg : save msg */
+/***********************************************************************/
+void tcb_Sua_msgqueue_pool:: add_msg( unsigned int sua_assoc_idx,
+ tcb_Sua_msg_elem sua_msg
+ )
+{
+ sua_msg.valid = true;
+ msg_store.instance[sua_assoc_idx].push(sua_msg);
+}
+
+/***********************************************************************/
+/* Sua_msg : get msg */
+/***********************************************************************/
+tcb_Sua_msg_elem tcb_Sua_msgqueue_pool:: get_msg( unsigned int sua_assoc_idx )
+{
+ tcb_Sua_msg_elem temp_sua_msg;
+
+ temp_sua_msg.valid = false;
+ if ( !msg_store.instance[sua_assoc_idx].empty() )
+ {
+ return( msg_store.instance[sua_assoc_idx].front());
+ }
+ else
+ {
+
+ return(temp_sua_msg);
+ }
+}
+
+/***********************************************************************/
+/* Sua_msg : Delete msg */
+/***********************************************************************/
+void tcb_Sua_msgqueue_pool:: delete_msg( unsigned int sua_assoc_idx )
+{
+ if ( !msg_store.instance[sua_assoc_idx].empty() )
+ msg_store.instance[sua_assoc_idx].pop();
+}
+
+// end of module sua_tcb.c
+
+
+
+
diff --git a/sualibrary/sua/sua_tcb.h b/sualibrary/sua/sua_tcb.h
new file mode 100644
index 0000000..dd2ec60
--- /dev/null
+++ b/sualibrary/sua/sua_tcb.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+ sua_tcb.h - description
+ -------------------
+ begin : Tue Jan 8 2002
+ copyright : (C) 2002 by Lode Coene
+ email : lode.coene@siemens.atea.be
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * $Id: sua_tcb.h,v 1.1.1.1 2002/02/04 14:30:42 p82609 Exp $
+ *
+ * SUA implementation according to SUA draft issue 6.
+ *
+ * Author(s): Lode Coene
+ *
+ *
+ * Copyright (C) 2001 by Siemens Atea, Herentals, Belgium.
+ *
+ * Realized in co-operation between Siemens Atea and
+ * Siemens AG, Munich, Germany.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact: gery.verwimp@siemens.atea.be
+ * lode.coene@siemens.atea.be
+ *
+ * The alternative comment
+ * inspiration : Isabelle
+ * "
+ * ""
+ *
+ * Purpose: This header-file defines the SUA Transaction Control Block(TCB)
+ * pool functions for(needed for SUA connection oriented):
+ * - initialising a single TCB
+ * - initialising the TCB pool
+ * - allocate a TCB
+ * - get a TCB
+ * - release a TCB
+ * And for the Saved SUA msg queue pool
+ * - add SUA msg to queue
+ * - get sua msg from queue
+ * - release the SUA msg from the queue
+ */
+
+#ifndef SUA_TCB_H
+#define SUA_TCB_H
+
+#include "sua_database.h"
+#include "sua_syntax.h"
+#include "sua.h"
+
+#include <string>
+#include <map>
+#include <queue>
+#include <arpa/inet.h>
+
+enum tcb_scoc_state_set {
+ scoc_idle, // idle state
+ scoc_incoming,
+ scoc_wait_m_CC,
+ scoc_outgoing,
+ scoc_active,
+ scoc_disconnect
+};
+
+class tcb_Sua_TCB_str
+{
+ public:
+ tcb_scoc_state_set state;
+ unsigned int Dest_LR;
+ unsigned int Source_LR;
+ unsigned int User_ref_id;
+ unsigned int sctp_Association_id;
+ protocol_class_set prcl_class;
+ unsigned int seq_number;
+ bool return_option;
+ sccp_addr_str remote_address;
+ public:
+ void init_TCB_elem();
+}; ///:~
+
+typedef map<int,tcb_Sua_TCB_str> tcb_sua_map_str;
+
+class tcb_Sua_TCB_arr
+{
+ public:
+ tcb_sua_map_str tcb;
+ /*private:*/
+ unsigned int last_allocated_tcb;
+ public:
+ void init_TCB_pool();
+ tcb_Sua_TCB_str *allocate_TCB(unsigned int &Sua_ConnId);
+ tcb_Sua_TCB_str *get_tcb(unsigned int Sua_ConnId);
+ void release_TCB(unsigned int Sua_ConnId);
+}; ///:~
+
+typedef pair<unsigned int, tcb_Sua_TCB_str> tcb_sua_pair_str;
+
+typedef pair<tcb_sua_map_str::iterator,bool> tcb_sua_map_iterator_str;
+
+struct tcb_Sua_msg_elem {
+ string byte;
+ int delivery_type;
+ int stream_id;
+ bool valid;
+};
+
+typedef queue<tcb_Sua_msg_elem> tcb_Sua_msgqueue;
+
+class tcb_Sua_msgqueue_pool
+{
+ public:
+ tcb_Sua_msgqueue instance[db_MAX_REMOTE_SUA];
+ public:
+ void add_msg( unsigned int sua_assoc_idx,
+ tcb_Sua_msg_elem sua_msg
+ );
+ tcb_Sua_msg_elem get_msg( unsigned int sua_assoc_idx );
+ void delete_msg( unsigned int sua_assoc_idx );
+}; ///:~
+
+
+#endif // SUA_TCB_H
+
+//end of module sua_tcb.h
+
+
+
+
+
+
+
+