Added creation of temporary channels.
[umurmur.git] / src / messages.c
1 /* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12    - Redistributions in binary form must reproduce the above copyright notice,
13      this list of conditions and the following disclaimer in the documentation
14      and/or other materials provided with the distribution.
15    - Neither the name of the Developers nor the names of its contributors may
16      be used to endorse or promote products derived from this software without
17      specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <arpa/inet.h>
36
37 #include "messages.h"
38 #include "client.h"
39 #include "pds.h"
40 #include "log.h"
41
42
43 void dumpmsg(uint8_t *data, int size);
44 static message_t *Msg_create_nopayload(messageType_t messageType);
45
46 void Msg_addPreamble(uint8_t *buffer, uint16_t type, uint32_t len)
47 {
48         type = htons(type);
49         len = htonl(len);
50         
51         buffer[0] = (type) & 0xff;
52         buffer[1] = (type >> 8) & 0xff;
53         
54         buffer[2] = (len) & 0xff;
55         buffer[3] = (len >> 8) & 0xff;
56         buffer[4] = (len >> 16) & 0xff;
57         buffer[5] = (len >> 24) & 0xff; 
58 }
59
60 static void Msg_getPreamble(uint8_t *buffer, int *type, int *len)
61 {
62         uint16_t msgType;
63         uint32_t msgLen;
64         
65         msgType = buffer[0] | (buffer[1] << 8);
66         msgLen = buffer[2] | (buffer[3] << 8) | (buffer[4] << 16) | (buffer[5] << 24);
67         *type = (int)ntohs(msgType);
68         *len = (int)ntohl(msgLen);
69 }
70
71 #define MAX_MSGSIZE (BUFSIZE - 6)
72 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
73 {
74         int len;
75         uint8_t *bufptr = buffer + 6;
76                 
77         Log_debug("To net: msg type %d", msg->messageType);
78         switch (msg->messageType) {
79         case Version:
80                 len = mumble_proto__version__get_packed_size(msg->payload.version);
81                 if (len > MAX_MSGSIZE) {
82                         Log_warn("Too big tx message. Discarding");
83                         break;
84                 }
85                 Msg_addPreamble(buffer, msg->messageType, len);
86                 Log_debug("To net: Version->release: %s Version->os: %s",
87                                   msg->payload.version->release, msg->payload.version->os);
88                 mumble_proto__version__pack(msg->payload.version, bufptr);
89                 break;
90         case UDPTunnel: /* Non-standard handling of tunneled voice traffic. */
91                 if (msg->payload.UDPTunnel->packet.len > MAX_MSGSIZE) {
92                         Log_warn("Too big tx message. Discarding");
93                         break;
94                 }
95                 Msg_addPreamble(buffer, msg->messageType, msg->payload.UDPTunnel->packet.len);
96                 memcpy(bufptr, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
97                 break;
98         case Authenticate:
99                 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
100                 if (len > MAX_MSGSIZE) {
101                         Log_warn("Too big tx message. Discarding");
102                         break;
103                         }
104                 Msg_addPreamble(buffer, msg->messageType, len);
105                 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
106                 break;
107         case Ping:
108                 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
109                 if (len > MAX_MSGSIZE) {
110                         Log_warn("Too big tx message. Discarding");
111                         break;
112                         }
113                 Msg_addPreamble(buffer, msg->messageType, len);
114                 mumble_proto__ping__pack(msg->payload.ping, bufptr);
115                 break;
116         case Reject:
117                 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
118                 if (len > MAX_MSGSIZE) {
119                         Log_warn("Too big tx message. Discarding");
120                         break;
121                         }
122                 Msg_addPreamble(buffer, msg->messageType, len);
123                 mumble_proto__reject__pack(msg->payload.reject, bufptr);
124                 break;
125         case ServerSync:
126                 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
127                 if (len > MAX_MSGSIZE) {
128                         Log_warn("Too big tx message. Discarding");
129                         break;
130                         }
131                 Msg_addPreamble(buffer, msg->messageType, len);
132                 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
133                 break;
134         case TextMessage:
135                 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
136                 if (len > MAX_MSGSIZE) {
137                         Log_warn("Too big tx message. Discarding");
138                         break;
139                         }
140                 Msg_addPreamble(buffer, msg->messageType, len);
141                 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
142                 break;
143         case PermissionDenied:
144                 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
145                 if (len > MAX_MSGSIZE) {
146                         Log_warn("Too big tx message. Discarding");
147                         break;
148                         }
149                 Msg_addPreamble(buffer, msg->messageType, len);
150                 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
151                 break;
152         case CryptSetup:
153                 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
154                 if (len > MAX_MSGSIZE) {
155                         Log_warn("Too big tx message. Discarding");
156                         break;
157                         }
158                 Msg_addPreamble(buffer, msg->messageType, len);
159                 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
160                 break;
161         case UserList:
162                 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
163                 if (len > MAX_MSGSIZE) {
164                         Log_warn("Too big tx message. Discarding");
165                         break;
166                         }
167                 Msg_addPreamble(buffer, msg->messageType, len);
168                 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
169                 break;
170         case UserState:
171                 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
172                 if (len > MAX_MSGSIZE) {
173                         Log_warn("Too big tx message. Discarding");
174                         break;
175                         }
176                 Msg_addPreamble(buffer, msg->messageType, len);
177                 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
178                 break;
179         case ChannelState:
180                 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
181                 if (len > MAX_MSGSIZE) {
182                         Log_warn("Too big tx message. Discarding");
183                         break;
184                         }
185                 Msg_addPreamble(buffer, msg->messageType, len);
186                 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
187                 break;
188         case VoiceTarget:
189                 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
190                 if (len > MAX_MSGSIZE) {
191                         Log_warn("Too big tx message. Discarding");
192                         break;
193                         }
194                 Msg_addPreamble(buffer, msg->messageType, len);
195                 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
196                 break;
197         case CodecVersion:
198                 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
199                 if (len > MAX_MSGSIZE) {
200                         Log_warn("Too big tx message. Discarding");
201                         break;
202                         }
203                 Msg_addPreamble(buffer, msg->messageType, len);
204                 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
205                 break;
206         case PermissionQuery:
207                 len = mumble_proto__permission_query__get_packed_size(msg->payload.permissionQuery);
208                 if (len > MAX_MSGSIZE) {
209                         Log_warn("Too big tx message. Discarding");
210                         break;
211                         }
212                 Msg_addPreamble(buffer, msg->messageType, len);
213                 mumble_proto__permission_query__pack(msg->payload.permissionQuery, bufptr);
214                 break;
215         case ChannelRemove:
216                 len = mumble_proto__channel_remove__get_packed_size(msg->payload.channelRemove);
217                 if (len > MAX_MSGSIZE) {
218                         Log_warn("Too big tx message. Discarding");
219                         break;
220                         }
221                 Msg_addPreamble(buffer, msg->messageType, len);
222                 mumble_proto__channel_remove__pack(msg->payload.channelRemove, bufptr);
223                 break;
224
225         default:
226                 Log_warn("Unsupported message %d", msg->messageType);
227                 return 0;
228         }
229         return len + 6;
230 }
231
232 message_t *Msg_create_nopayload(messageType_t messageType)
233 {
234         message_t *msg = malloc(sizeof(message_t));
235
236         if (msg == NULL)
237                 Log_fatal("Out of memory");
238         memset(msg, 0, sizeof(message_t));
239         msg->refcount = 1;
240         msg->messageType = messageType;
241         init_list_entry(&msg->node);
242         return msg;
243 }
244
245 message_t *Msg_create(messageType_t messageType)
246 {
247         message_t *msg = Msg_create_nopayload(messageType);
248         
249         switch (messageType) {
250         case Version:
251                 msg->payload.version = malloc(sizeof(MumbleProto__Version));
252                 mumble_proto__version__init(msg->payload.version);
253                 break;
254         case UDPTunnel:
255                 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
256                 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
257                 break;
258         case Authenticate:
259                 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
260                 mumble_proto__authenticate__init(msg->payload.authenticate);
261                 break;
262         case Ping:
263                 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
264                 mumble_proto__ping__init(msg->payload.ping);
265                 break;
266         case Reject:
267                 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
268                 mumble_proto__reject__init(msg->payload.reject);
269                 break;
270         case ServerSync:
271                 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
272                 mumble_proto__server_sync__init(msg->payload.serverSync);
273                 break;
274         case TextMessage:
275                 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
276                 mumble_proto__text_message__init(msg->payload.textMessage);
277                 break;
278         case PermissionDenied:
279                 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
280                 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
281                 break;
282         case CryptSetup:
283                 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
284                 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
285                 break;
286         case UserList:
287                 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
288                 mumble_proto__user_list__init(msg->payload.userList);
289                 break;
290         case UserState:
291                 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
292                 mumble_proto__user_state__init(msg->payload.userState);
293                 break;
294         case ChannelState:
295                 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
296                 mumble_proto__channel_state__init(msg->payload.channelState);
297                 break;
298         case UserRemove:
299                 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
300                 mumble_proto__user_remove__init(msg->payload.userRemove);
301                 break;
302         case VoiceTarget:
303                 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
304                 mumble_proto__voice_target__init(msg->payload.voiceTarget);
305                 break;
306         case CodecVersion:
307                 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
308                 mumble_proto__codec_version__init(msg->payload.codecVersion);
309                 break;
310         case PermissionQuery:
311                 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
312                 mumble_proto__permission_query__init(msg->payload.permissionQuery);
313                 break;
314         case ChannelRemove:
315                 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
316                 mumble_proto__channel_remove__init(msg->payload.channelRemove);
317                 break;
318
319         default:
320                 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
321                 break;
322         }
323
324         return msg;
325 }
326
327 void Msg_inc_ref(message_t *msg)
328 {
329         msg->refcount++;
330 }
331
332 void Msg_free(message_t *msg)
333 {
334         if (msg->refcount) msg->refcount--;
335         if (msg->refcount > 0)
336                 return;
337
338         switch (msg->messageType) {
339         case Version:
340                 if (msg->unpacked)
341                         mumble_proto__version__free_unpacked(msg->payload.version, NULL);
342                 else {
343                         if (msg->payload.version->release)
344                                 free(msg->payload.version->release);
345                         if (msg->payload.version->os)
346                                 free(msg->payload.version->os);
347                         if (msg->payload.version->os_version)
348                                 free(msg->payload.version->os_version);
349                         free(msg->payload.version);
350                 }
351                 break;
352         case UDPTunnel:
353                 if (msg->unpacked)
354                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
355                 else {
356                         free(msg->payload.UDPTunnel->packet.data);
357                         free(msg->payload.UDPTunnel);
358                 }
359                 break;
360         case Authenticate:
361                 if (msg->unpacked)
362                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
363                 else
364                         free(msg->payload.authenticate);
365                 break;
366         case Ping:
367                 if (msg->unpacked)
368                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
369                 else {
370                         free(msg->payload.ping);
371                 }
372                 break;
373         case Reject:
374                 if (msg->unpacked)
375                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
376                 else {
377                         free(msg->payload.reject->reason);
378                         free(msg->payload.reject);
379                 }
380                 break;
381         case ServerSync:
382                 if (msg->unpacked)
383                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
384                 else {
385                         free(msg->payload.serverSync->welcome_text);
386                         free(msg->payload.serverSync);
387                 }
388                 break;
389         case TextMessage:
390                 if (msg->unpacked)
391                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
392                 else {
393                         free(msg->payload.textMessage);
394                 }
395                 break;
396         case PermissionDenied:
397                 if (msg->unpacked)
398                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
399                 else {
400                         free(msg->payload.permissionDenied->reason);
401                         free(msg->payload.permissionDenied);
402                 }
403                 break;
404         case CryptSetup:
405                 if (msg->unpacked)
406                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
407                 else {
408                         free(msg->payload.cryptSetup);
409                 }
410                 break;
411         case UserList:
412                 if (msg->unpacked)
413                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
414                 else {
415                         free(msg->payload.userList);
416                 }
417                 break;
418         case UserState:
419                 if (msg->unpacked)
420                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
421                 else {
422                         free(msg->payload.userState->name);
423                         free(msg->payload.userState);
424                 }
425                 break;
426         case ChannelState:
427                 if (msg->unpacked)
428                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
429                 else {
430                         free(msg->payload.channelState->name);
431                         free(msg->payload.channelState->description);
432                         free(msg->payload.channelState);
433                 }
434                 break;
435         case UserRemove:
436                 if (msg->unpacked)
437                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
438                 else {
439                         free(msg->payload.userRemove);
440                 }
441                 break;
442         case VoiceTarget:
443                 if (msg->unpacked)
444                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
445                 else {
446                         free(msg->payload.voiceTarget);
447                 }
448                 break;
449         case CodecVersion:
450                 if (msg->unpacked)
451                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
452                 else {
453                         free(msg->payload.codecVersion);
454                 }
455                 break;
456         case PermissionQuery:
457                 if (msg->unpacked)
458                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
459                 else {
460                         free(msg->payload.permissionQuery);
461                 }
462                 break;
463         case ChannelRemove:
464                 if (msg->unpacked)
465                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
466                 else {
467                         free(msg->payload.channelRemove);
468                 }
469                 break;
470
471         default:
472                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
473                 break;
474         }
475         free(msg);
476 }
477
478 void dumpmsg(uint8_t *data, int size)
479 {
480         int i, r = 0, offset = 0;
481         char buf[512];
482         
483         while (r * 8 + i < size) {
484                 for (i = 0; i < 8 && r * 8 + i < size; i++) {
485                         offset += sprintf(buf + offset, "%x ", data[r * 8 + i]);
486                 }
487                 sprintf(buf + offset, "\n");
488                 printf(buf);
489                 offset = 0;
490                 r++;
491                 i = 0;
492         } 
493 }
494
495 message_t *Msg_networkToMessage(uint8_t *data, int size)
496 {
497         message_t *msg = NULL;
498         uint8_t *msgData = &data[6];
499         int messageType, msgLen;
500
501         Msg_getPreamble(data, &messageType, &msgLen);
502
503         Log_debug("Message type %d size %d", messageType, msgLen);
504         //dumpmsg(data, size);
505         
506         switch (messageType) {
507         case Version:
508         {
509                 msg = Msg_create_nopayload(Version);
510                 msg->unpacked = true;
511                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
512                 break;
513         }
514         case UDPTunnel: /* Non-standard handling of tunneled voice data */
515         {
516                 msg = Msg_create_nopayload(UDPTunnel);
517                 msg->unpacked = false;
518                 msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
519                 if (msg->payload.UDPTunnel == NULL)
520                         Log_fatal("Out of memory");
521                 msg->payload.UDPTunnel->packet.data = malloc(msgLen);
522                 if (msg->payload.UDPTunnel->packet.data == NULL)
523                         Log_fatal("Out of memory");
524                 memcpy(msg->payload.UDPTunnel->packet.data, msgData, msgLen);
525                 msg->payload.UDPTunnel->packet.len = msgLen;
526                 break;
527         }
528         case Authenticate:
529         {
530                 msg = Msg_create_nopayload(Authenticate);
531                 msg->unpacked = true;
532                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
533                 break;
534         }
535         case Ping:
536         {
537                 msg = Msg_create_nopayload(Ping);
538                 msg->unpacked = true;
539                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
540                 break;
541         }
542         case Reject:
543         {
544                 msg = Msg_create_nopayload(Reject);
545                 msg->unpacked = true;
546                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
547                 break;
548         }
549         case ServerSync:
550         {
551                 msg = Msg_create_nopayload(ServerSync);
552                 msg->unpacked = true;
553                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
554                 break;
555         }
556         case TextMessage:
557         {
558                 msg = Msg_create_nopayload(TextMessage);
559                 msg->unpacked = true;
560                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
561                 break;
562         }
563         case PermissionDenied:
564         {
565                 msg = Msg_create_nopayload(PermissionDenied);
566                 msg->unpacked = true;
567                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
568                 break;
569         }
570         case CryptSetup:
571         {
572                 msg = Msg_create_nopayload(CryptSetup);
573                 msg->unpacked = true;
574                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
575                 break;
576         }
577         case UserList:
578         {
579                 msg = Msg_create_nopayload(UserList);
580                 msg->unpacked = true;
581                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
582                 break;
583         }
584         case UserState:
585         {
586                 msg = Msg_create_nopayload(UserState);
587                 msg->unpacked = true;
588                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
589                 break;
590         }
591         case ChannelState:
592         {
593                 msg = Msg_create_nopayload(ChannelState);
594                 msg->unpacked = true;
595                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
596                 break;
597         }
598         case VoiceTarget:
599         {
600                 msg = Msg_create_nopayload(VoiceTarget);
601                 msg->unpacked = true;
602                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
603                 break;
604         }
605         case CodecVersion:
606         {
607                 msg = Msg_create_nopayload(CodecVersion);
608                 msg->unpacked = true;
609                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
610                 break;
611         }
612         case PermissionQuery:
613         {
614                 msg = Msg_create_nopayload(PermissionQuery);
615                 msg->unpacked = true;
616                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
617                 break;
618         }
619         case ChannelRemove:
620         {
621                 msg = Msg_create_nopayload(ChannelRemove);
622                 msg->unpacked = true;
623                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
624                 break;
625         }
626
627         default:
628                 Log_warn("Unsupported message %d", messageType);
629                 break;
630         }
631         return msg;
632 }