Asterisk - The Open Source Telephony Project GIT-master-7921072
Data Structures | Functions | Variables
parking_manager.c File Reference

Call Parking Manager Actions and Events. More...

#include "asterisk.h"
#include "res_parking.h"
#include "asterisk/config.h"
#include "asterisk/config_options.h"
#include "asterisk/utils.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/astobj2.h"
#include "asterisk/features.h"
#include "asterisk/manager.h"
#include "asterisk/bridge.h"
Include dependency graph for parking_manager.c:

Go to the source code of this file.

Data Structures

struct  park_list_data
 

Functions

int load_parking_manager (void)
 Register manager actions and setup subscriptions for stasis events. More...
 
static int manager_append_event_parking_lot_data_cb (void *obj, void *arg, void *data, int flags)
 
static struct ast_strmanager_build_parked_call_string (const struct ast_parked_call_payload *payload)
 Builds a manager string based on the contents of a parked call payload. More...
 
static int manager_park (struct mansession *s, const struct message *m)
 
static void manager_park_bridged (struct mansession *s, const struct message *m, struct ast_channel *chan, struct ast_channel *parker_chan, const char *parkinglot, int timeout_override)
 
static void manager_park_unbridged (struct mansession *s, const struct message *m, struct ast_channel *chan, const char *parkinglot, int timeout_override)
 
static int manager_parking_lot_list (struct mansession *s, const struct message *m)
 
static int manager_parking_status (struct mansession *s, const struct message *m)
 
static void manager_parking_status_all_lots (struct mansession *s, const struct message *m, const char *id_text)
 
static void manager_parking_status_single_lot (struct mansession *s, const struct message *m, const char *id_text, const char *lot_name)
 
static void parked_call_message_response (struct ast_parked_call_payload *parked_call)
 
static struct ast_parked_call_payloadparked_call_payload_from_failure (struct ast_channel *chan)
 
static struct ast_parked_call_payloadparked_call_payload_from_parked_user (struct parked_user *pu, enum ast_parked_call_event_type event_type)
 
static void parking_event_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void parking_manager_disable_stasis (void)
 
static void parking_manager_enable_stasis (void)
 
void publish_parked_call (struct parked_user *pu, enum ast_parked_call_event_type event_type)
 Publish a stasis parked call message for a given parked user. More...
 
void publish_parked_call_failure (struct ast_channel *parkee)
 Publish a stasis parked call message for the channel indicating failure to park. More...
 
void unload_parking_manager (void)
 Unregister manager actions and remove subscriptions for stasis events. More...
 

Variables

static struct stasis_subscriptionparking_sub
 subscription to the parking lot topic More...
 

Detailed Description

Call Parking Manager Actions and Events.

Author
Jonathan Rose jrose.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file parking_manager.c.

Function Documentation

◆ load_parking_manager()

int load_parking_manager ( void  )

Register manager actions and setup subscriptions for stasis events.

Since
12.0.0

Definition at line 704 of file parking_manager.c.

705{
706 int res;
707
712 return res ? -1 : 0;
713}
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
#define EVENT_FLAG_CALL
Definition: manager.h:76
static int manager_park(struct mansession *s, const struct message *m)
static void parking_manager_enable_stasis(void)
static int manager_parking_status(struct mansession *s, const struct message *m)
static int manager_parking_lot_list(struct mansession *s, const struct message *m)

References ast_manager_register_xml, EVENT_FLAG_CALL, manager_park(), manager_parking_lot_list(), manager_parking_status(), and parking_manager_enable_stasis().

Referenced by load_module().

◆ manager_append_event_parking_lot_data_cb()

static int manager_append_event_parking_lot_data_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 402 of file parking_manager.c.

403{
404 struct parking_lot *curlot = obj;
405 struct mansession *s = arg;
406 struct park_list_data *list_data = data;
407
408 astman_append(s, "Event: Parkinglot\r\n"
409 "%s" /* The Action ID */
410 "Name: %s\r\n"
411 "StartSpace: %d\r\n"
412 "StopSpace: %d\r\n"
413 "Timeout: %u\r\n"
414 "\r\n",
415 list_data->id_text,
416 curlot->name,
417 curlot->cfg->parking_start,
418 curlot->cfg->parking_stop,
419 curlot->cfg->parkingtime);
420 ++list_data->count;
421
422 return 0;
423}
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3302
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:1777
const char * id_text
unsigned int parkingtime
Definition: res_parking.h:69
struct parking_lot_cfg * cfg
Definition: res_parking.h:96
const ast_string_field name
Definition: res_parking.h:102

References astman_append(), parking_lot::cfg, park_list_data::count, park_list_data::id_text, parking_lot::name, parking_lot_cfg::parking_start, parking_lot_cfg::parking_stop, and parking_lot_cfg::parkingtime.

Referenced by manager_parking_lot_list().

◆ manager_build_parked_call_string()

static struct ast_str * manager_build_parked_call_string ( const struct ast_parked_call_payload payload)
static

Builds a manager string based on the contents of a parked call payload.

Definition at line 220 of file parking_manager.c.

221{
222 struct ast_str *out = ast_str_create(1024);
223 RAII_VAR(struct ast_str *, parkee_string, NULL, ast_free);
224 RAII_VAR(struct ast_str *, retriever_string, NULL, ast_free);
225
226 if (!out) {
227 return NULL;
228 }
229
230 parkee_string = ast_manager_build_channel_state_string_prefix(payload->parkee, "Parkee");
231 if (!parkee_string) {
232 ast_free(out);
233 return NULL;
234 }
235
236 if (payload->retriever) {
237 retriever_string = ast_manager_build_channel_state_string_prefix(payload->retriever, "Retriever");
238 if (!retriever_string) {
239 ast_free(out);
240 return NULL;
241 }
242 }
243
244 ast_str_set(&out, 0,
245 "%s" /* parkee channel state */
246 "%s" /* retriever channel state (when available) */
247 "ParkerDialString: %s\r\n"
248 "Parkinglot: %s\r\n"
249 "ParkingSpace: %u\r\n"
250 "ParkingTimeout: %lu\r\n"
251 "ParkingDuration: %lu\r\n",
252
253 ast_str_buffer(parkee_string),
254 retriever_string ? ast_str_buffer(retriever_string) : "",
255 payload->parker_dial_string,
256 payload->parkinglot,
257 payload->parkingspace,
258 payload->timeout,
259 payload->duration);
260
261 return out;
262}
#define ast_free(a)
Definition: astmm.h:180
struct ast_str * ast_manager_build_channel_state_string_prefix(const struct ast_channel_snapshot *snapshot, const char *prefix)
Generate the AMI message body from a channel snapshot.
#define NULL
Definition: resample.c:96
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
unsigned int parkingspace
Definition: parking.h:65
long unsigned int duration
Definition: parking.h:64
const ast_string_field parkinglot
Definition: parking.h:69
struct ast_channel_snapshot * retriever
Definition: parking.h:61
long unsigned int timeout
Definition: parking.h:63
struct ast_channel_snapshot * parkee
Definition: parking.h:60
const ast_string_field parker_dial_string
Definition: parking.h:69
Support for dynamic strings.
Definition: strings.h:623
FILE * out
Definition: utils/frame.c:33
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ast_free, ast_manager_build_channel_state_string_prefix(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_parked_call_payload::duration, NULL, out, ast_parked_call_payload::parkee, ast_parked_call_payload::parker_dial_string, ast_parked_call_payload::parkinglot, ast_parked_call_payload::parkingspace, RAII_VAR, ast_parked_call_payload::retriever, and ast_parked_call_payload::timeout.

Referenced by manager_parking_status_all_lots(), manager_parking_status_single_lot(), and parked_call_message_response().

◆ manager_park()

static int manager_park ( struct mansession s,
const struct message m 
)
static

Definition at line 524 of file parking_manager.c.

525{
526 const char *channel = astman_get_header(m, "Channel");
527 const char *timeout_channel = S_OR(astman_get_header(m, "TimeoutChannel"), astman_get_header(m, "Channel2"));
528 const char *announce_channel = astman_get_header(m, "AnnounceChannel");
529 const char *timeout = astman_get_header(m, "Timeout");
530 const char *parkinglot = astman_get_header(m, "Parkinglot");
531 const char *parkingspace = astman_get_header(m, "ParkingSpace");
532 char buf[BUFSIZ];
533 int timeout_override = -1;
534
535 RAII_VAR(struct ast_channel *, parker_chan, NULL, ao2_cleanup);
536 RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
537
538 if (ast_strlen_zero(channel)) {
539 astman_send_error(s, m, "Channel not specified");
540 return 0;
541 }
542
543 if (!ast_strlen_zero(timeout)) {
544 if (sscanf(timeout, "%30d", &timeout_override) != 1 || timeout_override < 0) {
545 astman_send_error(s, m, "Invalid Timeout value.");
546 return 0;
547 }
548
549 if (timeout_override) {
550 /* If greater than zero, convert to seconds for internal use. Must be >= 1 second. */
551 timeout_override = MAX(1, timeout_override / 1000);
552 }
553 }
554
555 if (!(chan = ast_channel_get_by_name(channel))) {
556 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
557 astman_send_error(s, m, buf);
558 return 0;
559 }
560
561 if (!ast_strlen_zero(timeout_channel)) {
562 ast_channel_lock(chan);
563 ast_bridge_set_transfer_variables(chan, timeout_channel, 0);
564 ast_channel_unlock(chan);
565 }
566
567 if (!ast_strlen_zero(parkingspace)) {
568 pbx_builtin_setvar_helper(chan, "PARKINGEXTEN", parkingspace);
569 }
570
571 parker_chan = ast_channel_bridge_peer(chan);
572 if (!parker_chan || strcmp(ast_channel_name(parker_chan), timeout_channel)) {
573 if (!ast_strlen_zero(announce_channel)) {
574 struct ast_channel *announce_chan = ast_channel_get_by_name(announce_channel);
575 if (!announce_channel) {
576 astman_send_error(s, m, "AnnounceChannel does not exist");
577 return 0;
578 }
579
580 create_parked_subscription(announce_chan, ast_channel_uniqueid(chan), 0);
581 ast_channel_cleanup(announce_chan);
582 }
583
584 manager_park_unbridged(s, m, chan, parkinglot, timeout_override);
585 return 0;
586 }
587
588 if (!ast_strlen_zero(announce_channel) && strcmp(announce_channel, timeout_channel)) {
589 /* When using an announce_channel in bridge mode, only add the announce channel if it isn't
590 * the same as the timeout channel (which will play announcements anyway) */
591 struct ast_channel *announce_chan = ast_channel_get_by_name(announce_channel);
592 if (!announce_channel) {
593 astman_send_error(s, m, "AnnounceChannel does not exist");
594 return 0;
595 }
596
597 create_parked_subscription(announce_chan, ast_channel_uniqueid(chan), 0);
598 ast_channel_cleanup(announce_chan);
599 }
600
601 manager_park_bridged(s, m, chan, parker_chan, parkinglot, timeout_override);
602 return 0;
603}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
void ast_bridge_set_transfer_variables(struct ast_channel *chan, const char *value, int is_attended)
Set the relevant transfer variables for a single channel.
Definition: bridge.c:4352
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: channel.c:10563
#define ast_channel_lock(chan)
Definition: channel.h:2922
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define ast_channel_unlock(chan)
Definition: channel.h:2923
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3381
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3042
int create_parked_subscription(struct ast_channel *chan, const char *parkee_uuid, int hangup_after)
Create a parking announcement subscription.
static void manager_park_bridged(struct mansession *s, const struct message *m, struct ast_channel *chan, struct ast_channel *parker_chan, const char *parkinglot, int timeout_override)
static void manager_park_unbridged(struct mansession *s, const struct message *m, struct ast_channel *chan, const char *parkinglot, int timeout_override)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Main Channel structure associated with a channel.
const ast_string_field parkinglot
#define MAX(a, b)
Definition: utils.h:233

References ao2_cleanup, ast_bridge_set_transfer_variables(), ast_channel_bridge_peer(), ast_channel_cleanup, ast_channel_get_by_name(), ast_channel_lock, ast_channel_name(), ast_channel_uniqueid(), ast_channel_unlock, ast_strlen_zero(), astman_get_header(), astman_send_error(), buf, ast_bridge_channel::chan, create_parked_subscription(), manager_park_bridged(), manager_park_unbridged(), MAX, NULL, ast_channel::parkinglot, pbx_builtin_setvar_helper(), RAII_VAR, and S_OR.

Referenced by load_parking_manager().

◆ manager_park_bridged()

static void manager_park_bridged ( struct mansession s,
const struct message m,
struct ast_channel chan,
struct ast_channel parker_chan,
const char *  parkinglot,
int  timeout_override 
)
static

Definition at line 478 of file parking_manager.c.

481{
482 struct ast_bridge_channel *bridge_channel;
483 char *app_data;
484
485 if (timeout_override != -1) {
486 if (ast_asprintf(&app_data, "%s,t(%d)", parkinglot, timeout_override) == -1) {
487 astman_send_error(s, m, "Park action failed\n");
488 return;
489 }
490 } else {
491 if (ast_asprintf(&app_data, "%s", parkinglot) == -1) {
492 astman_send_error(s, m, "Park action failed\n");
493 return;
494 }
495 }
496
497 ast_channel_lock(parker_chan);
498 bridge_channel = ast_channel_get_bridge_channel(parker_chan);
499 ast_channel_unlock(parker_chan);
500
501 if (!bridge_channel) {
503 astman_send_error(s, m, "Park action failed\n");
504 return;
505 }
506
507 /* Subscribe to park messages for the channel being parked */
510 astman_send_error(s, m, "Park action failed\n");
511 ao2_cleanup(bridge_channel);
512 return;
513 }
514
516 ast_channel_uniqueid(parker_chan), app_data);
517
519
520 astman_send_ack(s, m, "Park successful\n");
521 ao2_cleanup(bridge_channel);
522}
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
int ast_bridge_channel_write_park(struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
Have a bridge channel park a channel in the bridge.
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10581
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3413
Structure that contains information regarding a channel in a bridge.
struct ast_channel * chan

References ao2_cleanup, ast_asprintf, ast_bridge_channel_write_park(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_uniqueid(), ast_channel_unlock, ast_free, astman_send_ack(), astman_send_error(), ast_bridge_channel::chan, and create_parked_subscription().

Referenced by manager_park().

◆ manager_park_unbridged()

static void manager_park_unbridged ( struct mansession s,
const struct message m,
struct ast_channel chan,
const char *  parkinglot,
int  timeout_override 
)
static

Definition at line 457 of file parking_manager.c.

459{
460 struct ast_bridge *parking_bridge = park_common_setup(chan,
461 chan, parkinglot, NULL, 0, 0, timeout_override, 1);
462
463 if (!parking_bridge) {
464 astman_send_error(s, m, "Park action failed\n");
465 return;
466 }
467
468 if (ast_bridge_add_channel(parking_bridge, chan, NULL, 0, NULL)) {
469 astman_send_error(s, m, "Park action failed\n");
470 ao2_cleanup(parking_bridge);
471 return;
472 }
473
474 astman_send_ack(s, m, "Park successful\n");
475 ao2_cleanup(parking_bridge);
476}
int ast_bridge_add_channel(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_bridge_features *features, int play_tone, const char *xfersound)
Add an arbitrary channel to a bridge.
Definition: bridge.c:2471
struct ast_bridge * park_common_setup(struct ast_channel *parkee, struct ast_channel *parker, const char *lot_name, const char *comeback_override, int use_ringing, int randomize, int time_limit, int silence_announcements)
Setup a parked call on a parking bridge without needing to parse appdata.
Structure that contains information about a bridge.
Definition: bridge.h:349

References ao2_cleanup, ast_bridge_add_channel(), astman_send_ack(), astman_send_error(), NULL, and park_common_setup().

Referenced by manager_park().

◆ manager_parking_lot_list()

static int manager_parking_lot_list ( struct mansession s,
const struct message m 
)
static

Definition at line 425 of file parking_manager.c.

426{
427 const char *id = astman_get_header(m, "ActionID");
428 struct ao2_container *lot_container;
429 char id_text[256];
430 struct park_list_data list_data;
431
432 id_text[0] = '\0';
433 if (!ast_strlen_zero(id)) {
434 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
435 }
436
437 lot_container = get_parking_lot_container();
438 if (!lot_container) {
439 ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
440 astman_send_error(s, m, "Could not create parking lot list");
441 return 0;
442 }
443
444 astman_send_listack(s, m, "Parking lots will follow", "start");
445
446 list_data.id_text = id_text;
447 list_data.count = 0;
450
451 astman_send_list_complete_start(s, m, "ParkinglotsComplete", list_data.count);
453
454 return 0;
455}
#define ast_log
Definition: astobj2.c:42
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1723
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3423
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3459
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3467
#define LOG_ERROR
static int manager_append_event_parking_lot_data_cb(void *obj, void *arg, void *data, int flags)
struct ao2_container * get_parking_lot_container(void)
Get a pointer to the parking lot container for purposes such as iteration.
Definition: res_parking.c:597
Generic container type.

References ao2_callback_data, ast_log, ast_strlen_zero(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), park_list_data::count, get_parking_lot_container(), park_list_data::id_text, LOG_ERROR, manager_append_event_parking_lot_data_cb(), OBJ_MULTIPLE, and OBJ_NODATA.

Referenced by load_parking_manager().

◆ manager_parking_status()

static int manager_parking_status ( struct mansession s,
const struct message m 
)
static

Definition at line 377 of file parking_manager.c.

378{
379 const char *id = astman_get_header(m, "ActionID");
380 const char *lot_name = astman_get_header(m, "ParkingLot");
381 char id_text[256];
382
383 id_text[0] = '\0';
384 if (!ast_strlen_zero(id)) {
385 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
386 }
387
388 if (!ast_strlen_zero(lot_name)) {
389 manager_parking_status_single_lot(s, m, id_text, lot_name);
390 } else {
391 manager_parking_status_all_lots(s, m, id_text);
392 }
393
394 return 0;
395}
static void manager_parking_status_single_lot(struct mansession *s, const struct message *m, const char *id_text, const char *lot_name)
static void manager_parking_status_all_lots(struct mansession *s, const struct message *m, const char *id_text)

References ast_strlen_zero(), astman_get_header(), manager_parking_status_all_lots(), and manager_parking_status_single_lot().

Referenced by load_parking_manager().

◆ manager_parking_status_all_lots()

static void manager_parking_status_all_lots ( struct mansession s,
const struct message m,
const char *  id_text 
)
static

Definition at line 314 of file parking_manager.c.

315{
316 struct parked_user *curuser;
317 struct ao2_container *lot_container;
318 struct ao2_iterator iter_lots;
319 struct ao2_iterator iter_users;
320 struct parking_lot *curlot;
321 int total = 0;
322
323 lot_container = get_parking_lot_container();
324 if (!lot_container) {
325 ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
326 astman_send_error(s, m, "Could not create parking lot list");
327 return;
328 }
329
330 astman_send_listack(s, m, "Parked calls will follow", "start");
331
332 iter_lots = ao2_iterator_init(lot_container, 0);
333 while ((curlot = ao2_iterator_next(&iter_lots))) {
334 iter_users = ao2_iterator_init(curlot->parked_users, 0);
335 while ((curuser = ao2_iterator_next(&iter_users))) {
337 RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
338
340 if (!payload) {
341 ao2_ref(curuser, -1);
342 ao2_iterator_destroy(&iter_users);
343 ao2_ref(curlot, -1);
344 goto abort_list;
345 }
346
347 parked_call_string = manager_build_parked_call_string(payload);
348 if (!parked_call_string) {
349 ao2_ref(curuser, -1);
350 ao2_iterator_destroy(&iter_users);
351 ao2_ref(curlot, -1);
352 goto abort_list;
353 }
354
355 total++;
356
357 astman_append(s, "Event: ParkedCall\r\n"
358 "%s" /* The parked call string */
359 "%s" /* The action ID */
360 "\r\n",
361 ast_str_buffer(parked_call_string),
362 id_text);
363
364 ao2_ref(curuser, -1);
365 }
366 ao2_iterator_destroy(&iter_users);
367 ao2_ref(curlot, -1);
368 }
369abort_list:
370 ao2_iterator_destroy(&iter_lots);
371
372 astman_send_list_complete_start(s, m, "ParkedCallsComplete", total);
373 astman_append(s, "Total: %d\r\n", total);
375}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ PARKED_CALL
Definition: parking.h:47
static struct ast_str * manager_build_parked_call_string(const struct ast_parked_call_payload *payload)
Builds a manager string based on the contents of a parked call payload.
static struct ast_parked_call_payload * parked_call_payload_from_parked_user(struct parked_user *pu, enum ast_parked_call_event_type event_type)
static int total
Definition: res_adsi.c:970
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
A parked call message payload.
Definition: parking.h:59
struct ao2_container * parked_users
Definition: res_parking.h:95

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_free, ast_log, ast_str_buffer(), astman_append(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), get_parking_lot_container(), LOG_ERROR, manager_build_parked_call_string(), NULL, PARKED_CALL, parked_call_payload_from_parked_user(), parking_lot::parked_users, RAII_VAR, and total.

Referenced by manager_parking_status().

◆ manager_parking_status_single_lot()

static void manager_parking_status_single_lot ( struct mansession s,
const struct message m,
const char *  id_text,
const char *  lot_name 
)
static

Definition at line 264 of file parking_manager.c.

265{
266 RAII_VAR(struct parking_lot *, curlot, NULL, ao2_cleanup);
267 struct parked_user *curuser;
268 struct ao2_iterator iter_users;
269 int total = 0;
270
271 curlot = parking_lot_find_by_name(lot_name);
272 if (!curlot) {
273 astman_send_error(s, m, "Requested parking lot could not be found.");
274 return;
275 }
276
277 astman_send_listack(s, m, "Parked calls will follow", "start");
278
279 iter_users = ao2_iterator_init(curlot->parked_users, 0);
280 while ((curuser = ao2_iterator_next(&iter_users))) {
282 RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
283
285 if (!payload) {
286 ao2_ref(curuser, -1);
287 break;
288 }
289
290 parked_call_string = manager_build_parked_call_string(payload);
291 if (!parked_call_string) {
292 ao2_ref(curuser, -1);
293 break;
294 }
295
296 total++;
297
298 astman_append(s, "Event: ParkedCall\r\n"
299 "%s" /* The parked call string */
300 "%s" /* The action ID */
301 "\r\n",
302 ast_str_buffer(parked_call_string),
303 id_text);
304
305 ao2_ref(curuser, -1);
306 }
307 ao2_iterator_destroy(&iter_users);
308
309 astman_send_list_complete_start(s, m, "ParkedCallsComplete", total);
310 astman_append(s, "Total: %d\r\n", total);
312}
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
Definition: res_parking.c:602

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_free, ast_str_buffer(), astman_append(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), manager_build_parked_call_string(), NULL, PARKED_CALL, parked_call_payload_from_parked_user(), parking_lot_find_by_name(), RAII_VAR, and total.

Referenced by manager_parking_status().

◆ parked_call_message_response()

static void parked_call_message_response ( struct ast_parked_call_payload parked_call)
static

Definition at line 649 of file parking_manager.c.

650{
651 char *event_type = "";
652 RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
653
654 switch (parked_call->event_type) {
655 case PARKED_CALL:
656 event_type = "ParkedCall";
657 break;
659 event_type = "ParkedCallTimeOut";
660 break;
662 event_type = "ParkedCallGiveUp";
663 break;
665 event_type = "UnParkedCall";
666 break;
667 case PARKED_CALL_SWAP:
668 event_type = "ParkedCallSwap";
669 break;
671 /* PARKED_CALL_FAILED doesn't currently get a message and is used exclusively for bridging */
672 return;
673 }
674
675 parked_call_string = manager_build_parked_call_string(parked_call);
676 if (!parked_call_string) {
677 ast_log(LOG_ERROR, "Failed to issue an AMI event of '%s' in response to a stasis message.\n", event_type);
678 return;
679 }
680
681 manager_event(EVENT_FLAG_CALL, event_type,
682 "%s",
683 ast_str_buffer(parked_call_string)
684 );
685}
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
@ PARKED_CALL_TIMEOUT
Definition: parking.h:48
@ PARKED_CALL_UNPARKED
Definition: parking.h:50
@ PARKED_CALL_FAILED
Definition: parking.h:51
@ PARKED_CALL_GIVEUP
Definition: parking.h:49
@ PARKED_CALL_SWAP
Definition: parking.h:52
enum ast_parked_call_event_type event_type
Definition: parking.h:62

References ast_free, ast_log, ast_str_buffer(), EVENT_FLAG_CALL, ast_parked_call_payload::event_type, LOG_ERROR, manager_build_parked_call_string(), manager_event, NULL, PARKED_CALL, PARKED_CALL_FAILED, PARKED_CALL_GIVEUP, PARKED_CALL_SWAP, PARKED_CALL_TIMEOUT, PARKED_CALL_UNPARKED, and RAII_VAR.

Referenced by parking_event_cb().

◆ parked_call_payload_from_failure()

static struct ast_parked_call_payload * parked_call_payload_from_failure ( struct ast_channel chan)
static

Definition at line 183 of file parking_manager.c.

184{
185 RAII_VAR(struct ast_channel_snapshot *, parkee_snapshot, NULL, ao2_cleanup);
186
187 ast_channel_lock(chan);
188 parkee_snapshot = ast_channel_snapshot_create(chan);
189 ast_channel_unlock(chan);
190 if (!parkee_snapshot) {
191 return NULL;
192 }
193
194 return ast_parked_call_payload_create(PARKED_CALL_FAILED, parkee_snapshot, NULL, NULL, NULL, 0, 0, 0);
195}
struct ast_channel_snapshot * ast_channel_snapshot_create(struct ast_channel *chan)
Generate a snapshot of the channel state. This is an ao2 object, so ao2_cleanup() to deallocate.
struct ast_parked_call_payload * ast_parked_call_payload_create(enum ast_parked_call_event_type event_type, struct ast_channel_snapshot *parkee_snapshot, const char *parker_dial_string, struct ast_channel_snapshot *retriever_snapshot, const char *parkinglot, unsigned int parkingspace, unsigned long int timeout, unsigned long int duration)
Constructor for parked_call_payload objects.
Definition: parking.c:82
Structure representing a snapshot of channel state.

References ao2_cleanup, ast_channel_lock, ast_channel_snapshot_create(), ast_channel_unlock, ast_parked_call_payload_create(), NULL, PARKED_CALL_FAILED, and RAII_VAR.

Referenced by publish_parked_call_failure().

◆ parked_call_payload_from_parked_user()

static struct ast_parked_call_payload * parked_call_payload_from_parked_user ( struct parked_user pu,
enum ast_parked_call_event_type  event_type 
)
static

Definition at line 197 of file parking_manager.c.

198{
199 RAII_VAR(struct ast_channel_snapshot *, parkee_snapshot, NULL, ao2_cleanup);
200 long int timeout;
201 long int duration;
202 struct timeval now = ast_tvnow();
203 const char *lot_name = pu->lot->name;
204
206 parkee_snapshot = ast_channel_snapshot_create(pu->chan);
208 if (!parkee_snapshot) {
209 return NULL;
210 }
211
212 timeout = pu->start.tv_sec + (long) pu->time_limit - now.tv_sec;
213 duration = now.tv_sec - pu->start.tv_sec;
214
215 return ast_parked_call_payload_create(event_type, parkee_snapshot, pu->parker_dial_string, pu->retriever, lot_name, pu->parking_space, timeout, duration);
216
217}
char * parker_dial_string
Definition: res_parking.h:111
unsigned int time_limit
Definition: res_parking.h:112
int parking_space
Definition: res_parking.h:109
struct ast_channel * chan
Definition: res_parking.h:106
struct parking_lot * lot
Definition: res_parking.h:113
struct ast_channel_snapshot * retriever
Definition: res_parking.h:107
struct timeval start
Definition: res_parking.h:108
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ao2_cleanup, ast_channel_lock, ast_channel_snapshot_create(), ast_channel_unlock, ast_parked_call_payload_create(), ast_tvnow(), parked_user::chan, ast_parked_call_payload::duration, parked_user::lot, parking_lot::name, NULL, parked_user::parker_dial_string, parked_user::parking_space, RAII_VAR, parked_user::retriever, parked_user::start, parked_user::time_limit, and ast_parked_call_payload::timeout.

Referenced by manager_parking_status_all_lots(), manager_parking_status_single_lot(), and publish_parked_call().

◆ parking_event_cb()

static void parking_event_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 687 of file parking_manager.c.

688{
690 struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
691 parked_call_message_response(parked_call_message);
692 }
693}
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
static void parked_call_message_response(struct ast_parked_call_payload *parked_call)
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.

References ast_parked_call_type(), parked_call_message_response(), stasis_message_data(), and stasis_message_type().

Referenced by parking_manager_enable_stasis().

◆ parking_manager_disable_stasis()

static void parking_manager_disable_stasis ( void  )
static

Definition at line 715 of file parking_manager.c.

716{
718}
static struct stasis_subscription * parking_sub
subscription to the parking lot topic
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1134

References parking_sub, and stasis_unsubscribe_and_join().

Referenced by unload_parking_manager().

◆ parking_manager_enable_stasis()

static void parking_manager_enable_stasis ( void  )
static

Definition at line 695 of file parking_manager.c.

696{
697 if (!parking_sub) {
701 }
702}
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
static void parking_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
Definition: stasis.h:297
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1023
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1077
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:649

References ast_parked_call_type(), ast_parking_topic(), NULL, parking_event_cb(), parking_sub, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, and stasis_subscription_set_filter().

Referenced by load_parking_manager().

◆ publish_parked_call()

void publish_parked_call ( struct parked_user pu,
enum ast_parked_call_event_type  event_type 
)

Publish a stasis parked call message for a given parked user.

Since
12.0.0
Parameters
pupointer to a parked_user that we are generating the message for
event_typeWhat parked call event type is provoking this message

Definition at line 627 of file parking_manager.c.

628{
630 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
631
632 if (!ast_parked_call_type()) {
633 return;
634 }
635
636 payload = parked_call_payload_from_parked_user(pu, event_type);
637 if (!payload) {
638 return;
639 }
640
642 if (!msg) {
643 return;
644 }
645
647}
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511

References ao2_cleanup, ast_parked_call_type(), ast_parking_topic(), NULL, parked_call_payload_from_parked_user(), RAII_VAR, stasis_message_create(), and stasis_publish().

Referenced by bridge_parking_pull(), and bridge_parking_push().

◆ publish_parked_call_failure()

void publish_parked_call_failure ( struct ast_channel parkee)

Publish a stasis parked call message for the channel indicating failure to park.

Since
12.0.0
Parameters
parkeechannel belonging to the failed parkee

Definition at line 605 of file parking_manager.c.

606{
608 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
609
610 if (!ast_parked_call_type()) {
611 return;
612 }
613
614 payload = parked_call_payload_from_failure(parkee);
615 if (!payload) {
616 return;
617 }
618
620 if (!msg) {
621 return;
622 }
623
625}
static struct ast_parked_call_payload * parked_call_payload_from_failure(struct ast_channel *chan)

References ao2_cleanup, ast_parked_call_type(), ast_parking_topic(), NULL, parked_call_payload_from_failure(), RAII_VAR, stasis_message_create(), and stasis_publish().

Referenced by bridge_parking_push(), park_app_exec(), and parking_park_bridge_channel().

◆ unload_parking_manager()

void unload_parking_manager ( void  )

Unregister manager actions and remove subscriptions for stasis events.

Since
12.0.0

Definition at line 720 of file parking_manager.c.

721{
722 ast_manager_unregister("Parkinglots");
723 ast_manager_unregister("ParkedCalls");
726}
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8041
static void parking_manager_disable_stasis(void)

References ast_manager_unregister(), and parking_manager_disable_stasis().

Referenced by unload_module().

Variable Documentation

◆ parking_sub

struct stasis_subscription* parking_sub
static

subscription to the parking lot topic

Definition at line 181 of file parking_manager.c.

Referenced by parking_manager_disable_stasis(), and parking_manager_enable_stasis().