Remove unused function
[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 #define PREAMBLE_SIZE 6
43
44 static message_t *Msg_create_nopayload(messageType_t messageType);
45
46 static 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 - PREAMBLE_SIZE)
72 int Msg_messageToNetwork(message_t *msg, uint8_t *buffer)
73 {
74         int len;
75         uint8_t *bufptr = buffer + PREAMBLE_SIZE;
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                 mumble_proto__version__pack(msg->payload.version, bufptr);
87                 break;
88         case UDPTunnel: /* Non-standard handling of tunneled voice traffic. */
89                 if (msg->payload.UDPTunnel->packet.len > MAX_MSGSIZE) {
90                         Log_warn("Too big tx message. Discarding");
91                         break;
92                 }
93                 len = msg->payload.UDPTunnel->packet.len;
94                 Msg_addPreamble(buffer, msg->messageType, msg->payload.UDPTunnel->packet.len);
95                 memcpy(bufptr, msg->payload.UDPTunnel->packet.data, msg->payload.UDPTunnel->packet.len);
96                 break;
97         case Authenticate:
98                 len = mumble_proto__authenticate__get_packed_size(msg->payload.authenticate);
99                 if (len > MAX_MSGSIZE) {
100                         Log_warn("Too big tx message. Discarding");
101                         break;
102                         }
103                 Msg_addPreamble(buffer, msg->messageType, len);
104                 mumble_proto__authenticate__pack(msg->payload.authenticate, bufptr);
105                 break;
106         case Ping:
107                 len = mumble_proto__ping__get_packed_size(msg->payload.ping);
108                 if (len > MAX_MSGSIZE) {
109                         Log_warn("Too big tx message. Discarding");
110                         break;
111                         }
112                 Msg_addPreamble(buffer, msg->messageType, len);
113                 mumble_proto__ping__pack(msg->payload.ping, bufptr);
114                 break;
115         case Reject:
116                 len = mumble_proto__reject__get_packed_size(msg->payload.reject);
117                 if (len > MAX_MSGSIZE) {
118                         Log_warn("Too big tx message. Discarding");
119                         break;
120                         }
121                 Msg_addPreamble(buffer, msg->messageType, len);
122                 mumble_proto__reject__pack(msg->payload.reject, bufptr);
123                 break;
124         case ServerSync:
125                 len = mumble_proto__server_sync__get_packed_size(msg->payload.serverSync);
126                 if (len > MAX_MSGSIZE) {
127                         Log_warn("Too big tx message. Discarding");
128                         break;
129                         }
130                 Msg_addPreamble(buffer, msg->messageType, len);
131                 mumble_proto__server_sync__pack(msg->payload.serverSync, bufptr);
132                 break;
133         case TextMessage:
134                 len = mumble_proto__text_message__get_packed_size(msg->payload.textMessage);
135                 if (len > MAX_MSGSIZE) {
136                         Log_warn("Too big tx message. Discarding");
137                         break;
138                         }
139                 Msg_addPreamble(buffer, msg->messageType, len);
140                 mumble_proto__text_message__pack(msg->payload.textMessage, bufptr);
141                 break;
142         case PermissionDenied:
143                 len = mumble_proto__permission_denied__get_packed_size(msg->payload.permissionDenied);
144                 if (len > MAX_MSGSIZE) {
145                         Log_warn("Too big tx message. Discarding");
146                         break;
147                         }
148                 Msg_addPreamble(buffer, msg->messageType, len);
149                 mumble_proto__permission_denied__pack(msg->payload.permissionDenied, bufptr);
150                 break;
151         case CryptSetup:
152                 len = mumble_proto__crypt_setup__get_packed_size(msg->payload.cryptSetup);
153                 if (len > MAX_MSGSIZE) {
154                         Log_warn("Too big tx message. Discarding");
155                         break;
156                         }
157                 Msg_addPreamble(buffer, msg->messageType, len);
158                 mumble_proto__crypt_setup__pack(msg->payload.cryptSetup, bufptr);
159                 break;
160         case UserList:
161                 len = mumble_proto__user_list__get_packed_size(msg->payload.userList);
162                 if (len > MAX_MSGSIZE) {
163                         Log_warn("Too big tx message. Discarding");
164                         break;
165                         }
166                 Msg_addPreamble(buffer, msg->messageType, len);
167                 mumble_proto__user_list__pack(msg->payload.userList, bufptr);
168                 break;
169         case UserState:
170                 len = mumble_proto__user_state__get_packed_size(msg->payload.userState);
171                 if (len > MAX_MSGSIZE) {
172                         Log_warn("Too big tx message. Discarding");
173                         break;
174                         }
175                 Msg_addPreamble(buffer, msg->messageType, len);
176                 mumble_proto__user_state__pack(msg->payload.userState, bufptr);
177                 break;
178         case UserRemove:
179                 len = mumble_proto__user_remove__get_packed_size(msg->payload.userRemove);
180                 if (len > MAX_MSGSIZE) {
181                         Log_warn("Too big tx message. Discarding");
182                         break;
183                         }
184                 Msg_addPreamble(buffer, msg->messageType, len);
185                 mumble_proto__user_remove__pack(msg->payload.userRemove, bufptr);
186                 break;
187         case ChannelState:
188                 len = mumble_proto__channel_state__get_packed_size(msg->payload.channelState);
189                 if (len > MAX_MSGSIZE) {
190                         Log_warn("Too big tx message. Discarding");
191                         break;
192                         }
193                 Msg_addPreamble(buffer, msg->messageType, len);
194                 mumble_proto__channel_state__pack(msg->payload.channelState, bufptr);
195                 break;
196         case VoiceTarget:
197                 len = mumble_proto__voice_target__get_packed_size(msg->payload.voiceTarget);
198                 if (len > MAX_MSGSIZE) {
199                         Log_warn("Too big tx message. Discarding");
200                         break;
201                         }
202                 Msg_addPreamble(buffer, msg->messageType, len);
203                 mumble_proto__voice_target__pack(msg->payload.voiceTarget, bufptr);
204                 break;
205         case CodecVersion:
206                 len = mumble_proto__codec_version__get_packed_size(msg->payload.codecVersion);
207                 if (len > MAX_MSGSIZE) {
208                         Log_warn("Too big tx message. Discarding");
209                         break;
210                         }
211                 Msg_addPreamble(buffer, msg->messageType, len);
212                 mumble_proto__codec_version__pack(msg->payload.codecVersion, bufptr);
213                 break;
214         case PermissionQuery:
215                 len = mumble_proto__permission_query__get_packed_size(msg->payload.permissionQuery);
216                 if (len > MAX_MSGSIZE) {
217                         Log_warn("Too big tx message. Discarding");
218                         break;
219                         }
220                 Msg_addPreamble(buffer, msg->messageType, len);
221                 mumble_proto__permission_query__pack(msg->payload.permissionQuery, bufptr);
222                 break;
223         case ChannelRemove:
224                 len = mumble_proto__channel_remove__get_packed_size(msg->payload.channelRemove);
225                 if (len > MAX_MSGSIZE) {
226                         Log_warn("Too big tx message. Discarding");
227                         break;
228                         }
229                 Msg_addPreamble(buffer, msg->messageType, len);
230                 mumble_proto__channel_remove__pack(msg->payload.channelRemove, bufptr);
231                 break;
232
233         default:
234                 Log_warn("Msg_MessageToNetwork: Unsupported message %d", msg->messageType);
235                 return 0;
236         }
237         return len + PREAMBLE_SIZE;
238 }
239
240 static message_t *Msg_create_nopayload(messageType_t messageType)
241 {
242         message_t *msg = malloc(sizeof(message_t));
243
244         if (msg == NULL)
245                 Log_fatal("Out of memory");
246         memset(msg, 0, sizeof(message_t));
247         msg->refcount = 1;
248         msg->messageType = messageType;
249         init_list_entry(&msg->node);
250         return msg;
251 }
252
253 message_t *Msg_create(messageType_t messageType)
254 {
255         message_t *msg = Msg_create_nopayload(messageType);
256         
257         switch (messageType) {
258         case Version:
259                 msg->payload.version = malloc(sizeof(MumbleProto__Version));
260                 mumble_proto__version__init(msg->payload.version);
261                 break;
262         case UDPTunnel:
263                 msg->payload.UDPTunnel = malloc(sizeof(MumbleProto__UDPTunnel));
264                 mumble_proto__udptunnel__init(msg->payload.UDPTunnel);
265                 break;
266         case Authenticate:
267                 msg->payload.authenticate = malloc(sizeof(MumbleProto__Authenticate));
268                 mumble_proto__authenticate__init(msg->payload.authenticate);
269                 break;
270         case Ping:
271                 msg->payload.ping = malloc(sizeof(MumbleProto__Ping));
272                 mumble_proto__ping__init(msg->payload.ping);
273                 break;
274         case Reject:
275                 msg->payload.reject = malloc(sizeof(MumbleProto__Reject));
276                 mumble_proto__reject__init(msg->payload.reject);
277                 break;
278         case ServerSync:
279                 msg->payload.serverSync = malloc(sizeof(MumbleProto__ServerSync));
280                 mumble_proto__server_sync__init(msg->payload.serverSync);
281                 break;
282         case TextMessage:
283                 msg->payload.textMessage = malloc(sizeof(MumbleProto__TextMessage));
284                 mumble_proto__text_message__init(msg->payload.textMessage);
285                 break;
286         case PermissionDenied:
287                 msg->payload.permissionDenied = malloc(sizeof(MumbleProto__PermissionDenied));
288                 mumble_proto__permission_denied__init(msg->payload.permissionDenied);
289                 break;
290         case CryptSetup:
291                 msg->payload.cryptSetup = malloc(sizeof(MumbleProto__CryptSetup));
292                 mumble_proto__crypt_setup__init(msg->payload.cryptSetup);
293                 break;
294         case UserList:
295                 msg->payload.userList = malloc(sizeof(MumbleProto__UserList));
296                 mumble_proto__user_list__init(msg->payload.userList);
297                 break;
298         case UserState:
299                 msg->payload.userState = malloc(sizeof(MumbleProto__UserState));
300                 mumble_proto__user_state__init(msg->payload.userState);
301                 break;
302         case ChannelState:
303                 msg->payload.channelState = malloc(sizeof(MumbleProto__ChannelState));
304                 mumble_proto__channel_state__init(msg->payload.channelState);
305                 break;
306         case UserRemove:
307                 msg->payload.userRemove = malloc(sizeof(MumbleProto__UserRemove));
308                 mumble_proto__user_remove__init(msg->payload.userRemove);
309                 break;
310         case VoiceTarget:
311                 msg->payload.voiceTarget = malloc(sizeof(MumbleProto__VoiceTarget));
312                 mumble_proto__voice_target__init(msg->payload.voiceTarget);
313                 break;
314         case CodecVersion:
315                 msg->payload.codecVersion = malloc(sizeof(MumbleProto__CodecVersion));
316                 mumble_proto__codec_version__init(msg->payload.codecVersion);
317                 break;
318         case PermissionQuery:
319                 msg->payload.permissionQuery = malloc(sizeof(MumbleProto__PermissionQuery));
320                 mumble_proto__permission_query__init(msg->payload.permissionQuery);
321                 break;
322         case ChannelRemove:
323                 msg->payload.channelRemove = malloc(sizeof(MumbleProto__ChannelRemove));
324                 mumble_proto__channel_remove__init(msg->payload.channelRemove);
325                 break;
326
327         default:
328                 Log_warn("Msg_create: Unsupported message %d", msg->messageType);
329                 break;
330         }
331
332         return msg;
333 }
334
335 void Msg_inc_ref(message_t *msg)
336 {
337         msg->refcount++;
338 }
339
340 void Msg_free(message_t *msg)
341 {
342         if (msg->refcount) msg->refcount--;
343         if (msg->refcount > 0)
344                 return;
345
346         switch (msg->messageType) {
347         case Version:
348                 if (msg->unpacked)
349                         mumble_proto__version__free_unpacked(msg->payload.version, NULL);
350                 else {
351                         if (msg->payload.version->release)
352                                 free(msg->payload.version->release);
353                         if (msg->payload.version->os)
354                                 free(msg->payload.version->os);
355                         if (msg->payload.version->os_version)
356                                 free(msg->payload.version->os_version);
357                         free(msg->payload.version);
358                 }
359                 break;
360         case UDPTunnel:
361                 if (msg->unpacked)
362                         mumble_proto__udptunnel__free_unpacked(msg->payload.UDPTunnel, NULL);
363                 else {
364                         free(msg->payload.UDPTunnel->packet.data);
365                         free(msg->payload.UDPTunnel);
366                 }
367                 break;
368         case Authenticate:
369                 if (msg->unpacked)
370                         mumble_proto__authenticate__free_unpacked(msg->payload.authenticate, NULL);
371                 else
372                         free(msg->payload.authenticate);
373                 break;
374         case Ping:
375                 if (msg->unpacked)
376                         mumble_proto__ping__free_unpacked(msg->payload.ping, NULL);
377                 else {
378                         free(msg->payload.ping);
379                 }
380                 break;
381         case Reject:
382                 if (msg->unpacked)
383                         mumble_proto__reject__free_unpacked(msg->payload.reject, NULL);
384                 else {
385                         free(msg->payload.reject->reason);
386                         free(msg->payload.reject);
387                 }
388                 break;
389         case ServerSync:
390                 if (msg->unpacked)
391                         mumble_proto__server_sync__free_unpacked(msg->payload.serverSync, NULL);
392                 else {
393                         free(msg->payload.serverSync->welcome_text);
394                         free(msg->payload.serverSync);
395                 }
396                 break;
397         case TextMessage:
398                 if (msg->unpacked)
399                         mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL);
400                 else {
401                         free(msg->payload.textMessage);
402                 }
403                 break;
404         case PermissionDenied:
405                 if (msg->unpacked)
406                         mumble_proto__permission_denied__free_unpacked(msg->payload.permissionDenied, NULL);
407                 else {
408                         free(msg->payload.permissionDenied->reason);
409                         free(msg->payload.permissionDenied);
410                 }
411                 break;
412         case CryptSetup:
413                 if (msg->unpacked)
414                         mumble_proto__crypt_setup__free_unpacked(msg->payload.cryptSetup, NULL);
415                 else {
416                         free(msg->payload.cryptSetup);
417                 }
418                 break;
419         case UserList:
420                 if (msg->unpacked)
421                         mumble_proto__user_list__free_unpacked(msg->payload.userList, NULL);
422                 else {
423                         free(msg->payload.userList);
424                 }
425                 break;
426         case UserState:
427                 if (msg->unpacked)
428                         mumble_proto__user_state__free_unpacked(msg->payload.userState, NULL);
429                 else {
430                         free(msg->payload.userState->name);
431                         free(msg->payload.userState);
432                 }
433                 break;
434         case ChannelState:
435                 if (msg->unpacked)
436                         mumble_proto__channel_state__free_unpacked(msg->payload.channelState, NULL);
437                 else {
438                         if (msg->payload.channelState->name)
439                                 free(msg->payload.channelState->name);
440                         if (msg->payload.channelState->description)
441                                 free(msg->payload.channelState->description);
442                         if (msg->payload.channelState->links)
443                                 free(msg->payload.channelState->links);
444                         free(msg->payload.channelState);
445                 }
446                 break;
447         case UserRemove:
448                 if (msg->unpacked)
449                         mumble_proto__user_remove__free_unpacked(msg->payload.userRemove, NULL);
450                 else {
451                         free(msg->payload.userRemove);
452                 }
453                 break;
454         case VoiceTarget:
455                 if (msg->unpacked)
456                         mumble_proto__voice_target__free_unpacked(msg->payload.voiceTarget, NULL);
457                 else {
458                         free(msg->payload.voiceTarget);
459                 }
460                 break;
461         case CodecVersion:
462                 if (msg->unpacked)
463                         mumble_proto__codec_version__free_unpacked(msg->payload.codecVersion, NULL);
464                 else {
465                         free(msg->payload.codecVersion);
466                 }
467                 break;
468         case PermissionQuery:
469                 if (msg->unpacked)
470                         mumble_proto__permission_query__free_unpacked(msg->payload.permissionQuery, NULL);
471                 else {
472                         free(msg->payload.permissionQuery);
473                 }
474                 break;
475         case ChannelRemove:
476                 if (msg->unpacked)
477                         mumble_proto__channel_remove__free_unpacked(msg->payload.channelRemove, NULL);
478                 else {
479                         free(msg->payload.channelRemove);
480                 }
481                 break;
482
483         default:
484                 Log_warn("Msg_free: Unsupported message %d", msg->messageType);
485                 break;
486         }
487         free(msg);
488 }
489
490 message_t *Msg_CreateVoiceMsg(uint8_t *data, int size)
491 {
492         message_t *msg = NULL;
493         
494         msg = Msg_create_nopayload(UDPTunnel);
495         msg->unpacked = false;
496         msg->payload.UDPTunnel = malloc(sizeof(struct _MumbleProto__UDPTunnel));
497         if (msg->payload.UDPTunnel == NULL)
498                 Log_fatal("Out of memory");
499         msg->payload.UDPTunnel->packet.data = malloc(size);
500         if (msg->payload.UDPTunnel->packet.data == NULL)
501                 Log_fatal("Out of memory");
502         memcpy(msg->payload.UDPTunnel->packet.data, data, size);
503         msg->payload.UDPTunnel->packet.len = size;
504         return msg;
505 }
506
507 message_t *Msg_networkToMessage(uint8_t *data, int size)
508 {
509         message_t *msg = NULL;
510         uint8_t *msgData = &data[6];
511         int messageType, msgLen;
512
513         Msg_getPreamble(data, &messageType, &msgLen);
514
515         Log_debug("Message type %d size %d", messageType, msgLen);
516         //dumpmsg(data, size);
517         
518         switch (messageType) {
519         case Version:
520         {
521                 msg = Msg_create_nopayload(Version);
522                 msg->unpacked = true;
523                 msg->payload.version = mumble_proto__version__unpack(NULL, msgLen, msgData);
524                 if (msg->payload.version == NULL)
525                         goto err_out;
526                 break;
527         }
528         case UDPTunnel: /* Non-standard handling of tunneled voice data */
529         {
530                 msg = Msg_CreateVoiceMsg(msgData, msgLen);
531                 break;
532         }
533         case Authenticate:
534         {
535                 msg = Msg_create_nopayload(Authenticate);
536                 msg->unpacked = true;
537                 msg->payload.authenticate = mumble_proto__authenticate__unpack(NULL, msgLen, msgData);
538                 if (msg->payload.authenticate == NULL)
539                         goto err_out;
540                 break;
541         }
542         case Ping:
543         {
544                 msg = Msg_create_nopayload(Ping);
545                 msg->unpacked = true;
546                 msg->payload.ping = mumble_proto__ping__unpack(NULL, msgLen, msgData);
547                 if (msg->payload.ping == NULL)
548                         goto err_out;
549                 break;
550         }
551         case Reject:
552         {
553                 msg = Msg_create_nopayload(Reject);
554                 msg->unpacked = true;
555                 msg->payload.reject = mumble_proto__reject__unpack(NULL, msgLen, msgData);
556                 if (msg->payload.reject == NULL)
557                         goto err_out;
558                 break;
559         }
560         case ServerSync:
561         {
562                 msg = Msg_create_nopayload(ServerSync);
563                 msg->unpacked = true;
564                 msg->payload.serverSync = mumble_proto__server_sync__unpack(NULL, msgLen, msgData);
565                 if (msg->payload.serverSync == NULL)
566                         goto err_out;
567                 break;
568         }
569         case TextMessage:
570         {
571                 msg = Msg_create_nopayload(TextMessage);
572                 msg->unpacked = true;
573                 msg->payload.textMessage = mumble_proto__text_message__unpack(NULL, msgLen, msgData);
574                 if (msg->payload.textMessage == NULL)
575                         goto err_out;
576                 break;
577         }
578         case PermissionDenied:
579         {
580                 msg = Msg_create_nopayload(PermissionDenied);
581                 msg->unpacked = true;
582                 msg->payload.permissionDenied = mumble_proto__permission_denied__unpack(NULL, msgLen, msgData);
583                 if (msg->payload.permissionDenied == NULL)
584                         goto err_out;
585                 break;
586         }
587         case CryptSetup:
588         {
589                 msg = Msg_create_nopayload(CryptSetup);
590                 msg->unpacked = true;
591                 msg->payload.cryptSetup = mumble_proto__crypt_setup__unpack(NULL, msgLen, msgData);
592                 if (msg->payload.cryptSetup == NULL)
593                         goto err_out;
594                 break;
595         }
596         case UserList:
597         {
598                 msg = Msg_create_nopayload(UserList);
599                 msg->unpacked = true;
600                 msg->payload.userList = mumble_proto__user_list__unpack(NULL, msgLen, msgData);
601                 if (msg->payload.userList == NULL)
602                         goto err_out;
603                 break;
604         }
605         case UserState:
606         {
607                 msg = Msg_create_nopayload(UserState);
608                 msg->unpacked = true;
609                 msg->payload.userState = mumble_proto__user_state__unpack(NULL, msgLen, msgData);
610                 if (msg->payload.userState == NULL)
611                         goto err_out;
612                 break;
613         }
614         case ChannelState:
615         {
616                 msg = Msg_create_nopayload(ChannelState);
617                 msg->unpacked = true;
618                 msg->payload.channelState = mumble_proto__channel_state__unpack(NULL, msgLen, msgData);
619                 if (msg->payload.channelState == NULL)
620                         goto err_out;
621                 break;
622         }
623         case VoiceTarget:
624         {
625                 msg = Msg_create_nopayload(VoiceTarget);
626                 msg->unpacked = true;
627                 msg->payload.voiceTarget = mumble_proto__voice_target__unpack(NULL, msgLen, msgData);
628                 if (msg->payload.voiceTarget == NULL)
629                         goto err_out;
630                 break;
631         }
632         case CodecVersion:
633         {
634                 msg = Msg_create_nopayload(CodecVersion);
635                 msg->unpacked = true;
636                 msg->payload.codecVersion = mumble_proto__codec_version__unpack(NULL, msgLen, msgData);
637                 if (msg->payload.codecVersion == NULL)
638                         goto err_out;
639                 break;
640         }
641         case PermissionQuery:
642         {
643                 msg = Msg_create_nopayload(PermissionQuery);
644                 msg->unpacked = true;
645                 msg->payload.permissionQuery = mumble_proto__permission_query__unpack(NULL, msgLen, msgData);
646                 if (msg->payload.permissionQuery == NULL)
647                         goto err_out;
648                 break;
649         }
650         case ChannelRemove:
651         {
652                 msg = Msg_create_nopayload(ChannelRemove);
653                 msg->unpacked = true;
654                 msg->payload.channelRemove = mumble_proto__channel_remove__unpack(NULL, msgLen, msgData);
655                 if (msg->payload.channelRemove == NULL)
656                         goto err_out;
657                 break;
658         }
659
660         default:
661                 Log_warn("Unsupported message %d", messageType);
662                 break;
663         }
664         return msg;
665         
666 err_out:
667         free(msg);
668         return NULL;
669 }