summaryrefslogtreecommitdiff
path: root/TAO/IIOP/lib/giop.hh
blob: 70431ab9e7b367c93025591a5211d391b021404c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
// @(#)giop.hh	1.2 95/09/06
// Copyright 1994-1995 by Sun Microsystems Inc.
// All Rights Reserved
//
// GIOP 	data structures and support routines
//
// Note that some symbols in this module are part of the "Internet"
// Inter-ORB Protocol (IIOP), not the General IOP.  Only addressing
// information and certain details of connection usage are specific
// to IIOP; all other protocol details can be reused by ORB protocols
// that are built atop connection protocols other than TCP.
//
// THREADING NOTE:  Threads should never manipulate another thread's
// invocations.  In this implementation, all data structures used to
// represent invocations (and parts of them) are owned by the thread
// which created them.  Multiple threads may make of course concurrent
// invocations safely, since the GIOP code is reentrant.
//

#ifndef	_GIOP_HH
#define _GIOP_HH

#include <ace/OS.h>
#if defined(__IIOP_BUILD)
#  include	"orb.hh"
#  include	"stub.hh"
#else
#  include	<corba/orb.hh>
#  include	<corba/stub.hh>
#endif

#include	"connmgr.hh"
#include	"iiopobj.hh"		// XXX -- not generic!


// XXX this same typedef is used in other places, e.g. iiopobj.hh
typedef CORBA_SEQUENCE <CORBA_Octet> opaque;

class IOP {				// namespace
  public:
    //
    // Assigned Protocol/Profile tag values.  ORB protcols may be
    // uniquely identified by tags such as these.   This allows each
    // ORB's own objref profiles to be interchanged using IORs.
    //
    // Email to tag-request@omg.org to allocate tags
    //
    typedef CORBA_ULong	ProfileId;
    enum {
	TAG_INTERNET_IOP = 0,		// IIOP
	TAG_MULTIPLE_COMPONENTS = 1,	// DCE-CIOP

	//
	// This is a subset of the list of other profile tags
	//
	TAG_ONC_IOP = 0x4f4e4300	// ONC IOP
    };

    struct TaggedProfile {		// one per protocol
	ProfileId			tag;
	opaque				profile_data;
    };
    typedef CORBA_SEQUENCE <TaggedProfile>	TaggedProfileSeq;

    //
    // InteroperableObjectReference ... a set of protocol-specific
    // protocol profiles, plus a type ID.  Only one object is denoted
    // by all of this information.  It's OK to delete all profiles
    // except the one for the single protocol actually being used.
    //
    struct IOR {
	char				*type_id;
	TaggedProfileSeq		profiles;
    };

    //
    // Some protocols can be factored into a set of optional components.
    // Use of such components is defined by the protocol's specification.
    //
    // Email to tag-request@omg.org to allocate tags
    //
    typedef CORBA_ULong		ComponentId;
    enum {
	//
	// these are all defined by DCE-CIOP in OMG TC document 95-3-10
	//
	TAG_DCE_STRING_BINDING = 100,	// string binding handle
	TAG_DCE_BINDING_NAME = 101,	// CDS/GDS/... name
	TAG_DCE_NO_PIPES = 102,		// no component data
	TAG_OBJECT_KEY = 10,		// opaque
	TAG_ENDPOINT_ID = 11,		// uuid
	TAG_LOCATION_POLICY = 12	// octet/enum
    };

    //
    // One way to represent multicomponent profiles, e.g. as done by
    // the DCE-CIOP protocol.  One of these gets encapsulated in
    // TaggedProfile::profile_data.  TAG_MULTIPLE_COMPONENTS may be
    // used to represent protocol profiles structured in that way, 
    // but protocol-specific tags facilitate simpler scanning of IORs
    // since you can be assured that each profile only has data used
    // within a single ORB protocol.
    //
    struct TaggedComponent {
	ComponentId			tag;
	opaque		        	component_data;
    };
    typedef CORBA_SEQUENCE <TaggedComponent>	MultipleComponentProfile;
};


class GIOP {				// namespace

  public:
    struct Version { CORBA_Octet	major, minor; };

    //
    // GIOP protocol version information
    //
    enum { MY_MAJOR = 1, MY_MINOR = 0 };	// 1.0

    //
    // All GIOP messages include a header and message type.
    //
    enum MsgType {
	Request = 0,				// sent by client
	Reply = 1,                              // by server
	CancelRequest = 2,                      // by client
	LocateRequest = 3,                      // by client
	LocateReply = 4,                        // by server
	CloseConnection = 5,                    // by server
	MessageError = 6                        // by both
    };

    struct MessageHeader {
	CORBA_Char		magic [4];		// "GIOP"
	Version			giop_version;
	CORBA_Octet		byte_order;		// 0 = big, 1 = little
	CORBA_Octet		message_type;		// MsgType above
	CORBA_ULong		message_size;		// in byte_order!
    };

    //
    // Support for Implicit ORB Service Context
    //
    typedef CORBA_ULong 	ServiceID;
    enum {
	TransactionService = 0
	//
	// more service IDs may be defined by OMG
	//
    };
    struct ServiceContext {
	ServiceID		context_id;
	opaque			context_data;
    };
    typedef CORBA_SEQUENCE <ServiceContext>	ServiceContextList;

    //
    // Request, Reply headers
    //
    struct RequestHeader {
	ServiceContextList	service_info;
	CORBA_ULong		request_id;
	CORBA_Boolean		response_expected;
	opaque			object_key;
	CORBA_String		operation;
	CORBA_Principal_ptr	requesting_principal;
    };

    enum ReplyStatusType {
	NO_EXCEPTION,
	USER_EXCEPTION,
	SYSTEM_EXCEPTION,
	LOCATION_FORWARD
    };

    struct ReplyHeader {
	ServiceContextList	service_info;
	CORBA_ULong		request_id;
	ReplyStatusType		reply_status;
    };

    //
    // Cancellation -- applies both to Requests and LocateRequests.
    //
    struct CancelRequestHeader {
	CORBA_ULong		request_id;
    };

    //
    // Location service support
    //
    struct LocateRequestHeader {
	CORBA_ULong		request_id;
	opaque			object_key;
    };

    enum LocateStatusType {
	UNKNOWN_OBJECT,
	OBJECT_HERE,
	OBJECT_FORWARD
    };

    struct LocateReplyHeader {
	CORBA_ULong		request_id;
	LocateStatusType	locate_status;
    };


    //
    // Invocation:  Sends a Request, optionally reads associated Reply.
    // Uses transport info passed in, doesn't locate anything.
    //
    class Invocation {
      public:
			Invocation (
			    IIOP_Object			*data,
			    const char			*operation,
			    CORBA_Boolean		is_roundtrip
			);
			~Invocation ();

	//
	// "start" goes beyond initialising data structures, and 
	// makes calls that may fail -- and thus throw exceptions.
	//
	void		start (
			    CORBA_Environment		&env
			);

	void		put_param (
			    CORBA_TypeCode_ptr	tc,
			    void			*value,
			    CORBA_Environment		&env
			)
			{
			    (void) CDR::encoder (tc, value, 0, &stream, env);
			}

	ReplyStatusType	invoke (
			    CORBA_ExceptionList	&exceptions,
			    CORBA_Environment		&env
			);

	void		get_value (
			    CORBA_TypeCode_ptr	tc,
			    void			*value,
			    CORBA_Environment		&env
			)
			{
			    (void) CDR::decoder (tc, value, 0, &stream, env);
			}

	// no CORBA_Context support (deprecated)

      private:
	IIOP_Object		*_data;
	const char		*opname;
	CORBA_Boolean		do_rsvp;
	CORBA_ULong		my_request_id;

	unsigned char		buffer [CDR::DEFAULT_BUFSIZE];
	CDR			stream;

	autorelease <client_endpoint>	endpoint;
    };

    //
    // Close a connection, first sending GIOP::CloseConnection
    //
    static void		close_connection (ACE_HANDLE &fd, void *ctx);

    //
    // Generic server side data dispatch -- called for all file descriptors
    // on which incoming messages are expected.
    //
    // The handle_request() routine is used to handle request messages; its
    // 'reply' parameter is null if the request is "oneway" (or the client
    // isn't waiting for the response that this request normally creates).  
    //
    // The optional check_forward() routine is used to verify that the
    // request is to be delivered within this process by handle_request().
    // Each call to handle_request() is preceded by a call to this routine
    // if it's provided.  It's used when handling GIOP "Request" messages
    // as well as GIOP "LocateRequest" messages, and returns an enum to
    // indicate overal status (LocateStatusType) as well as an objref
    // in the case of OBJECT_FORWARD.  That objref is released.
    //
    static void	incoming_message (
		    ACE_HANDLE		&fd,
		    LocateStatusType	check_forward (
					    opaque		&key,
					    CORBA_Object_ptr	&objref,
					    void		*context
					),
		    void		handle_request (
					    RequestHeader	&req,
					    CDR			&request_body,
					    CDR			*reply,
					    void		*context,
					    CORBA_Environment	&env
					),
		    void		*context,
		    CORBA_Environment	&env
		);

    static CORBA_Boolean	send_message (
				    CDR			&stream,
				    ACE_HANDLE		&connection
				);

    //
    // Reads message, returns message type from header
    //
    static MsgType		read_message (
				    ACE_HANDLE		&connection,
				    CDR			&msg,
				    CORBA_Environment	&env
				);
};

#endif	// _GIOP_HH