aboutsummaryrefslogtreecommitdiffstats
path: root/sualibrary/sua/sua_cl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sualibrary/sua/sua_cl.cpp')
-rw-r--r--sualibrary/sua/sua_cl.cpp302
1 files changed, 239 insertions, 63 deletions
diff --git a/sualibrary/sua/sua_cl.cpp b/sualibrary/sua/sua_cl.cpp
index 4ec0bb7..10eaf6e 100644
--- a/sualibrary/sua/sua_cl.cpp
+++ b/sualibrary/sua/sua_cl.cpp
@@ -15,7 +15,7 @@
* *
***************************************************************************/
/*
- * $Id: sua_cl.cpp,v 1.1.1.1 2002/02/04 14:30:41 p82609 Exp $
+ * $Id: sua_cl.cpp,v 1.3 2002/03/01 12:57:38 p82609 Exp $
*
* SUA implementation according to SUA draft issue 6.
*
@@ -48,7 +48,9 @@
* inspiration : Dorothee
* "Always admire the local beauties in their natural enviroment."
*
- * Purpose: This code-file defines the SUA connectionless message handling:
+ * Purpose: This code-file defines the SUA connectionless message handling:
+ * - send a SUA message(CL or CO) to SCTP
+ * - route a SUA message(CL or CO)
* - send a Unitdata msg to remote node
* (- send a Unitdata Service msg to remote node)
* - Process a Unitdata msg
@@ -92,24 +94,180 @@ extern tcb_Sua_msgqueue_pool msg_store;
// import the received msg pool
extern vector<sua_save_str> rec_msg_pool;
+
+/***********************************************************************/
+/* sua_send_Message */
+/***********************************************************************/
+int sua_send_Message( signed int sctp_assoc_id,
+ short int sctp_stream_id,
+ int sctp_delivery_type,
+ unsigned int sctp_loadshare,
+ char *databuf,
+ unsigned int datalen
+ )
+{
+ signed int result;
+ /* send data to SCTP */
+ /* yes it does, continue, no problem, send the msg */
+#ifdef DEBUG
+ /* display byte array */
+ display_byte_array(databuf , datalen);
+#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,datalen);
+
+ result = sctp_send ( sctp_assoc_id,
+ sctp_stream_id,
+ (unsigned char *) databuf,
+ datalen,
+ SUA_PPI,
+ SCTP_USE_PRIMARY, /* replace in future with sctp_loadshare*/
+ SCTP_NO_CONTEXT,
+ SCTP_INFINITE_LIFETIME,
+ sctp_delivery_type,
+ SCTP_BUNDLING_DISABLED
+ );
+
+
+#ifdef DEBUG
+ cout << "sua_cl.c:result sctp send = "<< result << "\n";
+ printf( "%d \n", result);
+#endif
+
+ return(result);
+}
+
+/***********************************************************************/
+/* sua_route_Message */
+/***********************************************************************/
+int sua_route_Message( unsigned int sctp_assoc_id,
+ unsigned int local_sua_id,
+ Sua_container &msg,
+ sccp_addr_str &called_pty_address,
+ sccp_addr_str &calling_pty_address
+ )
+{
+ int result = 0;
+ short int sctp_stream_id = 0;
+ int sctp_delivery_type = SCTP_UNORDERED_DELIVERY;
+ signed int sctp_loadshare = SCTP_USE_PRIMARY;
+ int sua_assoc_id = 0;
+ int datalen = 0;
+ Sua_syntax_error_struct error;
+
+ // 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,
+ sua_assoc_id
+ );
+#ifdef DEBUG
+ cout << "routed to SCTP assoc " << sctp_assoc_id << "/SUA assoc id " << sua_assoc_id <<"\n";
+#endif
+
+ /* does association exist? */
+ if (sctp_assoc_id > 0)
+ {
+ /* YES, encode the SUA unitdata message and ... */
+ error = msg.sua_encode();
+
+ /* figure out SCTP delivery type, stream to send msg on,...and.. */
+ if (msg.sua_prim.prot_class_pres)
+ {
+ switch(msg.sua_prim.prot_class.pcl)
+ {
+ case(prot_class_0): /* connectionless transport, non sequenced */
+ sctp_delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ case(prot_class_1): /* connectionless transport, sequenced */
+ sctp_delivery_type = SCTP_ORDERED_DELIVERY;
+ break;
+ case(prot_class_2): /* connection-oriented transport, ... */
+ sctp_delivery_type = SCTP_ORDERED_DELIVERY;
+ break;
+ case(prot_class_3): /* connection-oriented transport, ... */
+ sctp_delivery_type = SCTP_ORDERED_DELIVERY;
+ break;
+ default:
+ sctp_delivery_type = SCTP_UNORDERED_DELIVERY;
+ break;
+ }
+ sctp_stream_id = Assoc_sua.instance[sua_assoc_id].nr_of_outbound_streams;
+ sctp_stream_id = 0;
+ }
+ else
+ {
+
+ sctp_stream_id = 0;
+ }
+
+ /* copy data into buffer, then finally... */
+ char* databuf = new char[msg.sua_msg.length()];
+ msg.sua_msg.copy(databuf, msg.sua_msg.length());
+
+ datalen = msg.sua_msg.length();
+
+ // send data to SCTP
+ result = sua_send_Message( sctp_assoc_id,
+ sctp_stream_id,
+ sctp_delivery_type,
+ sctp_loadshare,
+ databuf,
+ datalen
+ );
+
+ delete databuf;
+
+#ifdef DEBUG
+ cout.setf(ios::internal);
+ cout << "sua_cl.c:result sua send = "<< result << "\n";
+#endif
+
+ }
+ else if (sctp_assoc_id < 0)
+ {
+ /* NOPE, message is routable, but destination is blocked */
+ /* due to administration or management descisions */
+#ifdef DEBUG
+ cout << "sua_cl.c:sending msg prohibited \n";
+#endif
+ result = -1;
+ }
+ else
+ {
+ /* NOPE message is NOT routable, destination not found. */
+ /* drop the message, no route present for that address */
+ result = 0;
+ }
+
+ return(result);
+
+}
+
/***********************************************************************/
/* 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
- )
+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 error_value = 0;
int string_size, datalen;
signed int sctp_assoc_id;
- unsigned int sua_assoc_id;
- short stream_id = 0;
- int delivery_type, result;
+ int sua_assoc_id;
+ short sctp_stream_id = 0;
+ signed int sctp_loadshare = SCTP_USE_PRIMARY;
+ int sctp_delivery_type, result;
tcb_Sua_msg_elem sua_msg;
// init the message
@@ -134,14 +292,14 @@ int sua_send_Unitdata(sccp_QOS_str &QOS,
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;
+ sctp_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;
+ sctp_delivery_type = SCTP_ORDERED_DELIVERY;
break;
default:
return(PROTOCOL_CLASS_NOT_SPECIFIED);
@@ -297,46 +455,35 @@ int sua_send_Unitdata(sccp_QOS_str &QOS,
cout << "call routing function\n";
#endif
sctp_assoc_id = Assoc_sua.route_msg( called_pty_address,
- calling_pty_address
- );
+ calling_pty_address,
+ sua_assoc_id
+ );
#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()];
+ /* copy data into buffer, then finally... */
+ 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;
+ datalen = msg.sua_msg.length();
+
+ // send data to SCTP
+ result = sua_send_Message( sctp_assoc_id,
+ sctp_stream_id,
+ sctp_delivery_type,
+ sctp_loadshare,
+ databuf,
+ datalen
+ );
+
+ delete databuf;
#ifdef DEBUG
cout << "sua_cl.c:result sctp send = "<< result << "\n";
#endif
+ error_value = 0;
}
else if (sctp_assoc_id < 0)
{
@@ -361,12 +508,12 @@ int sua_send_Unitdata(sccp_QOS_str &QOS,
/* - 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.delivery_type = sctp_delivery_type;
+ sua_msg.stream_id = sctp_stream_id;
sua_msg.valid = true;
msg_store.add_msg ( sua_assoc_id,
- sua_msg
- );
+ sua_msg
+ );
error_value = -1;
}
@@ -385,8 +532,9 @@ short process_unitdata_msg ( int local_sua_id,
Sua_container &msg
)
{
-
sua_save_str temp;
+ int result = 0;
+ int sctp_assoc_id = 0;
temp.primitive = N_UNITDATA;
temp.user_ref = 0;
@@ -435,7 +583,7 @@ short process_unitdata_msg ( int local_sua_id,
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.family = Assoc_sua.instance[sua_assoc_id].Dest.pc.ITU14.family;
temp.calling_pty_address.pc.ss7.ITU24.pc = msg.sua_prim.source_addr.pc;
}
if (msg.sua_prim.source_addr.gt_pres == TRUE)
@@ -483,11 +631,25 @@ short process_unitdata_msg ( int local_sua_id,
// retrieve the called(=destination) address(=should be our own local addr)
// not completely done yet
+ if (msg.sua_prim.dest_addr.ip_addr_pres == TRUE)
+ {
+ temp.called_pty_address.address_fields_present.pc = ipvx_pc_present;
+ if (msg.sua_prim.dest_addr.ip_addr_type == ip_v4) {
+ temp.called_pty_address.pc.ipvx.sin = msg.sua_prim.dest_addr.ip_addr.ipv4;
+ temp.called_pty_address.pc.ipvx.sa.sa_family = AF_INET;
+ temp.called_pty_address.pc.ipvx.sin.sin_port = Assoc_sua.instance[sua_assoc_id].Dest.addrs[0].sin.sin_port;
+ }
+ else if (msg.sua_prim.dest_addr.ip_addr_type == ip_v6) {
+ temp.called_pty_address.pc.ipvx.sin6 = msg.sua_prim.dest_addr.ip_addr.ipv6;
+ temp.called_pty_address.pc.ipvx.sa.sa_family = AF_INET6;
+ temp.called_pty_address.pc.ipvx.sin6.sin6_port = Assoc_sua.instance[sua_assoc_id].Dest.addrs[0].sin.sin_port;
+ }
+ }
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;
+ temp.called_pty_address.pc.ss7.ITU24.family = Assoc_sua.instance[sua_assoc_id].Dest.pc.ITU14.family;
+ temp.called_pty_address.pc.ss7.ITU24.pc = msg.sua_prim.dest_addr.pc;
}
if (msg.sua_prim.dest_addr.hostname_pres == TRUE)
@@ -525,19 +687,33 @@ short process_unitdata_msg ( int local_sua_id,
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()
- );
+ /* Is this the final destination ? */
+ if ( Assoc_sua.Find_local_sua ( temp.called_pty_address) > 0 )
+ {
+ /* Yes, message has arrived at its final destination -> send to upper layer */
+ /* 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()
+ );
+ }
+ else
+ {
+ /* No, Message has not arrived at its final destination -> */
+ /* route it to the next SUA node via an SCTP association nr x */
+ result = sua_route_Message( sctp_assoc_id,
+ local_sua_id,
+ msg,
+ temp.called_pty_address,
+ temp.calling_pty_address
+ );
+ }
+
return(0);
}