diff options
author | jpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-05-14 16:52:30 +0000 |
---|---|---|
committer | jpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-05-14 16:52:30 +0000 |
commit | c41065a021e6166a11363bd9739b3c40b65521c7 (patch) | |
tree | 64c57e7d080fa3d3fa91b44e21d02d36d641bfc7 /main | |
parent | de696a3e8ca8fe88739bd09435b9a01e1cfb959b (diff) |
Fixed a few problems with multiparking: call not being parked in the correct parking spot, caller not being notified of parking spot position, and improperly hanging up the call during a transfer due to timing out (not providing the extension in which to transfer).
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@116297 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r-- | main/features.c | 83 | ||||
-rw-r--r-- | main/pbx.c | 4 |
2 files changed, 40 insertions, 47 deletions
diff --git a/main/features.c b/main/features.c index 106a850b5..0b8797fcc 100644 --- a/main/features.c +++ b/main/features.c @@ -451,7 +451,6 @@ struct ast_park_call_args { * was placed. */ int *extout; const char *orig_chan_name; - struct ast_parkinglot *parkinglot; const char *return_con; const char *return_ext; int return_pri; @@ -467,37 +466,38 @@ static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer struct ast_context *con; const char *parkinglotname; const char *parkingexten; + struct ast_parkinglot *parkinglot = NULL; parkinglotname = findparkinglotname(peer); if (parkinglotname) { if (option_debug) ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname); - args->parkinglot = find_parkinglot(parkinglotname); + parkinglot = find_parkinglot(parkinglotname); } - if (!args->parkinglot) - args->parkinglot = default_parkinglot; + if (!parkinglot) + parkinglot = default_parkinglot; - parkinglot_addref(args->parkinglot); + parkinglot_addref(parkinglot); if (option_debug) - ast_log(LOG_DEBUG, "Parkinglot: %s\n", args->parkinglot->name); + ast_log(LOG_DEBUG, "Parkinglot: %s\n", parkinglot->name); /* Allocate memory for parking data */ if (!(pu = ast_calloc(1, sizeof(*pu)))) { - parkinglot_unref(args->parkinglot); + parkinglot_unref(parkinglot); return -1; } /* Lock parking list */ - AST_LIST_LOCK(&args->parkinglot->parkings); + AST_LIST_LOCK(&parkinglot->parkings); /* Check for channel variable PARKINGEXTEN */ parkingexten = pbx_builtin_getvar_helper(chan, "PARKINGEXTEN"); if (!ast_strlen_zero(parkingexten)) { - if (ast_exists_extension(NULL, args->parkinglot->parking_con, parkingexten, 1, NULL)) { - AST_LIST_UNLOCK(&args->parkinglot->parkings); - parkinglot_unref(args->parkinglot); + if (ast_exists_extension(NULL, parkinglot->parking_con, parkingexten, 1, NULL)) { + AST_LIST_UNLOCK(&parkinglot->parkings); + parkinglot_unref(parkinglot); ast_free(pu); - ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, args->parkinglot->parking_con); + ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parkinglot->parking_con); return 1; /* Continue execution if possible */ } ast_copy_string(pu->parkingexten, parkingexten, sizeof(pu->parkingexten)); @@ -507,27 +507,28 @@ static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer struct parkeduser *cur = NULL; /* Select parking space within range */ - parking_range = args->parkinglot->parking_stop - args->parkinglot->parking_start + 1; + parking_range = parkinglot->parking_stop - parkinglot->parking_start + 1; if (ast_test_flag(args, AST_PARK_OPT_RANDOMIZE)) { - start = ast_random() % (args->parkinglot->parking_stop - args->parkinglot->parking_start + 1); + start = ast_random() % (parkinglot->parking_stop - parkinglot->parking_start + 1); } else { - start = args->parkinglot->parking_start; + start = parkinglot->parking_start; } for (i = start; 1; i++) { - if (i == args->parkinglot->parking_stop + 1) { - i = args->parkinglot->parking_start - 1; + if (i == parkinglot->parking_stop + 1) { + i = parkinglot->parking_start - 1; continue; } - AST_LIST_TRAVERSE(&args->parkinglot->parkings, cur, list) { + AST_LIST_TRAVERSE(&parkinglot->parkings, cur, list) { if (cur->parkingnum == i) { break; } } if (!cur || i == start - 1) { + x = i; break; } } @@ -535,13 +536,13 @@ static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer if (i == start - 1 && cur) { ast_log(LOG_WARNING, "No more parking spaces\n"); ast_free(pu); - AST_LIST_UNLOCK(&args->parkinglot->parkings); - parkinglot_unref(args->parkinglot); + AST_LIST_UNLOCK(&parkinglot->parkings); + parkinglot_unref(parkinglot); return -1; } /* Set pointer for next parking */ - if (args->parkinglot->parkfindnext) - args->parkinglot->parking_offset = x - args->parkinglot->parking_start + 1; + if (parkinglot->parkfindnext) + parkinglot->parking_offset = x - parkinglot->parking_start + 1; } chan->appl = "Parked Call"; @@ -555,15 +556,15 @@ static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer ast_indicate(pu->chan, AST_CONTROL_RINGING); } else { ast_indicate_data(pu->chan, AST_CONTROL_HOLD, - S_OR(args->parkinglot->mohclass, NULL), - !ast_strlen_zero(args->parkinglot->mohclass) ? strlen(args->parkinglot->mohclass) + 1 : 0); + S_OR(parkinglot->mohclass, NULL), + !ast_strlen_zero(parkinglot->mohclass) ? strlen(parkinglot->mohclass) + 1 : 0); } } pu->start = ast_tvnow(); pu->parkingnum = x; - pu->parkinglot = args->parkinglot; - pu->parkingtime = (args->timeout > 0) ? args->timeout : args->parkinglot->parkingtime; + pu->parkinglot = parkinglot; + pu->parkingtime = (args->timeout > 0) ? args->timeout : parkinglot->parkingtime; if (args->extout) *(args->extout) = x; @@ -581,16 +582,17 @@ static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer pu->priority = pu->priority ? pu->priority : (chan->macropriority ? chan->macropriority : chan->priority); - AST_LIST_INSERT_TAIL(&args->parkinglot->parkings, pu, list); + AST_LIST_INSERT_TAIL(&parkinglot->parkings, pu, list); /* If parking a channel directly, don't quiet yet get parking running on it */ if (peer == chan) pu->notquiteyet = 1; - AST_LIST_UNLOCK(&args->parkinglot->parkings); + AST_LIST_UNLOCK(&parkinglot->parkings); + /* Wake up the (presumably select()ing) thread */ pthread_kill(parking_thread, SIGURG); - ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, args->parkinglot->name, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000)); + ast_verb(2, "Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds\n", pu->chan->name, pu->parkingnum, parkinglot->name, pu->context, pu->exten, pu->priority, (pu->parkingtime/1000)); if (pu->parkingnum != -1) snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x); @@ -613,9 +615,9 @@ static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer ast_adsi_unload_session(peer); } - con = ast_context_find_or_create(NULL, NULL, args->parkinglot->parking_con, registrar); + con = ast_context_find_or_create(NULL, NULL, parkinglot->parking_con, registrar); if (!con) /* Still no context? Bad */ - ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", args->parkinglot->parking_con); + ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parkinglot->parking_con); /* Tell the peer channel the number of the parking space */ if (peer && ((pu->parkingnum != -1 && ast_strlen_zero(args->orig_chan_name)) || !strcasecmp(peer->name, args->orig_chan_name))) { /* Only say number if it's a number and the channel hasn't been masqueraded away */ /* If a channel is masqueraded into peer while playing back the parking slot number do not continue playing it back. This is the case if an attended transfer occurs. */ @@ -625,13 +627,13 @@ static int ast_park_call_full(struct ast_channel *chan, struct ast_channel *peer } if (con) { if (!ast_add_extension2(con, 1, pu->parkingexten, 1, NULL, NULL, parkedcall, ast_strdup(pu->parkingexten), ast_free_ptr, registrar)) - notify_metermaids(pu->parkingexten, args->parkinglot->parking_con, AST_DEVICE_INUSE); + notify_metermaids(pu->parkingexten, parkinglot->parking_con, AST_DEVICE_INUSE); } if (pu->notquiteyet) { /* Wake up parking thread if we're really done */ ast_indicate_data(pu->chan, AST_CONTROL_HOLD, - S_OR(args->parkinglot->mohclass, NULL), - !ast_strlen_zero(args->parkinglot->mohclass) ? strlen(args->parkinglot->mohclass) + 1 : 0); + S_OR(parkinglot->mohclass, NULL), + !ast_strlen_zero(parkinglot->mohclass) ? strlen(parkinglot->mohclass) + 1 : 0); pu->notquiteyet = 0; pthread_kill(parking_thread, SIGURG); } @@ -2595,9 +2597,6 @@ static int park_call_exec(struct ast_channel *chan, void *data) char orig_exten[AST_MAX_EXTENSION]; int orig_priority = chan->priority; - const char *parkinglotname = DEFAULT_PARKINGLOT; - struct ast_parkinglot *parkinglot = NULL; - /* Data is unused at the moment but could contain a parking lot context eventually */ int res = 0; @@ -2618,15 +2617,6 @@ static int park_call_exec(struct ast_channel *chan, void *data) ast_copy_string(orig_exten, chan->exten, sizeof(orig_exten)); - /* Check if the channel has a parking lot */ - parkinglotname = findparkinglotname(chan); - - if (parkinglotname) { - if (option_debug > 2) - ast_log(LOG_DEBUG, "Found chanvar Parkinglot: %s\n", parkinglotname); - parkinglot = find_parkinglot(parkinglotname); - } - /* Setup the exten/priority to be s/1 since we don't know where this call should return */ strcpy(chan->exten, "s"); @@ -2644,7 +2634,6 @@ static int park_call_exec(struct ast_channel *chan, void *data) if (!res) { struct ast_park_call_args args = { .orig_chan_name = orig_chan_name, - .parkinglot = parkinglot, }; struct ast_flags flags = { 0 }; diff --git a/main/pbx.c b/main/pbx.c index b2c5e22b3..86b4c0454 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -1843,6 +1843,10 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan, #ifdef NEED_DEBUG_HERE ast_log(LOG_NOTICE,"Looking for cont/ext/prio/label/action = %s/%s/%d/%s/%d\n", context, exten, priority, label, (int)action); #endif + + if (ast_strlen_zero(exten)) + return NULL; + /* Initialize status if appropriate */ if (q->stacklen == 0) { q->status = STATUS_NO_CONTEXT; |