summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--apps/app_agent_pool.c9
-rw-r--r--apps/app_confbridge.c16
-rw-r--r--apps/app_meetme.c17
-rw-r--r--apps/app_queue.c33
-rw-r--r--apps/app_voicemail.c18
-rw-r--r--channels/chan_dahdi.c32
-rw-r--r--channels/chan_iax2.c61
-rw-r--r--channels/chan_sip.c35
-rw-r--r--channels/chan_skinny.c30
-rw-r--r--include/asterisk/manager.h53
-rw-r--r--main/bridge.c11
-rw-r--r--main/db.c13
-rw-r--r--main/manager.c58
-rw-r--r--main/manager_bridges.c66
-rw-r--r--main/pbx.c20
-rw-r--r--res/parking/parking_manager.c76
-rw-r--r--res/res_fax.c17
-rw-r--r--res/res_manager_devicestate.c8
-rw-r--r--res/res_manager_presencestate.c8
-rw-r--r--res/res_mwi_external_ami.c8
-rw-r--r--res/res_pjsip/pjsip_configuration.c16
-rw-r--r--res/res_pjsip_outbound_registration.c33
-rw-r--r--res/res_pjsip_pubsub.c29
-rw-r--r--res/res_pjsip_registrar.c9
25 files changed, 328 insertions, 353 deletions
diff --git a/CHANGES b/CHANGES
index da94f287c..caa673ed0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -98,7 +98,6 @@ res_musiconhold
--- Functionality changes from Asterisk 13.1.0 to Asterisk 13.2.0 ------------
------------------------------------------------------------------------------
-=======
* New 'PJSIP_AOR' and 'PJSIP_CONTACT' dialplan functions have been added which
allow examining PJSIP AORs or contacts from the dialplan.
@@ -145,6 +144,10 @@ AMI
* "Language" (the default spoken language for the channel) is now included in
the standard channel state output for suitable events.
+ * AMI actions that return a list of events have been made to return consistent
+ headers for the action response event starting the list and the list complete
+ event. The AMI version has been bumped to 2.7.0 as a result.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13.0.0 to Asterisk 13.1.0 ------------
------------------------------------------------------------------------------
diff --git a/apps/app_agent_pool.c b/apps/app_agent_pool.c
index ad1745d8d..a36c77143 100644
--- a/apps/app_agent_pool.c
+++ b/apps/app_agent_pool.c
@@ -2525,13 +2525,14 @@ static int action_agents(struct mansession *s, const struct message *m)
struct ao2_iterator iter;
struct agent_pvt *agent;
struct ast_str *out = ast_str_alloca(4096);
+ int num_agents = 0;
if (!ast_strlen_zero(id)) {
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
} else {
id_text[0] = '\0';
}
- astman_send_ack(s, m, "Agents will follow");
+ astman_send_listack(s, m, "Agents will follow", "start");
iter = ao2_iterator_init(agents, 0);
for (; (agent = ao2_iterator_next(&iter)); ao2_ref(agent, -1)) {
@@ -2586,12 +2587,12 @@ static int action_agents(struct mansession *s, const struct message *m)
astman_append(s, "Event: Agents\r\n"
"%s%s\r\n",
ast_str_buffer(out), id_text);
+ ++num_agents;
}
ao2_iterator_destroy(&iter);
- astman_append(s, "Event: AgentsComplete\r\n"
- "%s"
- "\r\n", id_text);
+ astman_send_list_complete_start(s, m, "AgentsComplete", num_agents);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index 8bffb2958..b5d48452d 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -2897,12 +2897,8 @@ static int action_confbridgelist(struct mansession *s, const struct message *m)
ao2_unlock(conference);
ao2_ref(conference, -1);
- astman_append(s,
- "Event: ConfbridgeListComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, id_text);
+ astman_send_list_complete_start(s, m, "ConfbridgeListComplete", total);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -2952,12 +2948,8 @@ static int action_confbridgelistrooms(struct mansession *s, const struct message
ao2_iterator_destroy(&iter);
/* Send final confirmation */
- astman_append(s,
- "Event: ConfbridgeListRoomsComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", totalitems, id_text);
+ astman_send_list_complete_start(s, m, "ConfbridgeListRoomsComplete", totalitems);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index bc30f29be..907770e22 100644
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -5577,13 +5577,10 @@ static int action_meetmelist(struct mansession *s, const struct message *m)
ao2_iterator_destroy(&user_iter);
}
AST_LIST_UNLOCK(&confs);
+
/* Send final confirmation */
- astman_append(s,
- "Event: MeetmeListComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, idText);
+ astman_send_list_complete_start(s, m, "MeetmeListComplete", total);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -5645,12 +5642,8 @@ static int action_meetmelistrooms(struct mansession *s, const struct message *m)
AST_LIST_UNLOCK(&confs);
/* Send final confirmation */
- astman_append(s,
- "Event: MeetmeListRoomsComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", totalitems, idText);
+ astman_send_list_complete_start(s, m, "MeetmeListRoomsComplete", totalitems);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 1cf1f6ad3..d41641c62 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -9462,19 +9462,21 @@ static int manager_queues_summary(struct mansession *s, const struct message *m)
int qmemavail = 0;
int qchancount = 0;
int qlongestholdtime = 0;
+ int qsummaries = 0;
const char *id = astman_get_header(m, "ActionID");
const char *queuefilter = astman_get_header(m, "Queue");
- char idText[256] = "";
+ char idText[256];
struct call_queue *q;
struct queue_ent *qe;
struct member *mem;
struct ao2_iterator queue_iter;
struct ao2_iterator mem_iter;
- astman_send_ack(s, m, "Queue summary will follow");
+ astman_send_listack(s, m, "Queue summary will follow", "start");
time(&now);
+ idText[0] = '\0';
if (!ast_strlen_zero(id)) {
- snprintf(idText, 256, "ActionID: %s\r\n", id);
+ snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
}
queue_iter = ao2_iterator_init(queues, 0);
while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
@@ -9517,15 +9519,15 @@ static int manager_queues_summary(struct mansession *s, const struct message *m)
"%s"
"\r\n",
q->name, qmemcount, qmemavail, qchancount, q->holdtime, q->talktime, qlongestholdtime, idText);
+ ++qsummaries;
}
ao2_unlock(q);
queue_t_unref(q, "Done with iterator");
}
ao2_iterator_destroy(&queue_iter);
- astman_append(s,
- "Event: QueueSummaryComplete\r\n"
- "%s"
- "\r\n", idText);
+
+ astman_send_list_complete_start(s, m, "QueueSummaryComplete", qsummaries);
+ astman_send_list_complete_end(s);
return RESULT_SUCCESS;
}
@@ -9535,10 +9537,11 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
{
time_t now;
int pos;
+ int q_items = 0;
const char *id = astman_get_header(m,"ActionID");
const char *queuefilter = astman_get_header(m,"Queue");
const char *memberfilter = astman_get_header(m,"Member");
- char idText[256] = "";
+ char idText[256];
struct call_queue *q;
struct queue_ent *qe;
float sl = 0;
@@ -9546,8 +9549,9 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
struct ao2_iterator queue_iter;
struct ao2_iterator mem_iter;
- astman_send_ack(s, m, "Queue status will follow");
+ astman_send_listack(s, m, "Queue status will follow", "start");
time(&now);
+ idText[0] = '\0';
if (!ast_strlen_zero(id)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
}
@@ -9575,6 +9579,8 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
"\r\n",
q->name, q->maxlen, int2strat(q->strategy), q->count, q->holdtime, q->talktime, q->callscompleted,
q->callsabandoned, q->servicelevel, sl, q->weight, idText);
+ ++q_items;
+
/* List Queue Members */
mem_iter = ao2_iterator_init(q->members, 0);
while ((mem = ao2_iterator_next(&mem_iter))) {
@@ -9594,10 +9600,12 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
"\r\n",
q->name, mem->membername, mem->interface, mem->state_interface, mem->dynamic ? "dynamic" : "static",
mem->penalty, mem->calls, (int)mem->lastcall, mem->status, mem->paused, idText);
+ ++q_items;
}
ao2_ref(mem, -1);
}
ao2_iterator_destroy(&mem_iter);
+
/* List Queue Entries */
pos = 1;
for (qe = q->head; qe; qe = qe->next) {
@@ -9619,6 +9627,7 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
S_COR(ast_channel_connected(qe->chan)->id.number.valid, ast_channel_connected(qe->chan)->id.number.str, "unknown"),
S_COR(ast_channel_connected(qe->chan)->id.name.valid, ast_channel_connected(qe->chan)->id.name.str, "unknown"),
(long) (now - qe->start), idText);
+ ++q_items;
}
}
ao2_unlock(q);
@@ -9626,10 +9635,8 @@ static int manager_queues_status(struct mansession *s, const struct message *m)
}
ao2_iterator_destroy(&queue_iter);
- astman_append(s,
- "Event: QueueStatusComplete\r\n"
- "%s"
- "\r\n",idText);
+ astman_send_list_complete_start(s, m, "QueueStatusComplete", q_items);
+ astman_send_list_complete_end(s);
return RESULT_SUCCESS;
}
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 8cc7b60d4..6311263a4 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -13049,10 +13049,13 @@ static int manager_list_voicemail_users(struct mansession *s, const struct messa
{
struct ast_vm_user *vmu = NULL;
const char *id = astman_get_header(m, "ActionID");
- char actionid[128] = "";
+ char actionid[128];
+ int num_users = 0;
- if (!ast_strlen_zero(id))
+ actionid[0] = '\0';
+ if (!ast_strlen_zero(id)) {
snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id);
+ }
AST_LIST_LOCK(&users);
@@ -13062,20 +13065,20 @@ static int manager_list_voicemail_users(struct mansession *s, const struct messa
return RESULT_SUCCESS;
}
- astman_send_ack(s, m, "Voicemail user list will follow");
+ astman_send_listack(s, m, "Voicemail user list will follow", "start");
AST_LIST_TRAVERSE(&users, vmu, list) {
char dirname[256];
-
#ifdef IMAP_STORAGE
int new, old;
+
inboxcount(vmu->mailbox, &new, &old);
#endif
make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX");
astman_append(s,
- "%s"
"Event: VoicemailUserEntry\r\n"
+ "%s"
"VMContext: %s\r\n"
"VoiceMailbox: %s\r\n"
"Fullname: %s\r\n"
@@ -13144,8 +13147,11 @@ static int manager_list_voicemail_users(struct mansession *s, const struct messa
count_messages(vmu, dirname)
#endif
);
+ ++num_users;
}
- astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid);
+
+ astman_send_list_complete_start(s, m, "VoicemailUserEntryComplete", num_users);
+ astman_send_list_complete_end(s);
AST_LIST_UNLOCK(&users);
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index bb6bd2d42..10b6295cd 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -16068,7 +16068,7 @@ static int action_dahdishowchannels(struct mansession *s, const struct message *
struct dahdi_pvt *tmp = NULL;
const char *id = astman_get_header(m, "ActionID");
const char *dahdichannel = astman_get_header(m, "DAHDIChannel");
- char idText[256] = "";
+ char idText[256];
int channels = 0;
int dahdichanquery;
@@ -16077,9 +16077,12 @@ static int action_dahdishowchannels(struct mansession *s, const struct message *
dahdichanquery = -1;
}
- astman_send_ack(s, m, "DAHDI channel status will follow");
- if (!ast_strlen_zero(id))
+ idText[0] = '\0';
+ if (!ast_strlen_zero(id)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
+ }
+
+ astman_send_listack(s, m, "DAHDI channel status will follow", "start");
ast_mutex_lock(&iflock);
@@ -16142,13 +16145,9 @@ static int action_dahdishowchannels(struct mansession *s, const struct message *
ast_mutex_unlock(&iflock);
- astman_append(s,
- "Event: DAHDIShowChannelsComplete\r\n"
- "%s"
- "Items: %d\r\n"
- "\r\n",
- idText,
- channels);
+ astman_send_list_complete_start(s, m, "DAHDIShowChannelsComplete", channels);
+ astman_append(s, "Items: %d\r\n", channels);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -16177,7 +16176,7 @@ static int action_prishowspans(struct mansession *s, const struct message *m)
action_id[0] = '\0';
}
- astman_send_ack(s, m, "Span status will follow");
+ astman_send_listack(s, m, "Span status will follow", "start");
count = 0;
for (idx = 0; idx < ARRAY_LEN(pris); ++idx) {
@@ -16194,14 +16193,9 @@ static int action_prishowspans(struct mansession *s, const struct message *m)
}
}
- astman_append(s,
- "Event: %sComplete\r\n"
- "Items: %d\r\n"
- "%s"
- "\r\n",
- show_cmd,
- count,
- action_id);
+ astman_send_list_complete_start(s, m, "PRIShowSpansComplete", count);
+ astman_append(s, "Items: %d\r\n", count);
+ astman_send_list_complete_end(s);
return 0;
}
#endif /* defined(HAVE_PRI) */
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index c01bf5c7a..bb65df460 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -6872,31 +6872,23 @@ static void _iax2_show_peers_one(int fd, struct mansession *s, struct show_peers
}
if (s) {
-
if (cont->peerlist) { /* IAXpeerlist */
-
astman_append(s,
"Event: PeerEntry\r\n%s"
"Channeltype: IAX\r\n",
cont->idtext);
-
if (!ast_strlen_zero(peer->username)) {
-
astman_append(s,
"ObjectName: %s\r\n"
"ObjectUsername: %s\r\n",
peer->name,
peer->username);
-
} else {
-
astman_append(s,
"ObjectName: %s\r\n",
name);
}
-
} else { /* IAXpeers */
-
astman_append(s,
"Event: PeerEntry\r\n%s"
"Channeltype: IAX2\r\n"
@@ -6904,28 +6896,21 @@ static void _iax2_show_peers_one(int fd, struct mansession *s, struct show_peers
cont->idtext,
name);
}
-
astman_append(s,
"ChanObjectType: peer\r\n"
"IPaddress: %s\r\n",
tmp_host);
-
if (cont->peerlist) { /* IAXpeerlist */
-
astman_append(s,
"Mask: %s\r\n"
"Port: %s\r\n",
tmp_mask,
tmp_port);
-
} else { /* IAXpeers */
-
astman_append(s,
"IPport: %s\r\n",
tmp_port);
-
}
-
astman_append(s,
"Dynamic: %s\r\n"
"Trunk: %s\r\n"
@@ -6935,19 +6920,13 @@ static void _iax2_show_peers_one(int fd, struct mansession *s, struct show_peers
ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
peer->encmethods ? ast_str_buffer(encmethods) : "no",
status);
-
if (cont->peerlist) { /* IAXpeerlist */
-
astman_append(s, "\r\n");
-
} else { /* IAXpeers */
-
astman_append(s,
"Description: %s\r\n\r\n",
peer->description);
-
}
-
} else {
ast_cli(fd, PEERS_FORMAT,
name,
@@ -6962,7 +6941,6 @@ static void _iax2_show_peers_one(int fd, struct mansession *s, struct show_peers
}
cont->total_peers++;
-
}
static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
@@ -7275,16 +7253,14 @@ static int manager_iax2_show_peers(struct mansession *s, const struct message *m
snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
astman_send_listack(s, m, "Peer status list will follow", "start");
- /* List the peers in separate manager events */
+
+ /* List the peers in separate manager events */
__iax2_show_peers(-1, &total, s, 3, a);
- /* Send final confirmation */
- astman_append(s,
- "Event: PeerlistComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, idtext);
- return 0;
+
+ /* Send final confirmation */
+ astman_send_list_complete_start(s, m, "PeerlistComplete", total);
+ astman_send_list_complete_end(s);
+ return 0;
}
/*! \brief callback to display iax peers in manager format */
@@ -7312,25 +7288,16 @@ static int manager_iax2_show_peer_list(struct mansession *s, const struct messag
snprintf(cont.idtext, sizeof(cont.idtext), "ActionID: %s\r\n", id);
}
- astman_append(s,
- "Response: Success\r\n"
- "%sMessage: IAX Peer status list will follow\r\n\r\n",
- cont.idtext);
-
+ astman_send_listack(s, m, "IAX Peer status list will follow", "start");
i = ao2_iterator_init(peers, 0);
for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
-
_iax2_show_peers_one(-1, s, &cont, peer);
-
}
ao2_iterator_destroy(&i);
- astman_append(s,
- "Event: PeerlistComplete\r\n"
- "%sListItems: %d\r\n\r\n",
- cont.idtext,
- cont.total_peers);
+ astman_send_list_complete_start(s, m, "PeerlistComplete", cont.total_peers);
+ astman_send_list_complete_end(s);
return RESULT_SUCCESS;
}
@@ -7435,12 +7402,8 @@ static int manager_iax2_show_registry(struct mansession *s, const struct message
}
AST_LIST_UNLOCK(&registrations);
- astman_append(s,
- "Event: RegistrationsComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, idtext);
+ astman_send_list_complete_start(s, m, "RegistrationsComplete", total);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index dd3f2723f..1a0ff94b7 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -19257,12 +19257,8 @@ static int manager_show_registry(struct mansession *s, const struct message *m)
}
ao2_iterator_destroy(&iter);
- astman_append(s,
- "Event: RegistrationsComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, idtext);
+ astman_send_list_complete_start(s, m, "RegistrationsComplete", total);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -19280,15 +19276,13 @@ static int manager_sip_show_peers(struct mansession *s, const struct message *m)
snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
astman_send_listack(s, m, "Peer status list will follow", "start");
+
/* List the peers in separate manager events */
_sip_show_peers(-1, &total, s, m, 3, a);
+
/* Send final confirmation */
- astman_append(s,
- "Event: PeerlistComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, idtext);
+ astman_send_list_complete_start(s, m, "PeerlistComplete", total);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -20051,9 +20045,11 @@ static int manager_sip_peer_status(struct mansession *s, const struct message *m
{
const char *id = astman_get_header(m,"ActionID");
const char *peer_name = astman_get_header(m,"Peer");
- char idText[256] = "";
+ char idText[256];
struct sip_peer *peer = NULL;
+ int num_peers = 0;
+ idText[0] = '\0';
if (!ast_strlen_zero(id)) {
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
}
@@ -20071,15 +20067,17 @@ static int manager_sip_peer_status(struct mansession *s, const struct message *m
}
}
- astman_send_ack(s, m, "Peer status will follow");
+ astman_send_listack(s, m, "Peer status will follow", "start");
if (!peer) {
struct ao2_iterator i = ao2_iterator_init(peers, 0);
+
while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table for SIPpeerstatus"))) {
ao2_lock(peer);
send_manager_peer_status(s, peer, idText);
ao2_unlock(peer);
sip_unref_peer(peer, "unref peer for SIPpeerstatus");
+ ++num_peers;
}
ao2_iterator_destroy(&i);
} else {
@@ -20087,14 +20085,11 @@ static int manager_sip_peer_status(struct mansession *s, const struct message *m
send_manager_peer_status(s, peer, idText);
ao2_unlock(peer);
sip_unref_peer(peer, "unref peer for SIPpeerstatus");
+ ++num_peers;
}
-
- astman_append(s,
- "Event: SIPpeerstatusComplete\r\n"
- "%s"
- "\r\n",
- idText);
+ astman_send_list_complete_start(s, m, "SIPpeerstatusComplete", num_peers);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index b8202d33b..aabac57a3 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -4135,24 +4135,17 @@ static char *_skinny_show_devices(int fd, int *total, struct mansession *s, cons
/* Inspired from chan_sip */
static int manager_skinny_show_devices(struct mansession *s, const struct message *m)
{
- const char *id = astman_get_header(m, "ActionID");
const char *a[] = {"skinny", "show", "devices"};
- char idtext[256] = "";
int total = 0;
- if (!ast_strlen_zero(id))
- snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
-
astman_send_listack(s, m, "Device status list will follow", "start");
+
/* List the devices in separate manager events */
_skinny_show_devices(-1, &total, s, m, 3, a);
+
/* Send final confirmation */
- astman_append(s,
- "Event: DevicelistComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, idtext);
+ astman_send_list_complete_start(s, m, "DevicelistComplete", total);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -4384,24 +4377,17 @@ static char *_skinny_show_lines(int fd, int *total, struct mansession *s, const
/* Inspired from chan_sip */
static int manager_skinny_show_lines(struct mansession *s, const struct message *m)
{
- const char *id = astman_get_header(m, "ActionID");
const char *a[] = {"skinny", "show", "lines"};
- char idtext[256] = "";
int total = 0;
- if (!ast_strlen_zero(id))
- snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
-
astman_send_listack(s, m, "Line status list will follow", "start");
+
/* List the lines in separate manager events */
_skinny_show_lines(-1, &total, s, m, 3, a);
+
/* Send final confirmation */
- astman_append(s,
- "Event: LinelistComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", total, idtext);
+ astman_send_list_complete_start(s, m, "LinelistComplete", total);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h
index 387430fde..31f31b7f0 100644
--- a/include/asterisk/manager.h
+++ b/include/asterisk/manager.h
@@ -54,7 +54,7 @@
- \ref manager.c Main manager code file
*/
-#define AMI_VERSION "2.6.0"
+#define AMI_VERSION "2.7.0"
#define DEFAULT_MANAGER_PORT 5038 /* Default port for Asterisk management via TCP */
#define DEFAULT_MANAGER_TLS_PORT 5039 /* Default port for Asterisk management via TCP */
@@ -299,9 +299,58 @@ void astman_send_response(struct mansession *s, const struct message *m, char *r
/*! \brief Send ack in manager transaction */
void astman_send_ack(struct mansession *s, const struct message *m, char *msg);
-/*! \brief Send ack in manager list transaction */
+/*!
+ * \brief Send ack in manager transaction to begin a list.
+ *
+ * \param s - AMI session control struct.
+ * \param m - AMI action request that started the list.
+ * \param msg - Message contents describing the list to follow.
+ * \param listflag - Not used. Historically always set to "start".
+ *
+ * \note You need to call astman_send_list_complete_start() and
+ * astman_send_list_complete_end() to send the AMI list completion event.
+ *
+ * \return Nothing
+ */
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag);
+/*!
+ * \brief Start the list complete event.
+ * \since 13.2.0
+ *
+ * \param s - AMI session control struct.
+ * \param m - AMI action request that started the list.
+ * \param event_name - AMI list complete event name.
+ * \param count - Number of items in the list.
+ *
+ * \note You need to call astman_send_list_complete_end() to end
+ * the AMI list completion event.
+ *
+ * \note Between calling astman_send_list_complete_start() and
+ * astman_send_list_complete_end() you can add additonal headers
+ * using astman_append().
+ *
+ * \return Nothing
+ */
+void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count);
+
+/*!
+ * \brief End the list complete event.
+ * \since 13.2.0
+ *
+ * \param s - AMI session control struct.
+ *
+ * \note You need to call astman_send_list_complete_start() to start
+ * the AMI list completion event.
+ *
+ * \note Between calling astman_send_list_complete_start() and
+ * astman_send_list_complete_end() you can add additonal headers
+ * using astman_append().
+ *
+ * \return Nothing
+ */
+void astman_send_list_complete_end(struct mansession *s);
+
void __attribute__((format(printf, 2, 3))) astman_append(struct mansession *s, const char *fmt, ...);
/*! \brief Determinie if a manager session ident is authenticated */
diff --git a/main/bridge.c b/main/bridge.c
index 1e746a0f0..6b4778f5d 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -5198,6 +5198,7 @@ static int manager_bridge_tech_list(struct mansession *s, const struct message *
const char *id = astman_get_header(m, "ActionID");
RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free);
struct ast_bridge_technology *cur;
+ int num_items = 0;
if (!id_text) {
astman_send_error(s, m, "Internal error");
@@ -5208,7 +5209,7 @@ static int manager_bridge_tech_list(struct mansession *s, const struct message *
ast_str_set(&id_text, 0, "ActionID: %s\r\n", id);
}
- astman_send_ack(s, m, "Bridge technology listing will follow");
+ astman_send_listack(s, m, "Bridge technology listing will follow", "start");
AST_RWLIST_RDLOCK(&bridge_technologies);
AST_RWLIST_TRAVERSE(&bridge_technologies, cur, entry) {
@@ -5226,14 +5227,12 @@ static int manager_bridge_tech_list(struct mansession *s, const struct message *
"\r\n",
cur->name, type, cur->preference, AST_YESNO(cur->suspended),
ast_str_buffer(id_text));
+ ++num_items;
}
AST_RWLIST_UNLOCK(&bridge_technologies);
- astman_append(s,
- "Event: BridgeTechnologyListComplete\r\n"
- "%s"
- "\r\n",
- ast_str_buffer(id_text));
+ astman_send_list_complete_start(s, m, "BridgeTechnologyListComplete", num_items);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/main/db.c b/main/db.c
index 5a0f17434..4bb9355c6 100644
--- a/main/db.c
+++ b/main/db.c
@@ -841,7 +841,7 @@ static int manager_dbput(struct mansession *s, const struct message *m)
static int manager_dbget(struct mansession *s, const struct message *m)
{
const char *id = astman_get_header(m,"ActionID");
- char idText[256] = "";
+ char idText[256];
const char *family = astman_get_header(m, "Family");
const char *key = astman_get_header(m, "Key");
char tmp[MAX_DB_FIELD];
@@ -856,6 +856,7 @@ static int manager_dbget(struct mansession *s, const struct message *m)
return 0;
}
+ idText[0] = '\0';
if (!ast_strlen_zero(id))
snprintf(idText, sizeof(idText) ,"ActionID: %s\r\n", id);
@@ -863,7 +864,8 @@ static int manager_dbget(struct mansession *s, const struct message *m)
if (res) {
astman_send_error(s, m, "Database entry not found");
} else {
- astman_send_ack(s, m, "Result will follow");
+ astman_send_listack(s, m, "Result will follow", "start");
+
astman_append(s, "Event: DBGetResponse\r\n"
"Family: %s\r\n"
"Key: %s\r\n"
@@ -871,10 +873,9 @@ static int manager_dbget(struct mansession *s, const struct message *m)
"%s"
"\r\n",
family, key, tmp, idText);
- astman_append(s, "Event: DBGetComplete\r\n"
- "%s"
- "\r\n",
- idText);
+
+ astman_send_list_complete_start(s, m, "DBGetComplete", 1);
+ astman_send_list_complete_end(s);
}
return 0;
}
diff --git a/main/manager.c b/main/manager.c
index d599a4bde..4410cd7c5 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -2921,7 +2921,26 @@ static void astman_start_ack(struct mansession *s, const struct message *m)
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
{
- astman_send_response_full(s, m, "Success", msg, listflag);
+ astman_send_response_full(s, m, "Success", msg, "Start");
+}
+
+void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
+{
+ const char *id = astman_get_header(m, "ActionID");
+
+ astman_append(s, "Event: %s\r\n", event_name);
+ if (!ast_strlen_zero(id)) {
+ astman_append(s, "ActionID: %s\r\n", id);
+ }
+ astman_append(s,
+ "EventList: Complete\r\n"
+ "ListItems: %d\r\n",
+ count);
+}
+
+void astman_send_list_complete_end(struct mansession *s)
+{
+ astman_append(s, "\r\n");
}
/*! \brief Lock the 'mansession' structure. */
@@ -3347,7 +3366,7 @@ static int action_getconfig(struct mansession *s, const struct message *m)
}
if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
- astman_append(s, "No categories found\r\n");
+ astman_append(s, "Error: No categories found\r\n");
}
ast_config_destroy(cfg);
@@ -3385,7 +3404,7 @@ static int action_listcategories(struct mansession *s, const struct message *m)
}
if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
- astman_append(s, "Error: no categories found\r\n");
+ astman_append(s, "Error: No categories found\r\n");
}
ast_config_destroy(cfg);
@@ -4214,12 +4233,8 @@ static int action_hangup(struct mansession *s, const struct message *m)
regfree(&regexbuf);
ast_free(regex_string);
- astman_append(s,
- "Event: ChannelsHungupListComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", channels_matched, idText);
+ astman_send_list_complete_start(s, m, "ChannelsHungupListComplete", channels_matched);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -4309,7 +4324,7 @@ static int action_getvar(struct mansession *s, const struct message *m)
return 0;
}
-static void generate_status(struct mansession *s, struct ast_channel *chan, char **vars, int varc, int all_variables, char *id_text)
+static void generate_status(struct mansession *s, struct ast_channel *chan, char **vars, int varc, int all_variables, char *id_text, int *count)
{
struct timeval now;
long elapsed_seconds;
@@ -4339,7 +4354,6 @@ static void generate_status(struct mansession *s, struct ast_channel *chan, char
} else {
variable_str = ast_str_create(1024);
}
-
if (!variable_str) {
return;
}
@@ -4421,6 +4435,7 @@ static void generate_status(struct mansession *s, struct ast_channel *chan, char
(long)elapsed_seconds,
ast_str_buffer(variable_str),
id_text);
+ ++*count;
ao2_cleanup(bridge);
}
@@ -4466,7 +4481,7 @@ static int action_status(struct mansession *s, const struct message *m)
}
}
- astman_send_ack(s, m, "Channel status will follow");
+ astman_send_listack(s, m, "Channel status will follow", "start");
if (!ast_strlen_zero(id)) {
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
@@ -4482,8 +4497,7 @@ static int action_status(struct mansession *s, const struct message *m)
for (; chan; all ? chan = ast_channel_iterator_next(it_chans) : 0) {
ast_channel_lock(chan);
- generate_status(s, chan, vars.name, vars.argc, all_variables, id_text);
- channels++;
+ generate_status(s, chan, vars.name, vars.argc, all_variables, id_text, &channels);
ast_channel_unlock(chan);
chan = ast_channel_unref(chan);
@@ -4493,11 +4507,9 @@ static int action_status(struct mansession *s, const struct message *m)
ast_channel_iterator_destroy(it_chans);
}
- astman_append(s,
- "Event: StatusComplete\r\n"
- "%s"
- "Items: %d\r\n"
- "\r\n", id_text, channels);
+ astman_send_list_complete_start(s, m, "StatusComplete", channels);
+ astman_append(s, "Items: %d\r\n", channels);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -5940,12 +5952,8 @@ static int action_coreshowchannels(struct mansession *s, const struct message *m
}
ao2_iterator_destroy(&it_chans);
- astman_append(s,
- "Event: CoreShowChannelsComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
- "%s"
- "\r\n", numchans, idText);
+ astman_send_list_complete_start(s, m, "CoreShowChannelsComplete", numchans);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/main/manager_bridges.c b/main/manager_bridges.c
index 26b0e7882..10a5046d9 100644
--- a/main/manager_bridges.c
+++ b/main/manager_bridges.c
@@ -364,12 +364,17 @@ static int filter_bridge_type_cb(void *obj, void *arg, int flags)
return strcmp(bridge_type, snapshot->technology) ? CMP_MATCH : 0;
}
+struct bridge_list_data {
+ const char *id_text;
+ int count;
+};
+
static int send_bridge_list_item_cb(void *obj, void *arg, void *data, int flags)
{
struct ast_bridge_snapshot *snapshot = stasis_message_data(obj);
struct mansession *s = arg;
- char *id_text = data;
- RAII_VAR(struct ast_str *, bridge_info, ast_manager_build_bridge_state_string(snapshot), ast_free_ptr);
+ struct bridge_list_data *list_data = data;
+ RAII_VAR(struct ast_str *, bridge_info, ast_manager_build_bridge_state_string(snapshot), ast_free);
if (!bridge_info) {
return 0;
@@ -380,8 +385,9 @@ static int send_bridge_list_item_cb(void *obj, void *arg, void *data, int flags)
"%s"
"%s"
"\r\n",
- ast_str_buffer(bridge_info),
- id_text);
+ list_data->id_text,
+ ast_str_buffer(bridge_info));
+ ++list_data->count;
return 0;
}
@@ -391,6 +397,7 @@ static int manager_bridges_list(struct mansession *s, const struct message *m)
const char *type_filter = astman_get_header(m, "BridgeType");
RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free);
RAII_VAR(struct ao2_container *, bridges, NULL, ao2_cleanup);
+ struct bridge_list_data list_data;
if (!id_text) {
astman_send_error(s, m, "Internal error");
@@ -407,20 +414,21 @@ static int manager_bridges_list(struct mansession *s, const struct message *m)
return -1;
}
- astman_send_ack(s, m, "Bridge listing will follow");
+ astman_send_listack(s, m, "Bridge listing will follow", "start");
if (!ast_strlen_zero(type_filter)) {
char *type_filter_dup = ast_strdupa(type_filter);
- ao2_callback(bridges, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, filter_bridge_type_cb, type_filter_dup);
+
+ ao2_callback(bridges, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK,
+ filter_bridge_type_cb, type_filter_dup);
}
- ao2_callback_data(bridges, OBJ_NODATA, send_bridge_list_item_cb, s, ast_str_buffer(id_text));
+ list_data.id_text = ast_str_buffer(id_text);
+ list_data.count = 0;
+ ao2_callback_data(bridges, OBJ_NODATA, send_bridge_list_item_cb, s, &list_data);
- astman_append(s,
- "Event: BridgeListComplete\r\n"
- "%s"
- "\r\n",
- ast_str_buffer(id_text));
+ astman_send_list_complete_start(s, m, "BridgeListComplete", list_data.count);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -429,13 +437,13 @@ static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags)
{
char *uniqueid = obj;
struct mansession *s = arg;
- char *id_text = data;
+ struct bridge_list_data *list_data = data;
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
struct ast_channel_snapshot *snapshot;
RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
+
msg = stasis_cache_get(ast_channel_cache(),
ast_channel_snapshot_type(), uniqueid);
-
if (!msg) {
return 0;
}
@@ -455,8 +463,9 @@ static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags)
"%s"
"%s"
"\r\n",
- ast_str_buffer(channel_text),
- id_text);
+ list_data->id_text,
+ ast_str_buffer(channel_text));
+ ++list_data->count;
return 0;
}
@@ -468,6 +477,7 @@ static int manager_bridge_info(struct mansession *s, const struct message *m)
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
RAII_VAR(struct ast_str *, bridge_info, NULL, ast_free);
struct ast_bridge_snapshot *snapshot;
+ struct bridge_list_data list_data;
if (!id_text) {
astman_send_error(s, m, "Internal error");
@@ -489,20 +499,24 @@ static int manager_bridge_info(struct mansession *s, const struct message *m)
return 0;
}
- astman_send_ack(s, m, "Bridge channel listing will follow");
-
snapshot = stasis_message_data(msg);
bridge_info = ast_manager_build_bridge_state_string(snapshot);
+ if (!bridge_info) {
+ astman_send_error(s, m, "Internal error");
+ return -1;
+ }
- ao2_callback_data(snapshot->channels, OBJ_NODATA, send_bridge_info_item_cb, s, ast_str_buffer(id_text));
+ astman_send_listack(s, m, "Bridge channel listing will follow", "start");
- astman_append(s,
- "Event: BridgeInfoComplete\r\n"
- "%s"
- "%s"
- "\r\n",
- S_COR(bridge_info, ast_str_buffer(bridge_info), ""),
- ast_str_buffer(id_text));
+ list_data.id_text = ast_str_buffer(id_text);
+ list_data.count = 0;
+ ao2_callback_data(snapshot->channels, OBJ_NODATA, send_bridge_info_item_cb, s, &list_data);
+
+ astman_send_list_complete_start(s, m, "BridgeInfoComplete", list_data.count);
+ if (!ast_strlen_zero(ast_str_buffer(bridge_info))) {
+ astman_append(s, "%s", ast_str_buffer(bridge_info));
+ }
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/main/pbx.c b/main/pbx.c
index 77590963f..b2c365a9b 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -8333,14 +8333,13 @@ static int manager_show_dialplan(struct mansession *s, const struct message *m)
manager_dpsendack(s, m);
}
- astman_append(s, "Event: ShowDialPlanComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n"
+ astman_send_list_complete_start(s, m, "ShowDialPlanComplete", counters.total_items);
+ astman_append(s,
"ListExtensions: %d\r\n"
"ListPriorities: %d\r\n"
- "ListContexts: %d\r\n"
- "%s"
- "\r\n", counters.total_items, counters.total_exten, counters.total_prio, counters.total_context, idtext);
+ "ListContexts: %d\r\n",
+ counters.total_exten, counters.total_prio, counters.total_context);
+ astman_send_list_complete_end(s);
/* everything ok */
return 0;
@@ -12047,16 +12046,13 @@ static int action_extensionstatelist(struct mansession *s, const struct message
ast_extension_state2str(hint->laststate));
ao2_unlock(hint);
}
- astman_append(s, "Event: ExtensionStateListComplete\r\n");
- if (!ast_strlen_zero(action_id)) {
- astman_append(s, "ActionID: %s\r\n", action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", hint_count);
ao2_iterator_destroy(&it_hints);
ao2_unlock(hints);
+ astman_send_list_complete_start(s, m, "ExtensionStateListComplete", hint_count);
+ astman_send_list_complete_end(s);
+
return 0;
}
diff --git a/res/parking/parking_manager.c b/res/parking/parking_manager.c
index 73b5ff495..74b455928 100644
--- a/res/parking/parking_manager.c
+++ b/res/parking/parking_manager.c
@@ -210,11 +210,16 @@ static struct ast_str *manager_build_parked_call_string(const struct ast_parked_
parkee_string = ast_manager_build_channel_state_string_prefix(payload->parkee, "Parkee");
if (!parkee_string) {
+ ast_free(out);
return NULL;
}
if (payload->retriever) {
retriever_string = ast_manager_build_channel_state_string_prefix(payload->retriever, "Retriever");
+ if (!retriever_string) {
+ ast_free(out);
+ return NULL;
+ }
}
ast_str_set(&out, 0,
@@ -250,7 +255,7 @@ static void manager_parking_status_single_lot(struct mansession *s, const struct
return;
}
- astman_send_ack(s, m, "Parked calls will follow");
+ astman_send_listack(s, m, "Parked calls will follow", "start");
iter_users = ao2_iterator_init(curlot->parked_users, 0);
while ((curuser = ao2_iterator_next(&iter_users))) {
@@ -260,17 +265,13 @@ static void manager_parking_status_single_lot(struct mansession *s, const struct
payload = parked_call_payload_from_parked_user(curuser, PARKED_CALL);
if (!payload) {
ao2_ref(curuser, -1);
- ao2_iterator_destroy(&iter_users);
- astman_send_error(s, m, "Failed to retrieve parking data about a parked user.");
- return;
+ break;
}
parked_call_string = manager_build_parked_call_string(payload);
if (!parked_call_string) {
ao2_ref(curuser, -1);
- ao2_iterator_destroy(&iter_users);
- astman_send_error(s, m, "Failed to retrieve parking data about a parked user.");
- return;
+ break;
}
total++;
@@ -286,12 +287,9 @@ static void manager_parking_status_single_lot(struct mansession *s, const struct
}
ao2_iterator_destroy(&iter_users);
- astman_append(s,
- "Event: ParkedCallsComplete\r\n"
- "Total: %d\r\n"
- "%s"
- "\r\n",
- total, id_text);
+ astman_send_list_complete_start(s, m, "ParkedCallsComplete", total);
+ astman_append(s, "Total: %d\r\n", total);
+ astman_send_list_complete_end(s);
}
static void manager_parking_status_all_lots(struct mansession *s, const struct message *m, const char *id_text)
@@ -310,7 +308,7 @@ static void manager_parking_status_all_lots(struct mansession *s, const struct m
return;
}
- astman_send_ack(s, m, "Parked calls will follow");
+ astman_send_listack(s, m, "Parked calls will follow", "start");
iter_lots = ao2_iterator_init(lot_container, 0);
while ((curlot = ao2_iterator_next(&iter_lots))) {
@@ -324,8 +322,7 @@ static void manager_parking_status_all_lots(struct mansession *s, const struct m
ao2_ref(curuser, -1);
ao2_iterator_destroy(&iter_users);
ao2_ref(curlot, -1);
- ao2_iterator_destroy(&iter_lots);
- return;
+ goto abort_list;
}
parked_call_string = manager_build_parked_call_string(payload);
@@ -333,8 +330,7 @@ static void manager_parking_status_all_lots(struct mansession *s, const struct m
ao2_ref(curuser, -1);
ao2_iterator_destroy(&iter_users);
ao2_ref(curlot, -1);
- ao2_iterator_destroy(&iter_lots);
- return;
+ goto abort_list;
}
total++;
@@ -351,22 +347,21 @@ static void manager_parking_status_all_lots(struct mansession *s, const struct m
ao2_iterator_destroy(&iter_users);
ao2_ref(curlot, -1);
}
+abort_list:
ao2_iterator_destroy(&iter_lots);
- astman_append(s,
- "Event: ParkedCallsComplete\r\n"
- "Total: %d\r\n"
- "%s"
- "\r\n",
- total, id_text);
+ astman_send_list_complete_start(s, m, "ParkedCallsComplete", total);
+ astman_append(s, "Total: %d\r\n", total);
+ astman_send_list_complete_end(s);
}
static int manager_parking_status(struct mansession *s, const struct message *m)
{
const char *id = astman_get_header(m, "ActionID");
const char *lot_name = astman_get_header(m, "ParkingLot");
- char id_text[256] = "";
+ char id_text[256];
+ id_text[0] = '\0';
if (!ast_strlen_zero(id)) {
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
}
@@ -380,24 +375,30 @@ static int manager_parking_status(struct mansession *s, const struct message *m)
return 0;
}
+struct park_list_data {
+ const char *id_text;
+ int count;
+};
+
static int manager_append_event_parking_lot_data_cb(void *obj, void *arg, void *data, int flags)
{
struct parking_lot *curlot = obj;
struct mansession *s = arg;
- char *id_text = data;
+ struct park_list_data *list_data = data;
astman_append(s, "Event: Parkinglot\r\n"
+ "%s" /* The Action ID */
"Name: %s\r\n"
"StartSpace: %d\r\n"
"StopSpace: %d\r\n"
"Timeout: %u\r\n"
- "%s" /* The Action ID */
"\r\n",
+ list_data->id_text,
curlot->name,
curlot->cfg->parking_start,
curlot->cfg->parking_stop,
- curlot->cfg->parkingtime,
- id_text);
+ curlot->cfg->parkingtime);
+ ++list_data->count;
return 0;
}
@@ -405,9 +406,11 @@ static int manager_append_event_parking_lot_data_cb(void *obj, void *arg, void *
static int manager_parking_lot_list(struct mansession *s, const struct message *m)
{
const char *id = astman_get_header(m, "ActionID");
- char id_text[256] = "";
struct ao2_container *lot_container;
+ char id_text[256];
+ struct park_list_data list_data;
+ id_text[0] = '\0';
if (!ast_strlen_zero(id)) {
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
}
@@ -419,14 +422,15 @@ static int manager_parking_lot_list(struct mansession *s, const struct message *
return 0;
}
- astman_send_ack(s, m, "Parking lots will follow");
+ astman_send_listack(s, m, "Parking lots will follow", "start");
- ao2_callback_data(lot_container, OBJ_MULTIPLE | OBJ_NODATA, manager_append_event_parking_lot_data_cb, s, id_text);
+ list_data.id_text = id_text;
+ list_data.count = 0;
+ ao2_callback_data(lot_container, OBJ_MULTIPLE | OBJ_NODATA,
+ manager_append_event_parking_lot_data_cb, s, &list_data);
- astman_append(s,
- "Event: ParkinglotsComplete\r\n"
- "%s"
- "\r\n",id_text);
+ astman_send_list_complete_start(s, m, "ParkinglotsComplete", list_data.count);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/res/res_fax.c b/res/res_fax.c
index b5e5411ee..5f2798ab4 100644
--- a/res/res_fax.c
+++ b/res/res_fax.c
@@ -4190,17 +4190,18 @@ static int manager_fax_sessions_entry(struct mansession *s,
static int manager_fax_sessions(struct mansession *s, const struct message *m)
{
const char *action_id = astman_get_header(m, "ActionID");
- char id_text[256] = "";
+ char id_text[256];
struct ast_fax_session *session;
struct ao2_iterator iter;
int session_count = 0;
- astman_send_listack(s, m, "FAXSessionsEntry event list will follow", "Start");
-
+ id_text[0] = '\0';
if (!ast_strlen_zero(action_id)) {
snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", action_id);
}
+ astman_send_listack(s, m, "FAXSessionsEntry event list will follow", "Start");
+
iter = ao2_iterator_init(faxregistry.container, 0);
while ((session = ao2_iterator_next(&iter))) {
if (!manager_fax_sessions_entry(s, session, id_text)) {
@@ -4210,13 +4211,9 @@ static int manager_fax_sessions(struct mansession *s, const struct message *m)
}
ao2_iterator_destroy(&iter);
- astman_append(s, "Event: FAXSessionsComplete\r\n"
- "%s"
- "EventList: Complete\r\n"
- "Total: %d\r\n"
- "\r\n",
- id_text,
- session_count);
+ astman_send_list_complete_start(s, m, "FAXSessionsComplete", session_count);
+ astman_append(s, "Total: %d\r\n", session_count);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/res/res_manager_devicestate.c b/res/res_manager_devicestate.c
index 25eae87d7..3d1f1ab10 100644
--- a/res/res_manager_devicestate.c
+++ b/res/res_manager_devicestate.c
@@ -106,12 +106,8 @@ static int action_devicestatelist(struct mansession *s, const struct message *m)
}
ao2_iterator_destroy(&it_states);
- astman_append(s, "Event: DeviceStateListComplete\r\n");
- if (!ast_strlen_zero(action_id)) {
- astman_append(s, "ActionID: %s\r\n", action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", count);
+ astman_send_list_complete_start(s, m, "DeviceStateListComplete", count);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/res/res_manager_presencestate.c b/res/res_manager_presencestate.c
index e2cfca506..bb9e63ab9 100644
--- a/res/res_manager_presencestate.c
+++ b/res/res_manager_presencestate.c
@@ -106,12 +106,8 @@ static int action_presencestatelist(struct mansession *s, const struct message *
}
ao2_iterator_destroy(&it_states);
- astman_append(s, "Event: PresenceStateListComplete\r\n");
- if (!ast_strlen_zero(action_id)) {
- astman_append(s, "ActionID: %s\r\n", action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", count);
+ astman_send_list_complete_start(s, m, "PresenceStateListComplete", count);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/res/res_mwi_external_ami.c b/res/res_mwi_external_ami.c
index b1360e9e3..87ce411e6 100644
--- a/res/res_mwi_external_ami.c
+++ b/res/res_mwi_external_ami.c
@@ -226,12 +226,8 @@ static int mwi_mailbox_get(struct mansession *s, const struct message *m)
ao2_iterator_destroy(&iter);
ao2_ref(mailboxes, -1);
- astman_append(s,
- "Event: MWIGetComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %u\r\n"
- "%s"
- "\r\n", count, id_text);
+ astman_send_list_complete_start(s, m, "MWIGetComplete", count);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index f5c777b35..4dcc7afb1 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1172,12 +1172,8 @@ static int ami_show_endpoint(struct mansession *s, const struct message *m)
endpoint_name);
}
- astman_append(s, "Event: EndpointDetailComplete\r\n");
- if (!ast_strlen_zero(ami.action_id)) {
- astman_append(s, "ActionID: %s\r\n", ami.action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", ami.count + 1);
+ astman_send_list_complete_start(s, m, "EndpointDetailComplete", ami.count + 1);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -1255,12 +1251,8 @@ static int ami_show_endpoints(struct mansession *s, const struct message *m)
ao2_callback(endpoints, OBJ_NODATA, format_ami_endpoints, &ami);
- astman_append(s, "Event: EndpointListComplete\r\n");
- if (!ast_strlen_zero(ami.action_id)) {
- astman_append(s, "ActionID: %s\r\n", ami.action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", num);
+ astman_send_list_complete_start(s, m, "EndpointListComplete", num);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index b2e9bb045..3a01a9426 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -1367,10 +1367,10 @@ struct sip_ami_outbound {
static int ami_outbound_registration_task(void *obj)
{
struct sip_ami_outbound *ami = obj;
- RAII_VAR(struct ast_str *, buf,
- ast_sip_create_ami_event("OutboundRegistrationDetail", ami->ami), ast_free);
+ RAII_VAR(struct ast_str *, buf, NULL, ast_free);
struct sip_outbound_registration_state *state;
+ buf = ast_sip_create_ami_event("OutboundRegistrationDetail", ami->ami);
if (!buf) {
return -1;
}
@@ -1379,18 +1379,18 @@ static int ami_outbound_registration_task(void *obj)
if ((state = get_state(ast_sorcery_object_get_id(ami->registration)))) {
pjsip_regc_info info;
+
if (state->client_state->status == SIP_REGISTRATION_REGISTERED) {
++ami->registered;
} else {
++ami->not_registered;
}
- ast_str_append(&buf, 0, "Status: %s%s",
- sip_outbound_registration_status_str[
- state->client_state->status], "\r\n");
+ ast_str_append(&buf, 0, "Status: %s\r\n",
+ sip_outbound_registration_status_str[state->client_state->status]);
pjsip_regc_get_info(state->client_state->client, &info);
- ast_str_append(&buf, 0, "NextReg: %d%s", info.next_reg, "\r\n");
+ ast_str_append(&buf, 0, "NextReg: %d\r\n", info.next_reg);
ao2_ref(state, -1);
}
@@ -1420,20 +1420,19 @@ static int ami_show_outbound_registrations(struct mansession *s,
return -1;
}
- astman_send_listack(s, m, "Following are Events for each Outbound "
- "registration", "start");
+ astman_send_listack(s, m, "Following are Events for each Outbound registration",
+ "start");
ao2_callback(regs, OBJ_NODATA, ami_outbound_registration_detail, &ami_outbound);
- astman_append(s, "Event: OutboundRegistrationDetailComplete\r\n");
- if (!ast_strlen_zero(ami.action_id)) {
- astman_append(s, "ActionID: %s\r\n", ami.action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "Registered: %d\r\n"
- "NotRegistered: %d\r\n\r\n",
- ami_outbound.registered,
- ami_outbound.not_registered);
+ astman_send_list_complete_start(s, m, "OutboundRegistrationDetailComplete",
+ ami_outbound.registered + ami_outbound.not_registered);
+ astman_append(s,
+ "Registered: %d\r\n"
+ "NotRegistered: %d\r\n",
+ ami_outbound.registered,
+ ami_outbound.not_registered);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index 23f04bb04..f143fa015 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -3232,15 +3232,16 @@ static int ami_subscription_detail(struct sip_subscription_tree *sub_tree,
struct ast_sip_ami *ami,
const char *event)
{
- RAII_VAR(struct ast_str *, buf,
- ast_sip_create_ami_event(event, ami), ast_free);
+ struct ast_str *buf;
+ buf = ast_sip_create_ami_event(event, ami);
if (!buf) {
return -1;
}
sip_subscription_to_ami(sub_tree, &buf);
astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
+ ast_free(buf);
return 0;
}
@@ -3266,12 +3267,8 @@ static int ami_show_subscriptions_inbound(struct mansession *s, const struct mes
num = for_each_subscription(ami_subscription_detail_inbound, &ami);
- astman_append(s, "Event: InboundSubscriptionDetailComplete\r\n");
- if (!ast_strlen_zero(ami.action_id)) {
- astman_append(s, "ActionID: %s\r\n", ami.action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", num);
+ astman_send_list_complete_start(s, m, "InboundSubscriptionDetailComplete", num);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -3285,12 +3282,8 @@ static int ami_show_subscriptions_outbound(struct mansession *s, const struct me
num = for_each_subscription(ami_subscription_detail_outbound, &ami);
- astman_append(s, "Event: OutboundSubscriptionDetailComplete\r\n");
- if (!ast_strlen_zero(ami.action_id)) {
- astman_append(s, "ActionID: %s\r\n", ami.action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", num);
+ astman_send_list_complete_start(s, m, "OutboundSubscriptionDetailComplete", num);
+ astman_send_list_complete_end(s);
return 0;
}
@@ -3317,7 +3310,7 @@ static int format_ami_resource_lists(void *obj, void *arg, int flags)
static int ami_show_resource_lists(struct mansession *s, const struct message *m)
{
- struct ast_sip_ami ami = { .s = s, .m = m };
+ struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
int num;
struct ao2_container *lists;
@@ -3334,10 +3327,8 @@ static int ami_show_resource_lists(struct mansession *s, const struct message *m
ao2_callback(lists, OBJ_NODATA, format_ami_resource_lists, &ami);
- astman_append(s,
- "Event: ResourceListDetailComplete\r\n"
- "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", num);
+ astman_send_list_complete_start(s, m, "ResourceListDetailComplete", num);
+ astman_send_list_complete_end(s);
return 0;
}
diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c
index aad3dd4a7..2e298bd69 100644
--- a/res/res_pjsip_registrar.c
+++ b/res/res_pjsip_registrar.c
@@ -766,17 +766,14 @@ static int ami_show_registrations(struct mansession *s, const struct message *m)
{
int count = 0;
struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
+
astman_send_listack(s, m, "Following are Events for each Inbound "
"registration", "start");
ami_registrations_endpoints(&ami);
- astman_append(s, "Event: InboundRegistrationDetailComplete\r\n");
- if (!ast_strlen_zero(ami.action_id)) {
- astman_append(s, "ActionID: %s\r\n", ami.action_id);
- }
- astman_append(s, "EventList: Complete\r\n"
- "ListItems: %d\r\n\r\n", count);
+ astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count);
+ astman_send_list_complete_end(s);
return 0;
}