VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcm.h@ 102340

Last change on this file since 102340 was 7029, checked in by vboxsync, 16 years ago

XPCOM/IPC: Made IPC_AddName()/IPC_RemoveName(), IPC_DefineTarget() to return a failure when the name/target is already defined or when a non-existent name/target is requested for removal.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.1 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is Mozilla IPC.
15 *
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2002
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 * Darin Fisher <darin@netscape.com>
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#ifndef ipcm_h__
39#define ipcm_h__
40
41#include "ipcMessage.h"
42#include "ipcMessagePrimitives.h"
43
44//-----------------------------------------------------------------------------
45
46//
47// IPCM (IPC Manager) protocol support
48//
49
50// The IPCM message target identifier:
51extern const nsID IPCM_TARGET;
52
53//
54// Every IPCM message has the following structure:
55//
56// +-----------------------------------------+
57// | (ipc message header) |
58// +-----------------------------------------+
59// | DWORD : type |
60// +-----------------------------------------+
61// | DWORD : requestIndex |
62// +-----------------------------------------+
63// . .
64// . (payload) .
65// . .
66// +-----------------------------------------+
67//
68// where |type| is an integer uniquely identifying the message. the type is
69// composed of a message class identifier and a message number. there are 3
70// message classes:
71//
72// ACK - acknowledging a request
73// REQ - making a request
74// PSH - providing unrequested, "pushed" information
75//
76// The requestIndex field is initialized when a request is made. An
77// acknowledgement's requestIndex is equal to that of its corresponding
78// request message. This enables the requesting side of the message exchange
79// to match acknowledgements to requests. The requestIndex field is ignored
80// for PSH messages.
81//
82
83// The IPCM message class is stored in the most significant byte.
84#define IPCM_MSG_CLASS_REQ (1 << 24)
85#define IPCM_MSG_CLASS_ACK (2 << 24)
86#define IPCM_MSG_CLASS_PSH (4 << 24)
87
88// Requests
89#define IPCM_MSG_REQ_PING (IPCM_MSG_CLASS_REQ | 1)
90#define IPCM_MSG_REQ_FORWARD (IPCM_MSG_CLASS_REQ | 2)
91#define IPCM_MSG_REQ_CLIENT_HELLO (IPCM_MSG_CLASS_REQ | 3)
92#define IPCM_MSG_REQ_CLIENT_ADD_NAME (IPCM_MSG_CLASS_REQ | 4)
93#define IPCM_MSG_REQ_CLIENT_DEL_NAME (IPCM_MSG_CLASS_REQ | 5)
94#define IPCM_MSG_REQ_CLIENT_ADD_TARGET (IPCM_MSG_CLASS_REQ | 6)
95#define IPCM_MSG_REQ_CLIENT_DEL_TARGET (IPCM_MSG_CLASS_REQ | 7)
96#define IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME (IPCM_MSG_CLASS_REQ | 8)
97#define IPCM_MSG_REQ_QUERY_CLIENT_NAMES (IPCM_MSG_CLASS_REQ | 9) // TODO
98#define IPCM_MSG_REQ_QUERY_CLIENT_TARGETS (IPCM_MSG_CLASS_REQ | 10) // TODO
99
100// Acknowledgements
101#define IPCM_MSG_ACK_RESULT (IPCM_MSG_CLASS_ACK | 1)
102#define IPCM_MSG_ACK_CLIENT_ID (IPCM_MSG_CLASS_ACK | 2)
103#define IPCM_MSG_ACK_CLIENT_NAMES (IPCM_MSG_CLASS_ACK | 3) // TODO
104#define IPCM_MSG_ACK_CLIENT_TARGETS (IPCM_MSG_CLASS_ACK | 4) // TODO
105
106// Push messages
107#define IPCM_MSG_PSH_CLIENT_STATE (IPCM_MSG_CLASS_PSH | 1)
108#define IPCM_MSG_PSH_FORWARD (IPCM_MSG_CLASS_PSH | 2)
109
110//-----------------------------------------------------------------------------
111
112//
113// IPCM header
114//
115struct ipcmMessageHeader
116{
117 PRUint32 mType;
118 PRUint32 mRequestIndex;
119};
120
121//
122// returns IPCM message type.
123//
124static inline int
125IPCM_GetType(const ipcMessage *msg)
126{
127 return ((const ipcmMessageHeader *) msg->Data())->mType;
128}
129
130//
131// return IPCM message request index.
132//
133static inline PRUint32
134IPCM_GetRequestIndex(const ipcMessage *msg)
135{
136 return ((const ipcmMessageHeader *) msg->Data())->mRequestIndex;
137}
138
139//
140// return a request index that is unique to this process.
141//
142NS_HIDDEN_(PRUint32)
143IPCM_NewRequestIndex();
144
145//-----------------------------------------------------------------------------
146
147//
148// The IPCM protocol is detailed below:
149//
150
151// REQUESTS
152
153//
154// req: IPCM_MSG_REQ_PING
155// ack: IPCM_MSG_ACK_RESULT
156//
157// A PING can be sent from either a client to the daemon, or from the daemon
158// to a client. The expected acknowledgement is a RESULT message with a status
159// code of 0.
160//
161// This request message has no payload.
162//
163
164//
165// req: IPCM_MSG_REQ_FORWARD
166// ack: IPCM_MSG_ACK_RESULT
167//
168// A FORWARD is sent when a client wishes to send a message to another client.
169// The payload of this message is another message that should be forwarded by
170// the daemon's IPCM to the specified client. The expected acknowledgment is
171// a RESULT message with a status code indicating success or failure.
172//
173// When the daemon receives a FORWARD message, it creates a PSH_FORWARD message
174// and sends that on to the destination client.
175//
176// This request message has as its payload:
177//
178// +-----------------------------------------+
179// | DWORD : clientID |
180// +-----------------------------------------+
181// | (innerMsgHeader) |
182// +-----------------------------------------+
183// | (innerMsgData) |
184// +-----------------------------------------+
185//
186
187//
188// req: IPCM_MSG_REQ_CLIENT_HELLO
189// ack: IPCM_MSG_REQ_CLIENT_ID <or> IPCM_MSG_REQ_RESULT
190//
191// A CLIENT_HELLO is sent when a client connects to the IPC daemon. The
192// expected acknowledgement is a CLIENT_ID message informing the new client of
193// its ClientID. If for some reason the IPC daemon cannot accept the new
194// client, it returns a RESULT message with a failure status code.
195//
196// This request message has no payload.
197//
198
199//
200// req: IPCM_MSG_REQ_CLIENT_ADD_NAME
201// ack: IPCM_MSG_ACK_RESULT
202//
203// A CLIENT_ADD_NAME is sent when a client wishes to register an additional
204// name for itself. The expected acknowledgement is a RESULT message with a
205// status code indicating success or failure.
206//
207// This request message has as its payload a null-terminated ASCII character
208// string indicating the name of the client.
209//
210
211//
212// req: IPCM_MSG_REQ_CLIENT_DEL_NAME
213// ack: IPCM_MSG_ACK_RESULT
214//
215// A CLIENT_DEL_NAME is sent when a client wishes to unregister a name that it
216// has registered. The expected acknowledgement is a RESULT message with a
217// status code indicating success or failure.
218//
219// This request message has as its payload a null-terminated ASCII character
220// string indicating the name of the client.
221//
222
223//
224// req: IPCM_MSG_REQ_CLIENT_ADD_TARGET
225// ack: IPCM_MSG_ACK_RESULT
226//
227// A CLIENT_ADD_TARGET is sent when a client wishes to register an additional
228// target that it supports. The expected acknowledgement is a RESULT message
229// with a status code indicating success or failure.
230//
231// This request message has as its payload a 128-bit UUID indicating the
232// target to add.
233//
234
235//
236// req: IPCM_MSG_REQ_CLIENT_DEL_TARGET
237// ack: IPCM_MSG_ACK_RESULT
238//
239// A CLIENT_DEL_TARGET is sent when a client wishes to unregister a target
240// that it has registered. The expected acknowledgement is a RESULT message
241// with a status code indicating success or failure.
242//
243// This request message has as its payload a 128-bit UUID indicating the
244// target to remove.
245//
246
247//
248// req: IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME
249// ack: IPCM_MSG_ACK_CLIENT_ID <or> IPCM_MSG_ACK_RESULT
250//
251// A QUERY_CLIENT_BY_NAME may be sent by a client to discover the client that
252// is known by a common name. If more than one client matches the name, then
253// only the ID of the more recently registered client is returned. The
254// expected acknowledgement is a CLIENT_ID message carrying the ID of the
255// corresponding client. If no client matches the given name or if some error
256// occurs, then a RESULT message with a failure status code is returned.
257//
258// This request message has as its payload a null-terminated ASCII character
259// string indicating the client name to query.
260//
261
262// ACKNOWLEDGEMENTS
263
264//
265// ack: IPCM_MSG_ACK_RESULT
266//
267// This acknowledgement is returned to indicate a success or failure status.
268//
269// The payload consists of a single DWORD value.
270//
271// Possible status codes are listed below (negative values indicate failure
272// codes):
273//
274#define IPCM_OK 0 // success: generic
275#define IPCM_ERROR_GENERIC -1 // failure: generic
276#define IPCM_ERROR_NO_CLIENT -2 // failure: client does not exist
277#define IPCM_ERROR_INVALID_ARG -3 // failure: invalid request argument
278#define IPCM_ERROR_NO_SUCH_DATA -4 // failure: requested data does not exist
279#define IPCM_ERROR_ALREADY_EXISTS -5 // failure: data to set already exists
280
281//
282// ack: IPCM_MSG_ACK_CLIENT_ID
283//
284// This acknowledgement is returned to specify a client ID.
285//
286// The payload consists of a single DWORD value.
287//
288
289// PUSH MESSAGES
290
291//
292// psh: ICPM_MSG_PSH_CLIENT_STATE
293//
294// This message is sent to clients to indicate the status of other clients.
295//
296// The payload consists of:
297//
298// +-----------------------------------------+
299// | DWORD : clientID |
300// +-----------------------------------------+
301// | DWORD : clientState |
302// +-----------------------------------------+
303//
304// where, clientState is one of the following values indicating whether the
305// client has recently connected (up) or disconnected (down):
306//
307#define IPCM_CLIENT_STATE_UP 1
308#define IPCM_CLIENT_STATE_DOWN 2
309
310//
311// psh: IPCM_MSG_PSH_FORWARD
312//
313// This message is sent by the daemon to a client on behalf of another client.
314// The recipient is expected to unpack the contained message and process it.
315//
316// The payload of this message matches the payload of IPCM_MSG_REQ_FORWARD,
317// with the exception that the clientID field is set to the clientID of the
318// sender of the IPCM_MSG_REQ_FORWARD message.
319//
320
321//-----------------------------------------------------------------------------
322
323//
324// NOTE: This file declares some helper classes that simplify constructing
325// and parsing IPCM messages. Each class subclasses ipcMessage, but
326// adds no additional member variables. |operator new| should be used
327// to allocate one of the IPCM helper classes, e.g.:
328//
329// ipcMessage *msg = new ipcmMessageClientHello("foo");
330//
331// Given an arbitrary ipcMessage, it can be parsed using logic similar
332// to the following:
333//
334// void func(const ipcMessage *unknown)
335// {
336// if (unknown->Topic().Equals(IPCM_TARGET)) {
337// if (IPCM_GetMsgType(unknown) == IPCM_MSG_TYPE_CLIENT_ID) {
338// ipcMessageCast<ipcmMessageClientID> msg(unknown);
339// printf("Client ID: %u\n", msg->ClientID());
340// }
341// }
342// }
343//
344
345// REQUESTS
346
347class ipcmMessagePing : public ipcMessage_DWORD_DWORD
348{
349public:
350 ipcmMessagePing()
351 : ipcMessage_DWORD_DWORD(
352 IPCM_TARGET,
353 IPCM_MSG_REQ_PING,
354 IPCM_NewRequestIndex()) {}
355};
356
357class ipcmMessageForward : public ipcMessage
358{
359public:
360 // @param type the type of this message: IPCM_MSG_{REQ,PSH}_FORWARD
361 // @param clientID the client id of the sender or receiver
362 // @param target the message target
363 // @param data the message data
364 // @param dataLen the message data length
365 ipcmMessageForward(PRUint32 type,
366 PRUint32 clientID,
367 const nsID &target,
368 const char *data,
369 PRUint32 dataLen) NS_HIDDEN;
370
371 // set inner message data, constrained to the data length passed
372 // to this class's constructor.
373 NS_HIDDEN_(void) SetInnerData(PRUint32 offset, const char *data, PRUint32 dataLen);
374
375 NS_HIDDEN_(PRUint32) ClientID() const;
376 NS_HIDDEN_(const nsID &) InnerTarget() const;
377 NS_HIDDEN_(const char *) InnerData() const;
378 NS_HIDDEN_(PRUint32) InnerDataLen() const;
379};
380
381class ipcmMessageClientHello : public ipcMessage_DWORD_DWORD
382{
383public:
384 ipcmMessageClientHello()
385 : ipcMessage_DWORD_DWORD(
386 IPCM_TARGET,
387 IPCM_MSG_REQ_CLIENT_HELLO,
388 IPCM_NewRequestIndex()) {}
389};
390
391class ipcmMessageClientAddName : public ipcMessage_DWORD_DWORD_STR
392{
393public:
394 ipcmMessageClientAddName(const char *name)
395 : ipcMessage_DWORD_DWORD_STR(
396 IPCM_TARGET,
397 IPCM_MSG_REQ_CLIENT_ADD_NAME,
398 IPCM_NewRequestIndex(),
399 name) {}
400
401 const char *Name() const { return Third(); }
402};
403
404class ipcmMessageClientDelName : public ipcMessage_DWORD_DWORD_STR
405{
406public:
407 ipcmMessageClientDelName(const char *name)
408 : ipcMessage_DWORD_DWORD_STR(
409 IPCM_TARGET,
410 IPCM_MSG_REQ_CLIENT_DEL_NAME,
411 IPCM_NewRequestIndex(),
412 name) {}
413
414 const char *Name() const { return Third(); }
415};
416
417class ipcmMessageClientAddTarget : public ipcMessage_DWORD_DWORD_ID
418{
419public:
420 ipcmMessageClientAddTarget(const nsID &target)
421 : ipcMessage_DWORD_DWORD_ID(
422 IPCM_TARGET,
423 IPCM_MSG_REQ_CLIENT_ADD_TARGET,
424 IPCM_NewRequestIndex(),
425 target) {}
426
427 const nsID &Target() const { return Third(); }
428};
429
430class ipcmMessageClientDelTarget : public ipcMessage_DWORD_DWORD_ID
431{
432public:
433 ipcmMessageClientDelTarget(const nsID &target)
434 : ipcMessage_DWORD_DWORD_ID(
435 IPCM_TARGET,
436 IPCM_MSG_REQ_CLIENT_ADD_TARGET,
437 IPCM_NewRequestIndex(),
438 target) {}
439
440 const nsID &Target() const { return Third(); }
441};
442
443class ipcmMessageQueryClientByName : public ipcMessage_DWORD_DWORD_STR
444{
445public:
446 ipcmMessageQueryClientByName(const char *name)
447 : ipcMessage_DWORD_DWORD_STR(
448 IPCM_TARGET,
449 IPCM_MSG_REQ_QUERY_CLIENT_BY_NAME,
450 IPCM_NewRequestIndex(),
451 name) {}
452
453 const char *Name() const { return Third(); }
454 PRUint32 RequestIndex() const { return Second(); }
455};
456
457// ACKNOWLEDGEMENTS
458
459class ipcmMessageResult : public ipcMessage_DWORD_DWORD_DWORD
460{
461public:
462 ipcmMessageResult(PRUint32 requestIndex, PRInt32 status)
463 : ipcMessage_DWORD_DWORD_DWORD(
464 IPCM_TARGET,
465 IPCM_MSG_ACK_RESULT,
466 requestIndex,
467 (PRUint32) status) {}
468
469 PRInt32 Status() const { return (PRInt32) Third(); }
470};
471
472class ipcmMessageClientID : public ipcMessage_DWORD_DWORD_DWORD
473{
474public:
475 ipcmMessageClientID(PRUint32 requestIndex, PRUint32 clientID)
476 : ipcMessage_DWORD_DWORD_DWORD(
477 IPCM_TARGET,
478 IPCM_MSG_ACK_CLIENT_ID,
479 requestIndex,
480 clientID) {}
481
482 PRUint32 ClientID() const { return Third(); }
483};
484
485// PUSH MESSAGES
486
487class ipcmMessageClientState : public ipcMessage_DWORD_DWORD_DWORD_DWORD
488{
489public:
490 ipcmMessageClientState(PRUint32 clientID, PRUint32 clientStatus)
491 : ipcMessage_DWORD_DWORD_DWORD_DWORD(
492 IPCM_TARGET,
493 IPCM_MSG_PSH_CLIENT_STATE,
494 0,
495 clientID,
496 clientStatus) {}
497
498 PRUint32 ClientID() const { return Third(); }
499 PRUint32 ClientState() const { return Fourth(); }
500};
501
502#endif // !ipcm_h__
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use