Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 271517) +++ apps/app_queue.c (working copy) @@ -539,6 +539,24 @@ + + + Set Queue Parameters + + + + + + + + + + + + + Set Queue dynamic parameters. Useful after an asterisk restart + + Add interface to queue. @@ -565,8 +583,24 @@ + Set dynamic parameters for a Queue member. Useful after an asterisk restart. + + + Set Queue Member statistical info + + + + + + + + + + + + Makes a queue member temporarily unavailable. @@ -1020,6 +1054,8 @@ static void update_realtime_members(struct call_queue *q); static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused); +static int set_member_stats(const char *queuename, const char *interface, const char *callstaken, const char *lastcall); +static int set_queue_params(const char *queuename, const char *calls, const char *holdtime, const char *talktime, const char *completed, const char *abandoned, const char *servicelevel); static void queue_transfer_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan); /*! \brief sets the QUEUESTATUS channel variable */ @@ -4936,6 +4972,38 @@ ast_db_del(pm_family, pm_queue->name); } +static int set_queue_params(const char *queuename, const char *calls, const char *holdtime, const char *talktime, const char *completed, const char *abandoned, const char *servicelevel) +{ + int foundqueue = 0; + struct call_queue *q; + struct ao2_iterator queue_iter; + + queue_iter = ao2_iterator_init(queues, 0); + while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) { + ao2_lock(q); + if (queuename && !strcasecmp(q->name, queuename)) { + foundqueue++; + if (calls) q->count = atoi(calls); + if (holdtime) q->holdtime = atoi(holdtime); + if (talktime) q->talktime = atoi(talktime); + if (completed) q->callscompleted = atoi(completed); + if (abandoned) q->callsabandoned = atoi(abandoned); + if (servicelevel) q->servicelevel = atoi(servicelevel); + } + ao2_unlock(q); + queue_t_unref(q, "Done with iterator"); + } + ao2_iterator_destroy(&queue_iter); + + if (foundqueue) { + return RESULT_SUCCESS; + } else { + ast_log (LOG_ERROR, "Invalid queue\n"); + } + return RESULT_FAILURE; +} + + /*! \brief Remove member from queue * \retval RES_NOT_DYNAMIC when they aren't a RT member * \retval RES_NOSUCHQUEUE queue does not exist @@ -5124,6 +5192,47 @@ return found ? RESULT_SUCCESS : RESULT_FAILURE; } +/* \brief Sets members stats. */ +static int set_member_stats(const char *queuename, const char *interface, const char *callstaken, const char *lastcall) +{ + int foundinterface = 0, foundqueue = 0; + struct call_queue *q; + struct member *mem; + struct ao2_iterator queue_iter; + + if (callstaken && atoi(callstaken) < 0) { + ast_log(LOG_ERROR, "Invalid callstaken value (%s)\n", callstaken); + return RESULT_FAILURE; + } + + queue_iter = ao2_iterator_init(queues, 0); + while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) { + ao2_lock(q); + if (queuename && !strcasecmp(q->name, queuename)) { + foundqueue++; + if ((mem = interface_exists(q, interface))) { + foundinterface++; + if (callstaken) mem->calls = atoi(callstaken); + if (lastcall) mem->lastcall = (time_t) atoi(lastcall); + ao2_ref(mem, -1); + } + } + ao2_unlock(q); + queue_t_unref(q, "Done with iterator"); + } + ao2_iterator_destroy(&queue_iter); + + if (foundinterface) { + return RESULT_SUCCESS; + } else if (!foundqueue) { + ast_log (LOG_ERROR, "Invalid queuename\n"); + } else { + ast_log (LOG_ERROR, "Invalid interface\n"); + } + + return RESULT_FAILURE; +} + /* \brief Sets members penalty, if queuename=NULL we set member penalty in all the queues. */ static int set_member_penalty(const char *queuename, const char *interface, int penalty) { @@ -7026,6 +7135,32 @@ return RESULT_SUCCESS; } +/*! \brief Set various Queue parameters via AMI */ +static int manager_queue_params(struct mansession *s, const struct message *m) +{ + const char *queuename, *calls, *holdtime, *talktime, *completed, *abandoned, *servicelevel; + + queuename = astman_get_header(m, "Queue"); + calls = astman_get_header(m, "Calls"); + holdtime = astman_get_header(m, "Holdtime"); + talktime = astman_get_header(m, "Talktime"); + completed = astman_get_header(m, "Completed"); + abandoned = astman_get_header(m, "Abandoned"); + servicelevel = astman_get_header(m, "ServiceLevel"); + + if (ast_strlen_zero(queuename)) { + astman_send_error(s, m, "Need 'Queue' parameter."); + return 0; + } + + if (set_queue_params(queuename, calls, holdtime, talktime, completed, abandoned, servicelevel)) { + astman_send_error(s, m, "Queue not found"); + } else { + astman_send_ack(s, m, "Queue Params set successfully"); + } + return 0; +} + static int manager_add_queue_member(struct mansession *s, const struct message *m) { const char *queuename, *interface, *penalty_s, *paused_s, *membername, *state_interface; @@ -7135,6 +7270,34 @@ return 0; } +/*! \brief Set various Queue Member call parameters via AMI */ +static int manager_queue_member(struct mansession *s, const struct message *m) +{ + const char *queuename, *interface, *callstaken, *lastcall, *paused; + + queuename = astman_get_header(m, "Queue"); + interface = astman_get_header(m, "Interface"); + paused = astman_get_header(m, "Paused"); + callstaken = astman_get_header(m, "CallsTaken"); + lastcall = astman_get_header(m, "LastCall"); + + if (ast_strlen_zero(queuename) || ast_strlen_zero(interface) || ast_strlen_zero(paused)) { + astman_send_error(s, m, "Need 'Queue', 'Interface' and 'Paused' parameters."); + return 0; + } + + if (set_member_paused(queuename, interface, NULL, atoi(paused))) { + astman_send_error(s, m, "Interface not found"); + return 0; + } + if (set_member_stats(queuename, interface, callstaken, lastcall)) { + astman_send_error(s, m, "Interface not found"); + return 0; + } + astman_send_ack(s, m, "Queue Member Params set successfully"); + return 0; +} + static int manager_queue_log_custom(struct mansession *s, const struct message *m) { const char *queuename, *event, *message, *interface, *uniqueid; @@ -8093,9 +8256,11 @@ res |= ast_manager_register_xml("Queues", 0, manager_queues_show); res |= ast_manager_register_xml("QueueStatus", 0, manager_queues_status); res |= ast_manager_register_xml("QueueSummary", 0, manager_queues_summary); + res |= ast_manager_register_xml("QueueParams", EVENT_FLAG_AGENT, manager_queue_params); res |= ast_manager_register_xml("QueueAdd", EVENT_FLAG_AGENT, manager_add_queue_member); res |= ast_manager_register_xml("QueueRemove", EVENT_FLAG_AGENT, manager_remove_queue_member); res |= ast_manager_register_xml("QueuePause", EVENT_FLAG_AGENT, manager_pause_queue_member); + res |= ast_manager_register_xml("QueueMember", EVENT_FLAG_AGENT, manager_queue_member); res |= ast_manager_register_xml("QueueLog", EVENT_FLAG_AGENT, manager_queue_log_custom); res |= ast_manager_register_xml("QueuePenalty", EVENT_FLAG_AGENT, manager_queue_member_penalty); res |= ast_manager_register_xml("QueueRule", 0, manager_queue_rule_show); Index: doc/manager_1_1.txt =================================================================== --- doc/manager_1_1.txt (revision 271517) +++ doc/manager_1_1.txt (working copy) @@ -244,6 +244,30 @@ Variables: Queuename: The name of the queue on which to reset statistics +- Action: QueueParams + Modules: app_queue + Purpose: + Set Queue Parameters + Variables: + Queue: The name of the queue on which to set parameters + Calls: + Holdtime: + Talktime: + Completed: + Abandoned: + ServiceLevel: + +- Action: QueueMember + Modules: app_queue + Purpose: + Set Queue Member Parameters + Variables: + Queue: The name of the queue + Interface: The name of the Interface + CallsTaken: + LastCall: + Paused: + - Action: SKINNYdevices Modules: chan_skinny Purpose: