From a51db7172bbe07b3524825f0c11445af9153cbc0 Mon Sep 17 00:00:00 2001 From: Camille Oudot Date: Thu, 17 Jul 2014 11:51:00 +0200 Subject: [PATCH 1/2] new command: 'list' to retreive the list of active call-ids --- daemon/call.h | 1 + daemon/call_interfaces.c | 26 ++++++++++++++++++++++++++ daemon/control_ng.c | 2 ++ 3 files changed, 29 insertions(+) diff --git a/daemon/call.h b/daemon/call.h index fe451b3bf..379a3b8fc 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -369,6 +369,7 @@ const char *call_offer_ng(bencode_item_t *, struct callmaster *, bencode_item_t const char *call_answer_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); const char *call_delete_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); const char *call_query_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); +const char *call_list_ng(bencode_item_t *, struct callmaster *, bencode_item_t *); void calls_dump_redis(struct callmaster *); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index ec62ddfc0..ebfbb5c7a 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -845,6 +845,21 @@ stats: ng_stats(bencode_dictionary_add_dictionary(dict, "RTCP"), &totals->totals[1], NULL); } +void ng_list_add_call(gpointer key, gpointer value, gpointer user_data) { + + bencode_item_t *output = (bencode_item_t *) user_data; + + bencode_list_add_str(output, key); +} + +void ng_list_calls( struct callmaster *m, bencode_item_t *output) { + rwlock_lock_r(&m->hashlock); + g_hash_table_foreach (m->callhash, ng_list_add_call, output); + rwlock_unlock_r(&m->hashlock); +} + + + const char *call_query_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { str callid, fromtag, totag; struct call *call; @@ -864,3 +879,14 @@ const char *call_query_ng(bencode_item_t *input, struct callmaster *m, bencode_i return NULL; } + + +const char *call_list_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { + bencode_item_t *calls = NULL; + + bencode_dictionary_add_string(output, "result", "ok"); + calls = bencode_dictionary_add_list(output, "calls"); + ng_list_calls(m, calls); + + return NULL; +} diff --git a/daemon/control_ng.c b/daemon/control_ng.c index 2c22a0536..8e9696d3f 100644 --- a/daemon/control_ng.c +++ b/daemon/control_ng.c @@ -117,6 +117,8 @@ static void control_ng_incoming(struct obj *obj, str *buf, struct sockaddr_in6 * errstr = call_delete_ng(dict, c->callmaster, resp); else if (!str_cmp(&cmd, "query")) errstr = call_query_ng(dict, c->callmaster, resp); + else if (!str_cmp(&cmd, "list")) + errstr = call_list_ng(dict, c->callmaster, resp); else errstr = "Unrecognized command"; From 81d8616d4cd24d6682a2bc91ce486f35acd2eda3 Mon Sep 17 00:00:00 2001 From: Camille Oudot Date: Tue, 29 Jul 2014 16:58:04 +0200 Subject: [PATCH 2/2] list command: several fixes + documentation * duplicate strings when filling the bencode structure * limit the number of results to avoid going over the UDP packet size limit --- README.md | 11 +++++++++++ daemon/bencode.h | 14 ++++++++++++++ daemon/call_interfaces.c | 34 +++++++++++++++++++++------------- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a0c899017..3a6f2ed2e 100644 --- a/README.md +++ b/README.md @@ -701,6 +701,17 @@ of zero or more strings. The following flags are defined: The reply message may contain additional keys with statistics about the deleted call. Those additional keys are the same as used in the `query` reply. +`list` Message +---------------- + +The `list` command retrieves the list of currently active call-ids. This list is limited to 32 elements by +default. + +* `limit` + + Optional integer value that specifies the maximum number of results (default: 32). Must be > 0. Be + careful when setting big values, as the response may not fit in a UDP packet, and therefore be invalid. + `query` Message --------------- diff --git a/daemon/bencode.h b/daemon/bencode.h index fb5e91379..7c469ec6c 100644 --- a/daemon/bencode.h +++ b/daemon/bencode.h @@ -154,7 +154,9 @@ bencode_item_t *bencode_list_add(bencode_item_t *list, bencode_item_t *item); /* Convenience function to add the respective (newly created) objects to a list */ INLINE bencode_item_t *bencode_list_add_string(bencode_item_t *list, const char *s); +INLINE bencode_item_t *bencode_list_add_string_dup(bencode_item_t *list, const char *s); INLINE bencode_item_t *bencode_list_add_str(bencode_item_t *list, const str *s); +INLINE bencode_item_t *bencode_list_add_str_dup(bencode_item_t *list, const str *s); INLINE bencode_item_t *bencode_list_add_list(bencode_item_t *list); INLINE bencode_item_t *bencode_list_add_dictionary(bencode_item_t *list); @@ -442,10 +444,22 @@ INLINE bencode_item_t *bencode_list_add_string(bencode_item_t *list, const char return bencode_list_add(list, bencode_string(bencode_item_buffer(list), s)); } +INLINE bencode_item_t *bencode_list_add_string_dup(bencode_item_t *list, const char *s) { + if (!s) + return NULL; + return bencode_list_add(list, bencode_string_dup(bencode_item_buffer(list), s)); +} + INLINE bencode_item_t *bencode_list_add_str(bencode_item_t *list, const str *s) { return bencode_list_add(list, bencode_str(bencode_item_buffer(list), s)); } +INLINE bencode_item_t *bencode_list_add_str_dup(bencode_item_t *list, const str *s) { + if (!s) + return NULL; + return bencode_list_add(list, bencode_str_dup(bencode_item_buffer(list), s)); +} + INLINE bencode_item_t *bencode_list_add_list(bencode_item_t *list) { return bencode_list_add(list, bencode_list(bencode_item_buffer(list))); } diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index ebfbb5c7a..31222dd87 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -845,17 +845,18 @@ stats: ng_stats(bencode_dictionary_add_dictionary(dict, "RTCP"), &totals->totals[1], NULL); } -void ng_list_add_call(gpointer key, gpointer value, gpointer user_data) { +void ng_list_calls( struct callmaster *m, bencode_item_t *output, long long int limit) { + GHashTableIter iter; + gpointer key, value; - bencode_item_t *output = (bencode_item_t *) user_data; + rwlock_lock_r(&m->hashlock); - bencode_list_add_str(output, key); -} + g_hash_table_iter_init (&iter, m->callhash); + while (limit-- && g_hash_table_iter_next (&iter, &key, &value)) { + bencode_list_add_str_dup(output, key); + } -void ng_list_calls( struct callmaster *m, bencode_item_t *output) { - rwlock_lock_r(&m->hashlock); - g_hash_table_foreach (m->callhash, ng_list_add_call, output); - rwlock_unlock_r(&m->hashlock); + rwlock_unlock_r(&m->hashlock); } @@ -882,11 +883,18 @@ const char *call_query_ng(bencode_item_t *input, struct callmaster *m, bencode_i const char *call_list_ng(bencode_item_t *input, struct callmaster *m, bencode_item_t *output) { - bencode_item_t *calls = NULL; + bencode_item_t *calls = NULL; + long long int limit; - bencode_dictionary_add_string(output, "result", "ok"); - calls = bencode_dictionary_add_list(output, "calls"); - ng_list_calls(m, calls); + limit = bencode_dictionary_get_integer(input, "limit", 32); - return NULL; + if (limit < 0) { + return "invalid limit, must be >= 0"; + } + bencode_dictionary_add_string(output, "result", "ok"); + calls = bencode_dictionary_add_list(output, "calls"); + + ng_list_calls(m, calls, limit); + + return NULL; }