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; }