parking_tests: Fix assertions and possibly crashes in res_parking unit tests
[asterisk/asterisk.git] / res / parking / parking_bridge_features.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Jonathan Rose <jrose@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Parking Bridge DTMF and Interval features
22  *
23  * \author Jonathan Rose <jrose@digium.com>
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include "res_parking.h"
31 #include "asterisk/utils.h"
32 #include "asterisk/astobj2.h"
33 #include "asterisk/logger.h"
34 #include "asterisk/pbx.h"
35 #include "asterisk/bridge.h"
36 #include "asterisk/bridge_internal.h"
37 #include "asterisk/bridge_channel.h"
38 #include "asterisk/bridge_features.h"
39 #include "asterisk/features.h"
40 #include "asterisk/say.h"
41 #include "asterisk/datastore.h"
42 #include "asterisk/stasis.h"
43 #include "asterisk/module.h"
44 #include "asterisk/core_local.h"
45 #include "asterisk/causes.h"
46
47 struct parked_subscription_datastore {
48         struct stasis_subscription *parked_subscription;
49 };
50
51 struct parked_subscription_data {
52         struct transfer_channel_data *transfer_data;
53         char *parkee_uuid;
54         int hangup_after:1;
55         char parker_uuid[0];
56 };
57
58 static void parked_subscription_datastore_destroy(void *data)
59 {
60         struct parked_subscription_datastore *subscription_datastore = data;
61
62         stasis_unsubscribe(subscription_datastore->parked_subscription);
63         subscription_datastore->parked_subscription = NULL;
64
65         ast_free(subscription_datastore);
66 }
67
68 static const struct ast_datastore_info parked_subscription_info = {
69         .type = "park subscription",
70         .destroy = parked_subscription_datastore_destroy,
71 };
72
73 static void wipe_subscription_datastore(struct ast_channel *chan)
74 {
75         struct ast_datastore *datastore;
76
77         ast_channel_lock(chan);
78
79         datastore = ast_channel_datastore_find(chan, &parked_subscription_info, NULL);
80         if (datastore) {
81                 ast_channel_datastore_remove(chan, datastore);
82                 ast_datastore_free(datastore);
83         }
84         ast_channel_unlock(chan);
85 }
86
87 static void parker_parked_call_message_response(struct ast_parked_call_payload *message, struct parked_subscription_data *data,
88         struct stasis_subscription *sub)
89 {
90         const char *parkee_to_act_on = data->parkee_uuid;
91         char saynum_buf[16];
92         struct ast_channel_snapshot *parkee_snapshot = message->parkee;
93         RAII_VAR(struct ast_channel *, parker, NULL, ast_channel_cleanup);
94         RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
95
96         if (strcmp(parkee_to_act_on, parkee_snapshot->uniqueid)) {
97                 return;
98         }
99
100         if (message->event_type != PARKED_CALL && message->event_type != PARKED_CALL_FAILED) {
101                 /* We only care about these two event types */
102                 return;
103         }
104
105         parker = ast_channel_get_by_name(data->parker_uuid);
106         if (!parker) {
107                 return;
108         }
109
110         ast_channel_lock(parker);
111         bridge_channel = ast_channel_get_bridge_channel(parker);
112         ast_channel_unlock(parker);
113         if (!bridge_channel) {
114                 return;
115         }
116
117         /* This subscription callback will block for the duration of the announcement if
118          * parked_subscription_data is tracking a transfer_channel_data struct. */
119         if (message->event_type == PARKED_CALL) {
120                 /* queue the saynum on the bridge channel and hangup */
121                 snprintf(saynum_buf, sizeof(saynum_buf), "%d %u", data->hangup_after, message->parkingspace);
122                 if (!data->transfer_data) {
123                         ast_bridge_channel_queue_playfile(bridge_channel, say_parking_space, saynum_buf, NULL);
124                 } else {
125                         ast_bridge_channel_queue_playfile_sync(bridge_channel, say_parking_space, saynum_buf, NULL);
126                         data->transfer_data->completed = 1;
127                 }
128                 wipe_subscription_datastore(parker);
129         } else if (message->event_type == PARKED_CALL_FAILED) {
130                 if (!data->transfer_data) {
131                         ast_bridge_channel_queue_playfile(bridge_channel, NULL, "pbx-parkingfailed", NULL);
132                 } else {
133                         ast_bridge_channel_queue_playfile_sync(bridge_channel, NULL, "pbx-parkingfailed", NULL);
134                         data->transfer_data->completed = 1;
135                 }
136                 wipe_subscription_datastore(parker);
137         }
138 }
139
140 static void parker_update_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
141 {
142         if (stasis_subscription_final_message(sub, message)) {
143                 struct parked_subscription_data *ps_data = data;
144                 ao2_cleanup(ps_data->transfer_data);
145                 ps_data->transfer_data = NULL;
146                 ast_free(data);
147                 return;
148         }
149
150         if (stasis_message_type(message) == ast_parked_call_type()) {
151                 struct ast_parked_call_payload *parked_call_message = stasis_message_data(message);
152                 parker_parked_call_message_response(parked_call_message, data, sub);
153         }
154 }
155
156 static int create_parked_subscription_full(struct ast_channel *chan, const char *parkee_uuid, int hangup_after,
157         struct transfer_channel_data *parked_channel_data)
158 {
159         struct ast_datastore *datastore;
160         struct parked_subscription_datastore *parked_datastore;
161         struct parked_subscription_data *subscription_data;
162
163         char *parker_uuid = ast_strdupa(ast_channel_uniqueid(chan));
164         size_t parker_uuid_size = strlen(parker_uuid) + 1;
165
166         /* If there is already a subscription, get rid of it. */
167         wipe_subscription_datastore(chan);
168
169         if (!(datastore = ast_datastore_alloc(&parked_subscription_info, NULL))) {
170                 return -1;
171         }
172
173         if (!(parked_datastore = ast_calloc(1, sizeof(*parked_datastore)))) {
174                 ast_datastore_free(datastore);
175                 return -1;
176         }
177
178         if (!(subscription_data = ast_calloc(1, sizeof(*subscription_data) + parker_uuid_size +
179                         strlen(parkee_uuid) + 1))) {
180                 ast_datastore_free(datastore);
181                 ast_free(parked_datastore);
182                 return -1;
183         }
184
185         if (parked_channel_data) {
186                 subscription_data->transfer_data = parked_channel_data;
187                 ao2_ref(parked_channel_data, +1);
188         }
189
190         subscription_data->hangup_after = hangup_after;
191         subscription_data->parkee_uuid = subscription_data->parker_uuid + parker_uuid_size;
192         strcpy(subscription_data->parkee_uuid, parkee_uuid);
193         strcpy(subscription_data->parker_uuid, parker_uuid);
194
195         if (!(parked_datastore->parked_subscription = stasis_subscribe(ast_parking_topic(), parker_update_cb, subscription_data))) {
196                 return -1;
197         }
198
199         datastore->data = parked_datastore;
200
201         ast_channel_lock(chan);
202         ast_channel_datastore_add(chan, datastore);
203         ast_channel_unlock(chan);
204
205         return 0;
206 }
207
208 int create_parked_subscription(struct ast_channel *chan, const char *parkee_uuid, int hangup_after)
209 {
210         return create_parked_subscription_full(chan, parkee_uuid, hangup_after, NULL);
211 }
212
213 /*!
214  * \internal
215  * \brief Helper function that creates an outgoing channel and returns it immediately. This function is nearly
216  *        identical to the dial_transfer function in bridge_basic.c, however it doesn't swap the
217  *        local channel and the channel that instigated the park.
218  */
219 static struct ast_channel *park_local_transfer(struct ast_channel *parker, const char *context, const char *exten, struct transfer_channel_data *parked_channel_data)
220 {
221         char destination[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 1];
222         struct ast_channel *parkee;
223         struct ast_channel *parkee_side_2;
224         int cause;
225
226         /* Fill the variable with the extension and context we want to call */
227         snprintf(destination, sizeof(destination), "%s@%s", exten, context);
228
229         /* Now we request that chan_local prepare to call the destination */
230         parkee = ast_request("Local", ast_channel_nativeformats(parker), NULL, parker, destination,
231                 &cause);
232         if (!parkee) {
233                 return NULL;
234         }
235
236         /* Before we actually dial out let's inherit appropriate information. */
237         ast_channel_lock_both(parker, parkee);
238         ast_channel_req_accountcodes(parkee, parker, AST_CHANNEL_REQUESTOR_REPLACEMENT);
239         ast_connected_line_copy_from_caller(ast_channel_connected(parkee), ast_channel_caller(parker));
240         ast_channel_inherit_variables(parker, parkee);
241         ast_channel_datastore_inherit(parker, parkee);
242         ast_channel_unlock(parker);
243
244         parkee_side_2 = ast_local_get_peer(parkee);
245         ast_assert(parkee_side_2 != NULL);
246         ast_channel_unlock(parkee);
247
248         /* We need to have the parker subscribe to the new local channel before hand. */
249         if (create_parked_subscription_full(parker, ast_channel_uniqueid(parkee_side_2), 1, parked_channel_data)) {
250                 ast_channel_unref(parkee_side_2);
251                 ast_hangup(parkee);
252                 return NULL;
253         }
254
255         ast_bridge_set_transfer_variables(parkee_side_2, ast_channel_name(parker), 0);
256
257         ast_channel_unref(parkee_side_2);
258
259         /* Since the above worked fine now we actually call it and return the channel */
260         if (ast_call(parkee, destination, 0)) {
261                 ast_hangup(parkee);
262                 return NULL;
263         }
264
265         return parkee;
266 }
267
268 /*!
269  * \internal
270  * \brief Determine if an extension is a parking extension
271  */
272 static int parking_is_exten_park(const char *context, const char *exten)
273 {
274         struct ast_exten *exten_obj;
275         struct pbx_find_info info = { .stacklen = 0 }; /* the rest is reset in pbx_find_extension */
276         const char *app_at_exten;
277
278         ast_debug(4, "Checking if %s@%s is a parking exten\n", exten, context);
279         exten_obj = pbx_find_extension(NULL, NULL, &info, context, exten, 1, NULL, NULL, E_MATCH);
280         if (!exten_obj) {
281                 return 0;
282         }
283
284         app_at_exten = ast_get_extension_app(exten_obj);
285         if (!app_at_exten || strcasecmp(PARK_APPLICATION, app_at_exten)) {
286                 return 0;
287         }
288
289         return 1;
290 }
291
292 /*!
293  * \internal
294  * \since 12.0.0
295  * \brief Perform a blind transfer to a parking lot
296  *
297  * In general, most parking features should work to call this function. This will safely
298  * park either a channel in the bridge with \ref bridge_channel or will park the entire
299  * bridge if more than one channel is in the bridge. It will create the correct data to
300  * pass to the \ref AstBridging Bridging API to safely park the channel.
301  *
302  * \param bridge_channel The bridge_channel representing the channel performing the park
303  * \param context The context to blind transfer to
304  * \param exten The extension to blind transfer to
305  * \param parked_channel_cb Optional callback executed prior to sending the parked channel into the bridge
306  * \param parked_channel_data Data for the parked_channel_cb
307  *
308  * \retval 0 on success
309  * \retval non-zero on error
310  */
311 static int parking_blind_transfer_park(struct ast_bridge_channel *bridge_channel,
312                 const char *context, const char *exten, transfer_channel_cb parked_channel_cb,
313                 struct transfer_channel_data *parked_channel_data)
314 {
315         RAII_VAR(struct ast_bridge_channel *, other, NULL, ao2_cleanup);
316         RAII_VAR(struct ast_channel *, other_chan, NULL, ast_channel_cleanup);
317
318         struct ast_exten *e;
319         struct pbx_find_info find_info = { .stacklen = 0 };
320         int peer_count;
321
322         if (ast_strlen_zero(context) || ast_strlen_zero(exten)) {
323                 return -1;
324         }
325
326         if (!bridge_channel->in_bridge) {
327                 return -1;
328         }
329
330         if (!parking_is_exten_park(context, exten)) {
331                 return -1;
332         }
333
334         ast_bridge_channel_lock_bridge(bridge_channel);
335         peer_count = bridge_channel->bridge->num_channels;
336         if (peer_count == 2) {
337                 other = ast_bridge_channel_peer(bridge_channel);
338                 ao2_ref(other, +1);
339                 other_chan = other->chan;
340                 ast_channel_ref(other_chan);
341         }
342         ast_bridge_unlock(bridge_channel->bridge);
343
344         if (peer_count < 2) {
345                 /* There is nothing to do if there is no one to park. */
346                 return -1;
347         }
348
349         /* With a multiparty bridge, we need to do a regular blind transfer. We link the
350          * existing bridge to the parking lot with a Local channel rather than
351          * transferring others. */
352         if (peer_count > 2) {
353                 struct ast_channel *transfer_chan = NULL;
354
355                 transfer_chan = park_local_transfer(bridge_channel->chan, context, exten, parked_channel_data);
356                 if (!transfer_chan) {
357                         return -1;
358                 }
359                 ast_channel_ref(transfer_chan);
360
361                 if (parked_channel_cb) {
362                         parked_channel_cb(transfer_chan, parked_channel_data, AST_BRIDGE_TRANSFER_MULTI_PARTY);
363                 }
364
365                 if (ast_bridge_impart(bridge_channel->bridge, transfer_chan, NULL, NULL,
366                         AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
367                         ast_hangup(transfer_chan);
368                         ast_channel_unref(transfer_chan);
369                         return -1;
370                 }
371
372                 ast_channel_unref(transfer_chan);
373
374                 return 0;
375         }
376
377         /* Subscribe to park messages with the other channel entering */
378         if (create_parked_subscription_full(bridge_channel->chan, ast_channel_uniqueid(other->chan), 1, parked_channel_data)) {
379                 return -1;
380         }
381
382         if (parked_channel_cb) {
383                 parked_channel_cb(other_chan, parked_channel_data, AST_BRIDGE_TRANSFER_SINGLE_PARTY);
384         }
385
386         e = pbx_find_extension(NULL, NULL, &find_info, context, exten, 1, NULL, NULL, E_MATCH);
387
388         /* Write the park frame with the intended recipient and other data out to the bridge. */
389         ast_bridge_channel_write_park(bridge_channel,
390                 ast_channel_uniqueid(other_chan),
391                 ast_channel_uniqueid(bridge_channel->chan),
392                 e ? ast_get_extension_app_data(e) : NULL);
393
394         return 0;
395 }
396
397 /*!
398  * \internal
399  * \since 12.0.0
400  * \brief Perform a direct park on a channel in a bridge
401  *
402  * \note This will be called from within the \ref AstBridging Bridging API
403  *
404  * \param bridge_channel The bridge_channel representing the channel to be parked
405  * \param uuid_parkee The UUID of the channel being parked
406  * \param uuid_parker The UUID of the channel performing the park
407  * \param app_data Application parseable data to pass to the parking application
408  */
409 static int parking_park_bridge_channel(struct ast_bridge_channel *bridge_channel, const char *uuid_parkee, const char *uuid_parker, const char *app_data)
410 {
411         RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
412         RAII_VAR(struct ast_bridge *, original_bridge, NULL, ao2_cleanup);
413         RAII_VAR(struct ast_channel *, parker, NULL, ao2_cleanup);
414
415         if (strcmp(ast_channel_uniqueid(bridge_channel->chan), uuid_parkee)) {
416                 /* We aren't the parkee, so ignore this action. */
417                 return -1;
418         }
419
420         parker = ast_channel_get_by_name(uuid_parker);
421
422         if (!parker) {
423                 ast_log(LOG_NOTICE, "Channel with uuid %s left before we could start parking the call. Parking canceled.\n", uuid_parker);
424                 publish_parked_call_failure(bridge_channel->chan);
425                 return -1;
426         }
427
428         if (!(parking_bridge = park_application_setup(bridge_channel->chan, parker, app_data, NULL))) {
429                 publish_parked_call_failure(bridge_channel->chan);
430                 return -1;
431         }
432
433         ast_bridge_set_transfer_variables(bridge_channel->chan, ast_channel_name(parker), 0);
434
435         /* bridge_channel must be locked so we can get a reference to the bridge it is currently on */
436         ao2_lock(bridge_channel);
437
438         original_bridge = bridge_channel->bridge;
439         if (!original_bridge) {
440                 ao2_unlock(bridge_channel);
441                 publish_parked_call_failure(bridge_channel->chan);
442                 return -1;
443         }
444
445         ao2_ref(original_bridge, +1); /* Cleaned by RAII_VAR */
446
447         ao2_unlock(bridge_channel);
448
449         if (ast_bridge_move(parking_bridge, original_bridge, bridge_channel->chan, NULL, 1)) {
450                 ast_log(LOG_ERROR, "Failed to move %s into the parking bridge.\n",
451                         ast_channel_name(bridge_channel->chan));
452                 return -1;
453         }
454
455         return 0;
456 }
457
458 /*!
459  * \internal
460  * \since 12.0.0
461  * \brief Park a call
462  *
463  * \param parker The bridge_channel parking the call
464  * \param exten Optional. The extension where the call was parked.
465  * \param length Optional. If \c exten is specified, the length of the buffer.
466  *
467  * \note This will determine the context and extension to park the channel based on
468  * the configuration of the \ref ast_channel associated with \ref parker. It will then
469  * park either the channel or the entire bridge.
470  *
471  * \retval 0 on success
472  * \retval -1 on error
473  */
474 static int parking_park_call(struct ast_bridge_channel *parker, char *exten, size_t length)
475 {
476         RAII_VAR(struct parking_lot *, lot, NULL, ao2_cleanup);
477         const char *lot_name = NULL;
478
479         ast_channel_lock(parker->chan);
480         lot_name = find_channel_parking_lot_name(parker->chan);
481         if (!ast_strlen_zero(lot_name)) {
482                 lot_name = ast_strdupa(lot_name);
483         }
484         ast_channel_unlock(parker->chan);
485
486         if (ast_strlen_zero(lot_name)) {
487                 return -1;
488         }
489
490         lot = parking_lot_find_by_name(lot_name);
491         if (!lot) {
492                 ast_log(AST_LOG_WARNING, "Cannot Park %s: lot %s unknown\n",
493                         ast_channel_name(parker->chan), lot_name);
494                 return -1;
495         }
496
497         if (exten) {
498                 ast_copy_string(exten, lot->cfg->parkext, length);
499         }
500         return parking_blind_transfer_park(parker, lot->cfg->parking_con, lot->cfg->parkext, NULL, NULL);
501 }
502
503 static int feature_park_call(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
504 {
505         SCOPED_MODULE_USE(parking_get_module_info()->self);
506
507         return parking_park_call(bridge_channel, NULL, 0);
508 }
509
510 /*!
511  * \internal
512  * \brief Setup the caller features for when that channel is dialed.
513  * \since 12.0.0
514  *
515  * \param chan Parked channel leaving the parking lot.
516  * \param cfg Parking lot configuration.
517  *
518  * \return Nothing
519  */
520 static void parking_timeout_set_caller_features(struct ast_channel *chan, struct parking_lot_cfg *cfg)
521 {
522         char features[5];
523         char *pos;
524
525         /*
526          * We are setting the callee Dial flag values because in the
527          * timeout case, the caller is who is being called back.
528          */
529         pos = features;
530         if (cfg->parkedcalltransfers & AST_FEATURE_FLAG_BYCALLER) {
531                 *pos++ = 't';
532         }
533         if (cfg->parkedcallreparking & AST_FEATURE_FLAG_BYCALLER) {
534                 *pos++ = 'k';
535         }
536         if (cfg->parkedcallhangup & AST_FEATURE_FLAG_BYCALLER) {
537                 *pos++ = 'h';
538         }
539         if (cfg->parkedcallrecording & AST_FEATURE_FLAG_BYCALLER) {
540                 *pos++ = 'x';
541         }
542         *pos = '\0';
543
544         pbx_builtin_setvar_helper(chan, "BRIDGE_FEATURES", features);
545 }
546
547 /*! \internal
548  * \brief Interval hook. Pulls a parked call from the parking bridge after the timeout is passed and sets the resolution to timeout.
549  *
550  * \param bridge_channel bridge channel this interval hook is being executed on
551  * \param hook_pvt A pointer to the parked_user struct associated with the channel is stuffed in here
552  */
553 static int parking_duration_callback(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
554 {
555         struct parked_user *user = hook_pvt;
556         struct ast_channel *chan = user->chan;
557         struct ast_context *park_dial_context;
558         const char *dial_string;
559         char *dial_string_flat;
560         char parking_space[AST_MAX_EXTENSION];
561
562         char returnexten[AST_MAX_EXTENSION];
563         char *duplicate_returnexten;
564         struct ast_exten *existing_exten;
565         struct pbx_find_info pbx_finder = { .stacklen = 0 }; /* The rest is reset in pbx_find_extension */
566
567
568         /* We are still in the bridge, so it's possible for other stuff to mess with the parked call before we leave the bridge
569            to deal with this, lock the parked user, check and set resolution. */
570         ao2_lock(user);
571         if (user->resolution != PARK_UNSET) {
572                 /* Abandon timeout since something else has resolved the parked user before we got to it. */
573                 ao2_unlock(user);
574                 return -1;
575         }
576         user->resolution = PARK_TIMEOUT;
577         ao2_unlock(user);
578
579         ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE,
580                 AST_CAUSE_NORMAL_CLEARING);
581
582         dial_string = user->parker_dial_string;
583         dial_string_flat = ast_strdupa(dial_string);
584         flatten_dial_string(dial_string_flat);
585
586         /* Set parking timeout channel variables */
587         snprintf(parking_space, sizeof(parking_space), "%d", user->parking_space);
588         ast_channel_lock(chan);
589         ast_channel_stage_snapshot(chan);
590         pbx_builtin_setvar_helper(chan, "PARKING_SPACE", parking_space);
591         pbx_builtin_setvar_helper(chan, "PARKINGSLOT", parking_space); /* Deprecated version of PARKING_SPACE */
592         pbx_builtin_setvar_helper(chan, "PARKEDLOT", user->lot->name);
593         pbx_builtin_setvar_helper(chan, "PARKER", dial_string);
594         pbx_builtin_setvar_helper(chan, "PARKER_FLAT", dial_string_flat);
595         parking_timeout_set_caller_features(chan, user->lot->cfg);
596         ast_channel_stage_snapshot_done(chan);
597         ast_channel_unlock(chan);
598
599         /* Dialplan generation for park-dial extensions */
600
601         if (ast_wrlock_contexts()) {
602                 ast_log(LOG_ERROR, "Failed to lock the contexts list. Can't add the park-dial extension.\n");
603                 return -1;
604         }
605
606         if (!(park_dial_context = ast_context_find_or_create(NULL, NULL, PARK_DIAL_CONTEXT, BASE_REGISTRAR))) {
607                 ast_log(LOG_ERROR, "Parking dial context '%s' does not exist and unable to create\n", PARK_DIAL_CONTEXT);
608                 if (ast_unlock_contexts()) {
609                         ast_assert(0);
610                 }
611                 goto abandon_extension_creation;
612         }
613
614         if (ast_wrlock_context(park_dial_context)) {
615                 ast_log(LOG_ERROR, "failed to obtain write lock on context '%s'\n", PARK_DIAL_CONTEXT);
616                 if (ast_unlock_contexts()) {
617                         ast_assert(0);
618                 }
619                 goto abandon_extension_creation;
620         }
621
622         if (ast_unlock_contexts()) {
623                 ast_assert(0);
624         }
625
626         snprintf(returnexten, sizeof(returnexten), "%s,%u", dial_string,
627                 user->lot->cfg->comebackdialtime);
628
629         duplicate_returnexten = ast_strdup(returnexten);
630         if (!duplicate_returnexten) {
631                 ast_log(LOG_ERROR, "Failed to create parking redial parker extension %s@%s - Dial(%s)\n",
632                         dial_string_flat, PARK_DIAL_CONTEXT, returnexten);
633         }
634
635         /* If an extension already exists here because we registered it for another parked call timing out, then we may overwrite it. */
636         if ((existing_exten = pbx_find_extension(NULL, NULL, &pbx_finder, PARK_DIAL_CONTEXT, dial_string_flat, 1, NULL, NULL, E_MATCH)) &&
637             (strcmp(ast_get_extension_registrar(existing_exten), BASE_REGISTRAR))) {
638                 ast_debug(3, "An extension for '%s@%s' was already registered by another registrar '%s'\n",
639                         dial_string_flat, PARK_DIAL_CONTEXT, ast_get_extension_registrar(existing_exten));
640         } else if (ast_add_extension2_nolock(park_dial_context, 1, dial_string_flat, 1, NULL, NULL,
641                         "Dial", duplicate_returnexten, ast_free_ptr, BASE_REGISTRAR)) {
642                         ast_free(duplicate_returnexten);
643                 ast_log(LOG_ERROR, "Failed to create parking redial parker extension %s@%s - Dial(%s)\n",
644                         dial_string_flat, PARK_DIAL_CONTEXT, returnexten);
645         }
646
647         if (ast_unlock_context(park_dial_context)) {
648                 ast_assert(0);
649         }
650
651 abandon_extension_creation:
652
653         /* async_goto the proper PBX destination - this should happen when we come out of the bridge */
654         if (!ast_strlen_zero(user->comeback)) {
655                 ast_async_parseable_goto(chan, user->comeback);
656         } else {
657                 comeback_goto(user, user->lot);
658         }
659
660         return -1;
661 }
662
663 void say_parking_space(struct ast_bridge_channel *bridge_channel, const char *payload)
664 {
665         unsigned int numeric_value;
666         unsigned int hangup_after;
667
668         if (sscanf(payload, "%u %u", &hangup_after, &numeric_value) != 2) {
669                 /* If say_parking_space is called with a non-numeric string, we have a problem. */
670                 ast_assert(0);
671                 ast_bridge_channel_leave_bridge(bridge_channel,
672                         BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
673                 return;
674         }
675
676         ast_say_digits(bridge_channel->chan, numeric_value, "",
677                 ast_channel_language(bridge_channel->chan));
678
679         if (hangup_after) {
680                 ast_bridge_channel_leave_bridge(bridge_channel,
681                         BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
682         }
683 }
684
685 void parking_set_duration(struct ast_bridge_features *features, struct parked_user *user)
686 {
687         unsigned int time_limit;
688
689         time_limit = user->time_limit * 1000;
690
691         if (!time_limit) {
692                 /* There is no duration limit that we need to apply. */
693                 return;
694         }
695
696         /* If the time limit has already been passed, set a really low time limit so we can kick them out immediately. */
697         time_limit = ast_remaining_ms(user->start, time_limit);
698         if (time_limit <= 0) {
699                 time_limit = 1;
700         }
701
702         /* The interval hook is going to need a reference to the parked_user */
703         ao2_ref(user, +1);
704
705         if (ast_bridge_interval_hook(features, 0, time_limit,
706                 parking_duration_callback, user, __ao2_cleanup, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
707                 ast_log(LOG_ERROR, "Failed to apply duration limit to the parked call.\n");
708                 ao2_ref(user, -1);
709         }
710 }
711
712 struct ast_parking_bridge_feature_fn_table parking_provider = {
713         .module_version = PARKING_MODULE_VERSION,
714         .module_name = __FILE__,
715         .parking_is_exten_park = parking_is_exten_park,
716         .parking_blind_transfer_park = parking_blind_transfer_park,
717         .parking_park_bridge_channel = parking_park_bridge_channel,
718         .parking_park_call = parking_park_call,
719 };
720
721 void unload_parking_bridge_features(void)
722 {
723         ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_PARKCALL);
724         ast_parking_unregister_bridge_features(parking_provider.module_name);
725 }
726
727 int load_parking_bridge_features(void)
728 {
729         parking_provider.module_info = parking_get_module_info();
730
731         if (ast_parking_register_bridge_features(&parking_provider)) {
732                 return -1;
733         }
734
735         if (ast_bridge_features_register(AST_BRIDGE_BUILTIN_PARKCALL, feature_park_call, NULL)) {
736                 return -1;
737         }
738
739         return 0;
740 }