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.h b/daemon/call.h index 9103b2e7c..19835906b 100644 --- a/daemon/call.h +++ b/daemon/call.h @@ -375,6 +375,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 da5b6c628..40f35b6ae 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -845,6 +845,22 @@ stats: ng_stats(bencode_dictionary_add_dictionary(dict, "RTCP"), &totals->totals[1], NULL); } +void ng_list_calls( struct callmaster *m, bencode_item_t *output, long long int limit) { + GHashTableIter iter; + gpointer key, value; + + rwlock_lock_r(&m->hashlock); + + 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); + } + + 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 +880,21 @@ 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; + long long int limit; + + limit = bencode_dictionary_get_integer(input, "limit", 32); + + 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; +} 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";