diff options
Diffstat (limited to 'sualibrary/sua/sua_cl.cpp')
-rw-r--r-- | sualibrary/sua/sua_cl.cpp | 302 |
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); } |