diff --git a/recording-daemon/db.c b/recording-daemon/db.c index a38b1e9be..515e9c655 100644 --- a/recording-daemon/db.c +++ b/recording-daemon/db.c @@ -263,7 +263,7 @@ static void db_do_call_id(metafile_t *mf) { execute_wrap(&stm_insert_call, b, &mf->db_id); } static void db_do_call_metadata(metafile_t *mf) { - if (!mf->metadata_db) + if (mf->db_metadata_done) return; if (mf->db_id == 0) return; @@ -271,26 +271,17 @@ static void db_do_call_metadata(metafile_t *mf) { MYSQL_BIND b[3]; my_ull(&b[0], &mf->db_id); // stays persistent - // XXX offload this parsing to proxy module -> bencode list/dictionary - str all_meta = STR_INIT(mf->metadata_db); - while (all_meta.len > 1) { - str token; - if (str_token_sep(&token, &all_meta, '|')) - break; - - str key; - if (str_token(&key, &token, ':')) { - // key:value separator not found, skip - continue; - } - - my_str(&b[1], &key); - my_str(&b[2], &token); + metadata_ht_iter iter; + t_hash_table_iter_init(&iter, mf->metadata_parsed); + str *key, *token; + while (t_hash_table_iter_next(&iter, &key, &token)) { + my_str(&b[1], key); + my_str(&b[2], token); execute_wrap(&stm_insert_metadata, b, NULL); } - mf->metadata_db = NULL; + mf->db_metadata_done = 1; } void db_do_call(metafile_t *mf) { diff --git a/recording-daemon/metafile.c b/recording-daemon/metafile.c index bed0f666c..8c632be2f 100644 --- a/recording-daemon/metafile.c +++ b/recording-daemon/metafile.c @@ -42,6 +42,7 @@ static void meta_free(void *ptr) { tag_free(tag); } + t_hash_table_destroy(mf->metadata_parsed); g_ptr_array_free(mf->tags, TRUE); g_ptr_array_free(mf->streams, TRUE); g_slice_free1(sizeof(*mf), mf); @@ -165,10 +166,30 @@ static void meta_ptime(metafile_t *mf, unsigned long mnum, int ptime) mf->media_ptimes[mnum] = ptime; } +// mf is locked +// updates the contents, does not remove previously set entries +static void meta_metadata_parse(metafile_t *mf) { + // XXX offload this parsing to proxy module -> bencode list/dictionary + str all_meta = STR_INIT(mf->metadata); + while (all_meta.len > 1) { + str token; + if (str_token_sep(&token, &all_meta, '|')) + break; + + str key; + if (str_token(&key, &token, ':')) { + // key:value separator not found, skip + continue; + } + + t_hash_table_replace(mf->metadata_parsed, str_dup(&key), str_dup(&token)); + } +} + // mf is locked static void meta_metadata(metafile_t *mf, char *content) { mf->metadata = g_string_chunk_insert(mf->gsc, content); - mf->metadata_db = mf->metadata; + meta_metadata_parse(mf); db_do_call(mf); if (forward_to) start_forwarding_capture(mf, content); @@ -248,6 +269,7 @@ static metafile_t *metafile_get(char *name) { mf->forward_failed = 0; mf->recording_on = 1; mf->start_time = now_double(); + mf->metadata_parsed = metadata_ht_new(); if (decoding_enabled) { pthread_mutex_init(&mf->payloads_lock, NULL); diff --git a/recording-daemon/notify.c b/recording-daemon/notify.c index 95f7d689d..d277d966e 100644 --- a/recording-daemon/notify.c +++ b/recording-daemon/notify.c @@ -309,8 +309,8 @@ void notify_push_output(output_t *o, metafile_t *mf, tag_t *tag) { notify_add_header(req, "X-Recording-Stream-DB-ID: %llu", o->db_id); if (mf->metadata) notify_add_header(req, "X-Recording-Call-Metadata: %s", mf->metadata); - if (mf->metadata_db) - notify_add_header(req, "X-Recording-DB-Metadata: %s", mf->metadata_db); + if (mf->metadata) + notify_add_header(req, "X-Recording-DB-Metadata: %s", mf->metadata); if (tag) { notify_add_header(req, "X-Recording-Tag: %s", tag->name); diff --git a/recording-daemon/types.h b/recording-daemon/types.h index b50fc7e6e..492189a57 100644 --- a/recording-daemon/types.h +++ b/recording-daemon/types.h @@ -16,6 +16,7 @@ #include "codeclib.h" #include "poller.h" #include "socket.h" +#include "containers.h" struct iphdr; @@ -108,6 +109,9 @@ struct tag_s { typedef struct tag_s tag_t; +TYPED_GHASHTABLE(metadata_ht, str, str, str_hash, str_equal, str_free, str_free) + + struct metafile_s { pthread_mutex_t lock; char *name; @@ -115,7 +119,7 @@ struct metafile_s { char *call_id; char *random_tag; char *metadata; - char *metadata_db; + metadata_ht metadata_parsed; char *output_dest; char *output_path; char *output_pattern; @@ -147,6 +151,7 @@ struct metafile_s { unsigned int recording_on:1; unsigned int forwarding_on:1; unsigned int discard:1; + unsigned int db_metadata_done:1; };