/*************************************************************************** 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.2 2002/04/11 14:13:34 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 #endif #include #include #include #include #include #include #include #include /* includes also ! */ #include #include #include #define MAX_DATA_LENGTH 2000 using namespace std; /* definition of SUA local object and of remote object */ extern db_Sua_DatabaseList sua; typedef struct { unsigned int local_sua_id; unsigned int user_ref; string userdata; } sual_save_str; vector 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(); sua.local_sua.initialize(); sua.remote_sua.initialize(); sua.AssocDB.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++