Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 728 of file parking_manager.c.

729{
730 int res;
731
736 return res ? -1 : 0;
737}
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:192
#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 426 of file parking_manager.c.

427{
428 struct parking_lot *curlot = obj;
429 struct mansession *s = arg;
430 struct park_list_data *list_data = data;
431
432 astman_append(s, "Event: Parkinglot\r\n"
433 "%s" /* The Action ID */
434 "Name: %s\r\n"
435 "StartSpace: %d\r\n"
436 "StopSpace: %d\r\n"
437 "Timeout: %u\r\n"
438 "\r\n",
439 list_data->id_text,
440 curlot->name,
441 curlot->cfg->parking_start,
442 curlot->cfg->parking_stop,
443 curlot->cfg->parkingtime);
444 ++list_data->count;
445
446 return 0;
447}
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1907
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:327
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 244 of file parking_manager.c.

245{
246 struct ast_str *out = ast_str_create(1024);
247 RAII_VAR(struct ast_str *, parkee_string, NULL, ast_free);
248 RAII_VAR(struct ast_str *, retriever_string, NULL, ast_free);
249
250 if (!out) {
251 return NULL;
252 }
253
254 parkee_string = ast_manager_build_channel_state_string_prefix(payload->parkee, "Parkee");
255 if (!parkee_string) {
256 ast_free(out);
257 return NULL;
258 }
259
260 if (payload->retriever) {
261 retriever_string = ast_manager_build_channel_state_string_prefix(payload->retriever, "Retriever");
262 if (!retriever_string) {
263 ast_free(out);
264 return NULL;
265 }
266 }
267
268 ast_str_set(&out, 0,
269 "%s" /* parkee channel state */
270 "%s" /* retriever channel state (when available) */
271 "ParkerDialString: %s\r\n"
272 "Parkinglot: %s\r\n"
273 "ParkingSpace: %u\r\n"
274 "ParkingTimeout: %lu\r\n"
275 "ParkingDuration: %lu\r\n",
276
277 ast_str_buffer(parkee_string),
278 retriever_string ? ast_str_buffer(retriever_string) : "",
279 payload->parker_dial_string,
280 payload->parkinglot,
281 payload->parkingspace,
282 payload->timeout,
283 payload->duration);
284
285 return out;
286}
#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 548 of file parking_manager.c.

549{
550 const char *channel = astman_get_header(m, "Channel");
551 const char *timeout_channel = S_OR(astman_get_header(m, "TimeoutChannel"), astman_get_header(m, "Channel2"));
552 const char *announce_channel = astman_get_header(m, "AnnounceChannel");
553 const char *timeout = astman_get_header(m, "Timeout");
554 const char *parkinglot = astman_get_header(m, "Parkinglot");
555 const char *parkingspace = astman_get_header(m, "ParkingSpace");
556 char buf[BUFSIZ];
557 int timeout_override = -1;
558
559 RAII_VAR(struct ast_channel *, parker_chan, NULL, ao2_cleanup);
560 RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
561
562 if (ast_strlen_zero(channel)) {
563 astman_send_error(s, m, "Channel not specified");
564 return 0;
565 }
566
567 if (!ast_strlen_zero(timeout)) {
568 if (sscanf(timeout, "%30d", &timeout_override) != 1 || timeout_override < 0) {
569 astman_send_error(s, m, "Invalid Timeout value.");
570 return 0;
571 }
572
573 if (timeout_override) {
574 /* If greater than zero, convert to seconds for internal use. Must be >= 1 second. */
575 timeout_override = MAX(1, timeout_override / 1000);
576 }
577 }
578
579 if (!(chan = ast_channel_get_by_name(channel))) {
580 snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
581 astman_send_error(s, m, buf);
582 return 0;
583 }
584
585 if (!ast_strlen_zero(timeout_channel)) {
586 ast_channel_lock(chan);
587 ast_bridge_set_transfer_variables(chan, timeout_channel, 0);
588 ast_channel_unlock(chan);
589 }
590
591 if (!ast_strlen_zero(parkingspace)) {
592 pbx_builtin_setvar_helper(chan, "PARKINGEXTEN", parkingspace);
593 }
594
595 parker_chan = ast_channel_bridge_peer(chan);
596 if (!parker_chan || strcmp(ast_channel_name(parker_chan), timeout_channel)) {
597 if (!ast_strlen_zero(announce_channel)) {
598 struct ast_channel *announce_chan = ast_channel_get_by_name(announce_channel);
599 if (!announce_channel) {
600 astman_send_error(s, m, "AnnounceChannel does not exist");
601 return 0;
602 }
603
604 create_parked_subscription(announce_chan, ast_channel_uniqueid(chan), 0);
605 ast_channel_cleanup(announce_chan);
606 }
607
608 manager_park_unbridged(s, m, chan, parkinglot, timeout_override);
609 return 0;
610 }
611
612 if (!ast_strlen_zero(announce_channel) && strcmp(announce_channel, timeout_channel)) {
613 /* When using an announce_channel in bridge mode, only add the announce channel if it isn't
614 * the same as the timeout channel (which will play announcements anyway) */
615 struct ast_channel *announce_chan = ast_channel_get_by_name(announce_channel);
616 if (!announce_channel) {
617 astman_send_error(s, m, "AnnounceChannel does not exist");
618 return 0;
619 }
620
621 create_parked_subscription(announce_chan, ast_channel_uniqueid(chan), 0);
622 ast_channel_cleanup(announce_chan);
623 }
624
625 manager_park_bridged(s, m, chan, parker_chan, parkinglot, timeout_override);
626 return 0;
627}
#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:4421
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:10569
#define ast_channel_lock(chan)
Definition: channel.h:2972
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
Definition: channel.c:1397
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:3019
#define ast_channel_unlock(chan)
Definition: channel.h:2973
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:1986
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647
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.
#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, 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 502 of file parking_manager.c.

505{
506 struct ast_bridge_channel *bridge_channel;
507 char *app_data;
508
509 if (timeout_override != -1) {
510 if (ast_asprintf(&app_data, "%s,t(%d)", parkinglot, timeout_override) == -1) {
511 astman_send_error(s, m, "Park action failed\n");
512 return;
513 }
514 } else {
515 if (ast_asprintf(&app_data, "%s", parkinglot) == -1) {
516 astman_send_error(s, m, "Park action failed\n");
517 return;
518 }
519 }
520
521 ast_channel_lock(parker_chan);
522 bridge_channel = ast_channel_get_bridge_channel(parker_chan);
523 ast_channel_unlock(parker_chan);
524
525 if (!bridge_channel) {
527 astman_send_error(s, m, "Park action failed\n");
528 return;
529 }
530
531 /* Subscribe to park messages for the channel being parked */
534 astman_send_error(s, m, "Park action failed\n");
535 ao2_cleanup(bridge_channel);
536 return;
537 }
538
540 ast_channel_uniqueid(parker_chan), app_data);
541
543
544 astman_send_ack(s, m, "Park successful\n");
545 ao2_cleanup(bridge_channel);
546}
#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:10587
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2018
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 481 of file parking_manager.c.

483{
484 struct ast_bridge *parking_bridge = park_common_setup(chan,
485 chan, parkinglot, NULL, 0, 0, timeout_override, 1);
486
487 if (!parking_bridge) {
488 astman_send_error(s, m, "Park action failed\n");
489 return;
490 }
491
492 if (ast_bridge_add_channel(parking_bridge, chan, NULL, 0, NULL)) {
493 astman_send_error(s, m, "Park action failed\n");
494 ao2_cleanup(parking_bridge);
495 return;
496 }
497
498 astman_send_ack(s, m, "Park successful\n");
499 ao2_cleanup(parking_bridge);
500}
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:2540
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:353

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 449 of file parking_manager.c.

450{
451 const char *id = astman_get_header(m, "ActionID");
452 struct ao2_container *lot_container;
453 char id_text[256];
454 struct park_list_data list_data;
455
456 id_text[0] = '\0';
457 if (!ast_strlen_zero(id)) {
458 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
459 }
460
461 lot_container = get_parking_lot_container();
462 if (!lot_container) {
463 ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
464 astman_send_error(s, m, "Could not create parking lot list");
465 return 0;
466 }
467
468 astman_send_listack(s, m, "Parking lots will follow", "start");
469
470 list_data.id_text = id_text;
471 list_data.count = 0;
474
475 astman_send_list_complete_start(s, m, "ParkinglotsComplete", list_data.count);
477
478 return 0;
479}
#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:2028
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:2064
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2072
#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:657
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 401 of file parking_manager.c.

402{
403 const char *id = astman_get_header(m, "ActionID");
404 const char *lot_name = astman_get_header(m, "ParkingLot");
405 char id_text[256];
406
407 id_text[0] = '\0';
408 if (!ast_strlen_zero(id)) {
409 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
410 }
411
412 if (!ast_strlen_zero(lot_name)) {
413 manager_parking_status_single_lot(s, m, id_text, lot_name);
414 } else {
415 manager_parking_status_all_lots(s, m, id_text);
416 }
417
418 return 0;
419}
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 338 of file parking_manager.c.

339{
340 struct parked_user *curuser;
341 struct ao2_container *lot_container;
342 struct ao2_iterator iter_lots;
343 struct ao2_iterator iter_users;
344 struct parking_lot *curlot;
345 int total = 0;
346
347 lot_container = get_parking_lot_container();
348 if (!lot_container) {
349 ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
350 astman_send_error(s, m, "Could not create parking lot list");
351 return;
352 }
353
354 astman_send_listack(s, m, "Parked calls will follow", "start");
355
356 iter_lots = ao2_iterator_init(lot_container, 0);
357 while ((curlot = ao2_iterator_next(&iter_lots))) {
358 iter_users = ao2_iterator_init(curlot->parked_users, 0);
359 while ((curuser = ao2_iterator_next(&iter_users))) {
361 RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
362
364 if (!payload) {
365 ao2_ref(curuser, -1);
366 ao2_iterator_destroy(&iter_users);
367 ao2_ref(curlot, -1);
368 goto abort_list;
369 }
370
371 parked_call_string = manager_build_parked_call_string(payload);
372 if (!parked_call_string) {
373 ao2_ref(curuser, -1);
374 ao2_iterator_destroy(&iter_users);
375 ao2_ref(curlot, -1);
376 goto abort_list;
377 }
378
379 total++;
380
381 astman_append(s, "Event: ParkedCall\r\n"
382 "%s" /* The parked call string */
383 "%s" /* The action ID */
384 "\r\n",
385 ast_str_buffer(parked_call_string),
386 id_text);
387
388 ao2_ref(curuser, -1);
389 }
390 ao2_iterator_destroy(&iter_users);
391 ao2_ref(curlot, -1);
392 }
393abort_list:
394 ao2_iterator_destroy(&iter_lots);
395
396 astman_send_list_complete_start(s, m, "ParkedCallsComplete", total);
397 astman_append(s, "Total: %d\r\n", total);
399}
#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 288 of file parking_manager.c.

289{
290 RAII_VAR(struct parking_lot *, curlot, NULL, ao2_cleanup);
291 struct parked_user *curuser;
292 struct ao2_iterator iter_users;
293 int total = 0;
294
295 curlot = parking_lot_find_by_name(lot_name);
296 if (!curlot) {
297 astman_send_error(s, m, "Requested parking lot could not be found.");
298 return;
299 }
300
301 astman_send_listack(s, m, "Parked calls will follow", "start");
302
303 iter_users = ao2_iterator_init(curlot->parked_users, 0);
304 while ((curuser = ao2_iterator_next(&iter_users))) {
306 RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
307
309 if (!payload) {
310 ao2_ref(curuser, -1);
311 break;
312 }
313
314 parked_call_string = manager_build_parked_call_string(payload);
315 if (!parked_call_string) {
316 ao2_ref(curuser, -1);
317 break;
318 }
319
320 total++;
321
322 astman_append(s, "Event: ParkedCall\r\n"
323 "%s" /* The parked call string */
324 "%s" /* The action ID */
325 "\r\n",
326 ast_str_buffer(parked_call_string),
327 id_text);
328
329 ao2_ref(curuser, -1);
330 }
331 ao2_iterator_destroy(&iter_users);
332
333 astman_send_list_complete_start(s, m, "ParkedCallsComplete", total);
334 astman_append(s, "Total: %d\r\n", total);
336}
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
Definition: res_parking.c:662

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 673 of file parking_manager.c.

674{
675 char *event_type = "";
676 RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
677
678 switch (parked_call->event_type) {
679 case PARKED_CALL:
680 event_type = "ParkedCall";
681 break;
683 event_type = "ParkedCallTimeOut";
684 break;
686 event_type = "ParkedCallGiveUp";
687 break;
689 event_type = "UnParkedCall";
690 break;
691 case PARKED_CALL_SWAP:
692 event_type = "ParkedCallSwap";
693 break;
695 /* PARKED_CALL_FAILED doesn't currently get a message and is used exclusively for bridging */
696 return;
697 }
698
699 parked_call_string = manager_build_parked_call_string(parked_call);
700 if (!parked_call_string) {
701 ast_log(LOG_ERROR, "Failed to issue an AMI event of '%s' in response to a stasis message.\n", event_type);
702 return;
703 }
704
705 manager_event(EVENT_FLAG_CALL, event_type,
706 "%s",
707 ast_str_buffer(parked_call_string)
708 );
709}
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:254
@ 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 207 of file parking_manager.c.

208{
209 RAII_VAR(struct ast_channel_snapshot *, parkee_snapshot, NULL, ao2_cleanup);
210
211 ast_channel_lock(chan);
212 parkee_snapshot = ast_channel_snapshot_create(chan);
213 ast_channel_unlock(chan);
214 if (!parkee_snapshot) {
215 return NULL;
216 }
217
218 return ast_parked_call_payload_create(PARKED_CALL_FAILED, parkee_snapshot, NULL, NULL, NULL, 0, 0, 0);
219}
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 221 of file parking_manager.c.

222{
223 RAII_VAR(struct ast_channel_snapshot *, parkee_snapshot, NULL, ao2_cleanup);
224 long int timeout;
225 long int duration;
226 struct timeval now = ast_tvnow();
227 const char *lot_name = pu->lot->name;
228
230 parkee_snapshot = ast_channel_snapshot_create(pu->chan);
232 if (!parkee_snapshot) {
233 return NULL;
234 }
235
236 timeout = pu->start.tv_sec + (long) pu->time_limit - now.tv_sec;
237 duration = now.tv_sec - pu->start.tv_sec;
238
239 return ast_parked_call_payload_create(event_type, parkee_snapshot, pu->parker_dial_string, pu->retriever, lot_name, pu->parking_space, timeout, duration);
240
241}
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 711 of file parking_manager.c.

712{
714 struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
715 parked_call_message_response(parked_call_message);
716 }
717}
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 739 of file parking_manager.c.

740{
742}
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:1161

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 719 of file parking_manager.c.

720{
721 if (!parking_sub) {
725 }
726}
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:1050
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:1104
#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 651 of file parking_manager.c.

652{
654 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
655
656 if (!ast_parked_call_type()) {
657 return;
658 }
659
660 payload = parked_call_payload_from_parked_user(pu, event_type);
661 if (!payload) {
662 return;
663 }
664
666 if (!msg) {
667 return;
668 }
669
671}
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:1538

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 629 of file parking_manager.c.

630{
632 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
633
634 if (!ast_parked_call_type()) {
635 return;
636 }
637
638 payload = parked_call_payload_from_failure(parkee);
639 if (!payload) {
640 return;
641 }
642
644 if (!msg) {
645 return;
646 }
647
649}
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 744 of file parking_manager.c.

745{
746 ast_manager_unregister("Parkinglots");
747 ast_manager_unregister("ParkedCalls");
750}
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7697
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 205 of file parking_manager.c.

Referenced by parking_manager_disable_stasis(), and parking_manager_enable_stasis().