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_SESSION_H
22 #define _MW_SESSION_H
23 
24 
25 /** @file mw_session.h
26 
27     A client session with a Sametime server is encapsulated in the
28     mwSession structure. The session controls channels, provides
29     encryption ciphers, and manages services using messages over the
30     Master channel.
31 
32     A session does not directly communicate with a socket or stream,
33     instead the session is initialized from client code with an
34     instance of a mwSessionHandler structure. This session handler
35     provides functions as call-backs for common session events, and
36     provides functions for writing-to and closing the connection to
37     the server.
38 
39     A session does not perform reads on a socket directly. Instead, it
40     must be fed from an outside source via the mwSession_recv
41     function. The session will buffer and merge data passed to this
42     function to build complete protocol messages, and will act upon
43     each complete message accordingly.
44 */
45 
46 
47 #include "mw_common.h"
48 
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 
55 struct mwChannelSet;
56 struct mwCipher;
57 struct mwMessage;
58 struct mwService;
59 
60 
61 /** default protocol major version */
62 #define MW_PROTOCOL_VERSION_MAJOR  0x001e
63 
64 
65 /** default protocol minor version */
66 #define MW_PROTOCOL_VERSION_MINOR  0x001d
67 
68 
69 /** @section Session Properties
70     for use with mwSession_setProperty, et al.
71 */
72 /*@{*/
73 
74 /** char *, session user ID */
75 #define mwSession_AUTH_USER_ID      "session.auth.user"
76 
77 /** char *, plaintext password */
78 #define mwSession_AUTH_PASSWORD     "session.auth.password"
79 
80 /** struct mwOpaque *, authentication token */
81 #define mwSession_AUTH_TOKEN        "session.auth.token"
82 
83 /** char *, hostname of client */
84 #define mwSession_CLIENT_HOST       "client.host"
85 
86 /** guint32, local IP of client */
87 #define mwSession_CLIENT_IP         "client.ip"
88 
89 /** guint16, major version of client protocol */
90 #define mwSession_CLIENT_VER_MAJOR  "client.version.major"
91 
92 /** guint16, minor version of client protocol */
93 #define mwSession_CLIENT_VER_MINOR  "client.version.minor"
94 
95 /** guint16, client type identifier */
96 #define mwSession_CLIENT_TYPE_ID    "client.id"
97 
98 /** guint16, major version of server protocol */
99 #define mwSession_SERVER_VER_MAJOR  "server.version.major"
100 
101 /** guint16, minor version of server protocol */
102 #define mwSession_SERVER_VER_MINOR  "server.version.minor"
103 
104 /*@}*/
105 
106 
107 enum mwSessionState {
108   mwSession_STARTING,      /**< session is starting */
109   mwSession_HANDSHAKE,     /**< session has sent handshake */
110   mwSession_HANDSHAKE_ACK, /**< session has received handshake ack */
111   mwSession_LOGIN,         /**< session has sent login */
112   mwSession_LOGIN_REDIR,   /**< session has been redirected */
113   mwSession_LOGIN_ACK,     /**< session has received login ack */
114   mwSession_STARTED,       /**< session is active */
115   mwSession_STOPPING,      /**< session is shutting down */
116   mwSession_STOPPED,       /**< session is stopped */
117   mwSession_UNKNOWN,       /**< indicates an error determining state */
118   mwSession_LOGIN_CONT,    /**< session has sent a login continue */
119 };
120 
121 
122 #define mwSession_isState(session, state) \
123   (mwSession_getState((session)) == (state))
124 
125 #define mwSession_isStarting(s) \
126   (mwSession_isState((s), mwSession_STARTING)  || \
127    mwSession_isState((s), mwSession_HANDSHAKE) || \
128    mwSession_isState((s), mwSession_HANDSHAKE_ACK) || \
129    mwSession_isState((s), mwSession_LOGIN) || \
130    mwSession_isState((s), mwSession_LOGIN_ACK) || \
131    mwSession_isState((s), mwSession_LOGIN_REDIR) || \
132    mwSession_isState((s), mwSession_LOGIN_CONT))
133 
134 #define mwSession_isStarted(s) \
135   (mwSession_isState((s), mwSession_STARTED))
136 
137 #define mwSession_isStopping(s) \
138   (mwSession_isState((s), mwSession_STOPPING))
139 
140 #define mwSession_isStopped(s) \
141   (mwSession_isState((s), mwSession_STOPPED))
142 
143 
144 /** @struct mwSession
145 
146     Represents a Sametime client session */
147 struct mwSession;
148 
149 
150 /** @struct mwSessionHandler
151 
152     session handler. Structure which interfaces a session with client
153     code to provide I/O and event handling */
154 struct mwSessionHandler {
155 
156   /** write data to the server connection. Required. Should return
157       zero for success, non-zero for error */
158   int (*io_write)(struct mwSession *, const guchar *buf, gsize len);
159 
160   /** close the server connection. Required */
161   void (*io_close)(struct mwSession *);
162 
163   /** triggered by mwSession_free. Optional. Put cleanup code here */
164   void (*clear)(struct mwSession *);
165 
166   /** Called when the session has changed status.
167 
168       @see mwSession_getStateInfo for uses of info field
169 
170       @param s      the session
171       @param state  the session's state
172       @param info   additional state information */
173   void (*on_stateChange)(struct mwSession *s,
174 			 enum mwSessionState state, gpointer info);
175 
176   /** called when privacy information has been sent or received
177 
178       @see mwSession_getPrivacyInfo
179   */
180   void (*on_setPrivacyInfo)(struct mwSession *);
181 
182   /** called when user status has changed
183 
184       @see mwSession_getUserStatus */
185   void (*on_setUserStatus)(struct mwSession *);
186 
187   /** called when an admin messages has been received */
188   void (*on_admin)(struct mwSession *, const char *text);
189 
190   /** called when an announcement arrives */
191   void (*on_announce)(struct mwSession *, struct mwLoginInfo *from,
192 		      gboolean may_reply, const char *text);
193 
194 };
195 
196 
197 /** allocate a new session */
198 struct mwSession *mwSession_new(struct mwSessionHandler *);
199 
200 
201 /** stop, clear, free a session. Does not free contained ciphers or
202     services, these must be taken care of explicitly. */
203 void mwSession_free(struct mwSession *);
204 
205 
206 /** obtain a reference to the session's handler */
207 struct mwSessionHandler *mwSession_getHandler(struct mwSession *);
208 
209 
210 /** instruct the session to begin. This will result in the initial
211     handshake message being sent. */
212 void mwSession_start(struct mwSession *);
213 
214 
215 /** instruct the session to shut down with the following reason
216     code. */
217 void mwSession_stop(struct mwSession *, guint32 reason);
218 
219 
220 /** Data is buffered, unpacked, and parsed into a message, then
221     processed accordingly. */
222 void mwSession_recv(struct mwSession *, const guchar *, gsize);
223 
224 
225 /** primarily used by services to have messages serialized and sent
226     @param s    session to send message over
227     @param msg  message to serialize and send
228     @returns    0 for success */
229 int mwSession_send(struct mwSession *s, struct mwMessage *msg);
230 
231 
232 /** sends the keepalive byte */
233 int mwSession_sendKeepalive(struct mwSession *s);
234 
235 
236 /** respond to a login redirect message by forcing the login sequence
237     to continue through the immediate server. */
238 int mwSession_forceLogin(struct mwSession *s);
239 
240 
241 /** send an announcement to a list of users/groups. Targets of
242     announcement must be in the same community as the session.
243 
244     @param s          session to send announcement from
245     @param may_reply  permit clients to reply. Not all clients honor this.
246     @param text       text of announcement
247     @param recipients list of recipients. Each recipient is specified
248                       by a single string, prefix with "@U " for users
249                       and "@G " for Notes Address Book groups.
250 */
251 int mwSession_sendAnnounce(struct mwSession *s, gboolean may_reply,
252 			   const char *text, const GList *recipients);
253 
254 
255 /** set the internal privacy information, and inform the server as
256     necessary. Triggers the on_setPrivacyInfo call-back. */
257 int mwSession_setPrivacyInfo(struct mwSession *, struct mwPrivacyInfo *);
258 
259 
260 /** direct reference to the session's internal privacy structure */
261 struct mwPrivacyInfo *mwSession_getPrivacyInfo(struct mwSession *);
262 
263 
264 /** reference the login information for the session */
265 struct mwLoginInfo *mwSession_getLoginInfo(struct mwSession *);
266 
267 
268 /** set the internal user status state, and inform the server as
269     necessary. Triggers the on_setUserStatus call-back */
270 int mwSession_setUserStatus(struct mwSession *, struct mwUserStatus *);
271 
272 
273 struct mwUserStatus *mwSession_getUserStatus(struct mwSession *);
274 
275 
276 /** current status of the session */
277 enum mwSessionState mwSession_getState(struct mwSession *);
278 
279 
280 /** additional status-specific information. Depending on the state of
281     the session, this value has different meaning.
282 
283     @li @c mwSession_STOPPING guint32 error code causing
284     the session to shut down
285 
286     @li @c mwSession_STOPPED guint32 error code causing
287     the session to shut down
288 
289     @li @c mwSession_LOGIN_REDIR (char *) host to redirect
290     to
291 */
292 gpointer mwSession_getStateInfo(struct mwSession *);
293 
294 
295 struct mwChannelSet *mwSession_getChannels(struct mwSession *);
296 
297 
298 /** adds a service to the session. If the session is started (or when
299     the session is successfully started) and the service has a start
300     function, the session will request service availability from the
301     server. On receipt of the service availability notification, the
302     session will call the service's start function.
303 
304     @return TRUE if the session was added correctly */
305 gboolean mwSession_addService(struct mwSession *, struct mwService *);
306 
307 
308 /** find a service by its type identifier */
309 struct mwService *mwSession_getService(struct mwSession *, guint32 type);
310 
311 
312 /** removes a service from the session. If the session is started and
313     the service has a stop function, it will be called. Returns the
314     removed service */
315 struct mwService *mwSession_removeService(struct mwSession *, guint32 type);
316 
317 
318 /** a GList of services in this session. The GList needs to be freed
319     after use */
320 GList *mwSession_getServices(struct mwSession *);
321 
322 
323 /** instruct a STARTED session to check the server for the presense of
324     a given service. The service will be automatically started upon
325     receipt of an affirmative reply from the server. This function is
326     automatically called upon all services in a session when the
327     session is fully STARTED.
328 
329     Services which terminate due to an error may call this on
330     themselves to re-initialize when their server-side counterpart is
331     made available again.
332 
333     @param s     owning session
334     @param type  service type ID */
335 void mwSession_senseService(struct mwSession *s, guint32 type);
336 
337 
338 /** adds a cipher to the session. */
339 gboolean mwSession_addCipher(struct mwSession *, struct mwCipher *);
340 
341 
342 /** find a cipher by its type identifier */
343 struct mwCipher *mwSession_getCipher(struct mwSession *, guint16 type);
344 
345 
346 /** remove a cipher from the session */
347 struct mwCipher *mwSession_removeCipher(struct mwSession *, guint16 type);
348 
349 
350 /** a GList of ciphers in this session. The GList needs to be freed
351     after use */
352 GList *mwSession_getCiphers(struct mwSession *);
353 
354 
355 /** associate a key:value pair with the session. If an existing value is
356     associated with the same key, it will have its clear function called
357     and will be replaced with the new value */
358 void mwSession_setProperty(struct mwSession *, const char *key,
359 			   gpointer val, GDestroyNotify clear);
360 
361 
362 /** obtain the value of a previously set property, or NULL */
363 gpointer mwSession_getProperty(struct mwSession *, const char *key);
364 
365 
366 /** remove a property, calling the optional GDestroyNotify function
367     indicated in mwSession_setProperty if applicable */
368 void mwSession_removeProperty(struct mwSession *, const char *key);
369 
370 
371 /** associate arbitrary data with the session for use by the client
372     code. Only client applications should use this, never services.
373 
374     @param session  the session to associate the data with
375     @param data     arbitrary client data
376     @param clear    optional cleanup function called on data from
377                     mwSession_removeClientData and mwSession_free
378 */
379 void mwSession_setClientData(struct mwSession *session,
380 			     gpointer data, GDestroyNotify clear);
381 
382 
383 gpointer mwSession_getClientData(struct mwSession *session);
384 
385 
386 /** remove client data, calling the optional GDestroyNotify function
387     indicated in mwSession_setClientData if applicable */
388 void mwSession_removeClientData(struct mwSession *session);
389 
390 
391 #ifdef __cplusplus
392 }
393 #endif
394 
395 
396 #endif /* _MW_SESSION_H */
397 
398