From 4566bd37cff8bf879beae23a7ab7b28a4211228e Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 21 Mar 2017 10:25:44 -0400 Subject: [PATCH] TT#13005 store recording metadata to database Change-Id: Ic3974ebd9aadc0af35941b49e4a0e7fd6f536691 --- recording-daemon/db.c | 78 ++++++++++++++++++++++++++++++------- recording-daemon/metafile.c | 9 +++++ recording-daemon/types.h | 1 + 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/recording-daemon/db.c b/recording-daemon/db.c index d8abbf186..12dd38755 100644 --- a/recording-daemon/db.c +++ b/recording-daemon/db.c @@ -13,7 +13,8 @@ static MYSQL_STMT __thread *stm_close_call, *stm_insert_stream, *stm_close_stream, - *stm_config_stream; + *stm_config_stream, + *stm_insert_metadata; static void my_stmt_close(MYSQL_STMT **st) { @@ -30,6 +31,7 @@ static void reset_conn() { my_stmt_close(&stm_insert_stream); my_stmt_close(&stm_close_stream); my_stmt_close(&stm_config_stream); + my_stmt_close(&stm_insert_metadata); mysql_close(mysql_conn); mysql_conn = NULL; } @@ -79,6 +81,9 @@ static int check_conn() { goto err; if (prep(&stm_config_stream, "update recording_streams set channels = ?, sample_rate = ? where id = ?")) goto err; + if (prep(&stm_insert_metadata, "insert into recording_metakeys (`call`, `key`, `value`) values " \ + "(?,?,?)")) + goto err; ilog(LOG_INFO, "Connection to MySQL established"); @@ -96,14 +101,20 @@ err: } -INLINE void my_str(MYSQL_BIND *b, const char *s) { +INLINE void my_str_len(MYSQL_BIND *b, const char *s, unsigned int len) { *b = (MYSQL_BIND) { .buffer_type = MYSQL_TYPE_STRING, .buffer = (void *) s, - .buffer_length = strlen(s), + .buffer_length = len, .length = &b->buffer_length, }; } +INLINE void my_str(MYSQL_BIND *b, const str *s) { + my_str_len(b, s->s, s->len); +} +INLINE void my_cstr(MYSQL_BIND *b, const char *s) { + my_str_len(b, s, strlen(s)); +} INLINE void my_ull(MYSQL_BIND *b, const unsigned long long *ull) { *b = (MYSQL_BIND) { .buffer_type = MYSQL_TYPE_LONGLONG, @@ -150,17 +161,58 @@ err: } -void db_do_call(metafile_t *mf) { - if (check_conn()) - return; +static void db_do_call_id(metafile_t *mf) { if (mf->db_id > 0) return; + if (!mf->call_id) + return; MYSQL_BIND b[1]; - my_str(&b[0], mf->call_id); + my_cstr(&b[0], mf->call_id); execute_wrap(&stm_insert_call, b, &mf->db_id); } +static void db_do_call_metadata(metafile_t *mf) { + if (!mf->metadata) + return; + if (mf->db_id <= 0) + return; + + 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(&all_meta, mf->metadata); + while (all_meta.len > 1) { + str token; + if (str_token(&token, &all_meta, '|')) { + // separator not found, use remainder as token + token = all_meta; + all_meta.len = 0; + } + str key; + if (str_token(&key, &token, ':')) { + // key:value separator not found, skip + continue; + } + + my_str(&b[1], &key); + my_str(&b[2], &token); + + execute_wrap(&stm_insert_metadata, b, NULL); + } + + mf->metadata = NULL; +} + +void db_do_call(metafile_t *mf) { + if (check_conn()) + return; + + db_do_call_id(mf); + db_do_call_metadata(mf); +} void db_do_stream(metafile_t *mf, output_t *op, const char *type, unsigned int id, unsigned long ssrc) { @@ -173,12 +225,12 @@ void db_do_stream(metafile_t *mf, output_t *op, const char *type, unsigned int i MYSQL_BIND b[9]; my_ull(&b[0], &mf->db_id); - my_str(&b[1], op->file_name); - my_str(&b[2], op->file_format); - my_str(&b[3], op->full_filename); - my_str(&b[4], op->file_format); - my_str(&b[5], op->file_format); - my_str(&b[6], type); + my_cstr(&b[1], op->file_name); + my_cstr(&b[2], op->file_format); + my_cstr(&b[3], op->full_filename); + my_cstr(&b[4], op->file_format); + my_cstr(&b[5], op->file_format); + my_cstr(&b[6], type); b[7] = (MYSQL_BIND) { .buffer_type = MYSQL_TYPE_LONG, .buffer = &id, diff --git a/recording-daemon/metafile.c b/recording-daemon/metafile.c index 03e2d10ac..2d21892fa 100644 --- a/recording-daemon/metafile.c +++ b/recording-daemon/metafile.c @@ -94,6 +94,13 @@ static void meta_rtp_payload_type(metafile_t *mf, unsigned long mnum, unsigned i } +// mf is locked +static void meta_metadata(metafile_t *mf, char *content) { + mf->metadata = g_string_chunk_insert(mf->gsc, content); + db_do_call(mf); +} + + // mf is locked static void meta_section(metafile_t *mf, char *section, char *content, unsigned long len) { unsigned long lu; @@ -103,6 +110,8 @@ static void meta_section(metafile_t *mf, char *section, char *content, unsigned mf->call_id = g_string_chunk_insert(mf->gsc, content); else if (!strcmp(section, "PARENT")) mf->parent = g_string_chunk_insert(mf->gsc, content); + else if (!strcmp(section, "METADATA")) + meta_metadata(mf, content); else if (sscanf_match(section, "STREAM %lu interface", &lu) == 1) meta_stream_interface(mf, lu, content); else if (sscanf_match(section, "STREAM %lu details", &lu) == 1) diff --git a/recording-daemon/types.h b/recording-daemon/types.h index c84f82ea2..e387ce42b 100644 --- a/recording-daemon/types.h +++ b/recording-daemon/types.h @@ -88,6 +88,7 @@ struct metafile_s { char *name; char *parent; char *call_id; + char *metadata; off_t pos; unsigned long long db_id;