diff options
Diffstat (limited to 'sualibrary/sua/sua_co.cpp')
-rw-r--r-- | sualibrary/sua/sua_co.cpp | 1038 |
1 files changed, 690 insertions, 348 deletions
diff --git a/sualibrary/sua/sua_co.cpp b/sualibrary/sua/sua_co.cpp index cdfbbaa..607423e 100644 --- a/sualibrary/sua/sua_co.cpp +++ b/sualibrary/sua/sua_co.cpp @@ -15,7 +15,7 @@ * * ***************************************************************************/ /* - * $Id: sua_co.cpp,v 1.2 2002/03/01 12:57:38 p82609 Exp $ + * $Id: sua_co.cpp,v 1.7 2002/11/12 11:02:49 p82609 Exp $ * * SUA implementation according to SUA draft issue 6. * @@ -91,9 +91,7 @@ using namespace std; // import the dataobjects of SUA -extern db_Sua_LocalList local_sua; -extern db_Sua_RemoteList remote_sua; -extern db_Sua_AssociationList Assoc_sua; +extern db_Sua_DatabaseList sua; // import the TCB pool of SUA extern tcb_Sua_TCB_arr tcb_pool; @@ -117,16 +115,16 @@ int sua_send_CORE( sccp_QOS_str &QOS, tcb_Sua_TCB_str *tcb_ptr ) { - Sua_container msg; - Sua_syntax_error_struct error; - int error_value; - int string_size, datalen; - signed int SCTP_assoc_id; - int sua_assoc_id; - signed int sctp_loadshare = SCTP_USE_PRIMARY; - short sctp_stream_id = 0; - int sctp_delivery_type, result; - tcb_Sua_msg_elem sua_msg; + Sua_container msg; + Sua_syntax_error_struct error; + int error_value; + int i, string_size, datalen; + signed int SCTP_assoc_id; + int sua_assoc_id; + signed int sctp_loadshare = SCTP_USE_PRIMARY; + short sctp_stream_id = 0; + int sctp_delivery_type, result; + tcb_Sua_msg_elem sua_msg; // init the message @@ -214,10 +212,30 @@ int sua_send_CORE( sccp_QOS_str &QOS, case(route_on_name_gt): msg.sua_prim.source_addr.ip_addr_pres = FALSE; msg.sua_prim.source_addr.pc_pres = FALSE; - msg.sua_prim.source_addr.hostname_pres = TRUE; - msg.sua_prim.source_addr.hostname = calling_pty_address.name.HostName; - msg.sua_prim.source_addr_pres = TRUE; - msg.sua_prim.source_addr.rout_ind = ri_route_hostname; + if (calling_pty_address.address_fields_present.name_gt == hostname_present){ + msg.sua_prim.source_addr_pres = TRUE; + msg.sua_prim.source_addr.rout_ind = ri_route_hostname; + msg.sua_prim.source_addr.hostname_pres = TRUE; + msg.sua_prim.source_addr.gt_pres = FALSE; + msg.sua_prim.source_addr.hostname = calling_pty_address.name.HostName; + + } + else if (calling_pty_address.address_fields_present.name_gt == GT_present){ + msg.sua_prim.source_addr_pres = TRUE; + msg.sua_prim.source_addr.rout_ind = ri_route_GT; + msg.sua_prim.source_addr.hostname_pres = FALSE; + msg.sua_prim.source_addr.gt_pres = TRUE; + msg.sua_prim.source_addr.gt.translation_type = calling_pty_address.name.GT.Translation_Type; + msg.sua_prim.source_addr.gt.num_plan = calling_pty_address.name.GT.Numbering_Plan; + msg.sua_prim.source_addr.gt.nat_addr = calling_pty_address.name.GT.Nature_of_Address; + msg.sua_prim.source_addr.gt.nr_of_digits = calling_pty_address.name.GT.nr_of_digits; + for (i=0; i < calling_pty_address.name.GT.nr_of_digits; i++) + msg.sua_prim.source_addr.gt.digits[i] = calling_pty_address.name.GT.digits[i]; + + } + else + cout << "unsupported CLG name/GT address option\n"; + msg.sua_prim.source_addr.ssn_incl = TRUE; msg.sua_prim.source_addr.pc_incl = FALSE; msg.sua_prim.source_addr.gt_incl = TRUE; @@ -279,11 +297,30 @@ int sua_send_CORE( sccp_QOS_str &QOS, break; case(route_on_name_gt): msg.sua_prim.dest_addr.ip_addr_pres = FALSE; - msg.sua_prim.dest_addr.hostname_pres = TRUE; msg.sua_prim.dest_addr.pc_pres = FALSE; - msg.sua_prim.dest_addr.hostname = called_pty_address.name.HostName; - msg.sua_prim.dest_addr_pres = TRUE; - msg.sua_prim.dest_addr.rout_ind = ri_route_hostname; + if (called_pty_address.address_fields_present.name_gt == hostname_present){ + msg.sua_prim.dest_addr_pres = TRUE; + msg.sua_prim.dest_addr.rout_ind = ri_route_hostname; + msg.sua_prim.dest_addr.hostname_pres = TRUE; + msg.sua_prim.dest_addr.gt_pres = FALSE; + msg.sua_prim.dest_addr.hostname = called_pty_address.name.HostName; + + } + else if (called_pty_address.address_fields_present.name_gt == GT_present){ + msg.sua_prim.dest_addr_pres = TRUE; + msg.sua_prim.dest_addr.rout_ind = ri_route_GT; + msg.sua_prim.dest_addr.hostname_pres = FALSE; + msg.sua_prim.dest_addr.gt_pres = TRUE; + msg.sua_prim.dest_addr.gt.translation_type = called_pty_address.name.GT.Translation_Type; + msg.sua_prim.dest_addr.gt.num_plan = called_pty_address.name.GT.Numbering_Plan; + msg.sua_prim.dest_addr.gt.nat_addr = called_pty_address.name.GT.Nature_of_Address; + msg.sua_prim.dest_addr.gt.nr_of_digits = called_pty_address.name.GT.nr_of_digits; + for (i=0; i < called_pty_address.name.GT.nr_of_digits; i++) + msg.sua_prim.dest_addr.gt.digits[i] = called_pty_address.name.GT.digits[i]; + } + else + cout << "unsupported CLG name/GT address option\n"; + msg.sua_prim.dest_addr.ssn_incl = TRUE; msg.sua_prim.dest_addr.pc_incl = FALSE; msg.sua_prim.dest_addr.gt_incl = TRUE; @@ -320,10 +357,10 @@ int sua_send_CORE( sccp_QOS_str &QOS, #ifdef DEBUG cout << "call routing function\n"; #endif - SCTP_assoc_id = Assoc_sua.route_msg( called_pty_address, - calling_pty_address, - sua_assoc_id - ); + SCTP_assoc_id = sua.route_msg( called_pty_address, + calling_pty_address, + sua_assoc_id + ); #ifdef DEBUG cout << "routed to SCTP assoc " << SCTP_assoc_id << "/SUA association " << sua_assoc_id << "\n"; #endif @@ -346,15 +383,15 @@ int sua_send_CORE( sccp_QOS_str &QOS, 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 - ); + result = sua_send_Message( SCTP_assoc_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); - delete databuf; + delete databuf; error_value = 0; #ifdef DEBUG @@ -372,16 +409,14 @@ int sua_send_CORE( sccp_QOS_str &QOS, { /* NO it does NOT exist. */ /* - Try to set up the association */ - sua_assoc_id = Assoc_sua.Dynamic_Associate ( local_sua, - remote_sua, - called_pty_address, - calling_pty_address, - 1, - 1, - 1 - ); + sua_assoc_id = sua.Dynamic_Associate ( called_pty_address, + calling_pty_address, + 1, + 1, + 1 + ); /* save newly assigned SCTP association id in SCOC TCB */ - tcb_ptr->sctp_Association_id = Assoc_sua.instance[sua_assoc_id].SCTP_assoc_id; + tcb_ptr->sctp_Association_id = sua.AssocDB.instance[sua_assoc_id].SCTP_assoc_id; /* - save the msg till the association is setup or */ /* association setup fails -> drop saved msg */ @@ -391,11 +426,11 @@ int sua_send_CORE( sccp_QOS_str &QOS, sua_msg.valid = true; msg_store.add_msg ( sua_assoc_id, sua_msg - ); + ); error_value = -1; } - + return(error_value); } @@ -433,11 +468,11 @@ int sua_send_CORESP( sccp_QOS_str &QOS, msg.sua_prim.importance = 5; msg.sua_prim.hop_count_pres = TRUE; msg.sua_prim.hop_count = 15; - + // QOS choice switch (QOS.prot_class) { - case(class2): // connectionless transport, non-sequenced + case(class2): // connection-oriented transport, non-sequenced msg.sua_prim.prot_class_pres = TRUE; msg.sua_prim.prot_class.pcl = prot_class_2; msg.sua_prim.seq_control_pres = TRUE; @@ -455,7 +490,7 @@ int sua_send_CORESP( sccp_QOS_str &QOS, msg.sua_prim.prot_class.return_option = TRUE; else msg.sua_prim.prot_class.return_option = FALSE; - + // fill in the connection-oriented specific data of the msg msg.sua_prim.source_ref_pres = TRUE; msg.sua_prim.source_ref = tcb_ptr->Source_LR ; @@ -475,7 +510,7 @@ int sua_send_CORESP( sccp_QOS_str &QOS, if (len > 0) { msg.sua_prim.data_pres = TRUE; - string stemp(buffer,len); + string stemp(buffer,len); msg.sua_prim.data_string = stemp; } else @@ -492,32 +527,32 @@ int sua_send_CORESP( sccp_QOS_str &QOS, #endif #ifdef SUA_MANAGEMENT - sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id, + sua_assoc_id = sua.AssocDB.Find_association( SCTP_assoc_id, local_sua_id, remote_sua_id ); - if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active) + if (sua.AssocDB.instance[sua_assoc_id].asp.status == asp_active) { #endif /* copy data into buffer, then finally... */ - char* databuf = new char[msg.sua_msg.length()]; + 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; + result = sua_send_Message( SCTP_assoc_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; error_value = 0; - + #ifdef SUA_MANAGEMENT } else @@ -528,11 +563,11 @@ int sua_send_CORESP( sccp_QOS_str &QOS, error_value = -1; } #endif - + #ifdef DEBUG cout << "sua_co.c:result sctp send = "<< result << "\n"; #endif - + return(error_value); } @@ -556,7 +591,7 @@ int sua_send_CODATA( sccp_QOS_str &QOS, signed int sctp_loadshare = SCTP_USE_PRIMARY; short sctp_stream_id = 0; int sctp_delivery_type, result = 0; - + // init the message msg.sua_init(); @@ -593,8 +628,8 @@ int sua_send_CODATA( sccp_QOS_str &QOS, msg.sua_prim.prot_class.return_option = TRUE; else msg.sua_prim.prot_class.return_option = FALSE; - - + + // fill in the connection-oriented specific data of the msg msg.sua_prim.source_ref_pres = FALSE; msg.sua_prim.dest_ref_pres = TRUE; @@ -611,7 +646,7 @@ int sua_send_CODATA( sccp_QOS_str &QOS, // fill in the user data msg.sua_prim.data_pres = TRUE; - string stemp(buffer,len); + string stemp(buffer,len); msg.sua_prim.data_string = stemp; // encode the SUA unitdata message @@ -624,33 +659,33 @@ int sua_send_CODATA( sccp_QOS_str &QOS, cout << "routed to SCTP assoc " << SCTP_assoc_id << "\n"; #endif #ifdef SUA_MANAGEMENT - sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id, + sua_assoc_id = sua.AssocDB.Find_association( SCTP_assoc_id, local_sua_id, remote_sua_id ); - if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active) + if (sua.AssocDB.instance[sua_assoc_id].asp.status == asp_active) { #endif - /* copy data into buffer, then finally... */ - 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(); - + // send data to SCTP - result = sua_send_Message( SCTP_assoc_id, - sctp_stream_id, - sctp_delivery_type, - sctp_loadshare, - databuf, - datalen - ); - - delete databuf; + result = sua_send_Message( SCTP_assoc_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; error_value = 0; - + #ifdef SUA_MANAGEMENT } else @@ -661,11 +696,11 @@ int sua_send_CODATA( sccp_QOS_str &QOS, error_value = -1; } #endif - + #ifdef DEBUG cout << "sua_co.c:result sctp send = "<< result << "\n"; #endif - + return(error_value); } @@ -689,7 +724,7 @@ int sua_send_CORELRQ( sccp_QOS_str &QOS, signed int sctp_loadshare = SCTP_USE_PRIMARY; short sctp_stream_id = 0; int sctp_delivery_type, result = 0; - + // init the message msg.sua_init(); @@ -726,8 +761,8 @@ int sua_send_CORELRQ( sccp_QOS_str &QOS, msg.sua_prim.prot_class.return_option = TRUE; else msg.sua_prim.prot_class.return_option = FALSE; - - + + // fill in the connection-oriented specific data of the msg msg.sua_prim.source_ref_pres = TRUE; msg.sua_prim.source_ref = tcb_ptr->Source_LR ; @@ -748,7 +783,7 @@ int sua_send_CORELRQ( sccp_QOS_str &QOS, // fill in the user data msg.sua_prim.data_pres = TRUE; - string stemp(buffer,len); + string stemp(buffer,len); msg.sua_prim.data_string = stemp; // encode the SUA unitdata message @@ -762,32 +797,32 @@ int sua_send_CORELRQ( sccp_QOS_str &QOS, #endif #ifdef SUA_MANAGEMENT - sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id, - local_sua_id, - remote_sua_id - ); - - if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active) + sua_assoc_id = sua.AssocDB.Find_association( SCTP_assoc_id, + local_sua_id, + remote_sua_id + ); + + if (sua.AssocDB.instance[sua_assoc_id].asp.status == asp_active) { #endif - /* copy data into buffer, then finally... */ - 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(); - + // send data to SCTP - result = sua_send_Message( SCTP_assoc_id, - sctp_stream_id, - sctp_delivery_type, - sctp_loadshare, - databuf, - datalen - ); - - delete databuf; + result = sua_send_Message( SCTP_assoc_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; error_value = 0; - + #ifdef SUA_MANAGEMENT } else @@ -798,11 +833,11 @@ int sua_send_CORELRQ( sccp_QOS_str &QOS, error_value = -1; } #endif - + #ifdef DEBUG cout << "sua_co.c:result sctp send = "<< result << "\n"; #endif - + return(error_value); } @@ -826,7 +861,7 @@ int sua_send_CORELCO( sccp_QOS_str &QOS, signed int sctp_loadshare = SCTP_USE_PRIMARY; short sctp_stream_id = 0; int sctp_delivery_type, result = 0; - + // init the message msg.sua_init(); @@ -863,8 +898,8 @@ int sua_send_CORELCO( sccp_QOS_str &QOS, msg.sua_prim.prot_class.return_option = TRUE; else msg.sua_prim.prot_class.return_option = FALSE; - - + + // fill in the connection-oriented specific data of the msg msg.sua_prim.source_ref_pres = TRUE; msg.sua_prim.source_ref = tcb_ptr->Source_LR ; @@ -876,7 +911,7 @@ int sua_send_CORELCO( sccp_QOS_str &QOS, // fill in the user data msg.sua_prim.data_pres = TRUE; - string stemp(buffer,len); + string stemp(buffer,len); msg.sua_prim.data_string = stemp; // encode the SUA unitdata message @@ -895,32 +930,32 @@ int sua_send_CORELCO( sccp_QOS_str &QOS, #endif #ifdef SUA_MANAGEMENT - sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id, + sua_assoc_id = sua.AssocDB.Find_association( SCTP_assoc_id, local_sua_id, remote_sua_id ); - if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active) + if (sua.AssocDB.instance[sua_assoc_id].asp.status == asp_active) { #endif - /* copy data into buffer, then finally... */ - 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(); - + // send data to SCTP - result = sua_send_Message( SCTP_assoc_id, - sctp_stream_id, - sctp_delivery_type, - sctp_loadshare, - databuf, - datalen - ); - - delete databuf; + result = sua_send_Message( SCTP_assoc_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; error_value = 0; - + #ifdef SUA_MANAGEMENT } else @@ -931,14 +966,14 @@ int sua_send_CORELCO( sccp_QOS_str &QOS, error_value = -1; } #endif - + #ifdef DEBUG cout << "sua_co.c:result sctp send = "<< result << "\n"; #endif - + // release the TCB of this connection tcb_pool.release_TCB(Sua_ConnId); - + return(error_value); } @@ -962,7 +997,7 @@ int sua_send_COREF( sccp_QOS_str &QOS, signed int sctp_loadshare = SCTP_USE_PRIMARY; short sctp_stream_id = 0; int sctp_delivery_type, result = 0; - sccp_addr_str called_pty_address; + sccp_addr_str called_pty_address; // init the message msg.sua_init(); @@ -1001,17 +1036,17 @@ int sua_send_COREF( sccp_QOS_str &QOS, msg.sua_prim.prot_class.return_option = FALSE; called_pty_address = tcb_ptr->remote_address; - + // fill in the destination address(=remote sua address/CLD) - switch (called_pty_address.routing_ind) + switch (called_pty_address.routing_ind) { case (route_on_ssn): - + if (called_pty_address.address_fields_present.pc == ipvx_pc_present) { msg.sua_prim.dest_addr.ip_addr_pres = TRUE; if (called_pty_address.pc.ipvx.sa.sa_family == AF_INET) - { + { msg.sua_prim.dest_addr.ip_addr_type = ip_v4; msg.sua_prim.dest_addr.ip_addr.ipv4 = called_pty_address.pc.ipvx.sin; } @@ -1040,7 +1075,7 @@ int sua_send_COREF( sccp_QOS_str &QOS, return(INVALID_CLD_ADDRESS); break; } - + // fill in the connection-oriented specific data of the msg msg.sua_prim.source_ref_pres = FALSE; msg.sua_prim.dest_ref_pres = TRUE; @@ -1051,7 +1086,7 @@ int sua_send_COREF( sccp_QOS_str &QOS, // fill in the user data msg.sua_prim.data_pres = TRUE; - string stemp(buffer,len); + string stemp(buffer,len); msg.sua_prim.data_string = stemp; // encode the SUA unitdata message @@ -1070,32 +1105,32 @@ int sua_send_COREF( sccp_QOS_str &QOS, #endif #ifdef SUA_MANAGEMENT - sua_assoc_id = Assoc_sua.Find_association( SCTP_assoc_id, - local_sua_id, - remote_sua_id - ); - - if (Assoc_sua.instance[sua_assoc_id].asp.status == asp_active) + sua_assoc_id = sua.AssocDB.Find_association( SCTP_assoc_id, + local_sua_id, + remote_sua_id + ); + + if (sua.AssocDB.instance[sua_assoc_id].asp.status == asp_active) { #endif - /* copy data into buffer, then finally... */ - 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(); - + // send data to SCTP - result = sua_send_Message( SCTP_assoc_id, - sctp_stream_id, - sctp_delivery_type, - sctp_loadshare, - databuf, - datalen - ); + result = sua_send_Message( SCTP_assoc_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); - delete databuf; + delete databuf; error_value = 0; - + #ifdef SUA_MANAGEMENT } else @@ -1129,12 +1164,16 @@ short process_CORE_msg ( unsigned int sua_assoc_id, Sua_container &msg ) { - unsigned int local_sua_id = 0; - sua_save_str temp; + int i, result = 0; + int sctp_assoc_id = 0; + unsigned int local_sua_id = 0; + sua_save_str temp; + unsigned int Sua_Out_ConnId; + tcb_Sua_TCB_str *tcb_out_ptr; temp.primitive = N_CONNECT_IND; temp.user_ref = Sua_ConnId; - + if ( msg.sua_prim.prot_class_pres ) { // QOS choice @@ -1152,7 +1191,7 @@ short process_CORE_msg ( unsigned int sua_assoc_id, return(PROTOCOL_CLASS_NOT_SPECIFIED); break; } - + temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE); } @@ -1163,16 +1202,16 @@ short process_CORE_msg ( unsigned int sua_assoc_id, // which types are present in the address(ip pc, SS7 pc, GT, hostname) if (msg.sua_prim.source_addr.ip_addr_pres == TRUE) { - temp.calling_pty_address.address_fields_present.pc = ipvx_pc_present; + temp.calling_pty_address.address_fields_present.pc = ipvx_pc_present; if (msg.sua_prim.source_addr.ip_addr_type == ip_v4) { temp.calling_pty_address.pc.ipvx.sin = msg.sua_prim.source_addr.ip_addr.ipv4; temp.calling_pty_address.pc.ipvx.sa.sa_family = AF_INET; - temp.calling_pty_address.pc.ipvx.sin.sin_port = Assoc_sua.instance[sua_assoc_id].Dest.addrs[0].sin.sin_port; + temp.calling_pty_address.pc.ipvx.sin.sin_port = sua.AssocDB.instance[sua_assoc_id].Dest.addrs[0].sin.sin_port; } else if (msg.sua_prim.source_addr.ip_addr_type == ip_v6) { temp.calling_pty_address.pc.ipvx.sin6 = msg.sua_prim.source_addr.ip_addr.ipv6; temp.calling_pty_address.pc.ipvx.sa.sa_family = AF_INET6; - temp.calling_pty_address.pc.ipvx.sin6.sin6_port = Assoc_sua.instance[sua_assoc_id].Dest.addrs[0].sin6.sin6_port; + temp.calling_pty_address.pc.ipvx.sin6.sin6_port = sua.AssocDB.instance[sua_assoc_id].Dest.addrs[0].sin6.sin6_port; } else cout << "Unknown IP address format\n"; @@ -1180,16 +1219,29 @@ short process_CORE_msg ( unsigned int sua_assoc_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 = ITU24bit; temp.calling_pty_address.pc.ss7.ITU24.pc = msg.sua_prim.source_addr.pc; } if (msg.sua_prim.source_addr.gt_pres == TRUE) { cout << "Global Title : unsupported address format\n"; } + + if (msg.sua_prim.source_addr.gt_pres == TRUE) + { + temp.calling_pty_address.address_fields_present.name_gt = GT_present; + temp.calling_pty_address.name.GT.Translation_Type = msg.sua_prim.source_addr.gt.translation_type; + temp.calling_pty_address.name.GT.Numbering_Plan = msg.sua_prim.source_addr.gt.num_plan; + temp.calling_pty_address.name.GT.Nature_of_Address = msg.sua_prim.source_addr.gt.nat_addr; + temp.calling_pty_address.name.GT.nr_of_digits = msg.sua_prim.source_addr.gt.nr_of_digits; + for (i=0; i < temp.calling_pty_address.name.GT.nr_of_digits; i++) + temp.calling_pty_address.name.GT.digits[i] = msg.sua_prim.source_addr.gt.digits[i]; + temp.calling_pty_address.name.GT.digits[temp.calling_pty_address.name.GT.nr_of_digits] = '\0'; + } + if (msg.sua_prim.source_addr.hostname_pres == TRUE) { - temp.calling_pty_address.address_fields_present.name_gt = hostname_present; + temp.calling_pty_address.address_fields_present.name_gt = hostname_present; msg.sua_prim.source_addr.hostname.copy( temp.calling_pty_address.name.HostName, (msg.sua_prim.source_addr.hostname.length()+1 ) ); @@ -1222,31 +1274,60 @@ short process_CORE_msg ( unsigned int sua_assoc_id, break; } - if (msg.sua_prim.source_addr.ssn_incl == TRUE) { + if (msg.sua_prim.source_addr.ssn_incl == TRUE) { temp.calling_pty_address.address_fields_present.ssn_port = ssn_present; temp.calling_pty_address.ssn = msg.sua_prim.source_addr.ssn; } else temp.calling_pty_address.address_fields_present.ssn_port = no_sap_present; - + // 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 = sua.AssocDB.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 = sua.AssocDB.instance[sua_assoc_id].Dest.addrs[0].sin6.sin6_port; + } + else + cout << "Unknown IP address format\n"; + } 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 = ITU24bit; + temp.called_pty_address.pc.ss7.ITU24.pc = msg.sua_prim.dest_addr.pc; + } + + if (msg.sua_prim.dest_addr.gt_pres == TRUE) + { + temp.called_pty_address.address_fields_present.name_gt = GT_present; + temp.called_pty_address.name.GT.Translation_Type = msg.sua_prim.dest_addr.gt.translation_type; + temp.called_pty_address.name.GT.Numbering_Plan = msg.sua_prim.dest_addr.gt.num_plan; + temp.called_pty_address.name.GT.Nature_of_Address = msg.sua_prim.dest_addr.gt.nat_addr; + temp.called_pty_address.name.GT.nr_of_digits = msg.sua_prim.dest_addr.gt.nr_of_digits; + for (i=0; i < temp.called_pty_address.name.GT.nr_of_digits; i++) + temp.called_pty_address.name.GT.digits[i] = msg.sua_prim.dest_addr.gt.digits[i]; + temp.called_pty_address.name.GT.digits[temp.called_pty_address.name.GT.nr_of_digits] = '\0'; } if (msg.sua_prim.dest_addr.hostname_pres == TRUE) { - temp.called_pty_address.address_fields_present.name_gt = hostname_present; + temp.called_pty_address.address_fields_present.name_gt = hostname_present; msg.sua_prim.dest_addr.hostname.copy( temp.called_pty_address.name.HostName, (msg.sua_prim.dest_addr.hostname.length()+1 ) ); temp.called_pty_address.name.HostName[msg.sua_prim.dest_addr.hostname.length()] = '\0'; } + // routing indicator switch (msg.sua_prim.dest_addr.rout_ind) { @@ -1262,20 +1343,20 @@ short process_CORE_msg ( unsigned int sua_assoc_id, default: break; } - + temp.called_pty_address.address_fields_present.ssn_port = ssn_present; - temp.called_pty_address.ssn = msg.sua_prim.dest_addr.ssn; + temp.called_pty_address.ssn = msg.sua_prim.dest_addr.ssn; // fill in the allocated TCB tcb_ptr->Source_LR = Sua_ConnId; tcb_ptr->Dest_LR = msg.sua_prim.source_ref; tcb_ptr->User_ref_id = 1; - tcb_ptr->sctp_Association_id = Assoc_sua.instance[sua_assoc_id].SCTP_assoc_id; + tcb_ptr->sctp_Association_id = sua.AssocDB.instance[sua_assoc_id].SCTP_assoc_id; tcb_ptr->state = scoc_incoming; tcb_ptr->remote_address = temp.calling_pty_address; tcb_ptr->seq_number = Sua_ConnId % 255; - local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id; + local_sua_id = sua.AssocDB.instance[sua_assoc_id].local_sua_id; #ifdef DEBUG cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n"; @@ -1288,22 +1369,55 @@ short process_CORE_msg ( unsigned int sua_assoc_id, temp.userdata = msg.sua_prim.data_string; else cout << "sua_co.c: no sua user data in CORE msg \n"; - - // store primitive in a list(is retrieve via sua_receive_msg) - rec_msg_pool.push_back(temp); -#ifdef DEBUG - cout << "primitive stored , local_sua_id = " << local_sua_id << "\n"; -#endif + /* Is this the final destination ? */ + if ( 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 */ + sua.local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_ConnIndNotif + ( local_sua_id, + Sua_ConnId, + 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 */ + /* setup TCB linkage for CO */ - /* call the application/user callBack function */ - local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_ConnIndNotif - ( local_sua_id, - Sua_ConnId, - temp.userdata.length() - ); + tcb_out_ptr = tcb_pool.allocate_TCB(Sua_Out_ConnId); - return(0); + msg.sua_prim.source_ref = Sua_Out_ConnId; + + result = sua_route_Message( sctp_assoc_id, + local_sua_id, + msg, + temp.called_pty_address, + temp.calling_pty_address + ); + + + // fill in the allocated TCB + tcb_out_ptr->Source_LR = Sua_Out_ConnId; + tcb_out_ptr->User_ref_id = 1; + tcb_out_ptr->sctp_Association_id = sctp_assoc_id; + /* fill in link from TCB_out to first TCB */ + tcb_out_ptr->scoc_tcb_id = Sua_ConnId; + tcb_out_ptr->state = scoc_outgoing; + tcb_out_ptr->remote_address = temp.called_pty_address; + tcb_out_ptr->seq_number = Sua_Out_ConnId % 255; + + /* fill in the link from the first TCB to the TCB_out */ + tcb_ptr->scoc_tcb_id = Sua_Out_ConnId; + } + + return(0); } /***********************************************************************/ @@ -1317,12 +1431,15 @@ short process_COAK_msg ( unsigned int sua_assoc_id, { unsigned int local_sua_id = 0; sua_save_str temp; + unsigned int Sua_Out_ConnId; + tcb_Sua_TCB_str *tcb_out_ptr; + Sua_syntax_error_struct error; temp.primitive = N_CONNECT_CONF; temp.user_ref = sua_ConnId; - + if (msg.sua_prim.prot_class_pres) - { + { // QOS choice switch ( msg.sua_prim.prot_class.pcl) { @@ -1338,15 +1455,15 @@ short process_COAK_msg ( unsigned int sua_assoc_id, return(PROTOCOL_CLASS_NOT_SPECIFIED); break; } - + temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE); } temp.QOS.sequence_number = 0; temp.QOS.importance = msg.sua_prim.importance; - + // retrieve the clg(=source) address (=remote sua address) - + // retrieve the called(=destination) address(=should be our own local addr) // fill in the allocated TCB @@ -1354,7 +1471,7 @@ short process_COAK_msg ( unsigned int sua_assoc_id, tcb_ptr->User_ref_id = 1; tcb_ptr->state = scoc_active; - local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id; + local_sua_id = sua.AssocDB.instance[sua_assoc_id].local_sua_id; #ifdef DEBUG cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n"; @@ -1367,20 +1484,68 @@ short process_COAK_msg ( unsigned int sua_assoc_id, temp.userdata = msg.sua_prim.data_string; else cout << "sua_co.c: no sua user data in CODATA 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_ConnConfIndNotif - ( local_sua_id, - sua_ConnId, - temp.userdata.length() - ); + /* Look if this is the end or intermediate node */ + Sua_Out_ConnId = tcb_ptr->scoc_tcb_id; - return(0); + /* Is this the final destination ? */ + if ( Sua_Out_ConnId == 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 */ + sua.local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_ConnConfIndNotif + ( local_sua_id, + sua_ConnId, + 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 */ + /* get association id from SCOC TCB */ + + tcb_out_ptr = tcb_pool.get_tcb(Sua_Out_ConnId); + + msg.sua_prim.source_ref = tcb_out_ptr->Source_LR; + msg.sua_prim.dest_ref = tcb_out_ptr->Dest_LR; + + error = msg.sua_encode(); + + /* copy data into buffer, then finally... */ + signed int sctp_loadshare = SCTP_USE_PRIMARY; + short sctp_stream_id = 0; + int sctp_delivery_type = 0 ,datalen , result = 0; + 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( tcb_out_ptr->sctp_Association_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; + + // set the outgoing TCB on active + tcb_out_ptr->state = scoc_active; + + } + + + return(0); } /***********************************************************************/ @@ -1394,20 +1559,23 @@ short process_CODATA_msg ( unsigned int sua_assoc_id, { unsigned int local_sua_id = 0; sua_save_str temp; + unsigned int Sua_Out_ConnId; + tcb_Sua_TCB_str *tcb_out_ptr; + Sua_syntax_error_struct error; //temp.primitive = N_CODATA; temp.user_ref = sua_ConnId; - + temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE); temp.QOS.sequence_number = 0; temp.QOS.importance = msg.sua_prim.importance; - + // retrieve the clg(=source) address (=remote sua address) // not needed -> to be found in TCB // retrieve the called(=destination) address(=should be our own local addr) // not needed -> to be found in TCB - local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id; + local_sua_id = sua.AssocDB.instance[sua_assoc_id].local_sua_id; #ifdef DEBUG cout << "TCB source_LR = " << tcb_ptr->Source_LR << "\n"; @@ -1420,21 +1588,62 @@ short process_CODATA_msg ( unsigned int sua_assoc_id, temp.userdata = msg.sua_prim.data_string; else cout << "sua_co.c: no sua user data in CODATA 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_ConnDataIndNotif - ( local_sua_id, - sua_ConnId, - temp.userdata.length() - ); - return(0); + /* Look if this is the end or intermediate node */ + Sua_Out_ConnId = tcb_ptr->scoc_tcb_id; + + /* Is this the final destination ? */ + if ( Sua_Out_ConnId == 0 ) + { + // store primitive in a list(is retrieve via sua_receive_msg) + rec_msg_pool.push_back(temp); + + /* call the application/user callBack function */ + sua.local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_ConnDataIndNotif + ( local_sua_id, + sua_ConnId, + 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 */ + /* get association id from SCOC TCB */ + + tcb_out_ptr = tcb_pool.get_tcb(Sua_Out_ConnId); + + msg.sua_prim.source_ref = tcb_out_ptr->Source_LR; + msg.sua_prim.dest_ref = tcb_out_ptr->Dest_LR; + + error = msg.sua_encode(); + + /* copy data into buffer, then finally... */ + signed int sctp_loadshare = SCTP_USE_PRIMARY; + short sctp_stream_id = 0; + int sctp_delivery_type = 0 ,datalen , result = 0; + 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( tcb_out_ptr->sctp_Association_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; + } + + return(0); + } /***********************************************************************/ @@ -1450,16 +1659,19 @@ short process_CORELRQ_msg ( unsigned int sua_assoc_id, unsigned int release_cause = 0; unsigned int routing_Contex = 0; sua_save_str temp; + unsigned int Sua_Out_ConnId; + tcb_Sua_TCB_str *tcb_out_ptr; + Sua_syntax_error_struct error; temp.primitive = N_RELEASE_REQ; temp.user_ref = sua_ConnId; - routing_Contex = msg.sua_prim.rout_con; + routing_Contex = msg.sua_prim.rout_con; temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE); temp.QOS.sequence_number = 0; temp.QOS.importance = msg.sua_prim.importance; - + // retrieve the clg(=source) address (=remote sua address) - + // retrieve the called(=destination) address(=should be our own local addr) tcb_ptr->state = scoc_disconnect; @@ -1474,99 +1686,141 @@ short process_CORELRQ_msg ( unsigned int sua_assoc_id, temp.userdata = msg.sua_prim.data_string; else cout << "sua_co.c: no sua user data in CODATA msg \n"; - - // store primitive in a list(is retrieve via sua_receive_msg) - rec_msg_pool.push_back(temp); - - // send a CORELCONF back to the remote node - Sua_syntax_error_struct error; - int datalen; - unsigned int assoc_id; - short stream_id = 0; - int delivery_type, result; - // init the message - msg.sua_init(); - // fill in the main sua header - msg.sua_prim.hdr_msg_class = sua_co; - msg.sua_prim.hdr_msg_type.co = co_relco; - - msg.sua_prim.rout_con_pres = TRUE; - msg.sua_prim.rout_con = routing_Contex; - msg.sua_prim.importance_pres = TRUE; - msg.sua_prim.importance = 7; - - // QOS choice - delivery_type = SCTP_UNORDERED_DELIVERY; - - // fill in the connection-oriented specific data of the msg - msg.sua_prim.source_ref_pres = TRUE; - msg.sua_prim.source_ref = tcb_ptr->Source_LR ; - msg.sua_prim.dest_ref_pres = TRUE; - msg.sua_prim.dest_ref = tcb_ptr->Dest_LR ; - msg.sua_prim.SCCP_cause_pres = FALSE; + /* Look if this is the end or intermediate node */ + Sua_Out_ConnId = tcb_ptr->scoc_tcb_id; - // fill in the user data - msg.sua_prim.data_pres = FALSE; - - // encode the SUA Release complete message - error = msg.sua_encode(); - //string_size = msg.sua_msg.size(); - - assoc_id = tcb_ptr->sctp_Association_id; - local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id; - + /* Is this the final destination ? */ + if ( Sua_Out_ConnId == 0 ) + { + // store primitive in a list(is retrieve via sua_receive_msg) + rec_msg_pool.push_back(temp); + + // send a CORELCONF back to the remote node + Sua_syntax_error_struct error; + int datalen; + unsigned int assoc_id; + short stream_id = 0; + int delivery_type, result; + + // init the message + msg.sua_init(); + + // fill in the main sua header + msg.sua_prim.hdr_msg_class = sua_co; + msg.sua_prim.hdr_msg_type.co = co_relco; + + msg.sua_prim.rout_con_pres = TRUE; + msg.sua_prim.rout_con = routing_Contex; + msg.sua_prim.importance_pres = TRUE; + msg.sua_prim.importance = 7; + + // QOS choice + delivery_type = SCTP_UNORDERED_DELIVERY; + + // fill in the connection-oriented specific data of the msg + msg.sua_prim.source_ref_pres = TRUE; + msg.sua_prim.source_ref = tcb_ptr->Source_LR ; + msg.sua_prim.dest_ref_pres = TRUE; + msg.sua_prim.dest_ref = tcb_ptr->Dest_LR ; + msg.sua_prim.SCCP_cause_pres = FALSE; + + // fill in the user data + msg.sua_prim.data_pres = FALSE; + + // encode the SUA Release complete message + error = msg.sua_encode(); + //string_size = msg.sua_msg.size(); + + assoc_id = tcb_ptr->sctp_Association_id; + local_sua_id = sua.AssocDB.instance[sua_assoc_id].local_sua_id; + #ifdef DEBUG - cout << "routed to SCTP assoc " << assoc_id << "\n"; + cout << "routed to SCTP assoc " << assoc_id << "\n"; #endif - - tcb_ptr->state = scoc_idle; - - // send data to SCTP - char* databuf = new char[msg.sua_msg.length()]; - msg.sua_msg.copy(databuf, msg.sua_msg.length()); - datalen = msg.sua_msg.length(); - + + tcb_ptr->state = scoc_idle; + + // send data to SCTP + char* databuf = new char[msg.sua_msg.length()]; + msg.sua_msg.copy(databuf, msg.sua_msg.length()); + datalen = msg.sua_msg.length(); + #ifdef DEBUG - // display byte array - display_byte_array(databuf , msg.sua_msg.length()); + // 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", assoc_id); - event_log("sua_co.c",logstring); - log_byte_array("sua_co.c", databuf,msg.sua_msg.length()); - - result = sctp_send ( assoc_id, - stream_id, - (unsigned char *) databuf, - datalen, - SUA_PPI, - SCTP_USE_PRIMARY, - SCTP_NO_CONTEXT, - SCTP_INFINITE_LIFETIME, - delivery_type, - SCTP_BUNDLING_DISABLED - ); - - delete databuf; - - // release the TCB of this connection - tcb_pool.release_TCB(sua_ConnId); - + + char logstring[100]; + sprintf(logstring, "SUA encoded message, ready for being send to SCTP assoc %d", assoc_id); + event_log("sua_co.c",logstring); + log_byte_array("sua_co.c", databuf,msg.sua_msg.length()); + + result = sctp_send ( assoc_id, + stream_id, + (unsigned char *) databuf, + datalen, + SUA_PPI, + SCTP_USE_PRIMARY, + SCTP_NO_CONTEXT, + SCTP_INFINITE_LIFETIME, + delivery_type, + SCTP_BUNDLING_DISABLED + ); + + delete databuf; + + // release the TCB of this connection + tcb_pool.release_TCB(sua_ConnId); + #ifdef DEBUG - cout << "local_sua_id = " << local_sua_id << "\n"; + cout << "local_sua_id = " << local_sua_id << "\n"; #endif - - /* call the application/user callBack function */ - local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif - ( local_sua_id, - sua_ConnId, - release_cause, - temp.userdata.length() - ); - + + /* call the application/user callBack function */ + sua.local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif + ( local_sua_id, + sua_ConnId, + release_cause, + 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 */ + /* get association id from SCOC TCB */ + + tcb_out_ptr = tcb_pool.get_tcb(Sua_Out_ConnId); + + msg.sua_prim.source_ref = tcb_out_ptr->Source_LR; + msg.sua_prim.dest_ref = tcb_out_ptr->Dest_LR; + + error = msg.sua_encode(); + + /* copy data into buffer, then finally... */ + signed int sctp_loadshare = SCTP_USE_PRIMARY; + short sctp_stream_id = 0; + int sctp_delivery_type = 0 ,datalen , result = 0; + 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( tcb_out_ptr->sctp_Association_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; + } + return(0); } @@ -1583,18 +1837,21 @@ short process_CORELCO_msg ( unsigned int sua_assoc_id, unsigned int local_sua_id = 0; unsigned int release_cause = 0; sua_save_str temp; + unsigned int Sua_Out_ConnId; + tcb_Sua_TCB_str *tcb_out_ptr; + Sua_syntax_error_struct error; temp.primitive = N_RELEASE_CONF; temp.user_ref = sua_ConnId; - + temp.QOS.return_msg_on_error = (msg.sua_prim.prot_class.return_option == TRUE); temp.QOS.sequence_number = 0; temp.QOS.importance = msg.sua_prim.importance; - + // retrieve the clg(=source) address (=remote sua address) - + // retrieve the called(=destination) address(=should be our own local addr) - + tcb_ptr->state = scoc_idle; #ifdef DEBUG @@ -1604,21 +1861,62 @@ short process_CORELCO_msg ( unsigned int sua_assoc_id, cout << "TCB state = " << tcb_ptr->state << "\n"; #endif - local_sua_id = Assoc_sua.instance[sua_assoc_id].local_sua_id; + local_sua_id = sua.AssocDB.instance[sua_assoc_id].local_sua_id; - // store primitive in a list(is retrieve via sua_receive_msg) - rec_msg_pool.push_back(temp); - - // release the TCB of this connection - tcb_pool.release_TCB(sua_ConnId); + /* Look if this is the end or intermediate node */ + Sua_Out_ConnId = tcb_ptr->scoc_tcb_id; - /* call the application/user callBack function */ - local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif - ( local_sua_id, - sua_ConnId, - release_cause, - temp.userdata.length() - ); + /* Is this the final destination ? */ + if ( Sua_Out_ConnId == 0 ) + { + // store primitive in a list(is retrieve via sua_receive_msg) + rec_msg_pool.push_back(temp); + + // release the TCB of this connection + tcb_pool.release_TCB(sua_ConnId); + + /* call the application/user callBack function */ + sua.local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif + ( local_sua_id, + sua_ConnId, + release_cause, + 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 */ + /* get association id from SCOC TCB */ + + tcb_out_ptr = tcb_pool.get_tcb(Sua_Out_ConnId); + + msg.sua_prim.source_ref = tcb_out_ptr->Source_LR; + msg.sua_prim.dest_ref = tcb_out_ptr->Dest_LR; + + error = msg.sua_encode(); + + /* copy data into buffer, then finally... */ + signed int sctp_loadshare = SCTP_USE_PRIMARY; + short sctp_stream_id = 0; + int sctp_delivery_type = 0 ,datalen , result = 0; + 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( tcb_out_ptr->sctp_Association_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; + } return(0); } @@ -1636,7 +1934,10 @@ short process_COREF_msg ( unsigned int sua_assoc_id, unsigned int local_sua_id = 0; unsigned int release_cause = 0; sua_save_str temp; - + unsigned int Sua_Out_ConnId; + tcb_Sua_TCB_str *tcb_out_ptr; + Sua_syntax_error_struct error; + temp.primitive = N_CONNECT_REFUSED; temp.user_ref = sua_ConnId; @@ -1677,28 +1978,69 @@ short process_COREF_msg ( unsigned int sua_assoc_id, if (msg.sua_prim.data_pres == TRUE) temp.userdata = msg.sua_prim.data_string; - else - cout << "sua_co.c: no sua user data in CODATA msg \n"; - // store primitive in a list(is retrieve via sua_receive_msg) - rec_msg_pool.push_back(temp); - - // release the TCB of this connection - tcb_pool.release_TCB(sua_ConnId); + /* Look if this is the end or intermediate node */ + Sua_Out_ConnId = tcb_ptr->scoc_tcb_id; + + /* Is this the final destination ? */ + if ( Sua_Out_ConnId == 0 ) + { + // store primitive in a list(is retrieve via sua_receive_msg) + rec_msg_pool.push_back(temp); + + // release the TCB of this connection + tcb_pool.release_TCB(sua_ConnId); + #ifdef DEBUG - cout << "local_sua_id = " << local_sua_id << "\n"; + cout << "local_sua_id = " << local_sua_id << "\n"; #endif + + /* call the application/user callBack function */ + sua.local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif + ( local_sua_id, + sua_ConnId, + release_cause, + temp.userdata.length() + ); - /* call the application/user callBack function */ - local_sua.instance[local_sua_id].SUA_APLCallBack.ulp_DisConnIndNotif - ( local_sua_id, - sua_ConnId, - release_cause, - 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 */ + /* get association id from SCOC TCB */ + + tcb_out_ptr = tcb_pool.get_tcb(Sua_Out_ConnId); + + msg.sua_prim.source_ref = tcb_out_ptr->Source_LR; + msg.sua_prim.dest_ref = tcb_out_ptr->Dest_LR; + + error = msg.sua_encode(); + + /* copy data into buffer, then finally... */ + signed int sctp_loadshare = SCTP_USE_PRIMARY; + short sctp_stream_id = 0; + int sctp_delivery_type = 0 ,datalen , result = 0; + 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( tcb_out_ptr->sctp_Association_id, + sctp_stream_id, + sctp_delivery_type, + sctp_loadshare, + databuf, + datalen + ); + + delete databuf; + } - return(0); + return(0); } // end of module sua_co.c |