diff options
Diffstat (limited to 'sualibrary/sua/sua_sual.cpp')
-rw-r--r-- | sualibrary/sua/sua_sual.cpp | 686 |
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++ + |