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 #include "mw_channel.h"
22 #include "mw_debug.h"
23 #include "mw_error.h"
24 #include "mw_message.h"
25 #include "mw_service.h"
26 
27 
28 /* I tried to be explicit with the g_return_* calls, to make the debug
29    logging a bit more sensible. Hence all the explicit "foo != NULL"
30    checks. */
31 
32 
mwService_recvCreate(struct mwService * s,struct mwChannel * chan,struct mwMsgChannelCreate * msg)33 void mwService_recvCreate(struct mwService *s, struct mwChannel *chan,
34 			  struct mwMsgChannelCreate *msg) {
35 
36   /* ensure none are null, ensure that the service and channel belong
37      to the same session, and ensure that the message belongs on the
38      channel */
39   g_return_if_fail(s != NULL);
40   g_return_if_fail(chan != NULL);
41   g_return_if_fail(msg != NULL);
42   g_return_if_fail(s->session == mwChannel_getSession(chan));
43   g_return_if_fail(mwChannel_getId(chan) == msg->channel);
44 
45   if(s->recv_create) {
46     s->recv_create(s, chan, msg);
47   } else {
48     mwChannel_destroy(chan, ERR_FAILURE, NULL);
49   }
50 }
51 
52 
mwService_recvAccept(struct mwService * s,struct mwChannel * chan,struct mwMsgChannelAccept * msg)53 void mwService_recvAccept(struct mwService *s, struct mwChannel *chan,
54 			  struct mwMsgChannelAccept *msg) {
55 
56   /* ensure none are null, ensure that the service and channel belong
57      to the same session, and ensure that the message belongs on the
58      channel */
59   g_return_if_fail(s != NULL);
60   g_return_if_fail(chan != NULL);
61   g_return_if_fail(msg != NULL);
62   g_return_if_fail(s->session == mwChannel_getSession(chan));
63   g_return_if_fail(mwChannel_getId(chan) == msg->head.channel);
64 
65   if(s->recv_accept)
66     s->recv_accept(s, chan, msg);
67 }
68 
69 
mwService_recvDestroy(struct mwService * s,struct mwChannel * chan,struct mwMsgChannelDestroy * msg)70 void mwService_recvDestroy(struct mwService *s, struct mwChannel *chan,
71 			   struct mwMsgChannelDestroy *msg) {
72 
73   /* ensure none are null, ensure that the service and channel belong
74      to the same session, and ensure that the message belongs on the
75      channel */
76   g_return_if_fail(s != NULL);
77   g_return_if_fail(chan != NULL);
78   g_return_if_fail(msg != NULL);
79   g_return_if_fail(s->session == mwChannel_getSession(chan));
80   g_return_if_fail(mwChannel_getId(chan) == msg->head.channel);
81 
82   if(s->recv_destroy)
83     s->recv_destroy(s, chan, msg);
84 }
85 
86 
mwService_recv(struct mwService * s,struct mwChannel * chan,guint16 msg_type,struct mwOpaque * data)87 void mwService_recv(struct mwService *s, struct mwChannel *chan,
88 		    guint16 msg_type, struct mwOpaque *data) {
89 
90   /* ensure that none are null. zero-length messages are acceptable */
91   g_return_if_fail(s != NULL);
92   g_return_if_fail(chan != NULL);
93   g_return_if_fail(data != NULL);
94   g_return_if_fail(s->session == mwChannel_getSession(chan));
95 
96   /*
97   g_message("mwService_recv: session = %p, service = %p, b = %p, n = %u",
98 	    mwService_getSession(s), s, data->data, data->len);
99   */
100 
101   if(s->recv)
102     s->recv(s, chan, msg_type, data);
103 }
104 
105 
mwService_getType(struct mwService * s)106 guint32 mwService_getType(struct mwService *s) {
107   g_return_val_if_fail(s != NULL, 0x00);
108   return s->type;
109 }
110 
111 
mwService_getName(struct mwService * s)112 const char *mwService_getName(struct mwService *s) {
113   g_return_val_if_fail(s != NULL, NULL);
114   g_return_val_if_fail(s->get_name != NULL, NULL);
115 
116   return s->get_name(s);
117 }
118 
119 
mwService_getDesc(struct mwService * s)120 const char *mwService_getDesc(struct mwService *s) {
121   g_return_val_if_fail(s != NULL, NULL);
122   g_return_val_if_fail(s->get_desc != NULL, NULL);
123 
124   return s->get_desc(s);
125 }
126 
127 
mwService_getSession(struct mwService * s)128 struct mwSession *mwService_getSession(struct mwService *s) {
129   g_return_val_if_fail(s != NULL, NULL);
130   return s->session;
131 }
132 
133 
mwService_init(struct mwService * srvc,struct mwSession * sess,guint32 type)134 void mwService_init(struct mwService *srvc, struct mwSession *sess,
135 		    guint32 type) {
136 
137   /* ensure nothing is null, and there's no such thing as a zero
138      service type */
139   g_return_if_fail(srvc != NULL);
140   g_return_if_fail(sess != NULL);
141   g_return_if_fail(type != 0x00);
142 
143   srvc->session = sess;
144   srvc->type = type;
145   srvc->state = mwServiceState_STOPPED;
146 }
147 
148 
mwService_getState(struct mwService * srvc)149 enum mwServiceState mwService_getState(struct mwService *srvc) {
150   g_return_val_if_fail(srvc != NULL, mwServiceState_STOPPED);
151   return srvc->state;
152 }
153 
154 
mwService_start(struct mwService * srvc)155 void mwService_start(struct mwService *srvc) {
156   g_return_if_fail(srvc != NULL);
157 
158   if(! MW_SERVICE_IS_STOPPED(srvc))
159     return;
160 
161   srvc->state = mwServiceState_STARTING;
162   g_message("starting service %s", NSTR(mwService_getName(srvc)));
163 
164   if(srvc->start) {
165     srvc->start(srvc);
166   } else {
167     mwService_started(srvc);
168   }
169 }
170 
171 
mwService_started(struct mwService * srvc)172 void mwService_started(struct mwService *srvc) {
173   g_return_if_fail(srvc != NULL);
174 
175   srvc->state = mwServiceState_STARTED;
176   g_message("started service %s", NSTR(mwService_getName(srvc)));
177 }
178 
179 
mwService_error(struct mwService * srvc)180 void mwService_error(struct mwService *srvc) {
181   g_return_if_fail(srvc != NULL);
182 
183   if(MW_SERVICE_IS_DEAD(srvc))
184     return;
185 
186   srvc->state = mwServiceState_ERROR;
187   g_message("error in service %s", NSTR(mwService_getName(srvc)));
188 
189   if(srvc->stop) {
190     srvc->stop(srvc);
191   } else {
192     mwService_stopped(srvc);
193   }
194 }
195 
196 
mwService_stop(struct mwService * srvc)197 void mwService_stop(struct mwService *srvc) {
198   g_return_if_fail(srvc != NULL);
199 
200   if(MW_SERVICE_IS_DEAD(srvc))
201     return;
202 
203   srvc->state = mwServiceState_STOPPING;
204   g_message("stopping service %s", NSTR(mwService_getName(srvc)));
205 
206   if(srvc->stop) {
207     srvc->stop(srvc);
208   } else {
209     mwService_stopped(srvc);
210   }
211 }
212 
213 
mwService_stopped(struct mwService * srvc)214 void mwService_stopped(struct mwService *srvc) {
215   g_return_if_fail(srvc != NULL);
216 
217   if(srvc->state != mwServiceState_STOPPED) {
218     srvc->state = mwServiceState_STOPPED;
219     g_message("stopped service %s", NSTR(mwService_getName(srvc)));
220   }
221 }
222 
223 
mwService_free(struct mwService * srvc)224 void mwService_free(struct mwService *srvc) {
225   g_return_if_fail(srvc != NULL);
226 
227   mwService_stop(srvc);
228 
229   if(srvc->clear)
230     srvc->clear(srvc);
231 
232   if(srvc->client_cleanup)
233     srvc->client_cleanup(srvc->client_data);
234 
235   g_free(srvc);
236 }
237 
238 
239 /** @todo switch the following to using mw_datum */
240 
mwService_setClientData(struct mwService * srvc,gpointer data,GDestroyNotify cleanup)241 void mwService_setClientData(struct mwService *srvc,
242 			     gpointer data, GDestroyNotify cleanup) {
243 
244   g_return_if_fail(srvc != NULL);
245 
246   srvc->client_data = data;
247   srvc->client_cleanup = cleanup;
248 }
249 
250 
mwService_getClientData(struct mwService * srvc)251 gpointer mwService_getClientData(struct mwService *srvc) {
252   g_return_val_if_fail(srvc != NULL, NULL);
253   return srvc->client_data;
254 }
255 
256 
mwService_removeClientData(struct mwService * srvc)257 void mwService_removeClientData(struct mwService *srvc) {
258   g_return_if_fail(srvc != NULL);
259 
260   if(srvc->client_cleanup) {
261     srvc->client_cleanup(srvc->client_data);
262     srvc->client_cleanup = NULL;
263   }
264 
265   srvc->client_data = NULL;
266 }
267 
268