#if HAVE_CRT #define _CRTDBG_MAP_ALLOC #include #include #endif //HAVE_CRT /* * Copyright (C) 2020, University of the Basque Country (UPV/EHU) * * Contact for licensing options: * * This file is part of MCOP MCPTT Client * * This is free software: you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "tinymcptt/packet/tmcptt_mcptt_packet.h" #include "tinymcptt/packet/tmcptt_mcptt_packet_specific.h" #include "tnet_endianness.h" #include "tsk_memory.h" #include "tsk_debug.h" #include "tsk_string.h" static tsk_object_t* tmcptt_mcptt_packet_specific_binary_ctor(tsk_object_t * self, va_list * app) { tmcptt_mcptt_packet_specific_binary_t *specific = (tmcptt_mcptt_packet_specific_binary_t *)self; if(specific){ specific->f_id = 0; specific->f_length = 0; specific->f_h_value = 0; specific->f_l_value = 0; } return self; } static tsk_object_t* tmcptt_mcptt_packet_specific_binary_dtor(tsk_object_t * self) { tmcptt_mcptt_packet_specific_binary_t *specific = (tmcptt_mcptt_packet_specific_binary_t *)self; if(specific){ } return self; } static const tsk_object_def_t tmcptt_mcptt_packet_specific_binary_def_s = { sizeof(tmcptt_mcptt_packet_specific_binary_t), tmcptt_mcptt_packet_specific_binary_ctor, tmcptt_mcptt_packet_specific_binary_dtor, tsk_null, }; const tsk_object_def_t *tmcptt_mcptt_packet_specific_binary_def_t = &tmcptt_mcptt_packet_specific_binary_def_s; tmcptt_mcptt_packet_specific_binary_t* tmcptt_mcptt_packet_specific_binary_create_null() { tmcptt_mcptt_packet_specific_binary_t* specific; specific = (tmcptt_mcptt_packet_specific_binary_t*)tsk_object_new(tmcptt_mcptt_packet_specific_binary_def_t); return specific; } tmcptt_mcptt_packet_specific_binary_t* tmcptt_mcptt_packet_specific_binary_deserialize(const uint8_t fid, const void* data, tsk_size_t _size) { tmcptt_mcptt_packet_specific_binary_t* specific = tsk_null; const uint8_t* pdata = (const uint8_t*)data; int32_t size = (int32_t)_size; tsk_size_t field_size = 0; if(!data || size < TMCPTT_MCPTT_PACKET_SPECIFIC_BINARY_MIN_SIZE){ TSK_DEBUG_ERROR("Incorrect parameters"); goto bail; } if(pdata[0] != fid){ TSK_DEBUG_INFO("Incorrect field id"); specific = tsk_null; goto bail; } if(pdata[1] != 2){ TSK_DEBUG_INFO("Incorrect size id"); specific = tsk_null; goto bail; } if(!(specific = tmcptt_mcptt_packet_specific_binary_create_null())){ TSK_DEBUG_ERROR("Failed to create object"); goto bail; } specific->f_id = pdata[0]; specific->f_length = pdata[1]; pdata += 2*sizeof(uint8_t); size -= 2*sizeof(uint8_t); specific->f_h_value = pdata[0]; specific->f_l_value = pdata[1]; bail: return specific; } int tmcptt_mcptt_packet_specific_binary_serialize_to(const tmcptt_mcptt_packet_specific_binary_t* self, void* data, tsk_size_t size) { int ret = 0; uint8_t* pdata = (uint8_t*)data; tsk_size_t field_size = 0; uint16_t value_net = 0; if(!self || !data || size < tmcptt_mcptt_packet_specific_binary_get_size(self)){ return -1; } memcpy(pdata, &self->f_id, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_length, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_h_value, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_l_value, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); return ret; } tsk_size_t tmcptt_mcptt_packet_specific_binary_get_size(const tmcptt_mcptt_packet_specific_binary_t* self) { tsk_size_t size; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } size = 2*sizeof(uint8_t) + 2*sizeof(uint8_t); return size; } static tsk_object_t* tmcptt_mcptt_packet_specific_binary_16_ctor(tsk_object_t * self, va_list * app) { tmcptt_mcptt_packet_specific_binary_16_t *specific = (tmcptt_mcptt_packet_specific_binary_16_t *)self; if(specific){ specific->f_id = 0; specific->f_length = 0; specific->f_value = 0; } return self; } static tsk_object_t* tmcptt_mcptt_packet_specific_binary_16_dtor(tsk_object_t * self) { tmcptt_mcptt_packet_specific_binary_16_t *specific = (tmcptt_mcptt_packet_specific_binary_16_t *)self; if(specific){ } return self; } static const tsk_object_def_t tmcptt_mcptt_packet_specific_binary_16_def_s = { sizeof(tmcptt_mcptt_packet_specific_binary_16_t), tmcptt_mcptt_packet_specific_binary_16_ctor, tmcptt_mcptt_packet_specific_binary_16_dtor, tsk_null, }; const tsk_object_def_t *tmcptt_mcptt_packet_specific_binary_16_def_t = &tmcptt_mcptt_packet_specific_binary_16_def_s; tmcptt_mcptt_packet_specific_binary_16_t* tmcptt_mcptt_packet_specific_binary_16_create_null() { tmcptt_mcptt_packet_specific_binary_16_t* specific; specific = (tmcptt_mcptt_packet_specific_binary_16_t*)tsk_object_new(tmcptt_mcptt_packet_specific_binary_16_def_t); return specific; } tmcptt_mcptt_packet_specific_binary_16_t* tmcptt_mcptt_packet_specific_binary_16_deserialize(const uint8_t fid, const void* data, tsk_size_t _size) { tmcptt_mcptt_packet_specific_binary_16_t* specific = tsk_null; const uint8_t* pdata = (const uint8_t*)data; int32_t size = (int32_t)_size; tsk_size_t field_size = 0; if(!data || size < TMCPTT_MCPTT_PACKET_SPECIFIC_BINARY_16_MIN_SIZE){ TSK_DEBUG_ERROR("Incorrect parameters"); goto bail; } if(pdata[0] != fid){ TSK_DEBUG_INFO("Incorrect field id"); specific = tsk_null; goto bail; } if(pdata[1] != 2){ TSK_DEBUG_INFO("Incorrect size id"); specific = tsk_null; goto bail; } if(!(specific = tmcptt_mcptt_packet_specific_binary_16_create_null())){ TSK_DEBUG_ERROR("Failed to create object"); goto bail; } specific->f_id = pdata[0]; specific->f_length = pdata[1]; pdata += 2*sizeof(uint8_t); size -= 2*sizeof(uint8_t); specific->f_value = tnet_ntohs_2(pdata); pdata += sizeof(uint16_t); size -= sizeof(uint16_t); bail: return specific; } int tmcptt_mcptt_packet_specific_binary_16_serialize_to(const tmcptt_mcptt_packet_specific_binary_16_t* self, void* data, tsk_size_t size) { int ret = 0; uint8_t* pdata = (uint8_t*)data; tsk_size_t field_size = 0; uint16_t value_net = 0; if(!self || !data || size < tmcptt_mcptt_packet_specific_binary_16_get_size(self)){ return -1; } memcpy(pdata, &self->f_id, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_length, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); value_net = tnet_htons_2(&self->f_value); memcpy(pdata, &value_net, sizeof(uint16_t)); pdata += sizeof(uint16_t); size -= sizeof(uint16_t); return ret; } tsk_size_t tmcptt_mcptt_packet_specific_binary_32_get_size(const tmcptt_mcptt_packet_specific_ssrc_t* self) { tsk_size_t size; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } size = 2*sizeof(uint8_t) + sizeof(uint32_t)+ 2*sizeof(uint8_t); return size; } tsk_size_t tmcptt_mcptt_packet_specific_binary_16_get_size(const tmcptt_mcptt_packet_specific_binary_16_t* self) { tsk_size_t size; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } size = 2*sizeof(uint8_t) + sizeof(uint16_t); return size; } static tsk_object_t* tmcptt_mcptt_packet_specific_txt_ctor(tsk_object_t * self, va_list * app) { tmcptt_mcptt_packet_specific_txt_t *specific = (tmcptt_mcptt_packet_specific_txt_t *)self; if(specific){ specific->f_id = 0; specific->f_length = 0; specific->f_value = tsk_null; } return self; } static tsk_object_t* tmcptt_mcptt_packet_specific_txt_dtor(tsk_object_t * self) { tmcptt_mcptt_packet_specific_txt_t *specific = (tmcptt_mcptt_packet_specific_txt_t *)self; if(specific){ if(specific->f_value) TSK_FREE(specific->f_value); } return self; } //INIT new SSRC static tsk_object_t* tmcptt_mcptt_packet_specific_ssrc_ctor(tsk_object_t * self, va_list * app) { tmcptt_mcptt_packet_specific_ssrc_t *specific = (tmcptt_mcptt_packet_specific_ssrc_t *)self; if(specific){ specific->f_id = 0; specific->f_length = 0; specific->f_value = 0; } return self; } static tsk_object_t* tmcptt_mcptt_packet_specific_ssrc_dtor(tsk_object_t * self) { tmcptt_mcptt_packet_specific_ssrc_t *specific = (tmcptt_mcptt_packet_specific_ssrc_t *)self; if(specific){ if(specific->f_value) TSK_FREE(specific->f_value); } return self; } //END new SSRC static const tsk_object_def_t tmcptt_mcptt_packet_specific_txt_def_s = { sizeof(tmcptt_mcptt_packet_specific_txt_t), tmcptt_mcptt_packet_specific_txt_ctor, tmcptt_mcptt_packet_specific_txt_dtor, tsk_null, }; const tsk_object_def_t *tmcptt_mcptt_packet_specific_txt_def_t = &tmcptt_mcptt_packet_specific_txt_def_s; static const tsk_object_def_t tmcptt_mcptt_packet_specific_ssrc_def_s = { sizeof(tmcptt_mcptt_packet_specific_ssrc_t), tmcptt_mcptt_packet_specific_ssrc_ctor, tmcptt_mcptt_packet_specific_ssrc_dtor, tsk_null, }; const tsk_object_def_t *tmcptt_mcptt_packet_specific_ssrc_def_t = &tmcptt_mcptt_packet_specific_ssrc_def_s; tmcptt_mcptt_packet_specific_txt_t* tmcptt_mcptt_packet_specific_txt_create_null() { tmcptt_mcptt_packet_specific_txt_t* specific; specific = (tmcptt_mcptt_packet_specific_txt_t*)tsk_object_new(tmcptt_mcptt_packet_specific_txt_def_t); return specific; } tmcptt_mcptt_packet_specific_txt_t* tmcptt_mcptt_packet_specific_txt_deserialize(const uint8_t fid, const void* data, tsk_size_t _size) { tmcptt_mcptt_packet_specific_txt_t* specific = tsk_null; const uint8_t* pdata = (const uint8_t*)data; int32_t size = (int32_t)_size; tsk_size_t field_size = 0; if(!data || size < TMCPTT_MCPTT_PACKET_SPECIFIC_TXT_MIN_SIZE){ TSK_DEBUG_ERROR("Incorrect parameters"); goto bail; } if(pdata[0] != fid){ TSK_DEBUG_INFO("Incorrect field id"); specific = tsk_null; goto bail; } if(!(specific = tmcptt_mcptt_packet_specific_txt_create_null())){ TSK_DEBUG_ERROR("Failed to create object"); goto bail; } specific->f_id = pdata[0]; specific->f_length = pdata[1]; pdata += 2*sizeof(uint8_t); size -= 2*sizeof(uint8_t); if(specific->f_length > 0){ #if HAVE_CRT //Debug memory specific->f_value = (char *)malloc(specific->f_length * sizeof(char)); #else specific->f_value = (char *)tsk_malloc(specific->f_length * sizeof(char)); #endif //HAVE_CRT memcpy(specific->f_value, pdata, specific->f_length * sizeof(char)); pdata += specific->f_length; size -= specific->f_length; } bail: return specific; } int tmcptt_mcptt_packet_specific_txt_serialize_to(const tmcptt_mcptt_packet_specific_txt_t* self, void* data, tsk_size_t size) { int ret = 0; uint8_t* pdata = (uint8_t*)data; tsk_size_t field_size = 0; int padding_bytes = 0; if(!self || !data || size < tmcptt_mcptt_packet_specific_txt_get_size(self)){ return -1; } memcpy(pdata, &self->f_id, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_length, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); if(self->f_length > 0){ memcpy(pdata, self->f_value, self->f_length * sizeof(char)); pdata += self->f_length; size -= self->f_length; } /* Padding? */ if ((self->f_length + 2 * sizeof(uint8_t)) % 4 != 0) { padding_bytes = 4 - ((self->f_length + 2 * sizeof(uint8_t)) % 4); if (padding_bytes != 0) memset(pdata, 0, padding_bytes); } return ret; } tsk_size_t tmcptt_mcptt_packet_specific_txt_get_size(const tmcptt_mcptt_packet_specific_txt_t* self) { tsk_size_t size; int padding_bytes = 0; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } size = 2*sizeof(uint8_t) + self->f_length; if ((self->f_length + 2 * sizeof(uint8_t)) % 4 != 0) { //There is no 16 bit "value" field padding_bytes = 4 - ((self->f_length + 2 * sizeof(uint8_t)) % 4); size += padding_bytes; } return size; } //INIT new SSRC tmcptt_mcptt_packet_specific_ssrc_t* tmcptt_mcptt_packet_specific_ssrc_create_null() { tmcptt_mcptt_packet_specific_ssrc_t* specific; specific = (tmcptt_mcptt_packet_specific_ssrc_t*)tsk_object_new(tmcptt_mcptt_packet_specific_ssrc_def_t); return specific; } tmcptt_mcptt_packet_specific_ssrc_t* tmcptt_mcptt_packet_specific_ssrc_deserialize(const uint8_t fid, const void* data, tsk_size_t _size) { tmcptt_mcptt_packet_specific_ssrc_t* specific = tsk_null; const uint8_t* pdata = (const uint8_t*)data; int32_t size = (int32_t)_size; tsk_size_t field_size = 0; if(!data || size < TMCPTT_MCPTT_PACKET_SPECIFIC_TXT_MIN_SIZE){ TSK_DEBUG_ERROR("Incorrect parameters"); goto bail; } if(pdata[0] != fid){ TSK_DEBUG_INFO("Incorrect field id"); specific = tsk_null; goto bail; } if(!(specific = tmcptt_mcptt_packet_specific_ssrc_create_null())){ TSK_DEBUG_ERROR("Failed to create object"); goto bail; } specific->f_id = pdata[0]; specific->f_length = pdata[1]; if(specific->f_length!=6){ TSK_DEBUG_ERROR("Error in SSRC format. incorrect length"); return tsk_null; } pdata += 2*sizeof(uint8_t); size -= 2*sizeof(uint8_t); if(specific->f_length > 0){ uint32_t ssrc_net; memcpy(&ssrc_net, pdata, (specific->f_length-2) * sizeof(uint8_t)); specific->f_value=tnet_ntohl(ssrc_net); pdata += specific->f_length-2; size -= specific->f_length-2; } if(pdata[0]!=0x000 || pdata[1]!=0x000){//second and thiers byte is =0b00000000, value is 0; TSK_DEBUG_ERROR("Error in SSRC format. It does not have 2 bytes with value 0"); return tsk_null; } bail: return specific; } int tmcptt_mcptt_packet_specific_ssrc_serialize_to(const tmcptt_mcptt_packet_specific_ssrc_t* self, void* data, tsk_size_t size) { int ret = 0; uint8_t* pdata = (uint8_t*)data; tsk_size_t field_size = 0; int padding_bytes = 0; if(!self || !data || size < tmcptt_mcptt_packet_specific_ssrc_get_size(self)){ return -1; } memcpy(pdata, &self->f_id, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_length, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); if(self->f_length > 0){ memcpy(pdata, &self->f_value, self->f_length * sizeof(uint8_t)); pdata += self->f_length; size -= self->f_length; } /* Padding? */ if ((self->f_length + 2 * sizeof(uint8_t)) % 4 != 0) { padding_bytes = 4 - ((self->f_length + 2 * sizeof(uint8_t)) % 4); if (padding_bytes != 0) memset(pdata, 0, padding_bytes); } return ret; } tsk_size_t tmcptt_mcptt_packet_specific_ssrc_get_size(const tmcptt_mcptt_packet_specific_ssrc_t* self) { tsk_size_t size; int padding_bytes = 0; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } size = 2*sizeof(uint8_t) + self->f_length; if ((self->f_length + 2 * sizeof(uint8_t)) % 4 != 0) { //There is no 16 bit "value" field padding_bytes = 4 - ((self->f_length + 2 * sizeof(uint8_t)) % 4); size += padding_bytes; } return size; } //END new SSRC static tsk_object_t* tmcptt_mcptt_packet_specific_binary_8_txt_ctor(tsk_object_t * self, va_list * app) { tmcptt_mcptt_packet_specific_binary_8_txt_t *specific = (tmcptt_mcptt_packet_specific_binary_8_txt_t *)self; if(specific){ specific->f_id = 0; specific->f_length = 0; specific->f_bin_value = 0; specific->f_txt_value = tsk_null; } return self; } static tsk_object_t* tmcptt_mcptt_packet_specific_binary_8_txt_dtor(tsk_object_t * self) { tmcptt_mcptt_packet_specific_binary_8_txt_t *specific = (tmcptt_mcptt_packet_specific_binary_8_txt_t *)self; if(specific){ if(specific->f_txt_value) TSK_FREE(specific->f_txt_value); } return self; } static const tsk_object_def_t tmcptt_mcptt_packet_specific_binary_8_txt_def_s = { sizeof(tmcptt_mcptt_packet_specific_binary_8_txt_t), tmcptt_mcptt_packet_specific_binary_8_txt_ctor, tmcptt_mcptt_packet_specific_binary_8_txt_dtor, tsk_null, }; const tsk_object_def_t *tmcptt_mcptt_packet_specific_binary_8_txt_def_t = &tmcptt_mcptt_packet_specific_binary_8_txt_def_s; tmcptt_mcptt_packet_specific_binary_8_txt_t* tmcptt_mcptt_packet_specific_binary_8_txt_create_null() { tmcptt_mcptt_packet_specific_binary_8_txt_t* specific; specific = (tmcptt_mcptt_packet_specific_binary_8_txt_t*)tsk_object_new(tmcptt_mcptt_packet_specific_binary_8_txt_def_t); return specific; } tmcptt_mcptt_packet_specific_binary_8_txt_t* tmcptt_mcptt_packet_specific_binary_8_txt_deserialize(const uint8_t fid, const void* data, tsk_size_t _size) { tmcptt_mcptt_packet_specific_binary_8_txt_t* specific = tsk_null; const uint8_t* pdata = (const uint8_t*)data; int32_t size = (int32_t)_size; tsk_size_t field_size = 0; tsk_size_t field_txt_size = 0; if(!data || size < TMCPTT_MCPTT_PACKET_SPECIFIC_BINARY_8_TXT_MIN_SIZE){ TSK_DEBUG_ERROR("Incorrect parameters"); goto bail; } if(pdata[0] != fid){ TSK_DEBUG_INFO("Incorrect field id"); specific = tsk_null; goto bail; } if(!(specific = tmcptt_mcptt_packet_specific_binary_8_txt_create_null())){ TSK_DEBUG_ERROR("Failed to create object"); goto bail; } specific->f_id = pdata[0]; specific->f_length = pdata[1]; specific->f_bin_value = pdata[2]; pdata += 3*sizeof(uint8_t); size -= 3*sizeof(uint8_t); if (size > 0 && specific->f_length > sizeof(uint8_t)) { field_txt_size = specific->f_length - sizeof(uint8_t); if (field_txt_size > 0) { #if HAVE_CRT //Debug memory specific->f_txt_value = (char *)malloc(field_txt_size * sizeof(char)); #else specific->f_txt_value = (char *)tsk_malloc(field_txt_size * sizeof(char)); #endif //HAVE_CRT memcpy(specific->f_txt_value, pdata, field_txt_size); pdata += field_txt_size; size -= field_txt_size; } } bail: return specific; } int tmcptt_mcptt_packet_specific_binary_8_txt_serialize_to(const tmcptt_mcptt_packet_specific_binary_8_txt_t* self, void* data, tsk_size_t size) { int ret = 0; uint8_t* pdata = (uint8_t*)data; tsk_size_t field_size = 0; tsk_size_t field_txt_size = 0; int padding_bytes = 0; int i = 0; if(!self || !data || size < tmcptt_mcptt_packet_specific_binary_8_txt_get_size(self)){ return -1; } memcpy(pdata, &self->f_id, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_length, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_bin_value, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); if (self->f_txt_value != tsk_null && self->f_length > sizeof(uint8_t)) { field_txt_size = self->f_length - sizeof(uint8_t); if (field_txt_size > 0) { memcpy(pdata, self->f_txt_value, field_txt_size); pdata += field_txt_size; size -= field_txt_size; /* Padding? */ if ((2 * sizeof(uint8_t) + self->f_length) % 4 != 0) { padding_bytes = 4 - ((2 * sizeof(uint8_t) + self->f_length) % 4); if (padding_bytes != 0) memset(data, 0, padding_bytes); pdata += padding_bytes; size -= padding_bytes; } } } return ret; } tsk_size_t tmcptt_mcptt_packet_specific_binary_8_txt_get_size(const tmcptt_mcptt_packet_specific_binary_8_txt_t* self) { tsk_size_t size; int padding_bytes = 0; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } size = 2 * sizeof(uint8_t) + self->f_length; if ((self->f_length + 2 * sizeof(uint8_t)) % 4 != 0) { padding_bytes = 4 - ((self->f_length + 2 * sizeof(uint8_t)) % 4); size += padding_bytes; } return size; } static tsk_object_t* tmcptt_mcptt_packet_specific_binary_16_txt_ctor(tsk_object_t * self, va_list * app) { tmcptt_mcptt_packet_specific_binary_16_txt_t *specific = (tmcptt_mcptt_packet_specific_binary_16_txt_t *)self; if(specific){ specific->f_id = 0; specific->f_length = 0; specific->f_bin_value = 0; specific->f_txt_value = tsk_null; } return self; } static tsk_object_t* tmcptt_mcptt_packet_specific_binary_16_txt_dtor(tsk_object_t * self) { tmcptt_mcptt_packet_specific_binary_16_txt_t *specific = (tmcptt_mcptt_packet_specific_binary_16_txt_t *)self; if(specific){ if(specific->f_txt_value) TSK_FREE(specific->f_txt_value); } return self; } static const tsk_object_def_t tmcptt_mcptt_packet_specific_binary_16_txt_def_s = { sizeof(tmcptt_mcptt_packet_specific_binary_16_txt_t), tmcptt_mcptt_packet_specific_binary_16_txt_ctor, tmcptt_mcptt_packet_specific_binary_16_txt_dtor, tsk_null, }; const tsk_object_def_t *tmcptt_mcptt_packet_specific_binary_16_txt_def_t = &tmcptt_mcptt_packet_specific_binary_16_txt_def_s; tmcptt_mcptt_packet_specific_binary_16_txt_t* tmcptt_mcptt_packet_specific_binary_16_txt_create_null() { tmcptt_mcptt_packet_specific_binary_16_txt_t* specific; specific = (tmcptt_mcptt_packet_specific_binary_16_txt_t*)tsk_object_new(tmcptt_mcptt_packet_specific_binary_16_txt_def_t); return specific; } tmcptt_mcptt_packet_specific_binary_16_txt_t* tmcptt_mcptt_packet_specific_binary_16_txt_deserialize(const uint8_t fid, const void* data, tsk_size_t _size) { tmcptt_mcptt_packet_specific_binary_16_txt_t* specific = tsk_null; const uint8_t* pdata = (const uint8_t*)data; int32_t size = (int32_t)_size; tsk_size_t field_size = 0; tsk_size_t field_txt_size = 0; uint16_t net_value_s = 0; if(!data || size < TMCPTT_MCPTT_PACKET_SPECIFIC_BINARY_16_TXT_MIN_SIZE){ TSK_DEBUG_ERROR("Incorrect parameters"); goto bail; } if(pdata[0] != fid){ TSK_DEBUG_INFO("Incorrect field id"); specific = tsk_null; goto bail; } if(!(specific = tmcptt_mcptt_packet_specific_binary_16_txt_create_null())){ TSK_DEBUG_ERROR("Failed to create object"); goto bail; } specific->f_id = pdata[0]; specific->f_length = pdata[1]; pdata += 2*sizeof(uint8_t); size -= 2*sizeof(uint8_t); specific->f_bin_value = pdata[2]; memcpy(&net_value_s, pdata, sizeof(uint16_t)); specific->f_bin_value = tnet_ntohs(net_value_s); pdata += sizeof(uint16_t); if (specific->f_length > sizeof(uint16_t)) { field_txt_size = specific->f_length - sizeof(uint16_t); #if HAVE_CRT //Debug memory specific->f_txt_value = (char*)malloc(field_txt_size * sizeof(char)); #else specific->f_txt_value = (char*)tsk_malloc(field_txt_size * sizeof(char)); #endif //HAVE_CRT memcpy(specific->f_txt_value, pdata, field_txt_size); } bail: return specific; } int tmcptt_mcptt_packet_specific_binary_16_txt_serialize_to(const tmcptt_mcptt_packet_specific_binary_16_txt_t* self, void* data, tsk_size_t size) { int ret = 0; uint8_t* pdata = (uint8_t*)data; tsk_size_t field_size = 0; tsk_size_t field_txt_size = 0; int padding_bytes = 0; int i = 0; if(!self || !data || size < tmcptt_mcptt_packet_specific_binary_16_txt_get_size(self)){ return -1; } memcpy(pdata, &self->f_id, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_length, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_bin_value, sizeof(uint16_t)); pdata += sizeof(uint16_t); size -= sizeof(uint16_t); if (self->f_txt_value != tsk_null && self->f_length > sizeof(uint16_t)) { field_txt_size = self->f_length - sizeof(uint16_t); if (field_txt_size > 0) { memcpy(pdata, self->f_txt_value, field_txt_size); pdata += field_txt_size; size -= field_txt_size; /* Padding? */ if (field_txt_size % 4 != 0) { padding_bytes = 4 - (field_txt_size % 4); if (padding_bytes != 0) memset(data, 0, padding_bytes); pdata += padding_bytes; size -= padding_bytes; } } } return ret; } tsk_size_t tmcptt_mcptt_packet_specific_binary_16_txt_get_size(const tmcptt_mcptt_packet_specific_binary_16_txt_t* self) { tsk_size_t size; int padding_bytes = 0; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } size = 2 * sizeof(uint8_t) + self->f_length; if ((self->f_length - sizeof(uint16_t)) % 4 != 0) { padding_bytes = 4 - ((self->f_length - sizeof(uint16_t)) % 4); size += padding_bytes; } return size; } static tsk_object_t* tmcptt_mcptt_packet_specific_binary_txt_ref_ctor(tsk_object_t * self, va_list * app) { tmcptt_mcptt_packet_specific_binary_txt_ref_t *specific = (tmcptt_mcptt_packet_specific_binary_txt_ref_t *)self; if(specific){ specific->f_id = 0; specific->f_length = 0; specific->f_bin_h_value = 0; specific->f_bin_l_value = 0; specific->f_txt_value = tsk_null; specific->num_refs = 0; specific->f_refs = tsk_null; } return self; } static tsk_object_t* tmcptt_mcptt_packet_specific_binary_txt_ref_dtor(tsk_object_t * self) { tmcptt_mcptt_packet_specific_binary_txt_ref_t *specific = (tmcptt_mcptt_packet_specific_binary_txt_ref_t *)self; if(specific){ if(specific->f_txt_value) TSK_FREE(specific->f_txt_value); if(specific->f_refs) TSK_FREE(specific->f_refs); } return self; } static const tsk_object_def_t tmcptt_mcptt_packet_specific_binary_txt_ref_def_s = { sizeof(tmcptt_mcptt_packet_specific_binary_txt_ref_t), tmcptt_mcptt_packet_specific_binary_txt_ref_ctor, tmcptt_mcptt_packet_specific_binary_txt_ref_dtor, tsk_null, }; const tsk_object_def_t *tmcptt_mcptt_packet_specific_binary_txt_ref_def_t = &tmcptt_mcptt_packet_specific_binary_txt_ref_def_s; tmcptt_mcptt_packet_specific_binary_txt_ref_t* tmcptt_mcptt_packet_specific_binary_txt_ref_create_null() { tmcptt_mcptt_packet_specific_binary_txt_ref_t* specific; specific = (tmcptt_mcptt_packet_specific_binary_txt_ref_t*)tsk_object_new(tmcptt_mcptt_packet_specific_binary_txt_ref_def_t); return specific; } tmcptt_mcptt_packet_specific_binary_txt_ref_t* tmcptt_mcptt_packet_specific_binary_txt_ref_deserialize(const uint8_t fid, const void* data, tsk_size_t _size) { tmcptt_mcptt_packet_specific_binary_txt_ref_t* specific = tsk_null; const uint8_t* pdata = (const uint8_t*)data; int32_t size = (int32_t)_size; tsk_size_t field_size = 0; uint32_t net_l_value = 0; int padding_bytes = 0; int i = 0; if(!data || size < TMCPTT_MCPTT_PACKET_SPECIFIC_BINARY_TXT_REF_MIN_SIZE){ TSK_DEBUG_ERROR("Incorrect parameters"); goto bail; } if(pdata[0] != fid){ TSK_DEBUG_INFO("Incorrect field id"); specific = tsk_null; goto bail; } if(!(specific = tmcptt_mcptt_packet_specific_binary_txt_ref_create_null())){ TSK_DEBUG_ERROR("Failed to create object"); goto bail; } specific->f_id = pdata[0]; specific->f_length = pdata[1]; specific->f_bin_h_value = pdata[2]; specific->f_bin_l_value = pdata[3]; pdata += 4*sizeof(uint8_t); size -= 4*sizeof(uint8_t); if (size > 0 && specific->f_bin_l_value > 0) { #if HAVE_CRT //Debug memory specific->f_txt_value = (char *)malloc(specific->f_bin_l_value * sizeof(char)); #else specific->f_txt_value = (char *)tsk_malloc(specific->f_bin_l_value * sizeof(char)); #endif //HAVE_CRT memcpy(specific->f_txt_value, pdata, specific->f_bin_l_value * sizeof(char)); pdata += specific->f_bin_l_value; size -= specific->f_bin_l_value; /* Padding? */ if (specific->f_bin_l_value % 4 != 0) { padding_bytes = 4 - (specific->f_bin_l_value % 4); pdata += padding_bytes; size -= padding_bytes; } } //Length == Size(f_bin_h_value) + n*Size(ref) specific->num_refs = (specific->f_length - sizeof(uint8_t)) / sizeof(uint32_t); if (specific->num_refs > 0) { #if HAVE_CRT //Debug memory specific->f_refs = (uint32_t*)malloc(specific->num_refs * sizeof(uint32_t)); #else specific->f_refs = (uint32_t*)tsk_malloc(specific->num_refs * sizeof(uint32_t)); #endif //HAVE_CRT for (i = 0; i < specific->num_refs && size > 0; i++) { memcpy(&net_l_value, pdata, sizeof(uint32_t)); specific->f_refs[i] = tnet_ntohl(net_l_value); pdata += sizeof(uint32_t); size -= sizeof(uint32_t); } } bail: return specific; } int tmcptt_mcptt_packet_specific_binary_txt_ref_serialize_to(const tmcptt_mcptt_packet_specific_binary_txt_ref_t* self, void* data, tsk_size_t size) { int ret = 0; uint8_t* pdata = (uint8_t*)data; tsk_size_t field_size = 0; int padding_bytes = 0; int i = 0; uint32_t net_l_value = 0; if(!self || !data || size < tmcptt_mcptt_packet_specific_binary_txt_ref_get_size(self)){ return -1; } memcpy(pdata, &self->f_id, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_length, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_bin_h_value, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); memcpy(pdata, &self->f_bin_l_value, sizeof(uint8_t)); pdata += sizeof(uint8_t); size -= sizeof(uint8_t); if (self->f_txt_value != tsk_null) { memcpy(pdata, self->f_txt_value, self->f_bin_l_value); pdata += self->f_bin_l_value; size -= self->f_bin_l_value; /* Padding? */ if (self->f_bin_l_value % 4 != 0) { padding_bytes = 4 - (self->f_bin_l_value % 4); if (padding_bytes != 0) memset(pdata, 0, padding_bytes); pdata += padding_bytes; size -= padding_bytes; } } for (i = 0; i < self->num_refs; i++) { net_l_value = tnet_htonl(self->f_refs[i]); memcpy(data, &net_l_value, sizeof(uint32_t)); pdata += sizeof(uint32_t); size -= sizeof(uint32_t); } return ret; } tsk_size_t tmcptt_mcptt_packet_specific_binary_txt_ref_get_size(const tmcptt_mcptt_packet_specific_binary_txt_ref_t* self) { tsk_size_t size; int padding_bytes = 0; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return 0; } size = 4*sizeof(uint8_t) + self->f_bin_l_value + self->num_refs * sizeof(uint32_t); if (self->f_bin_l_value % 4 != 0) { padding_bytes = 4 - (self->f_bin_l_value % 4); size += padding_bytes; } return size; }