GIOP_Message_Generator_Parser_12.cpp

Go to the documentation of this file.
00001 #include "tao/GIOP_Message_Generator_Parser_12.h"
00002 #include "tao/GIOPC.h"
00003 #include "tao/GIOP_Utils.h"
00004 #include "tao/GIOP_Message_Locate_Header.h"
00005 #include "tao/operation_details.h"
00006 #include "tao/debug.h"
00007 #include "tao/Pluggable_Messaging_Utils.h"
00008 #include "tao/GIOP_Message_State.h"
00009 #include "tao/TAO_Server_Request.h"
00010 #include "tao/TAOC.h"
00011 #include "tao/ORB_Core.h"
00012 #include "tao/Transport.h"
00013 #include "tao/CDR.h"
00014 
00015 ACE_RCSID (tao,
00016            GIOP_Message_Gen_Parser_12,
00017            "$Id: GIOP_Message_Generator_Parser_12.cpp 79237 2007-08-07 09:48:21Z johnnyw $")
00018 
00019 // This is used by GIOP1.2. This is to align the message body on a
00020 // 8-octet boundary. This is declared static so that it is in file
00021 // scope.
00022 static const size_t TAO_GIOP_MESSAGE_ALIGN_PTR = 8;
00023 
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025 
00026 bool
00027 TAO_GIOP_Message_Generator_Parser_12::write_request_header (
00028     const TAO_Operation_Details &opdetails,
00029     TAO_Target_Specification &spec,
00030     TAO_OutputCDR &msg)
00031 {
00032   // First the request id
00033   msg << opdetails.request_id ();
00034 
00035   CORBA::Octet const response_flags = opdetails.response_flags ();
00036 
00037   // Here are the Octet values for different policies
00038   // '00000000' for SYNC_NONE
00039   // '00000000' for SYNC_WITH_TRANSPORT
00040   // '00000010' for SYNC_WITH_SERVER
00041   // '00000011' for SYNC_WITH_TARGET
00042   // '00000011' for regular two ways, but if they are invoked via a
00043   // DII with INV_NO_RESPONSE flag set then we need to send '00000001'
00044   //
00045   // We have not implemented the policy INV_NO_RESPONSE for DII.
00046   if (response_flags == TAO_TWOWAY_RESPONSE_FLAG)
00047     msg << ACE_OutputCDR::from_octet (3);
00048   // Second the response flags
00049   // Sync scope - ignored by server if request is not oneway.
00050   else if (response_flags == CORBA::Octet (Messaging::SYNC_NONE)
00051            || response_flags == CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT)
00052            || response_flags == CORBA::Octet (TAO::SYNC_DELAYED_BUFFERING))
00053     // No response required.
00054     msg << ACE_OutputCDR::from_octet (0);
00055 
00056   else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_SERVER))
00057     // Return before dispatching to the servant
00058     msg << ACE_OutputCDR::from_octet (1);
00059 
00060   else if (response_flags == CORBA::Octet (Messaging::SYNC_WITH_TARGET))
00061     // Return after dispatching servant.
00062     msg << ACE_OutputCDR::from_octet (3);
00063   else
00064     // Until more flags are defined by the OMG.
00065     return false;
00066 
00067   // The reserved field
00068   CORBA::Octet reserved[3] = {0, 0, 0};
00069 
00070   msg.write_octet_array (reserved, 3);
00071 
00072   if (this->marshall_target_spec (spec, msg) == false)
00073     return false;
00074 
00075   // Write the operation name
00076   msg.write_string (opdetails.opname_len (),
00077                     opdetails.opname ());
00078 
00079   // Write the service context list
00080   msg << opdetails.request_service_info ();
00081 
00082   // We align the pointer only if the operation has arguments.
00083   if (opdetails.argument_flag ()
00084       && msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00085     {
00086       return false;
00087     }
00088 
00089   return true;
00090 }
00091 
00092 bool
00093 TAO_GIOP_Message_Generator_Parser_12::write_locate_request_header (
00094     CORBA::ULong request_id,
00095     TAO_Target_Specification &spec,
00096     TAO_OutputCDR &msg)
00097 {
00098   // Write the request id
00099   msg << request_id;
00100 
00101   // Write the target address
00102   if (this->marshall_target_spec (spec,
00103                                   msg) == false)
00104     return false;
00105 
00106   // I dont think we need to align the pointer to an 8 byte boundary
00107   // here.
00108   // We need to align the pointer
00109   //  if (msg.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00110   //  return 0;
00111 
00112   // Return success
00113   return true;
00114 }
00115 
00116 bool
00117 TAO_GIOP_Message_Generator_Parser_12::write_reply_header (
00118     TAO_OutputCDR & output,
00119     TAO_Pluggable_Reply_Params_Base &reply)
00120 {
00121   // Write the request ID
00122   output.write_ulong (reply.request_id_);
00123 
00124    // Write the reply status
00125   if (reply.reply_status_ ==
00126       TAO_PLUGGABLE_MESSAGE_LOCATION_FORWARD_PERM)
00127     {
00128       // Not sure when we will use this.
00129       output.write_ulong (TAO_GIOP_LOCATION_FORWARD_PERM);
00130     }
00131   else if (reply.reply_status_ ==
00132            TAO_PLUGGABLE_MESSAGE_NEEDS_ADDRESSING_MODE)
00133     {
00134       // Not sure when we will use this.
00135       output.write_ulong (TAO_GIOP_LOC_NEEDS_ADDRESSING_MODE);
00136     }
00137   else
00138     {
00139       this->marshal_reply_status (output, reply);
00140     }
00141 
00142   if (!(output << reply.service_context_notowned ()))
00143     return false;
00144 
00145   if (reply.argument_flag_)
00146     {
00147       // If we have some data to be marshalled, then we align the
00148       // pointer to a 8 byte boundary.  Else, we just leave it throu
00149       if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00150         {
00151           return false;
00152         }
00153     }
00154   return true;
00155 }
00156 
00157 bool
00158 TAO_GIOP_Message_Generator_Parser_12::write_locate_reply_mesg (
00159     TAO_OutputCDR & output,
00160     CORBA::ULong request_id,
00161     TAO_GIOP_Locate_Status_Msg &status_info)
00162 {
00163   output.write_ulong (request_id);
00164 
00165   // Make the header for the locate request
00166   output.write_ulong (status_info.status);
00167 
00168   // Note: We dont align the pointer to an 8 byte boundary for a
00169   // locate reply body. This is due to an urgent issue raised by Michi
00170   // in the OMG. I discussed this with Michi today (09/07/2001) and I
00171   // learn that this has been passed. Hence the change..
00172   /*
00173   if (status_info.status == TAO_GIOP_OBJECT_FORWARD ||
00174       status_info.status == TAO_GIOP_OBJECT_FORWARD_PERM)
00175     {
00176       // We have to send some data, so align the pointer
00177       if (output.align_write_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR) == -1)
00178         {
00179           return false;
00180         }
00181     }
00182   */
00183   switch (status_info.status)
00184     {
00185     case TAO_GIOP_OBJECT_FORWARD:
00186 
00187       // More likely than not we will not have this in TAO
00188     case TAO_GIOP_OBJECT_FORWARD_PERM:
00189       {
00190         CORBA::Object_ptr object_ptr =
00191           status_info.forward_location_var.in ();
00192 
00193         if ( ! (output << object_ptr))
00194         {
00195           if (TAO_debug_level > 0)
00196             {
00197               ACE_ERROR ((
00198                   LM_ERROR,
00199                   ACE_TEXT ("TAO (%P|%t|%N|%l) write_locate_reply_mesg-")
00200                   ACE_TEXT (" cannot marshal object reference\n")
00201                 ));
00202             }
00203         }
00204       }
00205       break;
00206     case TAO_GIOP_LOC_SYSTEM_EXCEPTION:
00207     case TAO_GIOP_LOC_NEEDS_ADDRESSING_MODE:
00208       // Do we do these in TAO??
00209       // What to do here???? I dont really know. I have to do a survey
00210       // of the specifications that uses this.
00211       break;
00212     default:
00213       break;
00214     }
00215 
00216   return true;
00217 }
00218 
00219 bool
00220 TAO_GIOP_Message_Generator_Parser_12::write_fragment_header (
00221   TAO_OutputCDR & cdr,
00222   CORBA::ULong request_id)
00223 {
00224   return (cdr << request_id);
00225 
00226   // No need to align write pointer to an 8 byte boundary since it
00227   // should already be aligned (12 for GIOP messager + 4 for fragment
00228   // header = 16 -- a multiple of 8)
00229 }
00230 
00231 int
00232 TAO_GIOP_Message_Generator_Parser_12::parse_request_header (
00233     TAO_ServerRequest &request)
00234 {
00235   // Get the input CDR in the request class
00236   TAO_InputCDR & input = *request.incoming ();
00237 
00238   CORBA::Boolean hdr_status = (CORBA::Boolean) input.good_bit ();
00239 
00240   CORBA::ULong req_id = 0;
00241   // Get the rest of the request header ...
00242   hdr_status = hdr_status && input.read_ulong (req_id);
00243 
00244   request.request_id (req_id);
00245 
00246   CORBA::Octet response_flags = CORBA::Octet();
00247   hdr_status = hdr_status && input.read_octet (response_flags);
00248 
00249   request.response_expected ((response_flags > 0));
00250 
00251   // The high bit of the octet has been set if the SyncScope policy
00252   // value is SYNC_WITH_SERVER.
00253   request.sync_with_server ((response_flags == 1));
00254 
00255   // Reserved field
00256   input.skip_bytes (3);
00257 
00258   // Unmarshal the target address field.
00259   hdr_status =
00260     hdr_status && request.profile ().unmarshall_target_address(input);
00261 
00262   CORBA::ULong length = 0;
00263   hdr_status = hdr_status && input.read_ulong (length);
00264 
00265   if (hdr_status)
00266     {
00267       // Do not include NULL character at the end.
00268       // @@ This is not getting demarshaled using the codeset
00269       //    translators!
00270 
00271       // Notice that there are no memory allocations involved
00272       // here!
00273 
00274       request.operation (input.rd_ptr (),
00275                          length - 1,
00276                          0 /* TAO_ServerRequest does NOT own string */);
00277       hdr_status = input.skip_bytes (length);
00278     }
00279 
00280   // Tear out the service context ... we currently ignore it, but it
00281   // should probably be passed to each ORB service as appropriate
00282   // (e.g. transactions, security).
00283   //
00284   // NOTE: As security support kicks in, this is a good place to
00285   // verify a digital signature, if that is required in this security
00286   // environment.  It may be required even when using IPSEC security
00287   // infrastructure.
00288   IOP::ServiceContextList &req_service_info =
00289     request.request_service_info ();
00290 
00291   input >> req_service_info;
00292 
00293   // Check an process if BiDir contexts are available
00294   if (request.orb_core ()->bidir_giop_policy ())
00295     {
00296       this->check_bidirectional_context (request);
00297     }
00298 
00299   if (input.length () > 0)
00300     {
00301       // Reset the read_ptr to an 8-byte boundary.
00302       input.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00303     }
00304 
00305   return hdr_status ? 0 : -1;
00306 }
00307 
00308 
00309 int
00310 TAO_GIOP_Message_Generator_Parser_12::parse_locate_header (
00311     TAO_GIOP_Locate_Request_Header &request)
00312 {
00313   // Get the stream .
00314   TAO_InputCDR &msg = request.incoming_stream ();
00315 
00316   CORBA::Boolean hdr_status = 1;
00317 
00318   // Get the request id.
00319   CORBA::ULong req_id = 0;
00320   hdr_status = msg.read_ulong (req_id);
00321 
00322   // Store it in the Locate request classes
00323   request.request_id (req_id);
00324 
00325   // Unmarshal the target address field.
00326   hdr_status =
00327     hdr_status && request.profile ().unmarshall_target_address(msg);
00328 
00329   // Reset the pointer to an 8-byte bouns]dary
00330   msg.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00331 
00332   return hdr_status ? 0 : -1;
00333 }
00334 
00335 int
00336 TAO_GIOP_Message_Generator_Parser_12::parse_reply (
00337     TAO_InputCDR &cdr,
00338     TAO_Pluggable_Reply_Params &params)
00339 {
00340   if (TAO_GIOP_Message_Generator_Parser::parse_reply (cdr,
00341                                                       params) == -1)
00342 
00343     return -1;
00344 
00345   if ((cdr >> params.svc_ctx_) == 0)
00346     {
00347       // if (TAO_debug_level > 0)
00348         ACE_ERROR ((LM_ERROR,
00349                     ACE_TEXT ("TAO (%P|%t) parse_reply, ")
00350                     ACE_TEXT ("extracting context\n")));
00351 
00352       return -1;
00353     }
00354 
00355   if (cdr.length () > 0)
00356     {
00357       // Align the read pointer on an 8-byte boundary
00358       cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00359     }
00360 
00361   return 0;
00362 }
00363 
00364 int
00365 TAO_GIOP_Message_Generator_Parser_12::parse_locate_reply (
00366     TAO_InputCDR &cdr,
00367     TAO_Pluggable_Reply_Params &params)
00368 {
00369   if (TAO_GIOP_Message_Generator_Parser::parse_locate_reply (cdr,
00370                                                              params) == -1)
00371 
00372     return -1;
00373 
00374   // Note: We dont align the pointer to an 8 byte boundary for a
00375   // locate reply body. This is due to an urgent issue raised by Michi
00376   // in the OMG. I discussed this with Michi today (09/07/2001) and I
00377   // learn that this has been passed. Hence the change..
00378   /*if (cdr.length () > 0)
00379     {
00380       // Align the read pointer on an 8-byte boundary
00381       cdr.align_read_ptr (TAO_GIOP_MESSAGE_ALIGN_PTR);
00382       }*/
00383 
00384   return 0;
00385 }
00386 
00387 
00388 CORBA::Octet
00389 TAO_GIOP_Message_Generator_Parser_12::major_version (void) const
00390 {
00391   return static_cast<CORBA::Octet> (1);
00392 }
00393 
00394 
00395 CORBA::Octet
00396 TAO_GIOP_Message_Generator_Parser_12::minor_version (void) const
00397 {
00398   return static_cast<CORBA::Octet> (2);
00399 }
00400 
00401 bool
00402 TAO_GIOP_Message_Generator_Parser_12::is_ready_for_bidirectional (void) const
00403 {
00404   // We do support bidirectional
00405   return true;
00406 }
00407 
00408 bool
00409 TAO_GIOP_Message_Generator_Parser_12::marshall_target_spec (
00410     TAO_Target_Specification &spec,
00411     TAO_OutputCDR &msg)
00412 {
00413   switch (spec.specifier ())
00414     {
00415     case TAO_Target_Specification::Key_Addr:
00416       {
00417         // As this is a union send in the discriminant first
00418         msg << GIOP::KeyAddr;
00419 
00420         // Get the object key
00421         const TAO::ObjectKey *key = spec.object_key ();
00422 
00423         if (key)
00424           {
00425             // Marshall in the object key
00426             msg << *key;
00427           }
00428         else
00429           {
00430             if (TAO_debug_level)
00431               {
00432                 ACE_DEBUG ((LM_DEBUG,
00433                             ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00434               }
00435             return false;
00436           }
00437         break;
00438       }
00439     case TAO_Target_Specification::Profile_Addr:
00440       {
00441         // As this is a union send in the discriminant first
00442         msg << GIOP::ProfileAddr;
00443 
00444         // Get the profile
00445         const IOP::TaggedProfile *pfile = spec.profile ();
00446 
00447         if (pfile)
00448           {
00449             // Marshall in the object key
00450             msg << *pfile;
00451           }
00452         else
00453           {
00454             if (TAO_debug_level)
00455               {
00456                 ACE_DEBUG ((LM_DEBUG,
00457                             ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00458               }
00459             return false;
00460           }
00461         break;
00462       }
00463     case TAO_Target_Specification::Reference_Addr:
00464       {
00465         // As this is a union send in the discriminant first
00466         msg << GIOP::ReferenceAddr;
00467 
00468         // Get the IOR
00469         IOP::IOR *ior = 0;
00470         CORBA::ULong index = spec.iop_ior (ior);
00471 
00472         if (ior)
00473           {
00474             // This is a struct IORAddressingInfo. So, marshall each
00475             // member of the struct one after another in the order
00476             // defined.
00477             msg << index;
00478             msg << *ior;
00479           }
00480         else
00481           {
00482             if (TAO_debug_level)
00483               {
00484                 ACE_DEBUG ((LM_DEBUG,
00485                             ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00486               }
00487             return 0;
00488           }
00489         break;
00490       }
00491     default:
00492       if (TAO_debug_level)
00493         {
00494           ACE_DEBUG ((LM_DEBUG,
00495                       ACE_TEXT ("(%N |%l) Unable to handle this request \n")));
00496         }
00497       return false;
00498     }
00499 
00500   return true;
00501 }
00502 
00503 
00504 bool
00505 TAO_GIOP_Message_Generator_Parser_12::check_bidirectional_context (
00506     TAO_ServerRequest &request)
00507 {
00508   TAO_Service_Context &service_context = request.request_service_context ();
00509 
00510   // Check whether we have the BiDir service context info available in
00511   // the ServiceContextList
00512   if (service_context.is_service_id (IOP::BI_DIR_IIOP))
00513     {
00514       return this->process_bidir_context (service_context,
00515                                           request.transport ());
00516     }
00517 
00518   return false;
00519 }
00520 
00521 bool
00522 TAO_GIOP_Message_Generator_Parser_12::process_bidir_context (
00523     TAO_Service_Context &service_context,
00524     TAO_Transport *transport)
00525 {
00526   // Get the context info
00527   IOP::ServiceContext context;
00528   context.context_id = IOP::BI_DIR_IIOP;
00529 
00530   if (service_context.get_context (context) != 1)
00531       ACE_ERROR_RETURN ((LM_ERROR,
00532                          ACE_TEXT ("(%P|%t) Context info not found \n")),
00533                         false);
00534 
00535   TAO_InputCDR cdr (reinterpret_cast<const char*> (
00536                       context.context_data.get_buffer ()),
00537                     context.context_data.length ());
00538 
00539   return transport->tear_listen_point_list (cdr);
00540 }
00541 
00542 size_t
00543 TAO_GIOP_Message_Generator_Parser_12::fragment_header_length (void) const
00544 {
00545   return TAO_GIOP_MESSAGE_FRAGMENT_HEADER;
00546 }
00547 
00548 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:07:32 2008 for TAO by doxygen 1.3.6