comparison src/protocols/sametime/meanwhile/message.c @ 10969:3ef77720e577

[gaim-migrate @ 12790] importing meanwhile library for use in the sametime plugin committer: Tailor Script <tailor@pidgin.im>
author Christopher O'Brien <siege@pidgin.im>
date Sun, 05 Jun 2005 02:50:13 +0000
parents
children 0110fc7c6a8a
comparison
equal deleted inserted replaced
10968:e0d5038fbb7e 10969:3ef77720e577
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 <glib.h>
22
23 #include "mw_debug.h"
24 #include "mw_message.h"
25
26
27 /* 7.1 Layering and message encapsulation */
28 /* 7.1.1 The Sametime Message Header */
29
30
31 static void mwMessageHead_put(struct mwPutBuffer *b, struct mwMessage *msg) {
32 guint16_put(b, msg->type);
33 guint16_put(b, msg->options);
34 guint32_put(b, msg->channel);
35
36 if(msg->options & mwMessageOption_HAS_ATTRIBS)
37 mwOpaque_put(b, &msg->attribs);
38 }
39
40
41 static void mwMessageHead_get(struct mwGetBuffer *b, struct mwMessage *msg) {
42
43 if(mwGetBuffer_error(b)) return;
44
45 guint16_get(b, &msg->type);
46 guint16_get(b, &msg->options);
47 guint32_get(b, &msg->channel);
48
49 if(msg->options & mwMessageOption_HAS_ATTRIBS)
50 mwOpaque_get(b, &msg->attribs);
51 }
52
53
54 static void mwMessageHead_clone(struct mwMessage *to,
55 struct mwMessage *from) {
56
57 to->type = from->type;
58 to->options = from->options;
59 to->channel = from->channel;
60 mwOpaque_clone(&to->attribs, &from->attribs);
61 }
62
63
64 static void mwMessageHead_clear(struct mwMessage *msg) {
65 mwOpaque_clear(&msg->attribs);
66 }
67
68
69 /* 8.4 Messages */
70 /* 8.4.1 Basic Community Messages */
71 /* 8.4.1.1 Handshake */
72
73
74 static void HANDSHAKE_put(struct mwPutBuffer *b, struct mwMsgHandshake *msg) {
75 guint16_put(b, msg->major);
76 guint16_put(b, msg->minor);
77 guint32_put(b, msg->head.channel);
78 guint32_put(b, msg->srvrcalc_addr);
79 guint16_put(b, msg->login_type);
80 guint32_put(b, msg->loclcalc_addr);
81 }
82
83
84 static void HANDSHAKE_clear(struct mwMsgHandshake *msg) {
85 ; /* nothing to clean up */
86 }
87
88
89 /* 8.4.1.2 HandshakeAck */
90
91
92 static void HANDSHAKE_ACK_get(struct mwGetBuffer *b,
93 struct mwMsgHandshakeAck *msg) {
94
95 if(mwGetBuffer_error(b)) return;
96
97 guint16_get(b, &msg->major);
98 guint16_get(b, &msg->minor);
99 guint32_get(b, &msg->srvrcalc_addr);
100
101 /** @todo: get a better handle on what versions support what parts
102 of this message. eg: minor version 0x0018 doesn't send the
103 following */
104 if(msg->major >= 0x1e && msg->minor > 0x18) {
105 guint32_get(b, &msg->unknown);
106 mwOpaque_get(b, &msg->data);
107 }
108 }
109
110
111 static void HANDSHAKE_ACK_clear(struct mwMsgHandshakeAck *msg) {
112 mwOpaque_clear(&msg->data);
113 }
114
115
116 /* 8.4.1.3 Login */
117
118
119 static void LOGIN_put(struct mwPutBuffer *b, struct mwMsgLogin *msg) {
120 guint16_put(b, msg->login_type);
121 mwString_put(b, msg->name);
122
123 /* ordering reversed from draft?? */
124 mwOpaque_put(b, &msg->auth_data);
125 guint16_put(b, msg->auth_type);
126 }
127
128
129 static void LOGIN_clear(struct mwMsgLogin *msg) {
130 g_free(msg->name);
131 mwOpaque_clear(&msg->auth_data);
132 }
133
134
135 /* 8.4.1.4 LoginAck */
136
137
138 static void LOGIN_ACK_get(struct mwGetBuffer *b, struct mwMsgLoginAck *msg) {
139 guint16 junk;
140
141 if(mwGetBuffer_error(b)) return;
142
143 mwLoginInfo_get(b, &msg->login);
144 guint16_get(b, &junk);
145 mwPrivacyInfo_get(b, &msg->privacy);
146 mwUserStatus_get(b, &msg->status);
147 }
148
149
150 static void LOGIN_ACK_clear(struct mwMsgLoginAck *msg) {
151 mwLoginInfo_clear(&msg->login);
152 mwPrivacyInfo_clear(&msg->privacy);
153 mwUserStatus_clear(&msg->status);
154 }
155
156
157 /* 8.4.1.5 LoginCont */
158
159
160 static void LOGIN_CONTINUE_put(struct mwPutBuffer *b,
161 struct mwMsgLoginContinue *msg) {
162
163 ; /* nothing but a message header */
164 }
165
166
167 static void LOGIN_CONTINUE_clear(struct mwMsgLoginContinue *msg) {
168 ; /* this is a very simple message */
169 }
170
171
172 /* 8.4.1.6 AuthPassed */
173
174
175 static void LOGIN_REDIRECT_get(struct mwGetBuffer *b,
176 struct mwMsgLoginRedirect *msg) {
177
178 if(mwGetBuffer_error(b)) return;
179 mwString_get(b, &msg->host);
180 mwString_get(b, &msg->server_id);
181 }
182
183
184 static void LOGIN_REDIRECT_clear(struct mwMsgLoginRedirect *msg) {
185 g_free(msg->host);
186 msg->host = NULL;
187
188 g_free(msg->server_id);
189 msg->server_id = NULL;
190 }
191
192
193 /* 8.4.1.7 CreateCnl */
194
195
196 static void enc_offer_put(struct mwPutBuffer *b, struct mwEncryptOffer *enc) {
197 char tail = 0x07;
198
199 guint16_put(b, enc->mode);
200
201 if(enc->items) {
202 guint32 count;
203 struct mwPutBuffer *p;
204 struct mwOpaque o;
205 GList *list;
206
207 /* write the count, items, extra, and flag into a tmp buffer,
208 render that buffer into an opaque, and write it into b */
209
210 count = g_list_length(enc->items);
211 p = mwPutBuffer_new();
212
213
214 guint32_put(p, count);
215 for(list = enc->items; list; list = list->next) {
216 mwEncryptItem_put(p, list->data);
217 }
218
219 guint16_put(p, enc->extra);
220 gboolean_put(p, enc->flag);
221
222 mwPutBuffer_finalize(&o, p);
223 mwOpaque_put(b, &o);
224 mwOpaque_clear(&o);
225 }
226
227 guint32_put(b, 0x00);
228 guint32_put(b, 0x00);
229 gboolean_put(b, FALSE);
230 mwPutBuffer_write(b, &tail, 1);
231 }
232
233
234 static void CHANNEL_CREATE_put(struct mwPutBuffer *b,
235 struct mwMsgChannelCreate *msg) {
236
237 guint32_put(b, msg->reserved);
238 guint32_put(b, msg->channel);
239 mwIdBlock_put(b, &msg->target);
240 guint32_put(b, msg->service);
241 guint32_put(b, msg->proto_type);
242 guint32_put(b, msg->proto_ver);
243 guint32_put(b, msg->options);
244 mwOpaque_put(b, &msg->addtl);
245 gboolean_put(b, msg->creator_flag);
246
247 if(msg->creator_flag)
248 mwLoginInfo_put(b, &msg->creator);
249
250 enc_offer_put(b, &msg->encrypt);
251 }
252
253
254 static void enc_offer_get(struct mwGetBuffer *b,
255 struct mwEncryptOffer *enc) {
256 guint32 skip;
257
258 if(mwGetBuffer_error(b)) return;
259
260 guint16_get(b, &enc->mode);
261 guint32_get(b, &skip);
262
263 if(skip >= 7) {
264 guint32 count;
265
266 guint32_get(b, &count);
267
268 while(count-- && (! mwGetBuffer_error(b))) {
269 struct mwEncryptItem *ei = g_new0(struct mwEncryptItem, 1);
270 mwEncryptItem_get(b, ei);
271 enc->items = g_list_append(enc->items, ei);
272 }
273
274 guint16_get(b, &enc->extra);
275 gboolean_get(b, &enc->flag);
276 }
277 }
278
279
280 static void CHANNEL_CREATE_get(struct mwGetBuffer *b,
281 struct mwMsgChannelCreate *msg) {
282
283 if(mwGetBuffer_error(b)) return;
284
285 guint32_get(b, &msg->reserved);
286 guint32_get(b, &msg->channel);
287 mwIdBlock_get(b, &msg->target);
288 guint32_get(b, &msg->service);
289 guint32_get(b, &msg->proto_type);
290 guint32_get(b, &msg->proto_ver);
291 guint32_get(b, &msg->options);
292 mwOpaque_get(b, &msg->addtl);
293 gboolean_get(b, &msg->creator_flag);
294
295 if(msg->creator_flag)
296 mwLoginInfo_get(b, &msg->creator);
297
298 enc_offer_get(b, &msg->encrypt);
299 }
300
301
302 static void CHANNEL_CREATE_clear(struct mwMsgChannelCreate *msg) {
303 GList *list;
304
305 mwIdBlock_clear(&msg->target);
306 mwOpaque_clear(&msg->addtl);
307 mwLoginInfo_clear(&msg->creator);
308
309 for(list = msg->encrypt.items; list; list = list->next) {
310 mwEncryptItem_clear(list->data);
311 g_free(list->data);
312 }
313 g_list_free(msg->encrypt.items);
314 }
315
316
317 /* 8.4.1.8 AcceptCnl */
318
319
320 static void enc_accept_put(struct mwPutBuffer *b,
321 struct mwEncryptAccept *enc) {
322
323 char tail = 0x07;
324
325 guint16_put(b, enc->mode);
326
327 if(enc->item) {
328 struct mwPutBuffer *p;
329 struct mwOpaque o;
330
331 p = mwPutBuffer_new();
332
333 mwEncryptItem_put(p, enc->item);
334 guint16_put(p, enc->extra);
335 gboolean_put(p, enc->flag);
336
337 mwPutBuffer_finalize(&o, p);
338 mwOpaque_put(b, &o);
339 mwOpaque_clear(&o);
340 }
341
342 guint32_put(b, 0x00);
343 guint32_put(b, 0x00);
344 gboolean_put(b, FALSE);
345
346 mwPutBuffer_write(b, &tail, 1);
347 }
348
349
350 static void CHANNEL_ACCEPT_put(struct mwPutBuffer *b,
351 struct mwMsgChannelAccept *msg) {
352
353 guint32_put(b, msg->service);
354 guint32_put(b, msg->proto_type);
355 guint32_put(b, msg->proto_ver);
356 mwOpaque_put(b, &msg->addtl);
357 gboolean_put(b, msg->acceptor_flag);
358
359 if(msg->acceptor_flag)
360 mwLoginInfo_put(b, &msg->acceptor);
361
362 enc_accept_put(b, &msg->encrypt);
363 }
364
365
366 static void enc_accept_get(struct mwGetBuffer *b,
367 struct mwEncryptAccept *enc) {
368 guint32 skip;
369
370 if(mwGetBuffer_error(b)) return;
371
372 guint16_get(b, &enc->mode);
373 guint32_get(b, &skip);
374
375 if(skip >= 6) {
376 enc->item = g_new0(struct mwEncryptItem, 1);
377 mwEncryptItem_get(b, enc->item);
378 }
379
380 if(skip >= 9) {
381 guint16_get(b, &enc->extra);
382 gboolean_get(b, &enc->flag);
383 }
384 }
385
386
387 static void CHANNEL_ACCEPT_get(struct mwGetBuffer *b,
388 struct mwMsgChannelAccept *msg) {
389
390 if(mwGetBuffer_error(b)) return;
391
392 guint32_get(b, &msg->service);
393 guint32_get(b, &msg->proto_type);
394 guint32_get(b, &msg->proto_ver);
395 mwOpaque_get(b, &msg->addtl);
396 gboolean_get(b, &msg->acceptor_flag);
397
398 if(msg->acceptor_flag)
399 mwLoginInfo_get(b, &msg->acceptor);
400
401 enc_accept_get(b, &msg->encrypt);
402 }
403
404
405 static void CHANNEL_ACCEPT_clear(struct mwMsgChannelAccept *msg) {
406 mwOpaque_clear(&msg->addtl);
407 mwLoginInfo_clear(&msg->acceptor);
408
409 if(msg->encrypt.item) {
410 mwEncryptItem_clear(msg->encrypt.item);
411 g_free(msg->encrypt.item);
412 }
413 }
414
415
416 /* 8.4.1.9 SendOnCnl */
417
418
419 static void CHANNEL_SEND_put(struct mwPutBuffer *b,
420 struct mwMsgChannelSend *msg) {
421
422 guint16_put(b, msg->type);
423 mwOpaque_put(b, &msg->data);
424 }
425
426
427 static void CHANNEL_SEND_get(struct mwGetBuffer *b,
428 struct mwMsgChannelSend *msg) {
429
430 if(mwGetBuffer_error(b)) return;
431
432 guint16_get(b, &msg->type);
433 mwOpaque_get(b, &msg->data);
434 }
435
436
437 static void CHANNEL_SEND_clear(struct mwMsgChannelSend *msg) {
438 mwOpaque_clear(&msg->data);
439 }
440
441
442 /* 8.4.1.10 DestroyCnl */
443
444
445 static void CHANNEL_DESTROY_put(struct mwPutBuffer *b,
446 struct mwMsgChannelDestroy *msg) {
447 guint32_put(b, msg->reason);
448 mwOpaque_put(b, &msg->data);
449 }
450
451
452 static void CHANNEL_DESTROY_get(struct mwGetBuffer *b,
453 struct mwMsgChannelDestroy *msg) {
454
455 if(mwGetBuffer_error(b)) return;
456
457 guint32_get(b, &msg->reason);
458 mwOpaque_get(b, &msg->data);
459 }
460
461
462 static void CHANNEL_DESTROY_clear(struct mwMsgChannelDestroy *msg) {
463 mwOpaque_clear(&msg->data);
464 }
465
466
467 /* 8.4.1.11 SetUserStatus */
468
469
470 static void SET_USER_STATUS_put(struct mwPutBuffer *b,
471 struct mwMsgSetUserStatus *msg) {
472 mwUserStatus_put(b, &msg->status);
473 }
474
475
476 static void SET_USER_STATUS_get(struct mwGetBuffer *b,
477 struct mwMsgSetUserStatus *msg) {
478
479 if(mwGetBuffer_error(b)) return;
480 mwUserStatus_get(b, &msg->status);
481 }
482
483
484 static void SET_USER_STATUS_clear(struct mwMsgSetUserStatus *msg) {
485 mwUserStatus_clear(&msg->status);
486 }
487
488
489 /* 8.4.1.12 SetPrivacyList */
490
491
492 static void SET_PRIVACY_LIST_put(struct mwPutBuffer *b,
493 struct mwMsgSetPrivacyList *msg) {
494 mwPrivacyInfo_put(b, &msg->privacy);
495 }
496
497
498 static void SET_PRIVACY_LIST_get(struct mwGetBuffer *b,
499 struct mwMsgSetPrivacyList *msg) {
500
501 if(mwGetBuffer_error(b)) return;
502 mwPrivacyInfo_get(b, &msg->privacy);
503 }
504
505
506 static void SET_PRIVACY_LIST_clear(struct mwMsgSetPrivacyList *msg) {
507 mwPrivacyInfo_clear(&msg->privacy);
508 }
509
510
511 /* Sense Service messages */
512
513
514 static void SENSE_SERVICE_put(struct mwPutBuffer *b,
515 struct mwMsgSenseService *msg) {
516 guint32_put(b, msg->service);
517 }
518
519
520 static void SENSE_SERVICE_get(struct mwGetBuffer *b,
521 struct mwMsgSenseService *msg) {
522
523 if(mwGetBuffer_error(b)) return;
524 guint32_get(b, &msg->service);
525 }
526
527
528 static void SENSE_SERVICE_clear(struct mwMsgSenseService *msg) {
529 ;
530 }
531
532
533 /* Admin messages */
534
535
536 static void ADMIN_get(struct mwGetBuffer *b, struct mwMsgAdmin *msg) {
537 mwString_get(b, &msg->text);
538 }
539
540
541 static void ADMIN_clear(struct mwMsgAdmin *msg) {
542 g_free(msg->text);
543 msg->text = NULL;
544 }
545
546
547 #define CASE(v, t) \
548 case mwMessage_ ## v: \
549 msg = (struct mwMessage *) g_new0(struct t, 1); \
550 msg->type = type; \
551 break;
552
553
554 struct mwMessage *mwMessage_new(enum mwMessageType type) {
555 struct mwMessage *msg = NULL;
556
557 switch(type) {
558 CASE(HANDSHAKE, mwMsgHandshake);
559 CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
560 CASE(LOGIN, mwMsgLogin);
561 CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
562 CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
563 CASE(LOGIN_ACK, mwMsgLoginAck);
564 CASE(CHANNEL_CREATE, mwMsgChannelCreate);
565 CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
566 CASE(CHANNEL_SEND, mwMsgChannelSend);
567 CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
568 CASE(SET_USER_STATUS, mwMsgSetUserStatus);
569 CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
570 CASE(SENSE_SERVICE, mwMsgSenseService);
571 CASE(ADMIN, mwMsgAdmin);
572
573 default:
574 g_warning("unknown message type 0x%02x\n", type);
575 }
576
577 return msg;
578 }
579
580
581 #undef CASE
582
583
584 /* each type needs to be passed to a specially named _get functions,
585 and cast to a specific subclass of mwMessage. */
586 #define CASE(v, t) \
587 case mwMessage_ ## v: \
588 msg = (struct mwMessage *) g_new0(struct t, 1); \
589 mwMessageHead_clone(msg, &head); \
590 v ## _get(b, (struct t *) msg); \
591 break;
592
593
594 struct mwMessage *mwMessage_get(struct mwGetBuffer *b) {
595 struct mwMessage *msg = NULL;
596 struct mwMessage head;
597
598 g_return_val_if_fail(b != NULL, NULL);
599
600 head.attribs.len = 0;
601 head.attribs.data = NULL;
602
603 /* attempt to read the header first */
604 mwMessageHead_get(b, &head);
605
606 if(mwGetBuffer_error(b)) {
607 mwMessageHead_clear(&head);
608 g_warning("problem parsing message head from buffer");
609 return NULL;
610 }
611
612 /* load the rest of the message depending on the header type */
613 switch(head.type) {
614 CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
615 CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
616 CASE(LOGIN_ACK, mwMsgLoginAck);
617 CASE(CHANNEL_CREATE, mwMsgChannelCreate);
618 CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
619 CASE(CHANNEL_SEND, mwMsgChannelSend);
620 CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
621 CASE(SET_USER_STATUS, mwMsgSetUserStatus);
622 CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
623 CASE(SENSE_SERVICE, mwMsgSenseService);
624 CASE(ADMIN, mwMsgAdmin);
625
626 default:
627 g_warning("unknown message type 0x%02x, no parse handler", head.type);
628 }
629
630 if(mwGetBuffer_error(b)) {
631 g_warning("problem parsing message type 0x%02x, not enough data",
632 head.type);
633 }
634
635 mwMessageHead_clear(&head);
636
637 return msg;
638 }
639
640
641 #undef CASE
642
643
644 #define CASE(v, t) \
645 case mwMessage_ ## v: \
646 v ## _put(b, (struct t *) msg); \
647 break;
648
649
650 void mwMessage_put(struct mwPutBuffer *b, struct mwMessage *msg) {
651
652 g_return_if_fail(b != NULL);
653 g_return_if_fail(msg != NULL);
654
655 mwMessageHead_put(b, msg);
656
657 switch(msg->type) {
658 CASE(HANDSHAKE, mwMsgHandshake);
659 CASE(LOGIN, mwMsgLogin);
660 CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
661 CASE(CHANNEL_CREATE, mwMsgChannelCreate);
662 CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
663 CASE(CHANNEL_SEND, mwMsgChannelSend);
664 CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
665 CASE(SET_USER_STATUS, mwMsgSetUserStatus);
666 CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
667 CASE(SENSE_SERVICE, mwMsgSenseService);
668
669 default:
670 ; /* hrm. */
671 }
672 }
673
674
675 #undef CASE
676
677
678 #define CASE(v, t) \
679 case mwMessage_ ## v: \
680 v ## _clear((struct t *) msg); \
681 break;
682
683
684 void mwMessage_free(struct mwMessage *msg) {
685 if(! msg) return;
686
687 mwMessageHead_clear(msg);
688
689 switch(msg->type) {
690 CASE(HANDSHAKE, mwMsgHandshake);
691 CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
692 CASE(LOGIN, mwMsgLogin);
693 CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
694 CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
695 CASE(LOGIN_ACK, mwMsgLoginAck);
696 CASE(CHANNEL_CREATE, mwMsgChannelCreate);
697 CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
698 CASE(CHANNEL_SEND, mwMsgChannelSend);
699 CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
700 CASE(SET_USER_STATUS, mwMsgSetUserStatus);
701 CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
702 CASE(SENSE_SERVICE, mwMsgSenseService);
703 CASE(ADMIN, mwMsgAdmin);
704
705 default:
706 ; /* hrm. */
707 }
708
709 g_free(msg);
710 }
711
712
713 #undef CASE
714
715