comparison src/protocols/sametime/meanwhile/message.c @ 12956:921e17c06a1d

[gaim-migrate @ 15309] Add .cvsignore actions to meanwhile so cvs shuts up about it. committer: Tailor Script <tailor@pidgin.im>
author Ethan Blanton <elb@pidgin.im>
date Fri, 20 Jan 2006 00:19:53 +0000
parents
children
comparison
equal deleted inserted replaced
12955:1aee2fd04d4d 12956:921e17c06a1d
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 if(msg->major >= 0x001e && msg->minor >= 0x001d) {
83 guint16_put(b, msg->unknown_a);
84 guint32_put(b, msg->unknown_b);
85 mwString_put(b, msg->local_host);
86 }
87 }
88
89
90 static void HANDSHAKE_get(struct mwGetBuffer *b, struct mwMsgHandshake *msg) {
91 if(mwGetBuffer_error(b)) return;
92
93 guint16_get(b, &msg->major);
94 guint16_get(b, &msg->minor);
95 guint32_get(b, &msg->head.channel);
96 guint32_get(b, &msg->srvrcalc_addr);
97 guint16_get(b, &msg->login_type);
98 guint32_get(b, &msg->loclcalc_addr);
99
100 if(msg->major >= 0x001e && msg->minor >= 0x001d) {
101 guint16_get(b, &msg->unknown_a);
102 guint32_get(b, &msg->unknown_b);
103 mwString_get(b, &msg->local_host);
104 }
105 }
106
107
108 static void HANDSHAKE_clear(struct mwMsgHandshake *msg) {
109 ; /* nothing to clean up */
110 }
111
112
113 /* 8.4.1.2 HandshakeAck */
114
115
116 static void HANDSHAKE_ACK_get(struct mwGetBuffer *b,
117 struct mwMsgHandshakeAck *msg) {
118
119 if(mwGetBuffer_error(b)) return;
120
121 guint16_get(b, &msg->major);
122 guint16_get(b, &msg->minor);
123 guint32_get(b, &msg->srvrcalc_addr);
124
125 /** @todo: get a better handle on what versions support what parts
126 of this message. eg: minor version 0x0018 doesn't send the
127 following */
128 if(msg->major >= 0x1e && msg->minor > 0x18) {
129 guint32_get(b, &msg->magic);
130 mwOpaque_get(b, &msg->data);
131 }
132 }
133
134
135 static void HANDSHAKE_ACK_put(struct mwPutBuffer *b,
136 struct mwMsgHandshakeAck *msg) {
137
138 guint16_put(b, msg->major);
139 guint16_put(b, msg->minor);
140 guint32_put(b, msg->srvrcalc_addr);
141
142 if(msg->major >= 0x1e && msg->minor > 0x18) {
143 guint32_put(b, msg->magic);
144 mwOpaque_put(b, &msg->data);
145 }
146 }
147
148
149 static void HANDSHAKE_ACK_clear(struct mwMsgHandshakeAck *msg) {
150 mwOpaque_clear(&msg->data);
151 }
152
153
154 /* 8.4.1.3 Login */
155
156
157 static void LOGIN_put(struct mwPutBuffer *b, struct mwMsgLogin *msg) {
158 guint16_put(b, msg->login_type);
159 mwString_put(b, msg->name);
160
161 /* ordering reversed from houri draft?? */
162 mwOpaque_put(b, &msg->auth_data);
163 guint16_put(b, msg->auth_type);
164
165 guint16_put(b, 0x0000); /* unknown */
166 }
167
168
169 static void LOGIN_get(struct mwGetBuffer *b, struct mwMsgLogin *msg) {
170 if(mwGetBuffer_error(b)) return;
171
172 guint16_get(b, &msg->login_type);
173 mwString_get(b, &msg->name);
174 mwOpaque_get(b, &msg->auth_data);
175 guint16_get(b, &msg->auth_type);
176 }
177
178
179 static void LOGIN_clear(struct mwMsgLogin *msg) {
180 g_free(msg->name); msg->name = NULL;
181 mwOpaque_clear(&msg->auth_data);
182 }
183
184
185 /* 8.4.1.4 LoginAck */
186
187
188 static void LOGIN_ACK_get(struct mwGetBuffer *b, struct mwMsgLoginAck *msg) {
189 guint16 junk;
190
191 if(mwGetBuffer_error(b)) return;
192
193 mwLoginInfo_get(b, &msg->login);
194 guint16_get(b, &junk);
195 mwPrivacyInfo_get(b, &msg->privacy);
196 mwUserStatus_get(b, &msg->status);
197 }
198
199
200 static void LOGIN_ACK_clear(struct mwMsgLoginAck *msg) {
201 mwLoginInfo_clear(&msg->login);
202 mwPrivacyInfo_clear(&msg->privacy);
203 mwUserStatus_clear(&msg->status);
204 }
205
206
207 /* 8.4.1.5 LoginCont */
208
209
210 static void LOGIN_CONTINUE_put(struct mwPutBuffer *b,
211 struct mwMsgLoginContinue *msg) {
212
213 ; /* nothing but a message header */
214 }
215
216
217 static void LOGIN_CONTINUE_get(struct mwGetBuffer *b,
218 struct mwMsgLoginContinue *msg) {
219
220 ; /* nothing but a message header */
221 }
222
223
224 static void LOGIN_CONTINUE_clear(struct mwMsgLoginContinue *msg) {
225 ; /* this is a very simple message */
226 }
227
228
229 /* 8.4.1.6 AuthPassed */
230
231
232 static void LOGIN_REDIRECT_get(struct mwGetBuffer *b,
233 struct mwMsgLoginRedirect *msg) {
234
235 if(mwGetBuffer_error(b)) return;
236 mwString_get(b, &msg->host);
237 mwString_get(b, &msg->server_id);
238 }
239
240
241 static void LOGIN_REDIRECT_put(struct mwPutBuffer *b,
242 struct mwMsgLoginRedirect *msg) {
243 mwString_put(b, msg->host);
244 mwString_put(b, msg->server_id);
245 }
246
247
248 static void LOGIN_REDIRECT_clear(struct mwMsgLoginRedirect *msg) {
249 g_free(msg->host);
250 msg->host = NULL;
251
252 g_free(msg->server_id);
253 msg->server_id = NULL;
254 }
255
256
257 /* 8.4.1.7 CreateCnl */
258
259
260 static void enc_offer_put(struct mwPutBuffer *b, struct mwEncryptOffer *enc) {
261 guint16_put(b, enc->mode);
262
263 if(enc->items) {
264 guint32 count;
265 struct mwPutBuffer *p;
266 struct mwOpaque o;
267 GList *list;
268
269 /* write the count, items, extra, and flag into a tmp buffer,
270 render that buffer into an opaque, and write it into b */
271
272 count = g_list_length(enc->items);
273 p = mwPutBuffer_new();
274
275 guint32_put(p, count);
276 for(list = enc->items; list; list = list->next) {
277 mwEncryptItem_put(p, list->data);
278 }
279
280 guint16_put(p, enc->extra);
281 gboolean_put(p, enc->flag);
282
283 mwPutBuffer_finalize(&o, p);
284 mwOpaque_put(b, &o);
285 mwOpaque_clear(&o);
286 }
287 }
288
289
290 static void CHANNEL_CREATE_put(struct mwPutBuffer *b,
291 struct mwMsgChannelCreate *msg) {
292
293 guint32_put(b, msg->reserved);
294 guint32_put(b, msg->channel);
295 mwIdBlock_put(b, &msg->target);
296 guint32_put(b, msg->service);
297 guint32_put(b, msg->proto_type);
298 guint32_put(b, msg->proto_ver);
299 guint32_put(b, msg->options);
300 mwOpaque_put(b, &msg->addtl);
301 gboolean_put(b, msg->creator_flag);
302
303 if(msg->creator_flag)
304 mwLoginInfo_put(b, &msg->creator);
305
306 enc_offer_put(b, &msg->encrypt);
307
308 guint32_put(b, 0x00);
309 guint32_put(b, 0x00);
310 guint16_put(b, 0x07);
311 }
312
313
314 static void enc_offer_get(struct mwGetBuffer *b,
315 struct mwEncryptOffer *enc) {
316 guint32 skip;
317
318 if(mwGetBuffer_error(b)) return;
319
320 guint16_get(b, &enc->mode);
321 guint32_get(b, &skip);
322
323 if(skip >= 7) {
324 guint32 count;
325
326 guint32_get(b, &count);
327
328 while(count-- && (! mwGetBuffer_error(b))) {
329 struct mwEncryptItem *ei = g_new0(struct mwEncryptItem, 1);
330 mwEncryptItem_get(b, ei);
331 enc->items = g_list_append(enc->items, ei);
332 }
333
334 guint16_get(b, &enc->extra);
335 gboolean_get(b, &enc->flag);
336 }
337 }
338
339
340 static void CHANNEL_CREATE_get(struct mwGetBuffer *b,
341 struct mwMsgChannelCreate *msg) {
342
343 if(mwGetBuffer_error(b)) return;
344
345 guint32_get(b, &msg->reserved);
346 guint32_get(b, &msg->channel);
347 mwIdBlock_get(b, &msg->target);
348 guint32_get(b, &msg->service);
349 guint32_get(b, &msg->proto_type);
350 guint32_get(b, &msg->proto_ver);
351 guint32_get(b, &msg->options);
352 mwOpaque_get(b, &msg->addtl);
353 gboolean_get(b, &msg->creator_flag);
354
355 if(msg->creator_flag)
356 mwLoginInfo_get(b, &msg->creator);
357
358 enc_offer_get(b, &msg->encrypt);
359 }
360
361
362 static void CHANNEL_CREATE_clear(struct mwMsgChannelCreate *msg) {
363 GList *list;
364
365 mwIdBlock_clear(&msg->target);
366 mwOpaque_clear(&msg->addtl);
367 mwLoginInfo_clear(&msg->creator);
368
369 for(list = msg->encrypt.items; list; list = list->next) {
370 mwEncryptItem_clear(list->data);
371 g_free(list->data);
372 }
373 g_list_free(msg->encrypt.items);
374 }
375
376
377 /* 8.4.1.8 AcceptCnl */
378
379
380 static void enc_accept_put(struct mwPutBuffer *b,
381 struct mwEncryptAccept *enc) {
382
383 guint16_put(b, enc->mode);
384
385 if(enc->item) {
386 struct mwPutBuffer *p;
387 struct mwOpaque o;
388
389 p = mwPutBuffer_new();
390
391 mwEncryptItem_put(p, enc->item);
392 guint16_put(p, enc->extra);
393 gboolean_put(p, enc->flag);
394
395 mwPutBuffer_finalize(&o, p);
396 mwOpaque_put(b, &o);
397 mwOpaque_clear(&o);
398 }
399 }
400
401
402 static void CHANNEL_ACCEPT_put(struct mwPutBuffer *b,
403 struct mwMsgChannelAccept *msg) {
404
405 guint32_put(b, msg->service);
406 guint32_put(b, msg->proto_type);
407 guint32_put(b, msg->proto_ver);
408 mwOpaque_put(b, &msg->addtl);
409 gboolean_put(b, msg->acceptor_flag);
410
411 if(msg->acceptor_flag)
412 mwLoginInfo_put(b, &msg->acceptor);
413
414 enc_accept_put(b, &msg->encrypt);
415
416 guint32_put(b, 0x00);
417 guint32_put(b, 0x00);
418 guint16_put(b, 0x07);
419 }
420
421
422 static void enc_accept_get(struct mwGetBuffer *b,
423 struct mwEncryptAccept *enc) {
424 guint32 skip;
425
426 if(mwGetBuffer_error(b)) return;
427
428 guint16_get(b, &enc->mode);
429 guint32_get(b, &skip);
430
431 if(skip >= 6) {
432 enc->item = g_new0(struct mwEncryptItem, 1);
433 mwEncryptItem_get(b, enc->item);
434 }
435
436 if(skip >= 9) {
437 guint16_get(b, &enc->extra);
438 gboolean_get(b, &enc->flag);
439 }
440 }
441
442
443 static void CHANNEL_ACCEPT_get(struct mwGetBuffer *b,
444 struct mwMsgChannelAccept *msg) {
445
446 if(mwGetBuffer_error(b)) return;
447
448 guint32_get(b, &msg->service);
449 guint32_get(b, &msg->proto_type);
450 guint32_get(b, &msg->proto_ver);
451 mwOpaque_get(b, &msg->addtl);
452 gboolean_get(b, &msg->acceptor_flag);
453
454 if(msg->acceptor_flag)
455 mwLoginInfo_get(b, &msg->acceptor);
456
457 enc_accept_get(b, &msg->encrypt);
458 }
459
460
461 static void CHANNEL_ACCEPT_clear(struct mwMsgChannelAccept *msg) {
462 mwOpaque_clear(&msg->addtl);
463 mwLoginInfo_clear(&msg->acceptor);
464
465 if(msg->encrypt.item) {
466 mwEncryptItem_clear(msg->encrypt.item);
467 g_free(msg->encrypt.item);
468 }
469 }
470
471
472 /* 8.4.1.9 SendOnCnl */
473
474
475 static void CHANNEL_SEND_put(struct mwPutBuffer *b,
476 struct mwMsgChannelSend *msg) {
477
478 guint16_put(b, msg->type);
479 mwOpaque_put(b, &msg->data);
480 }
481
482
483 static void CHANNEL_SEND_get(struct mwGetBuffer *b,
484 struct mwMsgChannelSend *msg) {
485
486 if(mwGetBuffer_error(b)) return;
487
488 guint16_get(b, &msg->type);
489 mwOpaque_get(b, &msg->data);
490 }
491
492
493 static void CHANNEL_SEND_clear(struct mwMsgChannelSend *msg) {
494 mwOpaque_clear(&msg->data);
495 }
496
497
498 /* 8.4.1.10 DestroyCnl */
499
500
501 static void CHANNEL_DESTROY_put(struct mwPutBuffer *b,
502 struct mwMsgChannelDestroy *msg) {
503 guint32_put(b, msg->reason);
504 mwOpaque_put(b, &msg->data);
505 }
506
507
508 static void CHANNEL_DESTROY_get(struct mwGetBuffer *b,
509 struct mwMsgChannelDestroy *msg) {
510
511 if(mwGetBuffer_error(b)) return;
512
513 guint32_get(b, &msg->reason);
514 mwOpaque_get(b, &msg->data);
515 }
516
517
518 static void CHANNEL_DESTROY_clear(struct mwMsgChannelDestroy *msg) {
519 mwOpaque_clear(&msg->data);
520 }
521
522
523 /* 8.4.1.11 SetUserStatus */
524
525
526 static void SET_USER_STATUS_put(struct mwPutBuffer *b,
527 struct mwMsgSetUserStatus *msg) {
528 mwUserStatus_put(b, &msg->status);
529 }
530
531
532 static void SET_USER_STATUS_get(struct mwGetBuffer *b,
533 struct mwMsgSetUserStatus *msg) {
534
535 if(mwGetBuffer_error(b)) return;
536 mwUserStatus_get(b, &msg->status);
537 }
538
539
540 static void SET_USER_STATUS_clear(struct mwMsgSetUserStatus *msg) {
541 mwUserStatus_clear(&msg->status);
542 }
543
544
545 /* 8.4.1.12 SetPrivacyList */
546
547
548 static void SET_PRIVACY_LIST_put(struct mwPutBuffer *b,
549 struct mwMsgSetPrivacyList *msg) {
550 mwPrivacyInfo_put(b, &msg->privacy);
551 }
552
553
554 static void SET_PRIVACY_LIST_get(struct mwGetBuffer *b,
555 struct mwMsgSetPrivacyList *msg) {
556
557 if(mwGetBuffer_error(b)) return;
558 mwPrivacyInfo_get(b, &msg->privacy);
559 }
560
561
562 static void SET_PRIVACY_LIST_clear(struct mwMsgSetPrivacyList *msg) {
563 mwPrivacyInfo_clear(&msg->privacy);
564 }
565
566
567 /* Sense Service messages */
568
569
570 static void SENSE_SERVICE_put(struct mwPutBuffer *b,
571 struct mwMsgSenseService *msg) {
572 guint32_put(b, msg->service);
573 }
574
575
576 static void SENSE_SERVICE_get(struct mwGetBuffer *b,
577 struct mwMsgSenseService *msg) {
578
579 if(mwGetBuffer_error(b)) return;
580 guint32_get(b, &msg->service);
581 }
582
583
584 static void SENSE_SERVICE_clear(struct mwMsgSenseService *msg) {
585 ;
586 }
587
588
589 /* Admin messages */
590
591
592 static void ADMIN_get(struct mwGetBuffer *b, struct mwMsgAdmin *msg) {
593 mwString_get(b, &msg->text);
594 }
595
596
597 static void ADMIN_clear(struct mwMsgAdmin *msg) {
598 g_free(msg->text);
599 msg->text = NULL;
600 }
601
602
603 /* Announcement messages */
604
605
606 static void ANNOUNCE_get(struct mwGetBuffer *b, struct mwMsgAnnounce *msg) {
607 struct mwOpaque o = { 0, 0 };
608 struct mwGetBuffer *gb;
609 guint32 count;
610
611 gboolean_get(b, &msg->sender_present);
612 if(msg->sender_present)
613 mwLoginInfo_get(b, &msg->sender);
614 guint16_get(b, &msg->unknown_a);
615
616 mwOpaque_get(b, &o);
617 gb = mwGetBuffer_wrap(&o);
618
619 gboolean_get(gb, &msg->may_reply);
620 mwString_get(gb, &msg->text);
621
622 mwGetBuffer_free(gb);
623 mwOpaque_clear(&o);
624
625 guint32_get(b, &count);
626 while(count--) {
627 char *r = NULL;
628 mwString_get(b, &r);
629 msg->recipients = g_list_prepend(msg->recipients, r);
630 }
631 }
632
633
634 static void ANNOUNCE_put(struct mwPutBuffer *b, struct mwMsgAnnounce *msg) {
635 struct mwOpaque o = { 0, 0 };
636 struct mwPutBuffer *pb;
637 GList *l;
638
639 gboolean_put(b, msg->sender_present);
640 if(msg->sender_present)
641 mwLoginInfo_put(b, &msg->sender);
642 guint16_put(b, msg->unknown_a);
643
644 pb = mwPutBuffer_new();
645
646 gboolean_put(pb, msg->may_reply);
647 mwString_put(pb, msg->text);
648
649 mwPutBuffer_finalize(&o, pb);
650 mwOpaque_put(b, &o);
651 mwOpaque_clear(&o);
652
653 guint32_put(b, g_list_length(msg->recipients));
654 for(l = msg->recipients; l; l = l->next) {
655 mwString_put(b, l->data);
656 }
657 }
658
659
660 static void ANNOUNCE_clear(struct mwMsgAnnounce *msg) {
661 mwLoginInfo_clear(&msg->sender);
662
663 g_free(msg->text);
664 msg->text = NULL;
665
666 while(msg->recipients) {
667 g_free(msg->recipients->data);
668 msg->recipients = g_list_delete_link(msg->recipients, msg->recipients);
669 }
670 }
671
672
673 /* general functions */
674
675
676 #define CASE(v, t) \
677 case mwMessage_ ## v: \
678 msg = (struct mwMessage *) g_new0(struct t, 1); \
679 msg->type = type; \
680 break;
681
682
683 struct mwMessage *mwMessage_new(enum mwMessageType type) {
684 struct mwMessage *msg = NULL;
685
686 switch(type) {
687 CASE(HANDSHAKE, mwMsgHandshake);
688 CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
689 CASE(LOGIN, mwMsgLogin);
690 CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
691 CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
692 CASE(LOGIN_ACK, mwMsgLoginAck);
693 CASE(CHANNEL_CREATE, mwMsgChannelCreate);
694 CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
695 CASE(CHANNEL_SEND, mwMsgChannelSend);
696 CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
697 CASE(SET_USER_STATUS, mwMsgSetUserStatus);
698 CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
699 CASE(SENSE_SERVICE, mwMsgSenseService);
700 CASE(ADMIN, mwMsgAdmin);
701 CASE(ANNOUNCE, mwMsgAnnounce);
702
703 default:
704 g_warning("unknown message type 0x%02x\n", type);
705 }
706
707 return msg;
708 }
709
710
711 #undef CASE
712
713
714 /* each type needs to be passed to a specially named _get functions,
715 and cast to a specific subclass of mwMessage. */
716 #define CASE(v, t) \
717 case mwMessage_ ## v: \
718 msg = (struct mwMessage *) g_new0(struct t, 1); \
719 mwMessageHead_clone(msg, &head); \
720 v ## _get(b, (struct t *) msg); \
721 break;
722
723
724 struct mwMessage *mwMessage_get(struct mwGetBuffer *b) {
725 struct mwMessage *msg = NULL;
726 struct mwMessage head;
727
728 g_return_val_if_fail(b != NULL, NULL);
729
730 head.attribs.len = 0;
731 head.attribs.data = NULL;
732
733 /* attempt to read the header first */
734 mwMessageHead_get(b, &head);
735
736 if(mwGetBuffer_error(b)) {
737 mwMessageHead_clear(&head);
738 g_warning("problem parsing message head from buffer");
739 return NULL;
740 }
741
742 /* load the rest of the message depending on the header type */
743 switch(head.type) {
744 CASE(HANDSHAKE, mwMsgHandshake);
745 CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
746 CASE(LOGIN, mwMsgLogin);
747 CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
748 CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
749 CASE(LOGIN_ACK, mwMsgLoginAck);
750 CASE(CHANNEL_CREATE, mwMsgChannelCreate);
751 CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
752 CASE(CHANNEL_SEND, mwMsgChannelSend);
753 CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
754 CASE(SET_USER_STATUS, mwMsgSetUserStatus);
755 CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
756 CASE(SENSE_SERVICE, mwMsgSenseService);
757 CASE(ADMIN, mwMsgAdmin);
758 CASE(ANNOUNCE, mwMsgAnnounce);
759
760 default:
761 g_warning("unknown message type 0x%02x, no parse handler", head.type);
762 }
763
764 if(mwGetBuffer_error(b)) {
765 g_warning("problem parsing message type 0x%02x, not enough data",
766 head.type);
767 }
768
769 mwMessageHead_clear(&head);
770
771 return msg;
772 }
773
774
775 #undef CASE
776
777
778 #define CASE(v, t) \
779 case mwMessage_ ## v: \
780 v ## _put(b, (struct t *) msg); \
781 break;
782
783
784 void mwMessage_put(struct mwPutBuffer *b, struct mwMessage *msg) {
785
786 g_return_if_fail(b != NULL);
787 g_return_if_fail(msg != NULL);
788
789 mwMessageHead_put(b, msg);
790
791 switch(msg->type) {
792 CASE(HANDSHAKE, mwMsgHandshake);
793 CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
794 CASE(LOGIN, mwMsgLogin);
795 CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
796 CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
797 CASE(CHANNEL_CREATE, mwMsgChannelCreate);
798 CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
799 CASE(CHANNEL_SEND, mwMsgChannelSend);
800 CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
801 CASE(SET_USER_STATUS, mwMsgSetUserStatus);
802 CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
803 CASE(SENSE_SERVICE, mwMsgSenseService);
804 CASE(ANNOUNCE, mwMsgAnnounce);
805
806 default:
807 ; /* hrm. */
808 }
809 }
810
811
812 #undef CASE
813
814
815 #define CASE(v, t) \
816 case mwMessage_ ## v: \
817 v ## _clear((struct t *) msg); \
818 break;
819
820
821 void mwMessage_free(struct mwMessage *msg) {
822 if(! msg) return;
823
824 mwMessageHead_clear(msg);
825
826 switch(msg->type) {
827 CASE(HANDSHAKE, mwMsgHandshake);
828 CASE(HANDSHAKE_ACK, mwMsgHandshakeAck);
829 CASE(LOGIN, mwMsgLogin);
830 CASE(LOGIN_REDIRECT, mwMsgLoginRedirect);
831 CASE(LOGIN_CONTINUE, mwMsgLoginContinue);
832 CASE(LOGIN_ACK, mwMsgLoginAck);
833 CASE(CHANNEL_CREATE, mwMsgChannelCreate);
834 CASE(CHANNEL_DESTROY, mwMsgChannelDestroy);
835 CASE(CHANNEL_SEND, mwMsgChannelSend);
836 CASE(CHANNEL_ACCEPT, mwMsgChannelAccept);
837 CASE(SET_USER_STATUS, mwMsgSetUserStatus);
838 CASE(SET_PRIVACY_LIST, mwMsgSetPrivacyList);
839 CASE(SENSE_SERVICE, mwMsgSenseService);
840 CASE(ADMIN, mwMsgAdmin);
841 CASE(ANNOUNCE, mwMsgAnnounce);
842
843 default:
844 ; /* hrm. */
845 }
846
847 g_free(msg);
848 }
849
850
851 #undef CASE
852
853