Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / rtp_media.c
blob8bd31fef42bad1b0d6e1cb462acab7f457ee63c7
1 /* rtp_media.c
3 * RTP decoding routines for Wireshark.
4 * Copied from ui/gtk/rtp_player.c
6 * Copyright 2006, Alejandro Vaquero <alejandrovaquero@yahoo.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1999 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include "config.h"
17 #include <wsutil/codecs.h>
18 #include <wsutil/wslog.h>
20 #include <epan/rtp_pt.h>
21 #include <epan/dissectors/packet-rtp.h>
22 #include <epan/dissectors/packet-iuup.h>
23 #include <epan/dissectors/packet-amr.h>
25 #include <ui/rtp_media.h>
27 /****************************************************************************/
28 /* DECODING */
29 /****************************************************************************/
31 typedef struct _rtp_decoder_t {
32 codec_handle_t handle;
33 codec_context_t *context;
34 } rtp_decoder_t;
36 /****************************************************************************/
38 * Return rtp_decoder_t for packet
41 static inline rtp_decoder_t *
42 decode_rtp_find_decoder(uint8_t payload_type, GHashTable *decoders_hash)
44 /* Look for registered codecs */
45 return (rtp_decoder_t *)g_hash_table_lookup(decoders_hash, GUINT_TO_POINTER(payload_type));
48 static rtp_decoder_t *
49 decode_rtp_create_decoder(uint8_t payload_type, const char *payload_type_str, int payload_rate,
50 int payload_channels, wmem_map_t *payload_fmtp_map, GHashTable *decoders_hash)
52 rtp_decoder_t *decoder;
53 /* Put either valid or empty decoder into the hash table */
54 decoder = g_new(rtp_decoder_t, 1);
55 decoder->handle = NULL;
56 decoder->context = g_new(codec_context_t, 1);
57 decoder->context->sample_rate = payload_rate;
58 decoder->context->channels = payload_channels;
59 decoder->context->fmtp_map = payload_fmtp_map;
60 decoder->context->priv = NULL;
62 if (payload_type_str)
63 decoder->handle = find_codec(payload_type_str);
64 if (!decoder->handle) {
65 const char *p = try_val_to_str_ext(payload_type, &rtp_payload_type_short_vals_ext);
66 if (p)
67 decoder->handle = find_codec(p);
70 if (decoder->handle)
71 decoder->context->priv = codec_init(decoder->handle, decoder->context);
73 g_hash_table_insert(decoders_hash, GUINT_TO_POINTER(payload_type), decoder);
74 return decoder;
77 static rtp_decoder_t *
78 decode_rtp_find_or_create_decoder(uint8_t payload_type, const char *payload_type_str, int payload_rate,
79 int payload_channels, wmem_map_t *payload_fmtp_map, GHashTable *decoders_hash)
81 rtp_decoder_t *decoder;
83 /* Look for registered codecs */
84 decoder = decode_rtp_find_decoder(payload_type, decoders_hash);
85 if (!decoder)
86 decoder = decode_rtp_create_decoder(payload_type, payload_type_str, payload_rate,
87 payload_channels, payload_fmtp_map, decoders_hash);
88 ws_assert(decoder);
89 return decoder;
92 /****************************************************************************/
93 /** Decode payload from an RTP packet
94 * For RTP packets with dynamic payload types, the payload name, clock rate,
95 * and number of audio channels (e.g., from the SDP) can be provided.
96 * Note that the output sample rate and number of channels might not be the
97 * same as that of the input.
99 * @param decoder RTP decoder used to decode the audio in the RTP payload.
100 * @param payload_data Payload
101 * @param payload_len Length of payload
102 * @param out_buff Output audio samples.
103 * @param channels_ptr If non-NULL, receives the number of channels in the sample.
104 * @param sample_rate_ptr If non-NULL, receives the sample rate.
105 * @return The number of decoded bytes on success, 0 on failure.
108 static size_t
109 decode_rtp_packet_payload(rtp_decoder_t *decoder, uint8_t *payload_data, size_t payload_len,
110 SAMPLE **out_buff, unsigned *channels_ptr, unsigned *sample_rate_ptr)
112 SAMPLE *tmp_buff = NULL;
113 size_t tmp_buff_len;
114 size_t decoded_bytes = 0;
116 if (!decoder->handle) {
117 *out_buff = NULL;
118 return 0;
121 /* Decode with registered codec */
122 /* if output == NULL and outputSizeBytes == NULL => ask for expected size of the buffer */
123 tmp_buff_len = codec_decode(decoder->handle, decoder->context, payload_data, payload_len, NULL, NULL);
124 tmp_buff = (SAMPLE *)g_malloc(tmp_buff_len);
125 decoded_bytes = codec_decode(decoder->handle, decoder->context, payload_data, payload_len, tmp_buff, &tmp_buff_len);
126 *out_buff = tmp_buff;
128 if (channels_ptr) {
129 *channels_ptr = codec_get_channels(decoder->handle, decoder->context);
132 if (sample_rate_ptr) {
133 *sample_rate_ptr = codec_get_frequency(decoder->handle, decoder->context);
136 return decoded_bytes;
139 /****************************************************************************/
140 /** Prepend an AMR NB Octet-Aligned header (2 bytes) to the AMR payload.
141 * A new buffer is allocated, filled and returned. The caller is responsible of freeing it.
143 * @return The callee-allocated buffer containing the AMR OA header + payload
145 static uint8_t *
146 prepend_amr_oa_hdr(uint8_t amr_ft, uint8_t amr_q, const uint8_t *amr_payload, uint8_t amr_payload_len)
148 uint8_t *amr_hdr;
150 amr_hdr = (uint8_t *)g_malloc(AMR_NB_OA_HDR_LEN + amr_payload_len);
151 amr_hdr[0] = 0xf0; /* CMR = 15 = "no change" */
152 amr_hdr[1] = (0 << 7) | /* F=0 */
153 ((amr_ft & 0x0f) << 3) |
154 (amr_q && 0x01) << 2;
155 memcpy(amr_hdr + AMR_NB_OA_HDR_LEN, amr_payload, amr_payload_len);
156 return amr_hdr;
159 /****************************************************************************/
160 /** Parse IuUP header to obtain the AMR payload, generate a octet-aligned AMR
161 * buffer which the AMR decoder can digest and decode it.
163 * @return Number of decoded bytes
166 size_t
167 decode_iuup_packet(rtp_packet_t *rp, SAMPLE **out_buff, GHashTable *decoders_hash, unsigned *channels_ptr,
168 unsigned *sample_rate_ptr)
170 uint8_t iuup_pdu_type;
171 uint8_t iuup_frame_nr;
172 uint8_t iuup_fqc;
173 uint8_t iuup_hdr_len;
174 uint8_t *iuup_payload;
175 uint8_t iuup_payload_len;
176 int amr_ft;
177 uint8_t *amr_hdr;
178 rtp_decoder_t *decoder;
179 size_t decoded_bytes;
181 if (rp->info->info_payload_len < 1)
182 goto ret_err;
184 /* Parse the IuUP header into struct iuup_decoded dt: */
185 iuup_pdu_type = rp->payload_data[0] >> 4;
186 switch (iuup_pdu_type) {
187 case PDUTYPE_DATA_WITH_CRC:
188 iuup_hdr_len = PDUTYPE_DATA_WITH_CRC_HDR_LEN;
189 break;
190 case PDUTYPE_DATA_NO_CRC:
191 iuup_hdr_len = PDUTYPE_DATA_NO_CRC_HDR_LEN;
192 break;
193 default:
194 goto ret_err;
197 if (rp->info->info_payload_len < iuup_hdr_len)
198 goto ret_err;
200 iuup_frame_nr = rp->payload_data[0] & 0x0f;
201 iuup_fqc = rp->payload_data[1] >> 6;
202 iuup_payload = rp->payload_data + iuup_hdr_len;
203 iuup_payload_len = rp->info->info_payload_len - iuup_hdr_len;
204 ws_assert(rp->info->info_payload_len - iuup_hdr_len < sizeof(uint8_t));
206 /* Figure out AMR FT from size: */
207 amr_ft = amr_nb_bytes_to_ft(iuup_payload_len);
208 if (amr_ft < 0) {
209 ws_log(LOG_DOMAIN_QTUI, LOG_LEVEL_MESSAGE,
210 "#%u: IuUP with unknown AMR payload format: frame_nr=%u bytes=%u\n",
211 rp->frame_num, iuup_frame_nr, iuup_payload_len);
212 goto ret_err;
215 /* Prepend an octet-aligned header to the AMR payload, so that the decoder can digest it: */
216 amr_hdr = prepend_amr_oa_hdr(amr_ft, !iuup_fqc, iuup_payload, iuup_payload_len);
218 /* Look for registered codecs */
219 decoder = decode_rtp_find_decoder(rp->info->info_payload_type, decoders_hash);
220 if (!decoder) {
221 wmem_map_t *iuup_decode_amr_fmtp = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
222 wmem_map_insert(iuup_decode_amr_fmtp, "octet-align", "1");
223 decoder = decode_rtp_create_decoder(rp->info->info_payload_type,
224 "amr",
225 rp->info->info_payload_rate,
226 rp->info->info_payload_channels,
227 iuup_decode_amr_fmtp,
228 decoders_hash);
229 ws_assert(decoder);
231 decoded_bytes = decode_rtp_packet_payload(decoder, amr_hdr, AMR_NB_OA_HDR_LEN + iuup_payload_len,
232 out_buff, channels_ptr, sample_rate_ptr);
233 g_free(amr_hdr);
234 return decoded_bytes;
236 ret_err:
237 *out_buff = NULL;
238 return 0;
241 /****************************************************************************/
243 * @return Number of decoded bytes
246 size_t
247 decode_rtp_packet(rtp_packet_t *rp, SAMPLE **out_buff, GHashTable *decoders_hash, unsigned *channels_ptr,
248 unsigned *sample_rate_ptr)
250 rtp_decoder_t *decoder;
252 if ((rp->payload_data == NULL) || (rp->info->info_payload_len == 0) ) {
253 return 0;
256 if (rp->info->info_is_iuup)
257 return decode_iuup_packet(rp, out_buff, decoders_hash, channels_ptr, sample_rate_ptr);
259 /* Look for registered codecs */
260 decoder = decode_rtp_find_or_create_decoder(rp->info->info_payload_type,
261 rp->info->info_payload_type_str,
262 rp->info->info_payload_rate,
263 rp->info->info_payload_channels,
264 rp->info->info_payload_fmtp_map,
265 decoders_hash);
266 return decode_rtp_packet_payload(decoder,
267 rp->payload_data, rp->info->info_payload_len,
268 out_buff, channels_ptr, sample_rate_ptr);
271 /****************************************************************************/
272 static void
273 rtp_decoder_value_destroy(void *dec_arg)
275 rtp_decoder_t *dec = (rtp_decoder_t *)dec_arg;
277 if (dec->handle) {
278 codec_release(dec->handle, dec->context);
279 g_free(dec->context);
281 g_free(dec_arg);
284 GHashTable *rtp_decoder_hash_table_new(void)
286 return g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, rtp_decoder_value_destroy);