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

Parking Bridge Class. More...

#include "asterisk.h"
#include "res_parking.h"
#include "asterisk/astobj2.h"
#include "asterisk/logger.h"
#include "asterisk/say.h"
#include "asterisk/term.h"
#include "asterisk/features.h"
#include "asterisk/bridge_internal.h"
Include dependency graph for parking_bridge.c:

Go to the source code of this file.

Data Structures

struct  ast_bridge_parking
 

Functions

static struct ast_bridgeast_bridge_parking_init (struct ast_bridge_parking *self, struct parking_lot *bridge_lot)
 
static void bridge_parking_destroy (struct ast_bridge_parking *self)
 
static void bridge_parking_dissolving (struct ast_bridge_parking *self)
 
static void bridge_parking_get_merge_priority (struct ast_bridge_parking *self)
 
struct ast_bridgebridge_parking_new (struct parking_lot *bridge_lot)
 Create a new parking bridge. More...
 
static void bridge_parking_notify_masquerade (struct ast_bridge_parking *self, struct ast_bridge_channel *bridge_channel)
 
static void bridge_parking_pull (struct ast_bridge_parking *self, struct ast_bridge_channel *bridge_channel)
 
static int bridge_parking_push (struct ast_bridge_parking *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 
static void destroy_parked_user (void *obj)
 
static struct parked_usergenerate_parked_user (struct parking_lot *lot, struct ast_channel *chan, const char *parker_channel_name, const char *parker_dial_string, int use_random_space, int time_limit)
 
static int parked_user_set_parker_dial_string (struct parked_user *pu, const char *parker_channel_name)
 

Variables

struct ast_bridge_methods ast_bridge_parking_v_table
 

Detailed Description

Parking Bridge Class.

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

Definition in file parking_bridge.c.

Function Documentation

◆ ast_bridge_parking_init()

static struct ast_bridge * ast_bridge_parking_init ( struct ast_bridge_parking self,
struct parking_lot bridge_lot 
)
static

Definition at line 432 of file parking_bridge.c.

433{
434 if (!self) {
435 return NULL;
436 }
437
438 /* If no lot is defined for the bridge, then we aren't allowing the bridge to be initialized. */
439 if (!bridge_lot) {
440 ao2_ref(self, -1);
441 return NULL;
442 }
443
444 /* It doesn't need to be a reference since the bridge only lives as long as the parking lot lives. */
445 self->lot = bridge_lot;
446
447 return &self->base;
448}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define NULL
Definition: resample.c:96
struct ast_bridge base
struct parking_lot * lot

References ao2_ref, ast_bridge_parking::base, ast_bridge_parking::lot, and NULL.

Referenced by bridge_parking_new().

◆ bridge_parking_destroy()

static void bridge_parking_destroy ( struct ast_bridge_parking self)
static

Definition at line 52 of file parking_bridge.c.

53{
55}
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:923
ast_bridge_destructor_fn destroy
Definition: bridge.h:261

References ast_bridge_base_v_table, ast_bridge_parking::base, and ast_bridge_methods::destroy.

◆ bridge_parking_dissolving()

static void bridge_parking_dissolving ( struct ast_bridge_parking self)
static

Definition at line 57 of file parking_bridge.c.

58{
59 self->lot = NULL;
61}
ast_bridge_dissolving_fn dissolving
Definition: bridge.h:263

References ast_bridge_base_v_table, ast_bridge_parking::base, ast_bridge_methods::dissolving, ast_bridge_parking::lot, and NULL.

◆ bridge_parking_get_merge_priority()

static void bridge_parking_get_merge_priority ( struct ast_bridge_parking self)
static

Definition at line 417 of file parking_bridge.c.

418{
420}
ast_bridge_merge_priority_fn get_merge_priority
Definition: bridge.h:271

References ast_bridge_base_v_table, ast_bridge_parking::base, and ast_bridge_methods::get_merge_priority.

◆ bridge_parking_new()

struct ast_bridge * bridge_parking_new ( struct parking_lot bridge_lot)

Create a new parking bridge.

Since
12.0.0
Parameters
bridge_lotParking lot which the new bridge should be based on
Return values
NULLif the bridge can not be created
Returns
Newly created parking bridge

Definition at line 450 of file parking_bridge.c.

451{
452 void *bridge;
453
457 | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, "Parking", bridge_lot->name, NULL);
458 bridge = ast_bridge_parking_init(bridge, bridge_lot);
459 bridge = bridge_register(bridge);
460 return bridge;
461}
@ AST_BRIDGE_CAPABILITY_HOLDING
Definition: bridge.h:86
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:691
struct ast_bridge * bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Initialize the base class of the bridge.
Definition: bridge.c:742
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:706
struct ast_bridge_methods ast_bridge_parking_v_table
static struct ast_bridge * ast_bridge_parking_init(struct ast_bridge_parking *self, struct parking_lot *bridge_lot)
const ast_string_field name
Definition: res_parking.h:102

References AST_BRIDGE_CAPABILITY_HOLDING, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO, AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, ast_bridge_parking_init(), ast_bridge_parking_v_table, bridge_alloc(), bridge_base_init(), bridge_register(), parking_lot::name, and NULL.

Referenced by parking_lot_get_bridge().

◆ bridge_parking_notify_masquerade()

static void bridge_parking_notify_masquerade ( struct ast_bridge_parking self,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 412 of file parking_bridge.c.

413{
414 ast_bridge_base_v_table.notify_masquerade(&self->base, bridge_channel);
415}
ast_bridge_notify_masquerade_fn notify_masquerade
Definition: bridge.h:269

References ast_bridge_base_v_table, ast_bridge_parking::base, and ast_bridge_methods::notify_masquerade.

◆ bridge_parking_pull()

static void bridge_parking_pull ( struct ast_bridge_parking self,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 338 of file parking_bridge.c.

339{
340 RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup);
341
342 ast_bridge_base_v_table.pull(&self->base, bridge_channel);
343
344 /* Take over the bridge channel's pu reference. It will be released when we are done. */
345 pu = bridge_channel->bridge_pvt;
346 bridge_channel->bridge_pvt = NULL;
347
348 /* This should only happen if the exiting channel was swapped out */
349 if (!pu) {
350 return;
351 }
352
353 /* If we got here without the resolution being set, that's because the call was hung up for some reason without
354 * timing out or being picked up. There may be some forcible park removals later, but the resolution should be
355 * handled in those cases */
356 ao2_lock(pu);
357 if (pu->resolution == PARK_UNSET) {
358 pu->resolution = PARK_ABANDON;
359 }
360 ao2_unlock(pu);
361
362 /* Pull can still happen after the bridge starts dissolving, so make sure we still have a lot before trying to notify metermaids. */
363 if (self->lot) {
365 }
366
367 switch (pu->resolution) {
368 case PARK_UNSET:
369 /* This should be impossible now since the resolution is forcibly set to abandon if it was unset at this point. Resolution
370 isn't allowed to be changed when it isn't currently PARK_UNSET. */
371 break;
372 case PARK_ABANDON:
373 /* Since the call was abandoned without additional handling, we need to issue the give up event and unpark the user. */
376 break;
377 case PARK_FORCED:
378 /* PARK_FORCED is currently unused, but it is expected that it would be handled similar to PARK_ANSWERED.
379 * There is currently no event related to forced parked calls either */
380 break;
381 case PARK_ANSWERED:
382 /* If answered or forced, the channel should be pulled from the bridge as part of that process and unlinked from
383 * the parking lot afterwards. We do need to apply bridge features though and play the courtesy tone if set. */
386
387 if (pu->lot->cfg->parkedplay & AST_FEATURE_FLAG_BYCALLEE) {
388 ast_bridge_channel_queue_playfile(bridge_channel, NULL, pu->lot->cfg->courtesytone, NULL);
389 }
390 break;
391 case PARK_TIMEOUT:
392 /* Timeout is similar to abandon because it simply sets the bridge state to end and doesn't
393 * actually pull the channel. Because of that, unpark should happen in here. */
397 break;
398 }
399}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
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.
@ AST_DEVICE_NOT_INUSE
Definition: devicestate.h:54
@ AST_FEATURE_FLAG_BYCALLEE
Definition: features.h:37
@ PARKED_CALL_TIMEOUT
Definition: parking.h:48
@ PARKED_CALL_UNPARKED
Definition: parking.h:50
@ PARKED_CALL_GIVEUP
Definition: parking.h:49
void parked_call_retrieve_enable_features(struct ast_channel *chan, struct parking_lot *lot, int recipient_mode)
Apply features based on the parking lot feature options.
int unpark_parked_user(struct parked_user *pu)
Pull a parked user out of its parking lot. Use this when you don't want to use the parked user afterw...
void parking_notify_metermaids(int exten, const char *context, enum ast_device_state state)
Notify metermaids that we've changed an extension.
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.
@ PARK_ANSWERED
Definition: res_parking.h:45
@ PARK_TIMEOUT
Definition: res_parking.h:43
@ PARK_FORCED
Definition: res_parking.h:44
@ PARK_UNSET
Definition: res_parking.h:41
@ PARK_ABANDON
Definition: res_parking.h:42
void * bridge_pvt
Bridge class private channel data.
struct ast_channel * chan
ast_bridge_pull_channel_fn pull
Definition: bridge.h:267
const ast_string_field parking_con
Definition: res_parking.h:89
struct parking_lot_cfg * cfg
Definition: res_parking.h: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:941

References ao2_cleanup, ao2_lock, ao2_unlock, ast_bridge_base_v_table, ast_bridge_channel_queue_playfile(), AST_DEVICE_NOT_INUSE, AST_FEATURE_FLAG_BYCALLEE, ast_bridge_parking::base, ast_bridge_channel::bridge_pvt, parking_lot::cfg, ast_bridge_channel::chan, ast_bridge_parking::lot, NULL, PARK_ABANDON, PARK_ANSWERED, PARK_FORCED, PARK_TIMEOUT, PARK_UNSET, PARKED_CALL_GIVEUP, parked_call_retrieve_enable_features(), PARKED_CALL_TIMEOUT, PARKED_CALL_UNPARKED, parking_lot_cfg::parking_con, parking_notify_metermaids(), publish_parked_call(), ast_bridge_methods::pull, RAII_VAR, and unpark_parked_user().

◆ bridge_parking_push()

static int bridge_parking_push ( struct ast_bridge_parking self,
struct ast_bridge_channel bridge_channel,
struct ast_bridge_channel swap 
)
static

Definition at line 204 of file parking_bridge.c.

205{
206 struct parked_user *pu;
207 const char *blind_transfer;
208 struct ast_channel_snapshot *parker = NULL;
209 const char *parker_channel_name = NULL;
211
212 ast_bridge_base_v_table.push(&self->base, bridge_channel, swap);
213
214 ast_assert(self->lot != NULL);
215
216 /* Answer the channel if needed */
217 if (ast_channel_state(bridge_channel->chan) != AST_STATE_UP) {
218 ast_answer(bridge_channel->chan);
219 }
220
221 if (swap) {
222 int use_ringing = 0;
223
225 pu = swap->bridge_pvt;
226 if (!pu) {
227 /* This should be impossible since the only way a channel can enter in the first place
228 * is if it has a parked user associated with it */
229 publish_parked_call_failure(bridge_channel->chan);
231 return -1;
232 }
233
234 /* Give the swap channel's parked user reference to the incoming channel */
235 pu->chan = bridge_channel->chan;
236 bridge_channel->bridge_pvt = pu;
237 swap->bridge_pvt = NULL;
238
239 if (ast_bridge_channel_has_role(swap, "holding_participant")) {
240 const char *idle_mode = ast_bridge_channel_get_role_option(swap, "holding_participant", "idle_mode");
241
242 if (!ast_strlen_zero(idle_mode) && !strcmp(idle_mode, "ringing")) {
243 use_ringing = 1;
244 }
245 }
246
248
249 parking_set_duration(bridge_channel->features, pu);
250
251 if (parking_channel_set_roles(bridge_channel->chan, self->lot, use_ringing)) {
252 ast_log(LOG_WARNING, "Failed to apply holding bridge roles to %s while joining the parking lot.\n",
253 ast_channel_name(bridge_channel->chan));
254 }
255
257
258 return 0;
259 }
260
261 if (!(park_datastore = get_park_common_datastore_copy(bridge_channel->chan))) {
262 /* There was either a failure to apply the datastore when performing park common setup or else we had alloc failures while cloning. Abort. */
263 return -1;
264 }
265 parker = ast_channel_snapshot_get_latest(park_datastore->parker_uuid);
266
267 /* If the parker and the parkee are the same channel pointer, then the channel entered using
268 * the park application. It's possible that the channel that transferred it is still alive (particularly
269 * when a multichannel bridge is parked), so try to get the real parker if possible. */
270 ast_channel_lock(bridge_channel->chan);
271 blind_transfer = pbx_builtin_getvar_helper(bridge_channel->chan, "BLINDTRANSFER");
272 blind_transfer = ast_strdupa(S_OR(blind_transfer, ""));
273 ast_channel_unlock(bridge_channel->chan);
274 if (!parker || !strcmp(parker->base->name, ast_channel_name(bridge_channel->chan))) {
275 if (ast_strlen_zero(blind_transfer) && parker) {
276 /* If no BLINDTRANSFER exists but the parker does then use their channel name */
277 parker_channel_name = parker->base->name;
278 } else {
279 /* Even if there is no BLINDTRANSFER dialplan variable then blind_transfer will
280 * be an empty string.
281 */
282 parker_channel_name = blind_transfer;
283 }
284 } else {
285 parker_channel_name = parker->base->name;
286 }
287
288 pu = generate_parked_user(self->lot, bridge_channel->chan, parker_channel_name,
289 park_datastore->parker_dial_string, park_datastore->randomize, park_datastore->time_limit);
290 ao2_cleanup(parker);
291 if (!pu) {
292 publish_parked_call_failure(bridge_channel->chan);
293 return -1;
294 }
295
296 /* If a comeback_override was provided, set it for the parked user's comeback string. */
297 if (park_datastore->comeback_override) {
298 ast_copy_string(pu->comeback, park_datastore->comeback_override, sizeof(pu->comeback));
299 }
300
301 /* Generate ParkedCall Stasis Message */
303
304 /* If not a blind transfer and silence_announce isn't set, play the announcement to the parkee */
305 if (ast_strlen_zero(blind_transfer) && !park_datastore->silence_announce) {
306 char saynum_buf[16];
307
308 snprintf(saynum_buf, sizeof(saynum_buf), "%d %d", 0, pu->parking_space);
309 ast_bridge_channel_queue_playfile(bridge_channel, say_parking_space, saynum_buf, NULL);
310 }
311
312 /* Apply parking duration limits */
313 parking_set_duration(bridge_channel->features, pu);
314
315 /* Set this to the bridge pvt so that we don't have to refind the parked user associated with this bridge channel again. */
316 bridge_channel->bridge_pvt = pu;
317
318 ast_verb(3, "Parking '" COLORIZE_FMT "' in '" COLORIZE_FMT "' at space %d\n",
319 COLORIZE(COLOR_BRMAGENTA, 0, ast_channel_name(bridge_channel->chan)),
320 COLORIZE(COLOR_BRMAGENTA, 0, self->lot->name),
321 pu->parking_space);
322
324
325 return 0;
326}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
const char * ast_bridge_channel_get_role_option(struct ast_bridge_channel *bridge_channel, const char *role_name, const char *option)
Retrieve the value of a requested role option from a bridge channel.
Definition: bridge_roles.c:423
int ast_bridge_channel_has_role(struct ast_bridge_channel *bridge_channel, const char *role_name)
Check to see if a bridge channel inherited a specific role from its channel.
Definition: bridge_roles.c:414
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2805
#define ast_channel_unlock(chan)
Definition: channel.h:2923
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
@ AST_DEVICE_INUSE
Definition: devicestate.h:55
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
#define ast_verb(level,...)
#define LOG_WARNING
@ PARKED_CALL
Definition: parking.h:47
@ PARKED_CALL_SWAP
Definition: parking.h:52
void park_common_datastore_free(struct park_common_datastore *datastore)
Free a park common datastore struct.
struct park_common_datastore * get_park_common_datastore_copy(struct ast_channel *parkee)
Get a copy of the park_common_datastore from a channel that is being parked.
static struct parked_user * generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, const char *parker_channel_name, const char *parker_dial_string, int use_random_space, int time_limit)
void parking_set_duration(struct ast_bridge_features *features, struct parked_user *user)
Setup timeout interval feature on an ast_bridge_features for parking.
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...
int parking_channel_set_roles(struct ast_channel *chan, struct parking_lot *lot, int force_ringing)
Set necessary bridge roles on a channel that is about to enter a parking lot.
void publish_parked_call_failure(struct ast_channel *parkee)
Publish a stasis parked call message for the channel indicating failure to park.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
struct ast_bridge_features * features
ast_bridge_push_channel_fn push
Definition: bridge.h:265
const ast_string_field name
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
int parking_space
Definition: res_parking.h:109
struct ast_channel * chan
Definition: res_parking.h:106
char comeback[AST_MAX_CONTEXT]
Definition: res_parking.h:110
#define COLORIZE(fg, bg, str)
Definition: term.h:72
#define COLORIZE_FMT
Shortcut macros for coloring a set of text.
Definition: term.h:71
#define COLOR_BRMAGENTA
Definition: term.h:61
#define ast_assert(a)
Definition: utils.h:739

References ao2_cleanup, ast_answer(), ast_assert, ast_bridge_base_v_table, ast_bridge_channel_get_role_option(), ast_bridge_channel_has_role(), ast_bridge_channel_lock, ast_bridge_channel_queue_playfile(), ast_bridge_channel_unlock, ast_channel_lock, ast_channel_name(), ast_channel_snapshot_get_latest(), ast_channel_unlock, ast_copy_string(), AST_DEVICE_INUSE, ast_log, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_verb, ast_channel_snapshot::base, ast_bridge_parking::base, ast_bridge_channel::bridge_pvt, parking_lot::cfg, ast_bridge_channel::chan, parked_user::chan, COLOR_BRMAGENTA, COLORIZE, COLORIZE_FMT, parked_user::comeback, ast_bridge_channel::features, generate_parked_user(), get_park_common_datastore_copy(), LOG_WARNING, ast_bridge_parking::lot, ast_channel_snapshot_base::name, parking_lot::name, NULL, park_common_datastore_free(), PARKED_CALL, PARKED_CALL_SWAP, parking_channel_set_roles(), parking_lot_cfg::parking_con, parking_notify_metermaids(), parking_set_duration(), parked_user::parking_space, pbx_builtin_getvar_helper(), publish_parked_call(), publish_parked_call_failure(), ast_bridge_methods::push, RAII_VAR, S_OR, and say_parking_space().

◆ destroy_parked_user()

static void destroy_parked_user ( void *  obj)
static

Definition at line 63 of file parking_bridge.c.

64{
65 struct parked_user *pu = obj;
66
67 ao2_cleanup(pu->lot);
70}
#define ast_free(a)
Definition: astmm.h:180
char * parker_dial_string
Definition: res_parking.h:111
struct parking_lot * lot
Definition: res_parking.h:113
struct ast_channel_snapshot * retriever
Definition: res_parking.h:107

References ao2_cleanup, ast_free, parked_user::lot, parked_user::parker_dial_string, and parked_user::retriever.

Referenced by generate_parked_user().

◆ generate_parked_user()

static struct parked_user * generate_parked_user ( struct parking_lot lot,
struct ast_channel chan,
const char *  parker_channel_name,
const char *  parker_dial_string,
int  use_random_space,
int  time_limit 
)
static

Definition at line 107 of file parking_bridge.c.

108{
109 struct parked_user *new_parked_user;
110 int preferred_space = -1; /* Initialize to use parking lot defaults */
111 int parking_space;
112 const char *parkingexten;
113
114 if (lot->mode == PARKINGLOT_DISABLED) {
115 ast_log(LOG_NOTICE, "Tried to park in a parking lot that is no longer able to be parked to.\n");
116 return NULL;
117 }
118
119 new_parked_user = ao2_alloc(sizeof(*new_parked_user), destroy_parked_user);
120 if (!new_parked_user) {
121 return NULL;
122 }
123
124 if (use_random_space) {
125 preferred_space = ast_random() % (lot->cfg->parking_stop - lot->cfg->parking_start + 1);
126 preferred_space += lot->cfg->parking_start;
127 } else {
129 if ((parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"))) {
130 parkingexten = ast_strdupa(parkingexten);
131 }
133
134 if (!ast_strlen_zero(parkingexten)) {
135 if (sscanf(parkingexten, "%30d", &preferred_space) != 1 || preferred_space <= 0) {
136 ast_log(LOG_WARNING, "PARKINGEXTEN='%s' is not a valid parking space.\n", parkingexten);
137 ao2_ref(new_parked_user, -1);
138 return NULL;
139 }
140 }
141 }
142
143 /* We need to keep the lot locked between parking_lot_get_space and actually placing it in the lot. Or until we decide not to. */
144 ao2_lock(lot);
145
146 parking_space = parking_lot_get_space(lot, preferred_space);
147 if (parking_space == -1) {
148 ast_log(LOG_NOTICE, "Failed to get parking space in lot '%s'. All full.\n", lot->name);
149 ao2_ref(new_parked_user, -1);
151 return NULL;
152 }
153
155 new_parked_user->chan = chan;
156 new_parked_user->parking_space = parking_space;
157
158 /* Have the parked user take a reference to the parking lot. This reference should be immutable and released at destruction */
159 new_parked_user->lot = lot;
160 ao2_ref(lot, +1);
161
162 new_parked_user->start = ast_tvnow();
163 new_parked_user->time_limit = (time_limit >= 0) ? time_limit : lot->cfg->parkingtime;
164
167 } else {
168 if (ast_strlen_zero(parker_channel_name) || parked_user_set_parker_dial_string(new_parked_user, parker_channel_name)) {
169 ao2_ref(new_parked_user, -1);
171 return NULL;
172 }
173 }
174
175 if (!new_parked_user->parker_dial_string) {
176 ao2_ref(new_parked_user, -1);
178 return NULL;
179 }
180
181 /* Insert into the parking lot's parked user list. We can unlock the lot now. */
182 ao2_link(lot->parked_users, new_parked_user);
184
185 return new_parked_user;
186}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define LOG_NOTICE
static void destroy_parked_user(void *obj)
static int parked_user_set_parker_dial_string(struct parked_user *pu, const char *parker_channel_name)
int parking_lot_get_space(struct parking_lot *lot, int target_override)
Get an available parking space within a parking lot.
@ PARKINGLOT_DISABLED
Definition: res_parking.h:61
unsigned int time_limit
Definition: res_parking.h:112
struct timeval start
Definition: res_parking.h:108
unsigned int parkingtime
Definition: res_parking.h:69
int next_space
Definition: res_parking.h:93
enum parking_lot_modes mode
Definition: res_parking.h:97
struct ao2_container * parked_users
Definition: res_parking.h:95
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
long int ast_random(void)
Definition: utils.c:2312

References ao2_alloc, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_channel_lock, ast_channel_unlock, ast_log, ast_random(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_tvnow(), parking_lot::cfg, parked_user::chan, destroy_parked_user(), if(), LOG_NOTICE, LOG_WARNING, parked_user::lot, parking_lot::mode, parking_lot::name, parking_lot::next_space, NULL, parked_user_set_parker_dial_string(), parking_lot::parked_users, parked_user::parker_dial_string, parking_lot_get_space(), parked_user::parking_space, parking_lot_cfg::parking_start, parking_lot_cfg::parking_stop, PARKINGLOT_DISABLED, parking_lot_cfg::parkingtime, pbx_builtin_getvar_helper(), parked_user::start, and parked_user::time_limit.

Referenced by bridge_parking_push().

◆ parked_user_set_parker_dial_string()

static int parked_user_set_parker_dial_string ( struct parked_user pu,
const char *  parker_channel_name 
)
static

Definition at line 73 of file parking_bridge.c.

74{
75 char *dial_string = ast_strdupa(parker_channel_name);
76
78 pu->parker_dial_string = ast_strdup(dial_string);
79
80 if (!pu->parker_dial_string) {
81 return -1;
82 }
83
84 return 0;
85}
void ast_channel_name_to_dial_string(char *channel_name)
Removes the trailing identifiers from a channel name string.
Definition: channel.c:6839

References ast_channel_name_to_dial_string(), ast_strdup, ast_strdupa, and parked_user::parker_dial_string.

Referenced by generate_parked_user().

Variable Documentation

◆ ast_bridge_parking_v_table

struct ast_bridge_methods ast_bridge_parking_v_table

Definition at line 422 of file parking_bridge.c.

Referenced by bridge_parking_new().