libsua/sualibrary/sua/sua_database.cpp

840 lines
27 KiB
C++

/***************************************************************************
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.5 2003/08/28 09:30:20 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( SCTP_ulp_Callbacks APLCallbackFunctions,
Sua_ULP_CallBacks SUACallbackFunctions
){
int i;
short sua_portnumber = SUA_PORT;
#ifdef DEBUG
cout << "Number of local sua instance to register = " << num_of_instance << "\n";
#endif
for(i=1; i <= num_of_instance; i++)
{
#ifdef DEBUG
cout << "Register SUA(& SCTP) local instance nr " << i << ", SSN = "<< instance[i].ssn.ssn <<" \n";
#endif
char logstring[100];
sprintf(logstring, "Register SUA(& SCTP) local instance nr %d, SSN = %d",i,instance[i].ssn.ssn );
event_log("sua_database.c",logstring);
instance[i].SUA_APLCallBack.ulp_ClDataIndNotif = SUACallbackFunctions.ulp_ClDataIndNotif;
instance[i].SUA_APLCallBack.ulp_ConnIndNotif = SUACallbackFunctions.ulp_ConnIndNotif;
instance[i].SUA_APLCallBack.ulp_ConnConfIndNotif = SUACallbackFunctions.ulp_ConnConfIndNotif;
instance[i].SUA_APLCallBack.ulp_ConnDataIndNotif = SUACallbackFunctions.ulp_ConnDataIndNotif;
instance[i].SUA_APLCallBack.ulp_DisConnIndNotif = SUACallbackFunctions.ulp_DisConnIndNotif;
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].max_streams,
instance[i].max_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);
return(0);
}
/***********************************************************************/
/* Sua_LocalList::found */
/***********************************************************************/
bool db_Sua_LocalList:: found( SS7union pc ){
int i = 1;
bool found_pc = false;
while (( i <= num_of_instance ) && (!found_pc))
{
if (pc.ITU14.family == ITU14bit) // standard ITU: 14 bits
found_pc = ((pc.ITU14.pc == instance[i].Source.pc.ITU14.pc));
else if (pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits
found_pc = ((pc.ITU24.pc == instance[i].Source.pc.ITU24.pc));
else if (pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits
found_pc = ((pc.ANSI24.pc == instance[i].Source.pc.ANSI24.pc));
else
found_pc = false;
i++;
}
return(found_pc);
}
/***********************************************************************/
/* functions of the object class SUA Remote Object */
/***********************************************************************/
/***********************************************************************/
/* Sua_RemoteObject::initalize */
/***********************************************************************/
void db_Sua_RemoteObject::initialize(){
status = ssnm_unavailable;
}
/***********************************************************************/
/* 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);
};
/***********************************************************************/
/* Sua_RemoteList::Dest_Available */
/***********************************************************************/
void db_Sua_RemoteList:: Dest_Available( SS7union pc)
{
int i = 0;
bool found_pc = false;
while (( i < num_of_instance ) && (!found_pc))
{
i++;
if (pc.ITU14.family == ITU14bit) // standard ITU: 14 bits
found_pc = ((pc.ITU14.pc == instance[i].Dest.pc.ITU14.pc));
else if (pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits
found_pc = ((pc.ITU24.pc == instance[i].Dest.pc.ITU24.pc));
else if (pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits
found_pc = ((pc.ANSI24.pc == instance[i].Dest.pc.ANSI24.pc));
else
found_pc = false;
};
if (found_pc)
instance[i].status = ssnm_available;
}
/***********************************************************************/
/* Sua_RemoteList::Dest_Unavailable */
/***********************************************************************/
void db_Sua_RemoteList:: Dest_Unavailable( SS7union pc)
{
int i = 0;
bool found_pc = false;
while (( i < num_of_instance ) && (!found_pc))
{
i++;
if (pc.ITU14.family == ITU14bit) // standard ITU: 14 bits
found_pc = ((pc.ITU14.pc == instance[i].Dest.pc.ITU14.pc));
else if (pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits
found_pc = ((pc.ITU24.pc == instance[i].Dest.pc.ITU24.pc));
else if (pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits
found_pc = ((pc.ANSI24.pc == instance[i].Dest.pc.ANSI24.pc));
else
found_pc = false;
};
if (found_pc)
instance[i].status = ssnm_unavailable;
}
/***********************************************************************/
/* Sua_RemoteList::deactivate_dests */
/***********************************************************************/
void db_Sua_RemoteList:: Deactivate_dests( unsigned int sua_assoc_id)
{
int i = 0;
while (( i < num_of_instance ))
{
i++;
if (sua_assoc_id == instance[i].SUA_assoc_id) // found assoc_id
instance[i].status = ssnm_unavailable;
}
}
/***********************************************************************/
/* Sua_RemoteList::Activate_dests */
/***********************************************************************/
void db_Sua_RemoteList:: Activate_dests( unsigned int sua_assoc_id)
{
int i = 0;
while (( i < num_of_instance ))
{
i++;
if (sua_assoc_id == instance[i].SUA_assoc_id) // found assoc_id
instance[i].status = ssnm_available;
}
}
/***********************************************************************/
/* Sua_RemoteList::get_Dest_status */
/***********************************************************************/
snm_Sua_pc_state_set db_Sua_RemoteList:: get_Dest_status( SS7union pc )
{
int i = 0;
bool found_pc = false;
while (( i < num_of_instance ) && (!found_pc))
{
i++;
if (pc.ITU14.family == ITU14bit) // standard ITU: 14 bits
found_pc = ((pc.ITU14.pc == instance[i].Dest.pc.ITU14.pc));
else if (pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits
found_pc = ((pc.ITU24.pc == instance[i].Dest.pc.ITU24.pc));
else if (pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits
found_pc = ((pc.ANSI24.pc == instance[i].Dest.pc.ANSI24.pc));
else
found_pc = false;
}
if (found_pc)
return(instance[i].status);
else
return(ssnm_unavailable);
}
/***********************************************************************/
/* Sua_RemoteList::found */
/***********************************************************************/
bool db_Sua_RemoteList:: found( SS7union pc ){
int i = 0;
bool found_pc = false;
while (( i < num_of_instance ) && (!found_pc))
{
i++;
if (pc.ITU14.family == ITU14bit) // standard ITU: 14 bits
found_pc = ((pc.ITU14.pc == instance[i].Dest.pc.ITU14.pc));
else if (pc.ITU24.family == ITU24bit) // chinese PC length: 24 bits
found_pc = ((pc.ITU24.pc == instance[i].Dest.pc.ITU24.pc));
else if (pc.ANSI24.family == ANSI24bit) // ANSI PC length: 24 bits
found_pc = ((pc.ANSI24.pc == instance[i].Dest.pc.ANSI24.pc));
else
found_pc = false;
}
return(found_pc);
}
/***********************************************************************/
/* 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