aboutsummaryrefslogtreecommitdiffstats
path: root/sualibrary/sua/sua_sual.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sualibrary/sua/sua_sual.cpp')
-rw-r--r--sualibrary/sua/sua_sual.cpp686
1 files changed, 686 insertions, 0 deletions
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++
+