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