1/*  D-BUS Service Utilities
2 *
3 *  Provides utilities for construction of D-BUS "Services"
4 *
5 *  Copyright(C) Jason Vas Dias, Red Hat Inc., 2005
6 *  Modified by Adam Tkac, Red Hat Inc., 2007
7 *
8 *  This program is free software; you can redistribute it and/or modify
9 *  it under the terms of the GNU General Public License as published by
10 *  the Free Software Foundation at
11 *           http://www.fsf.org/licensing/licenses/gpl.txt
12 *  and included in this software distribution as the "LICENSE" file.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 */
20
21#ifndef D_BUS_SERVER_UTILITIES_H
22#define D_BUS_SERVER_UTILITIES_H
23
24#include <stdint.h>
25#include <stdarg.h>
26#include <isc/types.h>
27
28typedef struct dbcs_s* DBUS_SVC;
29
30typedef enum
31{ HANDLED, NOT_HANDLED, HANDLED_NOW
32} dbus_svc_HandlerResult;
33
34typedef enum
35{  INVALID, CALL, RETURN, ERROR, SIGNAL
36} dbus_svc_MessageType;
37
38typedef enum
39{
40    DBUS_SESSION,
41    DBUS_SYSTEM,
42    DBUS_STARTER,
43    DBUS_PRIVATE_SYSTEM,
44    DBUS_PRIVATE_SESSION
45} dbus_svc_DBUS_TYPE;
46
47typedef enum /* D-BUS Protocol Type Codes / Signature Chars */
48{
49   TYPE_INVALID  =   (int)'\0',
50   TYPE_BYTE     =   (int)'y',
51   TYPE_BOOLEAN  =   (int)'b',
52   TYPE_INT16    =   (int)'n',
53   TYPE_UINT16   =   (int)'q',
54   TYPE_INT32    =   (int)'i',
55   TYPE_UINT32   =   (int)'u',
56   TYPE_INT64    =   (int)'x',
57   TYPE_UINT64   =   (int)'t',
58   TYPE_DOUBLE   =   (int)'d',
59   TYPE_STRING   =   (int)'s',
60   TYPE_OBJECT_PATH =(int)'o',
61   TYPE_SIGNATURE=   (int)'g',
62   TYPE_ARRAY    =   (int)'a',
63   TYPE_VARIANT  =   (int)'v',
64   TYPE_STRUCT   =   (int)'r',
65   TYPE_DICT_ENTRY = (int)'e',
66   STRUCT_BEGIN  =   (int)'(',
67   STRUCT_END    =   (int)')',
68   DICT_ENTRY_BEGIN =(int)'{',
69   DICT_ENTRY_END   =(int)'}'
70} dbus_svc_DataType;
71
72typedef struct DBusMessage* dbus_svc_MessageHandle;
73
74typedef int
75(*dbus_svc_ErrorHandler)
76( const char *errorFmt, ...
77); /* Error Handler function prototype - handle FATAL errors from D-BUS calls */
78
79typedef enum
80{
81    WATCH_ENABLE = 8,
82    WATCH_ERROR  = 4,
83    WATCH_WRITE  = 2,
84    WATCH_READ   = 1
85} dbus_svc_WatchFlags;
86
87typedef void (*dbus_svc_WatchHandler)( int, dbus_svc_WatchFlags, void *arg );
88
89typedef dbus_svc_HandlerResult
90(*dbus_svc_MessageHandler)
91( DBUS_SVC dbus,
92  dbus_svc_MessageType type,
93  uint8_t  reply_expected,   /* 1 / 0 */
94  uint32_t serial,           /* serial number of message; needed to reply */
95  const char *destination,         /* D-BUS connection name / destination */
96  const char *path,                /* D-BUS Object Path */
97  const char *member,              /* D-BUS Object Member */
98  const char *interface,           /* D-BUS Object interface */
99  const char *if_suffix,           /* remainder of interface prefixed by ifPrefix */
100  const char *sender,              /* Senders' connection destination */
101  const char *signature,           /* Signature String composed of Type Codes      */
102  dbus_svc_MessageHandle msg,/* Message pointer: call dbus_svc_get_args(msg,...) to get data */
103  const char *prefix,              /* If non-null, this is the root prefix for this sub-path message */
104  const char *suffix,              /* If non-null, this is the suffix of this sub-path message */
105  void *prefixObject,        /* If non-null, this is the object that was registered for the prefix */
106  void *object               /* If non-null, this is the object that was registered for the complete path */
107); /* Message Handler function prototype */
108
109#define DBusMsgHandlerArgs \
110  DBUS_SVC dbus, \
111  dbus_svc_MessageType type, \
112  uint8_t  reply_expected, \
113  uint32_t serial,         \
114  const char *destination,       \
115  const char *path,              \
116  const char *member,            \
117  const char *interface,         \
118  const char *if_suffix,         \
119  const char *sender,            \
120  const char *signature,         \
121  dbus_svc_MessageHandle msg, \
122  const char *prefix,            \
123  const char *suffix,            \
124  void *prefixObject,      \
125  void *object
126
127#define SHUTDOWN 255
128
129extern isc_result_t dbus_svc_init
130( dbus_svc_DBUS_TYPE bus,
131  char *name,                         /* name to register with D-BUS */
132  DBUS_SVC *dbus,                     /* dbus handle */
133  dbus_svc_WatchHandler wh,           /* optional handler for watch events */
134  dbus_svc_ErrorHandler eh,           /* optional error log message handler */
135  dbus_svc_ErrorHandler dh,           /* optional debug / info log message handler */
136  void *wh_arg                        /* optional watch handler arg */
137);
138/*
139 * Obtains connection to DBUS_BUS_STARTER and registers "name".
140 * "eh" will be called for all errors from this server session.
141 */
142
143/* EITHER :
144 *        pass a NULL WatchHandler to dbus_svc_init and use dbus_svc_main_loop
145 * OR:
146 *        supply a valid WatchHandler, and call dbus_svc_handle_watch when
147 *        select() returns the watch fd as ready for the watch action, and
148 *        call dbus_svc_dispatch when all watches have been handled.
149 */
150
151
152uint8_t
153dbus_svc_add_filter
154(  DBUS_SVC, dbus_svc_MessageHandler mh, void *obj, int n_matches, ... );
155/*
156 * Registers SINGLE message handler to handle ALL messages, adding match rules
157 */
158
159void  dbus_svc_main_loop( DBUS_SVC, void (*idle_handler)(DBUS_SVC) );
160
161void  dbus_svc_handle_watch( DBUS_SVC, int watch_fd, dbus_svc_WatchFlags action);
162
163void  dbus_svc_dispatch( DBUS_SVC );
164
165/*
166 * Enter message processing loop.
167 * If "idle_handler" is non-null, it will be called once per iteration of loop.
168 */
169
170const char *dbus_svc_unique_name( DBUS_SVC );
171/*
172 * Returns connection "unique" (socket) name
173 */
174
175void  dbus_svc_quit( DBUS_SVC );
176/*
177 * Exit message processing loop
178 */
179
180void  dbus_svc_shutdown( DBUS_SVC );
181/*
182 * Close connections and clean up.
183 * DBUS_SVC pointer is invalid after this.
184 */
185
186uint8_t
187dbus_svc_get_args( DBUS_SVC, dbus_svc_MessageHandle, dbus_svc_DataType, ... );
188/* get arguments from message  */
189
190uint8_t
191dbus_svc_get_args_va( DBUS_SVC, dbus_svc_MessageHandle, dbus_svc_DataType, va_list );
192/* get arguments from message  */
193
194
195typedef void (*dbus_svc_ShutdownHandler) ( DBUS_SVC, void * );
196uint8_t
197dbus_svc_add_shutdown_filter
198(
199    DBUS_SVC, dbus_svc_ShutdownHandler sh, void *obj
200);
201/* Registers a filter for D-BUS shutdown event.
202 * Cannot be used in conjunction with dbus_svc_add_message_filter.
203 */
204
205uint8_t
206dbus_svc_remove_message_filter
207( DBUS_SVC, dbus_svc_MessageHandler mh);
208/* Unregisters the message filter */
209
210uint8_t
211dbus_svc_send
212( DBUS_SVC,
213  dbus_svc_MessageType type,
214  int32_t reply_serial,
215  uint32_t *new_serial,
216  const char *destination,
217  const char *path,
218  const char *member,
219  const char *interface,
220  dbus_svc_DataType firstType,
221  ... /* pointer, { (dbus_svc_DataType, pointer )...} */
222); /* sends messages / replies to "destination" */
223
224uint8_t
225dbus_svc_send_va
226( DBUS_SVC cs,
227  dbus_svc_MessageType type,
228  int32_t reply_serial,
229  uint32_t *new_serial,
230  const char *destination,
231  const char *path,
232  const char *member,
233  const char *interface,
234  dbus_svc_DataType firstType,
235  va_list va
236); /* sends messages / replies to "destination" */
237
238dbus_svc_MessageHandle
239dbus_svc_call
240( DBUS_SVC cs,
241  const char *destination,
242  const char *path,
243  const char *member,
244  const char *interface,
245  dbus_svc_DataType firstType,
246  ...
247); /* constructs message, sends it, returns reply */
248
249dbus_svc_MessageHandle
250dbus_svc_new_message
251( DBUS_SVC cs,
252  dbus_svc_MessageType type,
253  int32_t reply_serial,
254  const char *destination,
255  const char *path,
256  const char *interface,
257  const char *member
258);
259
260uint8_t
261dbus_svc_send_message(DBUS_SVC , dbus_svc_MessageHandle , uint32_t *  );
262
263uint8_t
264dbus_svc_message_append_args( DBUS_SVC , dbus_svc_MessageHandle, dbus_svc_DataType, ...);
265
266typedef struct DBusMessageIter *dbus_svc_MessageIterator;
267
268dbus_svc_MessageIterator
269dbus_svc_message_iterator_new( DBUS_SVC, dbus_svc_MessageHandle );
270
271uint32_t
272dbus_svc_message_next_arg_type( DBUS_SVC, dbus_svc_MessageIterator );
273
274void
275dbus_svc_message_next_arg( DBUS_SVC, dbus_svc_MessageIterator,  void * );
276
277uint32_t
278dbus_svc_message_element_type( DBUS_SVC, dbus_svc_MessageIterator );
279
280void
281dbus_svc_message_get_elements( DBUS_SVC, dbus_svc_MessageIterator, uint32_t *n, void *array );
282
283uint8_t dbus_svc_message_type( dbus_svc_MessageHandle );
284
285void dbus_svc_message_iterator_free(  DBUS_SVC, dbus_svc_MessageIterator  );
286
287#endif
288