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_bridge_features.c File Reference

Parking Bridge DTMF and Interval features. More...

#include "asterisk.h"
#include "res_parking.h"
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
#include "asterisk/logger.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_internal.h"
#include "asterisk/bridge_channel.h"
#include "asterisk/bridge_features.h"
#include "asterisk/conversions.h"
#include "asterisk/features.h"
#include "asterisk/say.h"
#include "asterisk/datastore.h"
#include "asterisk/stasis.h"
#include "asterisk/module.h"
#include "asterisk/core_local.h"
#include "asterisk/causes.h"
Include dependency graph for parking_bridge_features.c:

Go to the source code of this file.

Data Structures

struct  parked_subscription_data
 
struct  parked_subscription_datastore
 

Functions

int create_parked_subscription (struct ast_channel *chan, const char *parkee_uuid, int hangup_after)
 Create a parking announcement subscription. More...
 
static int create_parked_subscription_full (struct ast_channel *chan, const char *parkee_uuid, int hangup_after, struct transfer_channel_data *parked_channel_data)
 
static int feature_park_call (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 
static int func_get_parkingslot_channel (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
 Dial plan function to get the parking lot channel of an occupied parking lot. More...
 
int load_parking_bridge_features (void)
 Register bridge features for parking. More...
 
static struct ast_channelpark_local_transfer (struct ast_channel *parker, const char *context, const char *exten, struct transfer_channel_data *parked_channel_data)
 
static void parked_subscription_datastore_destroy (void *data)
 
static void parker_parked_call_message_response (struct ast_parked_call_payload *message, struct parked_subscription_data *data, struct stasis_subscription *sub)
 
static void parker_update_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int parking_blind_transfer_park (struct ast_bridge_channel *bridge_channel, const char *context, const char *exten, transfer_channel_cb parked_channel_cb, struct transfer_channel_data *parked_channel_data)
 
static int parking_duration_callback (struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 
static int parking_is_exten_park (const char *context, const char *exten)
 
static int parking_park_bridge_channel (struct ast_bridge_channel *bridge_channel, const char *uuid_parkee, const char *uuid_parker, const char *app_data)
 
static int parking_park_call (struct ast_bridge_channel *parker, char *exten, size_t length)
 
void parking_set_duration (struct ast_bridge_features *features, struct parked_user *user)
 Setup timeout interval feature on an ast_bridge_features for parking. More...
 
static void parking_timeout_set_caller_features (struct ast_channel *chan, struct parking_lot_cfg *cfg)
 
void say_parking_space (struct ast_bridge_channel *bridge_channel, const char *payload)
 custom callback function for ast_bridge_channel_queue_playfile which plays a parking space and optionally hangs up the call afterwards based on the payload in playfile. More...
 
void unload_parking_bridge_features (void)
 Unregister features registered by load_parking_bridge_features. More...
 
static void wipe_subscription_datastore (struct ast_channel *chan)
 

Variables

static struct ast_custom_function getparkingslotchannel_function
 
static const struct ast_datastore_info parked_subscription_info
 
struct ast_parking_bridge_feature_fn_table parking_provider
 

Detailed Description

Parking Bridge DTMF and Interval features.

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

Definition in file parking_bridge_features.c.

Function Documentation

◆ create_parked_subscription()

int create_parked_subscription ( struct ast_channel chan,
const char *  parkee_uuid,
int  hangup_after 
)

Create a parking announcement subscription.

Since
12.3.0
Parameters
chanChannel that will receive the announcement
parkee_uuidUnique ID of the channel being parked
hangup_afterif non-zero, have the channel hangup after hearing the announcement
Return values
0on success
-1on failure

Definition at line 236 of file parking_bridge_features.c.

237{
238 return create_parked_subscription_full(chan, parkee_uuid, hangup_after, NULL);
239}
static int create_parked_subscription_full(struct ast_channel *chan, const char *parkee_uuid, int hangup_after, struct transfer_channel_data *parked_channel_data)
#define NULL
Definition: resample.c:96

References create_parked_subscription_full(), parked_subscription_data::hangup_after, NULL, and parked_subscription_data::parkee_uuid.

Referenced by manager_park(), and manager_park_bridged().

◆ create_parked_subscription_full()

static int create_parked_subscription_full ( struct ast_channel chan,
const char *  parkee_uuid,
int  hangup_after,
struct transfer_channel_data parked_channel_data 
)
static

Definition at line 177 of file parking_bridge_features.c.

179{
180 struct ast_datastore *datastore;
181 struct parked_subscription_datastore *parked_datastore;
182 struct parked_subscription_data *subscription_data;
183
185 size_t parker_uuid_size;
186 size_t parkee_uuid_size;
187
188 /* If there is already a subscription, get rid of it. */
190
191 if (!(datastore = ast_datastore_alloc(&parked_subscription_info, NULL))) {
192 return -1;
193 }
194
195 if (!(parked_datastore = ast_calloc(1, sizeof(*parked_datastore)))) {
196 ast_datastore_free(datastore);
197 return -1;
198 }
199
200 parker_uuid_size = strlen(parker_uuid) + 1;
201 parkee_uuid_size = strlen(parkee_uuid) + 1;
202
203 if (!(subscription_data = ast_calloc(1, sizeof(*subscription_data) + parker_uuid_size +
204 parkee_uuid_size))) {
205 ast_datastore_free(datastore);
206 ast_free(parked_datastore);
207 return -1;
208 }
209
210 if (parked_channel_data) {
211 subscription_data->transfer_data = parked_channel_data;
212 ao2_ref(parked_channel_data, +1);
213 }
214
215 subscription_data->hangup_after = hangup_after;
216 subscription_data->parkee_uuid = subscription_data->parker_uuid + parker_uuid_size;
217 ast_copy_string(subscription_data->parkee_uuid, parkee_uuid, parkee_uuid_size);
218 ast_copy_string(subscription_data->parker_uuid, parker_uuid, parker_uuid_size);
219
220 if (!(parked_datastore->parked_subscription = stasis_subscribe_pool(ast_parking_topic(), parker_update_cb, subscription_data))) {
221 return -1;
222 }
226
227 datastore->data = parked_datastore;
228
229 ast_channel_lock(chan);
230 ast_channel_datastore_add(chan, datastore);
231 ast_channel_unlock(chan);
232
233 return 0;
234}
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2354
#define ast_channel_lock(chan)
Definition: channel.h:2972
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2973
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
struct stasis_topic * ast_parking_topic(void)
accessor for the parking stasis topic
Definition: parking.c:67
struct stasis_message_type * ast_parked_call_type(void)
accessor for the parked call stasis message type
struct stasis_message_type * stasis_subscription_change_type(void)
Gets the message type for subscription change notices.
static void wipe_subscription_datastore(struct ast_channel *chan)
static const struct ast_datastore_info parked_subscription_info
static void parker_update_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_pool(topic, callback, data)
Definition: stasis.h:680
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
struct transfer_channel_data * transfer_data
struct stasis_subscription * parked_subscription

References ao2_ref, ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_uniqueid(), ast_channel_unlock, ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_free, ast_parked_call_type(), ast_parking_topic(), ast_strdupa, ast_datastore::data, parked_subscription_data::hangup_after, NULL, parked_subscription_datastore::parked_subscription, parked_subscription_info, parked_subscription_data::parkee_uuid, parker_update_cb(), parked_subscription_data::parker_uuid, stasis_subscribe_pool, stasis_subscription_accept_message_type(), stasis_subscription_change_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, stasis_subscription_set_filter(), parked_subscription_data::transfer_data, and wipe_subscription_datastore().

Referenced by create_parked_subscription(), park_local_transfer(), and parking_blind_transfer_park().

◆ feature_park_call()

static int feature_park_call ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Definition at line 527 of file parking_bridge_features.c.

528{
529 SCOPED_MODULE_USE(AST_MODULE_SELF);
530
531 parking_park_call(bridge_channel, NULL, 0);
532 return 0;
533}
#define SCOPED_MODULE_USE(module)
Definition: module.h:679
static int parking_park_call(struct ast_bridge_channel *parker, char *exten, size_t length)

References ast_channel::bridge_channel, NULL, parking_park_call(), and SCOPED_MODULE_USE.

Referenced by load_parking_bridge_features().

◆ func_get_parkingslot_channel()

static int func_get_parkingslot_channel ( struct ast_channel chan,
const char *  function,
char *  data,
char *  buf,
size_t  len 
)
static

Dial plan function to get the parking lot channel of an occupied parking lot.

Definition at line 734 of file parking_bridge_features.c.

735{
736 RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup);
737 RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
738 unsigned int space = 0;
739 const char *content = NULL;
740
742 AST_APP_ARG(parking_space);
744 AST_APP_ARG(other);
745 );
746
747 /* Parse the arguments. */
749
750 if (args.argc < 2) {
751 /* Didn't receive enough arguments to do anything */
752 ast_log(LOG_ERROR, "Usage: %s(<parking_space>,<parking_lot>)\n",
753 function);
754 return -1;
755 }
756
757 lot = parking_lot_find_by_name(args.parking_lot);
758 if (!lot) {
759 ast_log(LOG_ERROR, "Could not find parking lot: '%s'\n", args.parking_lot);
760 return -1;
761 }
762
763 if (!ast_strlen_zero(args.parking_space)) {
764 if (ast_str_to_uint(args.parking_space, &space) != 0) {
765 ast_log(LOG_ERROR, "value '%s' for parking_space argument is invalid. Must be an integer greater than 0.\n",
766 args.parking_space);
767 return -1;
768 }
769 }
770
771 pu = parking_lot_inspect_parked_user(lot, space);
772 if (!pu) {
773 return -1;
774 }
775
776 content = ast_channel_name(pu->chan);
777 ast_copy_string(buf, content, len);
778
779 return 0;
780}
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
const char * ast_channel_name(const struct ast_channel *chan)
int ast_str_to_uint(const char *str, unsigned int *res)
Convert the given string to an unsigned integer.
Definition: conversions.c:56
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define LOG_ERROR
struct parked_user * parking_lot_inspect_parked_user(struct parking_lot *lot, int target)
Determine if there is a parked user in a parking space and return it if there is.
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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
const char * args
#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 ao2_cleanup, args, AST_APP_ARG, ast_channel_name(), ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_str_to_uint(), ast_strlen_zero(), buf, pbx_find_info::data, len(), LOG_ERROR, NULL, parking_lot_find_by_name(), parking_lot_inspect_parked_user(), and RAII_VAR.

◆ load_parking_bridge_features()

int load_parking_bridge_features ( void  )

Register bridge features for parking.

Since
12.0.0
Return values
0on success
-1on failure

Definition at line 803 of file parking_bridge_features.c.

804{
805 parking_provider.module = AST_MODULE_SELF;
806
808
810 return -1;
811 }
812
814 return -1;
815 }
816
817 return 0;
818}
@ AST_BRIDGE_BUILTIN_PARKCALL
int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf)
Register a handler for a built in feature.
Definition: bridge.c:3131
int ast_parking_register_bridge_features(struct ast_parking_bridge_feature_fn_table *fn_table)
Register a parking provider.
Definition: parking.c:196
struct ast_parking_bridge_feature_fn_table parking_provider
static int feature_park_call(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
static struct ast_custom_function getparkingslotchannel_function
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1559
struct ast_module * module
The module info for the module registering this parking provider.
Definition: parking.h:202

References AST_BRIDGE_BUILTIN_PARKCALL, ast_bridge_features_register(), ast_custom_function_register, ast_parking_register_bridge_features(), feature_park_call(), getparkingslotchannel_function, ast_parking_bridge_feature_fn_table::module, NULL, and parking_provider.

Referenced by load_module().

◆ park_local_transfer()

static struct ast_channel * park_local_transfer ( struct ast_channel parker,
const char *  context,
const char *  exten,
struct transfer_channel_data parked_channel_data 
)
static

Definition at line 247 of file parking_bridge_features.c.

248{
249 char destination[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 1];
250 struct ast_channel *parkee;
251 struct ast_channel *parkee_side_2;
252 int cause;
253
254 /* Fill the variable with the extension and context we want to call */
255 snprintf(destination, sizeof(destination), "%s@%s", exten, context);
256
257 /* Now we request that chan_local prepare to call the destination */
258 parkee = ast_request("Local", ast_channel_nativeformats(parker), NULL, parker, destination,
259 &cause);
260 if (!parkee) {
261 return NULL;
262 }
263
264 /* Before we actually dial out let's inherit appropriate information. */
265 ast_channel_lock_both(parker, parkee);
267 ast_channel_parkinglot_set(parkee, ast_channel_parkinglot(parker));
269 ast_channel_inherit_variables(parker, parkee);
271 ast_channel_datastore_inherit(parker, parkee);
272 ast_channel_unlock(parker);
273
274 parkee_side_2 = ast_local_get_peer(parkee);
275 ast_assert(parkee_side_2 != NULL);
276 ast_channel_unlock(parkee);
277
278 /* We need to have the parker subscribe to the new local channel before hand. */
279 if (create_parked_subscription_full(parker, ast_channel_uniqueid(parkee_side_2), 1, parked_channel_data)) {
280 ast_channel_unref(parkee_side_2);
281 ast_hangup(parkee);
282 return NULL;
283 }
284
285 ast_channel_unref(parkee_side_2);
286
287 /* Since the above worked fine now we actually call it and return the channel */
288 if (ast_call(parkee, destination, 0)) {
289 ast_hangup(parkee);
290 return NULL;
291 }
292
293 return parkee;
294}
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
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6420
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2510
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition: channel.h:1527
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2979
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2337
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6393
const char * ast_channel_parkinglot(const struct ast_channel *chan)
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
Definition: channel.c:6735
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3008
#define AST_MAX_CONTEXT
Definition: channel.h:135
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8298
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6313
#define AST_MAX_EXTENSION
Definition: channel.h:134
struct ast_channel * ast_local_get_peer(struct ast_channel *ast)
Get the other local channel in the pair.
Definition: core_local.c:288
Main Channel structure associated with a channel.
char exten[AST_MAX_EXTENSION]
#define ast_assert(a)
Definition: utils.h:739

References ast_assert, ast_bridge_set_transfer_variables(), ast_call(), ast_channel_caller(), ast_channel_connected(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock_both, ast_channel_name(), ast_channel_nativeformats(), ast_channel_parkinglot(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_REPLACEMENT, ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_connected_line_copy_from_caller(), ast_hangup(), ast_local_get_peer(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_request(), voicemailpwcheck::context, create_parked_subscription_full(), ast_channel::exten, and NULL.

Referenced by parking_blind_transfer_park().

◆ parked_subscription_datastore_destroy()

static void parked_subscription_datastore_destroy ( void *  data)
static

Definition at line 79 of file parking_bridge_features.c.

80{
81 struct parked_subscription_datastore *subscription_datastore = data;
82
83 stasis_unsubscribe(subscription_datastore->parked_subscription);
84 subscription_datastore->parked_subscription = NULL;
85
86 ast_free(subscription_datastore);
87}
struct stasis_subscription * stasis_unsubscribe(struct stasis_subscription *subscription)
Cancel a subscription.
Definition: stasis.c:998

References ast_free, NULL, parked_subscription_datastore::parked_subscription, and stasis_unsubscribe().

◆ parker_parked_call_message_response()

static void parker_parked_call_message_response ( struct ast_parked_call_payload message,
struct parked_subscription_data data,
struct stasis_subscription sub 
)
static

Definition at line 108 of file parking_bridge_features.c.

110{
111 const char *parkee_to_act_on = data->parkee_uuid;
112 char saynum_buf[16];
113 struct ast_channel_snapshot *parkee_snapshot = message->parkee;
114 RAII_VAR(struct ast_channel *, parker, NULL, ast_channel_cleanup);
115 RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
116
117 if (strcmp(parkee_to_act_on, parkee_snapshot->base->uniqueid)) {
118 return;
119 }
120
121 if (message->event_type != PARKED_CALL && message->event_type != PARKED_CALL_FAILED) {
122 /* We only care about these two event types */
123 return;
124 }
125
126 parker = ast_channel_get_by_name(data->parker_uuid);
127 if (!parker) {
128 return;
129 }
130
131 ast_channel_lock(parker);
132 bridge_channel = ast_channel_get_bridge_channel(parker);
133 ast_channel_unlock(parker);
134 if (!bridge_channel) {
135 return;
136 }
137
138 /* This subscription callback will block for the duration of the announcement if
139 * parked_subscription_data is tracking a transfer_channel_data struct. */
140 if (message->event_type == PARKED_CALL) {
141 /* queue the saynum on the bridge channel and hangup */
142 snprintf(saynum_buf, sizeof(saynum_buf), "%d %u", data->hangup_after, message->parkingspace);
143 if (!data->transfer_data) {
144 ast_bridge_channel_queue_playfile(bridge_channel, say_parking_space, saynum_buf, NULL);
145 } else {
147 data->transfer_data->completed = 1;
148 }
150 } else if (message->event_type == PARKED_CALL_FAILED) {
151 if (!data->transfer_data) {
152 ast_bridge_channel_queue_playfile(bridge_channel, NULL, "pbx-parkingfailed", NULL);
153 } else {
154 ast_bridge_channel_queue_playfile_sync(bridge_channel, NULL, "pbx-parkingfailed", NULL);
155 data->transfer_data->completed = 1;
156 }
158 }
159}
int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Queue a bridge action play file frame onto the bridge channel.
int ast_bridge_channel_queue_playfile_sync(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Synchronously queue a bridge action play file frame onto the bridge channel.
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
Definition: channel.c:1397
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
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:3019
@ PARKED_CALL
Definition: parking.h:47
@ PARKED_CALL_FAILED
Definition: parking.h:51
void say_parking_space(struct ast_bridge_channel *bridge_channel, const char *payload)
custom callback function for ast_bridge_channel_queue_playfile which plays a parking space and option...
Structure that contains information regarding a channel in a bridge.
const ast_string_field uniqueid
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base

References ao2_cleanup, ast_bridge_channel_queue_playfile(), ast_bridge_channel_queue_playfile_sync(), ast_channel_cleanup, ast_channel_get_bridge_channel(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_snapshot::base, transfer_channel_data::completed, ast_datastore::data, parked_subscription_data::hangup_after, NULL, PARKED_CALL, PARKED_CALL_FAILED, parked_subscription_data::parker_uuid, RAII_VAR, say_parking_space(), parked_subscription_data::transfer_data, ast_channel_snapshot_base::uniqueid, and wipe_subscription_datastore().

Referenced by parker_update_cb().

◆ parker_update_cb()

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

Definition at line 161 of file parking_bridge_features.c.

162{
164 struct parked_subscription_data *ps_data = data;
165 ao2_cleanup(ps_data->transfer_data);
166 ps_data->transfer_data = NULL;
167 ast_free(data);
168 return;
169 }
170
172 struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
173 parker_parked_call_message_response(parked_call_message, data, sub);
174 }
175}
static void parker_parked_call_message_response(struct ast_parked_call_payload *message, struct parked_subscription_data *data, struct stasis_subscription *sub)
struct stasis_forward * sub
Definition: res_corosync.c:240
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.
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
Definition: stasis.c:1201
A parked call message payload.
Definition: parking.h:59

References ao2_cleanup, ast_free, ast_parked_call_type(), NULL, parker_parked_call_message_response(), stasis_message_data(), stasis_message_type(), stasis_subscription_final_message(), sub, and parked_subscription_data::transfer_data.

Referenced by create_parked_subscription_full().

◆ parking_blind_transfer_park()

static int parking_blind_transfer_park ( struct ast_bridge_channel bridge_channel,
const char *  context,
const char *  exten,
transfer_channel_cb  parked_channel_cb,
struct transfer_channel_data parked_channel_data 
)
static

Definition at line 339 of file parking_bridge_features.c.

342{
343 RAII_VAR(struct ast_bridge_channel *, other, NULL, ao2_cleanup);
344 RAII_VAR(struct ast_channel *, other_chan, NULL, ast_channel_cleanup);
345
346 struct ast_exten *e;
347 struct pbx_find_info find_info = { .stacklen = 0 };
348 int peer_count;
349
350 if (ast_strlen_zero(context) || ast_strlen_zero(exten)) {
351 return -1;
352 }
353
354 if (!bridge_channel->in_bridge) {
355 return -1;
356 }
357
358 if (!parking_is_exten_park(context, exten)) {
359 return -1;
360 }
361
362 ast_bridge_channel_lock_bridge(bridge_channel);
363 peer_count = bridge_channel->bridge->num_channels;
364 if (peer_count == 2) {
365 other = ast_bridge_channel_peer(bridge_channel);
366 ao2_ref(other, +1);
367 other_chan = other->chan;
368 ast_channel_ref(other_chan);
369 }
370 ast_bridge_unlock(bridge_channel->bridge);
371
372 if (peer_count < 2) {
373 /* There is nothing to do if there is no one to park. */
374 return -1;
375 }
376
377 /* With a multiparty bridge, we need to do a regular blind transfer. We link the
378 * existing bridge to the parking lot with a Local channel rather than
379 * transferring others. */
380 if (peer_count > 2) {
381 struct ast_channel *transfer_chan = NULL;
382
383 transfer_chan = park_local_transfer(bridge_channel->chan, context, exten, parked_channel_data);
384 if (!transfer_chan) {
385 return -1;
386 }
387 ast_channel_ref(transfer_chan);
388
389 if (parked_channel_cb) {
390 parked_channel_cb(transfer_chan, parked_channel_data, AST_BRIDGE_TRANSFER_MULTI_PARTY);
391 }
392
393 if (ast_bridge_impart(bridge_channel->bridge, transfer_chan, NULL, NULL,
395 ast_hangup(transfer_chan);
396 ast_channel_unref(transfer_chan);
397 return -1;
398 }
399
400 ast_channel_unref(transfer_chan);
401
402 return 0;
403 }
404
405 /* Subscribe to park messages with the other channel entering */
406 if (create_parked_subscription_full(bridge_channel->chan, ast_channel_uniqueid(other->chan), 1, parked_channel_data)) {
407 return -1;
408 }
409
410 if (parked_channel_cb) {
411 parked_channel_cb(other_chan, parked_channel_data, AST_BRIDGE_TRANSFER_SINGLE_PARTY);
412 }
413
414 e = pbx_find_extension(NULL, NULL, &find_info, context, exten, 1, NULL, NULL, E_MATCH);
415
416 /* Write the park frame with the intended recipient and other data out to the bridge. */
418 ast_channel_uniqueid(other_chan),
421
422 return 0;
423}
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:485
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1947
@ AST_BRIDGE_TRANSFER_SINGLE_PARTY
Definition: bridge.h:1115
@ AST_BRIDGE_TRANSFER_MULTI_PARTY
Definition: bridge.h:1117
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:594
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
struct ast_bridge_channel * ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel)
Get the peer bridge channel of a two party bridge.
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.
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2997
@ E_MATCH
Definition: extconf.h:217
static struct ast_channel * park_local_transfer(struct ast_channel *parker, const char *context, const char *exten, struct transfer_channel_data *parked_channel_data)
static int parking_is_exten_park(const char *context, const char *exten)
void * ast_get_extension_app_data(struct ast_exten *e)
Definition: pbx.c:8577
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: ael_main.c:152
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_channel * chan
unsigned int in_bridge
unsigned int num_channels
Definition: bridge.h:377
struct ast_bridge_channel * bridge_channel
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Definition: pbx.c:252
int stacklen
Definition: extconf.h:237

References ao2_cleanup, ao2_ref, ast_bridge_channel_lock_bridge(), ast_bridge_channel_peer(), ast_bridge_channel_write_park(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, AST_BRIDGE_TRANSFER_MULTI_PARTY, AST_BRIDGE_TRANSFER_SINGLE_PARTY, ast_bridge_unlock, ast_channel_cleanup, ast_channel_ref, ast_channel_uniqueid(), ast_channel_unref, ast_get_extension_app_data(), ast_hangup(), ast_strlen_zero(), ast_bridge_channel::bridge, ast_channel::bridge_channel, ast_bridge_channel::chan, voicemailpwcheck::context, create_parked_subscription_full(), E_MATCH, ast_channel::exten, ast_bridge_channel::in_bridge, NULL, ast_bridge::num_channels, park_local_transfer(), parking_is_exten_park(), pbx_find_extension(), RAII_VAR, and pbx_find_info::stacklen.

Referenced by parking_park_call().

◆ parking_duration_callback()

static int parking_duration_callback ( struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)
static

Definition at line 576 of file parking_bridge_features.c.

577{
578 struct parked_user *user = hook_pvt;
579 struct ast_channel *chan = user->chan;
580 struct ast_context *park_dial_context;
581 const char *dial_string;
582 char *dial_string_flat;
583 char parking_space[AST_MAX_EXTENSION];
584
585 char returnexten[AST_MAX_EXTENSION];
586 char *duplicate_returnexten;
587 struct ast_exten *existing_exten;
588 struct pbx_find_info pbx_finder = { .stacklen = 0 }; /* The rest is reset in pbx_find_extension */
589
590
591 /* We are still in the bridge, so it's possible for other stuff to mess with the parked call before we leave the bridge
592 to deal with this, lock the parked user, check and set resolution. */
593 ao2_lock(user);
594 if (user->resolution != PARK_UNSET) {
595 /* Abandon timeout since something else has resolved the parked user before we got to it. */
597 return -1;
598 }
599 user->resolution = PARK_TIMEOUT;
601
604
605 dial_string = user->parker_dial_string;
606 dial_string_flat = ast_strdupa(dial_string);
607 flatten_dial_string(dial_string_flat);
608
609 /* Set parking timeout channel variables */
610 snprintf(parking_space, sizeof(parking_space), "%d", user->parking_space);
611 ast_channel_lock(chan);
613 pbx_builtin_setvar_helper(chan, "PARKING_SPACE", parking_space);
614 pbx_builtin_setvar_helper(chan, "PARKEDLOT", user->lot->name);
615 pbx_builtin_setvar_helper(chan, "PARKER", dial_string);
616 pbx_builtin_setvar_helper(chan, "PARKER_FLAT", dial_string_flat);
619 ast_channel_unlock(chan);
620
621 /* Dialplan generation for park-dial extensions */
622
623 if (ast_wrlock_contexts()) {
624 ast_log(LOG_ERROR, "Failed to lock the contexts list. Can't add the park-dial extension.\n");
625 return -1;
626 }
627
629 ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", PARK_DIAL_CONTEXT);
630 if (ast_unlock_contexts()) {
631 ast_assert(0);
632 }
633 goto abandon_extension_creation;
634 }
635
636 if (ast_wrlock_context(park_dial_context)) {
637 ast_log(LOG_ERROR, "failed to obtain write lock on context '%s'\n", PARK_DIAL_CONTEXT);
638 if (ast_unlock_contexts()) {
639 ast_assert(0);
640 }
641 goto abandon_extension_creation;
642 }
643
644 if (ast_unlock_contexts()) {
645 ast_assert(0);
646 }
647
648 snprintf(returnexten, sizeof(returnexten), "%s,%u", dial_string,
649 user->lot->cfg->comebackdialtime);
650
651 duplicate_returnexten = ast_strdup(returnexten);
652 if (!duplicate_returnexten) {
653 ast_log(LOG_ERROR, "Failed to create parking redial parker extension %s@%s - Dial(%s)\n",
654 dial_string_flat, PARK_DIAL_CONTEXT, returnexten);
655 }
656
657 /* If an extension already exists here because we registered it for another parked call timing out, then we may overwrite it. */
658 if ((existing_exten = pbx_find_extension(NULL, NULL, &pbx_finder, PARK_DIAL_CONTEXT, dial_string_flat, 1, NULL, NULL, E_MATCH)) &&
659 (strcmp(ast_get_extension_registrar(existing_exten), BASE_REGISTRAR))) {
660 ast_debug(3, "An extension for '%s@%s' was already registered by another registrar '%s'\n",
661 dial_string_flat, PARK_DIAL_CONTEXT, ast_get_extension_registrar(existing_exten));
662 } else if (ast_add_extension2_nolock(park_dial_context, 1, dial_string_flat, 1, NULL, NULL,
663 "Dial", duplicate_returnexten, ast_free_ptr, BASE_REGISTRAR, NULL, 0)) {
664 ast_log(LOG_ERROR, "Failed to create parking redial parker extension %s@%s - Dial(%s)\n",
665 dial_string_flat, PARK_DIAL_CONTEXT, returnexten);
666 }
667
668 if (ast_unlock_context(park_dial_context)) {
669 ast_assert(0);
670 }
671
672abandon_extension_creation:
673
674 /* async_goto the proper PBX destination - this should happen when we come out of the bridge */
675 if (!ast_strlen_zero(user->comeback)) {
676 ast_async_parseable_goto(chan, user->comeback);
677 } else {
678 comeback_goto(user, user->lot);
679 }
680
681 return -1;
682}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
@ BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define ast_debug(level,...)
Log a DEBUG message.
static void parking_timeout_set_caller_features(struct ast_channel *chan, struct parking_lot_cfg *cfg)
void flatten_dial_string(char *dialstring)
Flattens a dial string so that it can be written to/found from PBX extensions.
int comeback_goto(struct parked_user *pu, struct parking_lot *lot)
Set a channel's position in the PBX after timeout using the parking lot settings.
int ast_wrlock_contexts(void)
Write locks the context list.
Definition: pbx.c:8478
int ast_wrlock_context(struct ast_context *con)
Write locks a given context.
Definition: pbx.c:8496
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6164
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.
int ast_unlock_context(struct ast_context *con)
Definition: pbx.c:8506
int ast_async_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:8886
int ast_add_extension2_nolock(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar, const char *registrar_file, int registrar_line)
Same as ast_add_extension2, but assumes you have already locked context.
Definition: pbx.c:7281
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8488
const char * ast_get_extension_registrar(struct ast_exten *e)
Definition: pbx.c:8547
@ PARK_TIMEOUT
Definition: res_parking.h:43
@ PARK_UNSET
Definition: res_parking.h:41
#define BASE_REGISTRAR
Definition: res_parking.h:36
#define PARK_DIAL_CONTEXT
Definition: res_parking.h:37
ast_context: An extension context
Definition: pbx.c:299
structure to hold users read from users.conf

References ao2_lock, ao2_unlock, ast_add_extension2_nolock(), ast_assert, ast_async_parseable_goto(), ast_bridge_channel_leave_bridge(), AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_unlock, ast_context_find_or_create(), ast_debug, ast_free_ptr(), ast_get_extension_registrar(), ast_log, AST_MAX_EXTENSION, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_unlock_context(), ast_unlock_contexts(), ast_wrlock_context(), ast_wrlock_contexts(), BASE_REGISTRAR, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, comeback_goto(), E_MATCH, flatten_dial_string(), LOG_ERROR, NULL, PARK_DIAL_CONTEXT, PARK_TIMEOUT, PARK_UNSET, parking_timeout_set_caller_features(), pbx_builtin_setvar_helper(), pbx_find_extension(), and pbx_find_info::stacklen.

Referenced by parking_set_duration().

◆ parking_is_exten_park()

static int parking_is_exten_park ( const char *  context,
const char *  exten 
)
static

Definition at line 300 of file parking_bridge_features.c.

301{
302 struct ast_exten *exten_obj;
303 struct pbx_find_info info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
304 const char *app_at_exten;
305
306 ast_debug(4, "Checking if %s@%s is a parking exten\n", exten, context);
307 exten_obj = pbx_find_extension(NULL, NULL, &info, context, exten, 1, NULL, NULL, E_MATCH);
308 if (!exten_obj) {
309 return 0;
310 }
311
312 app_at_exten = ast_get_extension_app(exten_obj);
313 if (!app_at_exten || strcasecmp(PARK_APPLICATION, app_at_exten)) {
314 return 0;
315 }
316
317 return 1;
318}
def info(msg)
#define PARK_APPLICATION
The default parking application that Asterisk expects.
Definition: parking.h:35
const char * ast_get_extension_app(struct ast_exten *e)
Definition: pbx.c:8572

References ast_debug, ast_get_extension_app(), voicemailpwcheck::context, E_MATCH, sip_to_pjsip::info(), NULL, PARK_APPLICATION, and pbx_find_extension().

Referenced by parking_blind_transfer_park().

◆ parking_park_bridge_channel()

static int parking_park_bridge_channel ( struct ast_bridge_channel bridge_channel,
const char *  uuid_parkee,
const char *  uuid_parker,
const char *  app_data 
)
static

Definition at line 437 of file parking_bridge_features.c.

438{
439 RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
440 RAII_VAR(struct ast_bridge *, original_bridge, NULL, ao2_cleanup);
441 RAII_VAR(struct ast_channel *, parker, NULL, ao2_cleanup);
442
443 if (strcmp(ast_channel_uniqueid(bridge_channel->chan), uuid_parkee)) {
444 /* We aren't the parkee, so ignore this action. */
445 return -1;
446 }
447
448 parker = ast_channel_get_by_name(uuid_parker);
449
450 if (!parker) {
451 ast_log(LOG_NOTICE, "Channel with uuid %s left before we could start parking the call. Parking canceled.\n", uuid_parker);
452 publish_parked_call_failure(bridge_channel->chan);
453 return -1;
454 }
455
456 if (!(parking_bridge = park_application_setup(bridge_channel->chan, parker, app_data, NULL))) {
457 publish_parked_call_failure(bridge_channel->chan);
458 return -1;
459 }
460
461 ast_bridge_set_transfer_variables(bridge_channel->chan, ast_channel_name(parker), 0);
462
463 /* bridge_channel must be locked so we can get a reference to the bridge it is currently on */
464 ao2_lock(bridge_channel);
465
466 original_bridge = bridge_channel->bridge;
467 if (!original_bridge) {
468 ao2_unlock(bridge_channel);
469 publish_parked_call_failure(bridge_channel->chan);
470 return -1;
471 }
472
473 ao2_ref(original_bridge, +1); /* Cleaned by RAII_VAR */
474
475 ao2_unlock(bridge_channel);
476
477 if (ast_bridge_move(parking_bridge, original_bridge, bridge_channel->chan, NULL, 1)) {
478 ast_log(LOG_ERROR, "Failed to move %s into the parking bridge.\n",
479 ast_channel_name(bridge_channel->chan));
480 return -1;
481 }
482
483 return 0;
484}
int ast_bridge_move(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
Move a channel from one bridge to another.
Definition: bridge.c:2529
#define LOG_NOTICE
struct ast_bridge * park_application_setup(struct ast_channel *parkee, struct ast_channel *parker, const char *app_data, int *silence_announcements)
Function to prepare a channel for parking by determining which parking bridge should be used,...
void publish_parked_call_failure(struct ast_channel *parkee)
Publish a stasis parked call message for the channel indicating failure to park.
Structure that contains information about a bridge.
Definition: bridge.h:353

References ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, ast_bridge_move(), ast_bridge_set_transfer_variables(), ast_channel_get_by_name(), ast_channel_name(), ast_channel_uniqueid(), ast_log, ast_bridge_channel::bridge, ast_channel::bridge_channel, ast_bridge_channel::chan, LOG_ERROR, LOG_NOTICE, NULL, park_application_setup(), publish_parked_call_failure(), and RAII_VAR.

◆ parking_park_call()

static int parking_park_call ( struct ast_bridge_channel parker,
char *  exten,
size_t  length 
)
static

Definition at line 502 of file parking_bridge_features.c.

503{
504 RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
505 const char *lot_name;
506
507 ast_channel_lock(parker->chan);
509 ast_channel_unlock(parker->chan);
510
511 lot = parking_lot_find_by_name(lot_name);
512 if (!lot) {
513 lot = parking_create_dynamic_lot(lot_name, parker->chan);
514 }
515 if (!lot) {
516 ast_log(AST_LOG_WARNING, "Cannot Park %s: lot %s unknown\n",
517 ast_channel_name(parker->chan), lot_name);
518 return -1;
519 }
520
521 if (exten) {
522 ast_copy_string(exten, lot->cfg->parkext, length);
523 }
524 return parking_blind_transfer_park(parker, lot->cfg->parking_con, lot->cfg->parkext, NULL, NULL);
525}
#define AST_LOG_WARNING
static int parking_blind_transfer_park(struct ast_bridge_channel *bridge_channel, const char *context, const char *exten, transfer_channel_cb parked_channel_cb, struct transfer_channel_data *parked_channel_data)
struct parking_lot * parking_create_dynamic_lot(const char *name, struct ast_channel *chan)
Create a dynamic parking lot.
Definition: res_parking.c:1120
const char * find_channel_parking_lot_name(struct ast_channel *chan)
Find parking lot name from channel.
Definition: res_parking.c:668

References ao2_cleanup, ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_copy_string(), ast_log, AST_LOG_WARNING, ast_strdupa, ast_bridge_channel::chan, ast_channel::exten, find_channel_parking_lot_name(), NULL, parking_blind_transfer_park(), parking_create_dynamic_lot(), parking_lot_find_by_name(), and RAII_VAR.

Referenced by feature_park_call().

◆ parking_set_duration()

void parking_set_duration ( struct ast_bridge_features features,
struct parked_user user 
)

Setup timeout interval feature on an ast_bridge_features for parking.

Since
12.0.0
Parameters
featuresThe ast_bridge_features we are establishing the interval hook on
userThe parked_user receiving the timeout duration limits

Definition at line 706 of file parking_bridge_features.c.

707{
708 unsigned int time_limit;
709
710 time_limit = user->time_limit * 1000;
711
712 if (!time_limit) {
713 /* There is no duration limit that we need to apply. */
714 return;
715 }
716
717 /* If the time limit has already been passed, set a really low time limit so we can kick them out immediately. */
718 time_limit = ast_remaining_ms(user->start, time_limit);
719 if (time_limit <= 0) {
720 time_limit = 1;
721 }
722
723 /* The interval hook is going to need a reference to the parked_user */
724 ao2_ref(user, +1);
725
726 if (ast_bridge_interval_hook(features, 0, time_limit,
728 ast_log(LOG_ERROR, "Failed to apply duration limit to the parked call.\n");
729 ao2_ref(user, -1);
730 }
731}
void __ao2_cleanup(void *obj)
Definition: astobj2.c:677
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3388
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL
static int parking_duration_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: utils.c:2281

References __ao2_cleanup(), ao2_ref, AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_bridge_interval_hook(), ast_log, ast_remaining_ms(), LOG_ERROR, and parking_duration_callback().

Referenced by bridge_parking_push().

◆ parking_timeout_set_caller_features()

static void parking_timeout_set_caller_features ( struct ast_channel chan,
struct parking_lot_cfg cfg 
)
static

Definition at line 543 of file parking_bridge_features.c.

544{
545 char features[5];
546 char *pos;
547
548 /*
549 * We are setting the callee Dial flag values because in the
550 * timeout case, the caller is who is being called back.
551 */
552 pos = features;
554 *pos++ = 't';
555 }
557 *pos++ = 'k';
558 }
560 *pos++ = 'h';
561 }
563 *pos++ = 'x';
564 }
565 *pos = '\0';
566
567 pbx_builtin_setvar_helper(chan, "BRIDGE_FEATURES", features);
568}
@ AST_FEATURE_FLAG_BYCALLER
Definition: features.h:38
int parkedcalltransfers
Definition: res_parking.h:76
int parkedcallreparking
Definition: res_parking.h:77
int parkedcallrecording
Definition: res_parking.h:79

References AST_FEATURE_FLAG_BYCALLER, parking_lot_cfg::parkedcallhangup, parking_lot_cfg::parkedcallrecording, parking_lot_cfg::parkedcallreparking, parking_lot_cfg::parkedcalltransfers, and pbx_builtin_setvar_helper().

Referenced by parking_duration_callback().

◆ say_parking_space()

void say_parking_space ( struct ast_bridge_channel bridge_channel,
const char *  payload 
)

custom callback function for ast_bridge_channel_queue_playfile which plays a parking space and optionally hangs up the call afterwards based on the payload in playfile.

Since
12.0.0

Definition at line 684 of file parking_bridge_features.c.

685{
686 unsigned int numeric_value;
687 unsigned int hangup_after;
688
689 if (sscanf(payload, "%u %u", &hangup_after, &numeric_value) != 2) {
690 /* If say_parking_space is called with a non-numeric string, we have a problem. */
691 ast_assert(0);
692 ast_bridge_channel_leave_bridge(bridge_channel,
694 return;
695 }
696
697 ast_say_digits(bridge_channel->chan, numeric_value, "",
698 ast_channel_language(bridge_channel->chan));
699
700 if (hangup_after) {
701 ast_bridge_channel_leave_bridge(bridge_channel,
703 }
704}
const char * ast_channel_language(const struct ast_channel *chan)
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8258

References ast_assert, ast_bridge_channel_leave_bridge(), AST_CAUSE_NORMAL_CLEARING, ast_channel_language(), ast_say_digits(), BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, and ast_bridge_channel::chan.

Referenced by bridge_parking_push(), and parker_parked_call_message_response().

◆ unload_parking_bridge_features()

void unload_parking_bridge_features ( void  )

Unregister features registered by load_parking_bridge_features.

Since
12.0.0

Definition at line 796 of file parking_bridge_features.c.

797{
801}
int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
Unregister a handler for a built in feature.
Definition: bridge.c:3147
int ast_parking_unregister_bridge_features(const char *module_name)
Unregister the current parking provider.
Definition: parking.c:223
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
const char * module_name
The name of the module that provides this parking functionality.
Definition: parking.h:139

References AST_BRIDGE_BUILTIN_PARKCALL, ast_bridge_features_unregister(), ast_custom_function_unregister(), ast_parking_unregister_bridge_features(), getparkingslotchannel_function, ast_parking_bridge_feature_fn_table::module_name, and parking_provider.

Referenced by unload_module().

◆ wipe_subscription_datastore()

static void wipe_subscription_datastore ( struct ast_channel chan)
static

Definition at line 94 of file parking_bridge_features.c.

95{
96 struct ast_datastore *datastore;
97
98 ast_channel_lock(chan);
99
101 if (datastore) {
102 ast_channel_datastore_remove(chan, datastore);
103 ast_datastore_free(datastore);
104 }
105 ast_channel_unlock(chan);
106}
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2363
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2368

References ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_datastore_free(), NULL, and parked_subscription_info.

Referenced by create_parked_subscription_full(), and parker_parked_call_message_response().

Variable Documentation

◆ getparkingslotchannel_function

struct ast_custom_function getparkingslotchannel_function
static
Initial value:
= {
.name = "PARK_GET_CHANNEL",
}
static int func_get_parkingslot_channel(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
Dial plan function to get the parking lot channel of an occupied parking lot.

Definition at line 782 of file parking_bridge_features.c.

Referenced by load_parking_bridge_features(), and unload_parking_bridge_features().

◆ parked_subscription_info

const struct ast_datastore_info parked_subscription_info
static
Initial value:
= {
.type = "park subscription",
}
static void parked_subscription_datastore_destroy(void *data)

Definition at line 89 of file parking_bridge_features.c.

Referenced by create_parked_subscription_full(), and wipe_subscription_datastore().

◆ parking_provider

struct ast_parking_bridge_feature_fn_table parking_provider