1 
2 /*
3   Meanwhile - Unofficial Lotus Sametime Community Client Library
4   Copyright (C) 2004  Christopher (siege) O'Brien
5 
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Library General Public
8   License as published by the Free Software Foundation; either
9   version 2 of the License, or (at your option) any later version.
10 
11   This library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   Library General Public License for more details.
15 
16   You should have received a copy of the GNU Library General Public
17   License along with this library; if not, write to the Free
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 #ifndef _MW_SERVICE_H
22 #define _MW_SERVICE_H
23 
24 
25 #include "mw_common.h"
26 
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 
33 /* place-holders */
34 struct mwChannel;
35 struct mwService;
36 struct mwSession;
37 struct mwMsgChannelCreate;
38 struct mwMsgChannelAccept;
39 struct mwMsgChannelDestroy;
40 
41 
42 /** State-tracking for a service */
43 enum mwServiceState {
44   mwServiceState_STOPPED,   /**< the service is not active */
45   mwServiceState_STOPPING,  /**< the service is shutting down */
46   mwServiceState_STARTED,   /**< the service is active */
47   mwServiceState_STARTING,  /**< the service is starting up */
48   mwServiceState_ERROR,     /**< error in service, shutting down */
49   mwServiceState_UNKNOWN,   /**< error determining state */
50 };
51 
52 
53 /** Casts a concrete service (such as mwServiceAware) into a mwService */
54 #define MW_SERVICE(srv) ((struct mwService *) srv)
55 
56 
57 #define MW_SERVICE_IS_STATE(srvc, state) \
58   (mwService_getState(MW_SERVICE(srvc)) == (state))
59 
60 #define MW_SERVICE_IS_STOPPED(srvc)  \
61   MW_SERVICE_IS_STATE(srvc, mwServiceState_STOPPED)
62 
63 #define MW_SERVICE_IS_STOPPING(srvc) \
64   MW_SERVICE_IS_STATE(srvc, mwServiceState_STOPPING)
65 
66 #define MW_SERVICE_IS_STARTED(srvc)  \
67   MW_SERVICE_IS_STATE(srvc, mwServiceState_STARTED)
68 
69 #define MW_SERVICE_IS_STARTING(srvc) \
70   MW_SERVICE_IS_STATE(srvc, mwServiceState_STARTING)
71 
72 
73 /** If a service is STARTING or STARTED, it's considered LIVE */
74 #define MW_SERVICE_IS_LIVE(srvc) \
75   (MW_SERVICE_IS_STARTING(srvc) || MW_SERVICE_IS_STARTED(srvc))
76 
77 /** If a service is STOPPING or STOPPED, it's considered DEAD */
78 #define MW_SERVICE_IS_DEAD(srvc) \
79   (MW_SERVICE_IS_STOPPING(srvc) || MW_SERVICE_IS_STOPPED(srvc))
80 
81 
82 typedef void (*mwService_funcStart)(struct mwService *service);
83 
84 typedef void (*mwService_funcStop)(struct mwService *service);
85 
86 typedef void (*mwService_funcClear)(struct mwService *service);
87 
88 typedef const char *(*mwService_funcGetName)(struct mwService *service);
89 
90 typedef const char *(*mwService_funcGetDesc)(struct mwService *service);
91 
92 /** @todo remove msg and replace with appropriate additional parameters */
93 typedef void (*mwService_funcRecvCreate)
94      (struct mwService *service,
95       struct mwChannel *channel,
96       struct mwMsgChannelCreate *msg);
97 
98 /** @todo remove msg and replace with appropriate additional parameters */
99 typedef void (*mwService_funcRecvAccept)
100      (struct mwService *service,
101       struct mwChannel *channel,
102       struct mwMsgChannelAccept *msg);
103 
104 /** @todo remove msg and replace with appropriate additional parameters */
105 typedef void (*mwService_funcRecvDestroy)
106      (struct mwService *service,
107       struct mwChannel *channel,
108       struct mwMsgChannelDestroy *msg);
109 
110 typedef void (*mwService_funcRecv)
111      (struct mwService *service,
112       struct mwChannel *channel,
113       guint16 msg_type,
114       struct mwOpaque *data);
115 
116 
117 /** A service is the recipient of sendOnCnl messages sent over
118     channels marked with the corresponding service id. Services
119     provide functionality such as IM relaying, Awareness tracking and
120     notification, and Conference handling.  It is a service's
121     responsibility to accept or destroy channels, and to process data
122     sent over those channels */
123 struct mwService {
124 
125   /** the unique identifier by which this service is registered. The
126       type value also relates to those channels which will be directed
127       to this service */
128   guint32 type;
129 
130   /** the state of this service. Determines whether or not the session
131       should call the start function upon receipt of a service
132       available message. Should not be set or checked by hand.
133 
134       @relates mwService_getState */
135   enum mwServiceState state;
136 
137   /** session this service is attached to.
138       @relates mwService_getSession */
139   struct mwSession *session;
140 
141   /** @return string short name of the service
142       @relates mwService_getName */
143   mwService_funcGetName get_name;
144 
145   /** @return string short description of the service
146       @relates mwService_getDesc */
147   mwService_funcGetDesc get_desc;
148 
149   /** The service's channel create handler. Called when the session
150       receives a channel create message with a service matching this
151       service's type.
152 
153       @relates mwService_recvCreate */
154   mwService_funcRecvCreate recv_create;
155 
156   /** The service's channel accept handler. Called when the session
157       receives a channel accept message for a channel with a service
158       matching this service's type.
159 
160       @relates mwService_recvAccept */
161   mwService_funcRecvAccept recv_accept;
162 
163   /** The service's channel destroy handler. Called when the session
164       receives a channel destroy message for a channel with a service
165       matching this service's type.
166 
167       @relates mwService_recvDestroy */
168   mwService_funcRecvDestroy recv_destroy;
169 
170   /** The service's input handler. Called when the session receives
171       data on a channel belonging to this service
172 
173       @relates mwService_recv */
174   mwService_funcRecv recv;
175 
176   /** The service's start handler. Called upon the receipt of a
177       service available message.
178 
179       @relates mwService_start */
180   mwService_funcStart start;
181 
182   /** The service's stop handler. Called when the session is shutting
183       down, or when the service is free'd.
184 
185       @relates mwService_stop */
186   mwService_funcStop stop;
187 
188   /** The service's cleanup handler. Service implementations should
189       presume that mwService::stop will be called first. The clear
190       handler is not for shutting down channels or generating
191       non-cleanup side-effects, it is only for handling tear-down of
192       the service, and will only be called once for any instance.
193 
194       @relates mwService_free */
195   mwService_funcClear clear;
196 
197   /** Optional client data, not for use by service implementations
198 
199       @relates mwService_getClientData
200       @relates mwService_setClientData */
201   gpointer client_data;
202 
203   /** Optional client data cleanup function. Called with client_data
204       from mwService_free
205 
206       @relates mwService_getClientData
207       @relates mwService_setClientData */
208   GDestroyNotify client_cleanup;
209 };
210 
211 
212 /** @name Service Extension API
213 
214     These functions are for use by service implementations */
215 /*@{*/
216 
217 
218 /** Prepares a newly allocated service for use.
219 
220     Intended for use by service implementations, rather than by code
221     utilizing a service.
222 
223     The service state will be initialized to STOPPED.
224 
225     @param service       the service to initialize
226     @param session       the service's owning session
227     @param service_type  the service ID number */
228 void mwService_init(struct mwService *service,
229 		    struct mwSession *session,
230 		    guint32 service_type);
231 
232 
233 /** Indicate that a service is started. To be used by service
234     implementations when the service is fully started. */
235 void mwService_started(struct mwService *service);
236 
237 
238 /** Indicate that a service is stopped. To be used by service
239     implementations when the service is fully stopped. */
240 void mwService_stopped(struct mwService *service);
241 
242 
243 /*@}*/
244 
245 
246 /** @name General Services API
247 
248     These functions provide unified access to the general functions of
249     a client service, with some simple sanity-checking. */
250 /*@{*/
251 
252 
253 /** Triggers the recv_create handler on the service.
254 
255     @param service  the service to handle the message
256     @param channel  the channel being created
257     @param msg      the channel create message */
258 void mwService_recvCreate(struct mwService *service,
259 			  struct mwChannel *channel,
260 			  struct mwMsgChannelCreate *msg);
261 
262 
263 /** Triggers the recv_accept handler on the service.
264 
265     @param service  the service to handle the message
266     @param channel  the channel being accepted
267     @param msg      the channel accept message */
268 void mwService_recvAccept(struct mwService *service,
269 			  struct mwChannel *channel,
270 			  struct mwMsgChannelAccept *msg);
271 
272 
273 /** Triggers the recv_destroy handler on the service.
274 
275     @param service  the service to handle the message
276     @param channel  the channel being destroyed
277     @param msg      the channel destroy message */
278 void mwService_recvDestroy(struct mwService *service,
279 			   struct mwChannel *channel,
280 			   struct mwMsgChannelDestroy *msg);
281 
282 
283 /** Triggers the input handler on the service
284 
285     @param service   the service to receive the input
286     @param channel   the channel the input was received from
287     @param msg_type  the service-dependant message type
288     @param data      the message data */
289 void mwService_recv(struct mwService *service,
290 		    struct mwChannel *channel,
291 		    guint16 msg_type,
292 		    struct mwOpaque *data);
293 
294 
295 /** @return the appropriate type id for the service */
296 guint32 mwService_getType(struct mwService *);
297 
298 
299 /** @return string short name of the service */
300 const char *mwService_getName(struct mwService *);
301 
302 
303 /** @return string short description of the service */
304 const char *mwService_getDesc(struct mwService *);
305 
306 
307 /** @return the service's session */
308 struct mwSession *mwService_getSession(struct mwService *service);
309 
310 
311 /** @returns the service's state
312 */
313 enum mwServiceState mwService_getState(struct mwService *service);
314 
315 
316 /** Triggers the start handler for the service. Normally called from
317     the session upon receipt of a service available message. Service
318     implementations should use this handler to open any necessary
319     channels, etc. Checks that the service is STOPPED, or returns.
320 
321     @param service The service to start
322 */
323 void mwService_start(struct mwService *service);
324 
325 
326 /** Triggers the stop handler for the service. Normally called from
327     the session before closing down the connection. Checks that the
328     service is STARTED or STARTING, or returns
329 
330     @param service The service to stop
331 */
332 void mwService_stop(struct mwService *service);
333 
334 
335 /** Frees memory used by a service. Will trigger the stop handler if
336     the service is STARTED or STARTING. Triggers clear handler to allow
337     cleanup.
338 
339     @param service The service to clear and free
340 */
341 void mwService_free(struct mwService *service);
342 
343 
344 /** Associates client data with service. If there is existing data, it
345     will not have its cleanup function called. Client data is not for
346     use by service implementations. Rather, it is for use by client
347     code which may later make use of those service implementations. */
348 void mwService_setClientData(struct mwService *service,
349 			     gpointer data, GDestroyNotify cleanup);
350 
351 
352 /** Reference associated client data */
353 gpointer mwService_getClientData(struct mwService *service);
354 
355 
356 /** Removes client data from service. If there is a cleanup function,
357     it will be called. */
358 void mwService_removeClientData(struct mwService *service);
359 
360 
361 /*@}*/
362 
363 
364 #ifdef __cplusplus
365 }
366 #endif
367 
368 
369 #endif /* _MW_SERVICE_H */
370 
371