Asterisk - The Open Source Telephony Project  18.5.0
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 694 of file parking_manager.c.

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().

695 {
696  int res;
697 
702  return res ? -1 : 0;
703 }
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)
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:186

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

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().

398 {
399  struct parking_lot *curlot = obj;
400  struct mansession *s = arg;
401  struct park_list_data *list_data = data;
402 
403  astman_append(s, "Event: Parkinglot\r\n"
404  "%s" /* The Action ID */
405  "Name: %s\r\n"
406  "StartSpace: %d\r\n"
407  "StopSpace: %d\r\n"
408  "Timeout: %u\r\n"
409  "\r\n",
410  list_data->id_text,
411  curlot->name,
412  curlot->cfg->parking_start,
413  curlot->cfg->parking_stop,
414  curlot->cfg->parkingtime);
415  ++list_data->count;
416 
417  return 0;
418 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
const char * id_text
unsigned int parkingtime
Definition: res_parking.h:69
In case you didn't read that giant block of text above the mansession_session struct, the struct mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
Definition: manager.c:1625
const ast_string_field name
Definition: res_parking.h:100
struct parking_lot_cfg * cfg
Definition: res_parking.h:96

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

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().

216 {
217  struct ast_str *out = ast_str_create(1024);
218  RAII_VAR(struct ast_str *, parkee_string, NULL, ast_free);
219  RAII_VAR(struct ast_str *, retriever_string, NULL, ast_free);
220 
221  if (!out) {
222  return NULL;
223  }
224 
225  parkee_string = ast_manager_build_channel_state_string_prefix(payload->parkee, "Parkee");
226  if (!parkee_string) {
227  ast_free(out);
228  return NULL;
229  }
230 
231  if (payload->retriever) {
232  retriever_string = ast_manager_build_channel_state_string_prefix(payload->retriever, "Retriever");
233  if (!retriever_string) {
234  ast_free(out);
235  return NULL;
236  }
237  }
238 
239  ast_str_set(&out, 0,
240  "%s" /* parkee channel state */
241  "%s" /* retriever channel state (when available) */
242  "ParkerDialString: %s\r\n"
243  "Parkinglot: %s\r\n"
244  "ParkingSpace: %u\r\n"
245  "ParkingTimeout: %lu\r\n"
246  "ParkingDuration: %lu\r\n",
247 
248  ast_str_buffer(parkee_string),
249  retriever_string ? ast_str_buffer(retriever_string) : "",
250  payload->parker_dial_string,
251  payload->parkinglot,
252  payload->parkingspace,
253  payload->timeout,
254  payload->duration);
255 
256  return out;
257 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
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
long unsigned int duration
Definition: parking.h:64
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:1065
struct ast_channel_snapshot * parkee
Definition: parking.h:60
#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:911
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
unsigned int parkingspace
Definition: parking.h:65
long unsigned int timeout
Definition: parking.h:63
#define ast_free(a)
Definition: astmm.h:182
const ast_string_field parkinglot
Definition: parking.h:69
FILE * out
Definition: utils/frame.c:33
const ast_string_field parker_dial_string
Definition: parking.h:69
struct ast_channel_snapshot * retriever
Definition: parking.h:61
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:620

◆ manager_park()

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

Definition at line 519 of file parking_manager.c.

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, parkinglot, RAII_VAR, S_OR, and timeout.

Referenced by load_parking_manager().

520 {
521  const char *channel = astman_get_header(m, "Channel");
522  const char *timeout_channel = S_OR(astman_get_header(m, "TimeoutChannel"), astman_get_header(m, "Channel2"));
523  const char *announce_channel = astman_get_header(m, "AnnounceChannel");
524  const char *timeout = astman_get_header(m, "Timeout");
525  const char *parkinglot = astman_get_header(m, "Parkinglot");
526  char buf[BUFSIZ];
527  int timeout_override = -1;
528 
529  RAII_VAR(struct ast_channel *, parker_chan, NULL, ao2_cleanup);
530  RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
531 
532  if (ast_strlen_zero(channel)) {
533  astman_send_error(s, m, "Channel not specified");
534  return 0;
535  }
536 
537  if (!ast_strlen_zero(timeout)) {
538  if (sscanf(timeout, "%30d", &timeout_override) != 1 || timeout_override < 0) {
539  astman_send_error(s, m, "Invalid Timeout value.");
540  return 0;
541  }
542 
543  if (timeout_override) {
544  /* If greater than zero, convert to seconds for internal use. Must be >= 1 second. */
545  timeout_override = MAX(1, timeout_override / 1000);
546  }
547  }
548 
549  if (!(chan = ast_channel_get_by_name(channel))) {
550  snprintf(buf, sizeof(buf), "Channel does not exist: %s", channel);
551  astman_send_error(s, m, buf);
552  return 0;
553  }
554 
555  if (!ast_strlen_zero(timeout_channel)) {
556  ast_channel_lock(chan);
557  ast_bridge_set_transfer_variables(chan, timeout_channel, 0);
558  ast_channel_unlock(chan);
559  }
560 
561  parker_chan = ast_channel_bridge_peer(chan);
562  if (!parker_chan || strcmp(ast_channel_name(parker_chan), timeout_channel)) {
563  if (!ast_strlen_zero(announce_channel)) {
564  struct ast_channel *announce_chan = ast_channel_get_by_name(announce_channel);
565  if (!announce_channel) {
566  astman_send_error(s, m, "AnnounceChannel does not exist");
567  return 0;
568  }
569 
570  create_parked_subscription(announce_chan, ast_channel_uniqueid(chan), 0);
571  ast_channel_cleanup(announce_chan);
572  }
573 
574  manager_park_unbridged(s, m, chan, parkinglot, timeout_override);
575  return 0;
576  }
577 
578  if (!ast_strlen_zero(announce_channel) && strcmp(announce_channel, timeout_channel)) {
579  /* When using an announce_channel in bridge mode, only add the announce channel if it isn't
580  * the same as the timeout channel (which will play announcements anyway) */
581  struct ast_channel *announce_chan = ast_channel_get_by_name(announce_channel);
582  if (!announce_channel) {
583  astman_send_error(s, m, "AnnounceChannel does not exist");
584  return 0;
585  }
586 
587  create_parked_subscription(announce_chan, ast_channel_uniqueid(chan), 0);
588  ast_channel_cleanup(announce_chan);
589  }
590 
591  manager_park_bridged(s, m, chan, parker_chan, parkinglot, timeout_override);
592  return 0;
593 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:163
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int timeout
Definition: cdr_mysql.c:86
Definition: muted.c:95
#define NULL
Definition: resample.c:96
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define MAX(a, b)
Definition: utils.h:228
#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:911
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
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)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void manager_park_unbridged(struct mansession *s, const struct message *m, struct ast_channel *chan, const char *parkinglot, int timeout_override)
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:4404
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: channel.c:10765
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
int create_parked_subscription(struct ast_channel *chan, const char *parkee_uuid, int hangup_after)
Create a parking announcement subscription.

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

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(), and create_parked_subscription().

Referenced by manager_park().

476 {
477  struct ast_bridge_channel *bridge_channel;
478  char *app_data;
479 
480  if (timeout_override != -1) {
481  if (ast_asprintf(&app_data, "%s,t(%d)", parkinglot, timeout_override) == -1) {
482  astman_send_error(s, m, "Park action failed\n");
483  return;
484  }
485  } else {
486  if (ast_asprintf(&app_data, "%s", parkinglot) == -1) {
487  astman_send_error(s, m, "Park action failed\n");
488  return;
489  }
490  }
491 
492  ast_channel_lock(parker_chan);
493  bridge_channel = ast_channel_get_bridge_channel(parker_chan);
494  ast_channel_unlock(parker_chan);
495 
496  if (!bridge_channel) {
497  ast_free(app_data);
498  astman_send_error(s, m, "Park action failed\n");
499  return;
500  }
501 
502  /* Subscribe to park messages for the channel being parked */
503  if (create_parked_subscription(parker_chan, ast_channel_uniqueid(chan), 1)) {
504  ast_free(app_data);
505  astman_send_error(s, m, "Park action failed\n");
506  ao2_cleanup(bridge_channel);
507  return;
508  }
509 
511  ast_channel_uniqueid(parker_chan), app_data);
512 
513  ast_free(app_data);
514 
515  astman_send_ack(s, m, "Park successful\n");
516  ao2_cleanup(bridge_channel);
517 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:163
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.
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_free(a)
Definition: astmm.h:182
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
int create_parked_subscription(struct ast_channel *chan, const char *parkee_uuid, int hangup_after)
Create a parking announcement subscription.

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

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

Referenced by manager_park().

454 {
455  struct ast_bridge *parking_bridge = park_common_setup(chan,
456  chan, parkinglot, NULL, 0, 0, timeout_override, 1);
457 
458  if (!parking_bridge) {
459  astman_send_error(s, m, "Park action failed\n");
460  return;
461  }
462 
463  if (ast_bridge_add_channel(parking_bridge, chan, NULL, 0, NULL)) {
464  astman_send_error(s, m, "Park action failed\n");
465  ao2_cleanup(parking_bridge);
466  return;
467  }
468 
469  astman_send_ack(s, m, "Park successful\n");
470  ao2_cleanup(parking_bridge);
471 }
static char parkinglot[AST_MAX_CONTEXT]
Definition: chan_mgcp.c:163
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
#define NULL
Definition: resample.c:96
Structure that contains information about a bridge.
Definition: bridge.h:357
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:2519
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
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.

◆ manager_parking_lot_list()

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

Definition at line 420 of file parking_manager.c.

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().

421 {
422  const char *id = astman_get_header(m, "ActionID");
423  struct ao2_container *lot_container;
424  char id_text[256];
425  struct park_list_data list_data;
426 
427  id_text[0] = '\0';
428  if (!ast_strlen_zero(id)) {
429  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
430  }
431 
432  lot_container = get_parking_lot_container();
433  if (!lot_container) {
434  ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
435  astman_send_error(s, m, "Could not create parking lot list");
436  return 0;
437  }
438 
439  astman_send_listack(s, m, "Parking lots will follow", "start");
440 
441  list_data.id_text = id_text;
442  list_data.count = 0;
443  ao2_callback_data(lot_container, OBJ_MULTIPLE | OBJ_NODATA,
445 
446  astman_send_list_complete_start(s, m, "ParkinglotsComplete", list_data.count);
448 
449  return 0;
450 }
const char * id_text
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:3237
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:596
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
static int manager_append_event_parking_lot_data_cb(void *obj, void *arg, void *data, int flags)
#define LOG_ERROR
Definition: logger.h:285
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1743
Generic container type.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
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:3201

◆ manager_parking_status()

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

Definition at line 372 of file parking_manager.c.

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

Referenced by load_parking_manager().

373 {
374  const char *id = astman_get_header(m, "ActionID");
375  const char *lot_name = astman_get_header(m, "ParkingLot");
376  char id_text[256];
377 
378  id_text[0] = '\0';
379  if (!ast_strlen_zero(id)) {
380  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
381  }
382 
383  if (!ast_strlen_zero(lot_name)) {
384  manager_parking_status_single_lot(s, m, id_text, lot_name);
385  } else {
386  manager_parking_status_all_lots(s, m, id_text);
387  }
388 
389  return 0;
390 }
const char * id_text
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
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)

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

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().

310 {
311  struct parked_user *curuser;
312  struct ao2_container *lot_container;
313  struct ao2_iterator iter_lots;
314  struct ao2_iterator iter_users;
315  struct parking_lot *curlot;
316  int total = 0;
317 
318  lot_container = get_parking_lot_container();
319  if (!lot_container) {
320  ast_log(LOG_ERROR, "Failed to obtain parking lot list. Action canceled.\n");
321  astman_send_error(s, m, "Could not create parking lot list");
322  return;
323  }
324 
325  astman_send_listack(s, m, "Parked calls will follow", "start");
326 
327  iter_lots = ao2_iterator_init(lot_container, 0);
328  while ((curlot = ao2_iterator_next(&iter_lots))) {
329  iter_users = ao2_iterator_init(curlot->parked_users, 0);
330  while ((curuser = ao2_iterator_next(&iter_users))) {
331  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
332  RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
333 
335  if (!payload) {
336  ao2_ref(curuser, -1);
337  ao2_iterator_destroy(&iter_users);
338  ao2_ref(curlot, -1);
339  goto abort_list;
340  }
341 
342  parked_call_string = manager_build_parked_call_string(payload);
343  if (!parked_call_string) {
344  ao2_ref(curuser, -1);
345  ao2_iterator_destroy(&iter_users);
346  ao2_ref(curlot, -1);
347  goto abort_list;
348  }
349 
350  total++;
351 
352  astman_append(s, "Event: ParkedCall\r\n"
353  "%s" /* The parked call string */
354  "%s" /* The action ID */
355  "\r\n",
356  ast_str_buffer(parked_call_string),
357  id_text);
358 
359  ao2_ref(curuser, -1);
360  }
361  ao2_iterator_destroy(&iter_users);
362  ao2_ref(curlot, -1);
363  }
364 abort_list:
365  ao2_iterator_destroy(&iter_lots);
366 
367  astman_send_list_complete_start(s, m, "ParkedCallsComplete", total);
368  astman_append(s, "Total: %d\r\n", total);
370 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
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:3237
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct ao2_container * parked_users
Definition: res_parking.h:95
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
A parked call message payload.
Definition: parking.h:59
#define NULL
Definition: resample.c:96
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:596
#define ast_log
Definition: astobj2.c:42
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
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.
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static struct ast_parked_call_payload * parked_call_payload_from_parked_user(struct parked_user *pu, enum ast_parked_call_event_type event_type)
#define ast_free(a)
Definition: astmm.h:182
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int total
Definition: res_adsi.c:968
Generic container type.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
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:3201

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

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().

260 {
261  RAII_VAR(struct parking_lot *, curlot, NULL, ao2_cleanup);
262  struct parked_user *curuser;
263  struct ao2_iterator iter_users;
264  int total = 0;
265 
266  curlot = parking_lot_find_by_name(lot_name);
267  if (!curlot) {
268  astman_send_error(s, m, "Requested parking lot could not be found.");
269  return;
270  }
271 
272  astman_send_listack(s, m, "Parked calls will follow", "start");
273 
274  iter_users = ao2_iterator_init(curlot->parked_users, 0);
275  while ((curuser = ao2_iterator_next(&iter_users))) {
276  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
277  RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
278 
280  if (!payload) {
281  ao2_ref(curuser, -1);
282  break;
283  }
284 
285  parked_call_string = manager_build_parked_call_string(payload);
286  if (!parked_call_string) {
287  ao2_ref(curuser, -1);
288  break;
289  }
290 
291  total++;
292 
293  astman_append(s, "Event: ParkedCall\r\n"
294  "%s" /* The parked call string */
295  "%s" /* The action ID */
296  "\r\n",
297  ast_str_buffer(parked_call_string),
298  id_text);
299 
300  ao2_ref(curuser, -1);
301  }
302  ao2_iterator_destroy(&iter_users);
303 
304  astman_send_list_complete_start(s, m, "ParkedCallsComplete", total);
305  astman_append(s, "Total: %d\r\n", total);
307 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
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:3237
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
A parked call message payload.
Definition: parking.h:59
#define NULL
Definition: resample.c:96
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#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:911
#define ao2_ref(o, delta)
Definition: astobj2.h:464
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
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.
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static struct ast_parked_call_payload * parked_call_payload_from_parked_user(struct parked_user *pu, enum ast_parked_call_event_type event_type)
#define ast_free(a)
Definition: astmm.h:182
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static int total
Definition: res_adsi.c:968
struct parking_lot * parking_lot_find_by_name(const char *lot_name)
Find a parking lot based on its name.
Definition: res_parking.c:601
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
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:3201

◆ parked_call_message_response()

static void parked_call_message_response ( struct ast_parked_call_payload parked_call)
static

Definition at line 639 of file parking_manager.c.

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().

640 {
641  char *event_type = "";
642  RAII_VAR(struct ast_str *, parked_call_string, NULL, ast_free);
643 
644  switch (parked_call->event_type) {
645  case PARKED_CALL:
646  event_type = "ParkedCall";
647  break;
648  case PARKED_CALL_TIMEOUT:
649  event_type = "ParkedCallTimeOut";
650  break;
651  case PARKED_CALL_GIVEUP:
652  event_type = "ParkedCallGiveUp";
653  break;
655  event_type = "UnParkedCall";
656  break;
657  case PARKED_CALL_SWAP:
658  event_type = "ParkedCallSwap";
659  break;
660  case PARKED_CALL_FAILED:
661  /* PARKED_CALL_FAILED doesn't currently get a message and is used exclusively for bridging */
662  return;
663  }
664 
665  parked_call_string = manager_build_parked_call_string(parked_call);
666  if (!parked_call_string) {
667  ast_log(LOG_ERROR, "Failed to issue an AMI event of '%s' in response to a stasis message.\n", event_type);
668  return;
669  }
670 
671  manager_event(EVENT_FLAG_CALL, event_type,
672  "%s",
673  ast_str_buffer(parked_call_string)
674  );
675 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define NULL
Definition: resample.c:96
enum ast_parked_call_event_type event_type
Definition: parking.h:62
#define ast_log
Definition: astobj2.c:42
#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:911
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
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.
#define ast_free(a)
Definition: astmm.h:182
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:248

◆ parked_call_payload_from_failure()

static struct ast_parked_call_payload* parked_call_payload_from_failure ( struct ast_channel chan)
static

Definition at line 178 of file parking_manager.c.

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().

179 {
180  RAII_VAR(struct ast_channel_snapshot *, parkee_snapshot, NULL, ao2_cleanup);
181 
182  ast_channel_lock(chan);
183  parkee_snapshot = ast_channel_snapshot_create(chan);
184  ast_channel_unlock(chan);
185  if (!parkee_snapshot) {
186  return NULL;
187  }
188 
189  return ast_parked_call_payload_create(PARKED_CALL_FAILED, parkee_snapshot, NULL, NULL, NULL, 0, 0, 0);
190 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
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.
#define NULL
Definition: resample.c:96
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...
#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:911
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

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

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 timeout.

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

193 {
194  RAII_VAR(struct ast_channel_snapshot *, parkee_snapshot, NULL, ao2_cleanup);
195  long int timeout;
196  long int duration;
197  struct timeval now = ast_tvnow();
198  const char *lot_name = pu->lot->name;
199 
200  ast_channel_lock(pu->chan);
201  parkee_snapshot = ast_channel_snapshot_create(pu->chan);
203  if (!parkee_snapshot) {
204  return NULL;
205  }
206 
207  timeout = pu->start.tv_sec + (long) pu->time_limit - now.tv_sec;
208  duration = now.tv_sec - pu->start.tv_sec;
209 
210  return ast_parked_call_payload_create(event_type, parkee_snapshot, pu->parker_dial_string, pu->retriever, lot_name, pu->parking_space, timeout, duration);
211 
212 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
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
static int timeout
Definition: cdr_mysql.c:86
Structure representing a snapshot of channel state.
unsigned int time_limit
Definition: res_parking.h:110
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
struct parking_lot * lot
Definition: res_parking.h:111
struct timeval start
Definition: res_parking.h:106
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...
#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:911
char * parker_dial_string
Definition: res_parking.h:109
int parking_space
Definition: res_parking.h:107
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const ast_string_field name
Definition: res_parking.h:100
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_channel_snapshot * retriever
Definition: res_parking.h:105
struct ast_channel * chan
Definition: res_parking.h:104

◆ parking_event_cb()

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

Definition at line 677 of file parking_manager.c.

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

Referenced by parking_manager_enable_stasis().

678 {
679  if (stasis_message_type(message) == ast_parked_call_type()) {
680  struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
681  parked_call_message_response(parked_call_message);
682  }
683 }
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
A parked call message payload.
Definition: parking.h:59
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static void parked_call_message_response(struct ast_parked_call_payload *parked_call)

◆ parking_manager_disable_stasis()

static void parking_manager_disable_stasis ( void  )
static

Definition at line 705 of file parking_manager.c.

References stasis_unsubscribe_and_join().

Referenced by unload_parking_manager().

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

◆ parking_manager_enable_stasis()

static void parking_manager_enable_stasis ( void  )
static

Definition at line 685 of file parking_manager.c.

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

Referenced by load_parking_manager().

686 {
687  if (!parking_sub) {
691  }
692 }
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
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:1079
#define NULL
Definition: resample.c:96
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:652
static void parking_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static struct stasis_subscription * parking_sub
subscription to the parking lot topic
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
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:1025

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

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().

618 {
619  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
620  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
621 
622  if (!ast_parked_call_type()) {
623  return;
624  }
625 
627  if (!payload) {
628  return;
629  }
630 
632  if (!msg) {
633  return;
634  }
635 
637 }
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
A parked call message payload.
Definition: parking.h:59
#define NULL
Definition: resample.c:96
enum ast_parked_call_event_type event_type
Definition: parking.h:62
#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:911
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
static struct ast_parked_call_payload * parked_call_payload_from_parked_user(struct parked_user *pu, enum ast_parked_call_event_type event_type)
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

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

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().

596 {
597  RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup);
598  RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
599 
600  if (!ast_parked_call_type()) {
601  return;
602  }
603 
604  payload = parked_call_payload_from_failure(parkee);
605  if (!payload) {
606  return;
607  }
608 
610  if (!msg) {
611  return;
612  }
613 
615 }
static struct ast_parked_call_payload * parked_call_payload_from_failure(struct ast_channel *chan)
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
A parked call message payload.
Definition: parking.h:59
#define NULL
Definition: resample.c:96
#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:911
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&#39;s subscribers.
Definition: stasis.c:1511
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ unload_parking_manager()

void unload_parking_manager ( void  )

Unregister manager actions and remove subscriptions for stasis events.

Since
12.0.0

Definition at line 710 of file parking_manager.c.

References ast_manager_unregister(), and parking_manager_disable_stasis().

Referenced by unload_module().

711 {
712  ast_manager_unregister("Parkinglots");
713  ast_manager_unregister("ParkedCalls");
714  ast_manager_unregister("Park");
716 }
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7258
static void parking_manager_disable_stasis(void)

Variable Documentation

◆ parking_sub

struct stasis_subscription* parking_sub
static

subscription to the parking lot topic

Definition at line 176 of file parking_manager.c.