[asterisk-commits] jpeeler: branch jpeeler/bug13494 r170810 - /team/jpeeler/bug13494/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jan 23 17:20:54 CST 2009
Author: jpeeler
Date: Fri Jan 23 17:20:53 2009
New Revision: 170810
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=170810
Log:
Pull out the slot assignment functionality from park_call_full and put into park_slot_reserve, enabling one to check and see if an attempt to enter the parking lot will succeed without doing so. The idea is to call park_slot_reserve before doing any masquerades and bail out if the parking lot entry will fail while also leaving the bridge up as well.
I believe this does what I want here... the only thing I'm concerned about is if anywhere in park_call_full needs to be protected with the parkinglock.
Modified:
team/jpeeler/bug13494/res/res_features.c
Modified: team/jpeeler/bug13494/res/res_features.c
URL: http://svn.digium.com/svn-view/asterisk/team/jpeeler/bug13494/res/res_features.c?view=diff&rev=170810&r1=170809&r2=170810
==============================================================================
--- team/jpeeler/bug13494/res/res_features.c (original)
+++ team/jpeeler/bug13494/res/res_features.c Fri Jan 23 17:20:53 2009
@@ -71,6 +71,14 @@
#define AST_MAX_WATCHERS 256
+#define FEATURE_RETURN_HANGUP -1
+#define FEATURE_RETURN_SUCCESSBREAK 0
+#define FEATURE_RETURN_PASSDIGITS 21
+#define FEATURE_RETURN_STOREDIGITS 22
+#define FEATURE_RETURN_SUCCESS 23
+#define FEATURE_RETURN_KEEPTRYING 24
+#define FEATURE_RETURN_PARKFAILED 25
+
enum {
AST_FEATURE_FLAG_NEEDSDTMF = (1 << 0),
AST_FEATURE_FLAG_ONPEER = (1 << 1),
@@ -302,16 +310,12 @@
return AST_DEVICE_INUSE;
}
-static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, const char *orig_chan_name)
-{
- struct parkeduser *pu, *cur;
- int i, x = -1, parking_range, parkingnum_copy;
- struct ast_context *con;
+static int park_slot_reserve(struct ast_channel *chan)
+{
+ struct parkeduser *cur;
+ int i, x = -1, parking_range;
const char *parkingexten;
-
- /* Allocate memory for parking data */
- if (!(pu = ast_calloc(1, sizeof(*pu))))
- return -1;
+ char validparkingexten[AST_MAX_EXTENSION];
/* Lock parking lot */
ast_mutex_lock(&parking_lock);
@@ -327,16 +331,14 @@
if (sscanf(parkingexten, "%d", &x) != 1 || x < 0) {
ast_log(LOG_WARNING, "PARKINGEXTEN does not indicate a valid parking slot: '%s'.\n", parkingexten);
ast_mutex_unlock(&parking_lock);
- free(pu);
- return 1; /* Continue execution if possible */
- }
- snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
-
- if (ast_exists_extension(NULL, parking_con, pu->parkingexten, 1, NULL)) {
+ return -1;
+ }
+ snprintf(validparkingexten, sizeof(validparkingexten), "%d", x);
+
+ if (ast_exists_extension(NULL, parking_con, validparkingexten, 1, NULL)) {
ast_mutex_unlock(&parking_lock);
- free(pu);
ast_log(LOG_WARNING, "Requested parking extension already exists: %s@%s\n", parkingexten, parking_con);
- return 1; /* Continue execution if possible */
+ return -1;
}
} else {
/* Select parking space within range */
@@ -355,15 +357,36 @@
if (!(i < parking_range)) {
ast_log(LOG_WARNING, "No more parking spaces\n");
- free(pu);
ast_mutex_unlock(&parking_lock);
return -1;
}
/* Set pointer for next parking */
if (parkfindnext)
parking_offset = x - parking_start + 1;
- snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
- }
+ }
+ ast_mutex_unlock(&parking_lock);
+
+ return x;
+}
+
+static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout, const char *orig_chan_name, int reserved)
+{
+ struct parkeduser *pu;
+ int x, parkingnum_copy;
+ struct ast_context *con;
+
+ /* Allocate memory for parking data */
+ if (!(pu = ast_calloc(1, sizeof(*pu))))
+ return -1;
+
+ if (reserved < 0)
+ x = park_slot_reserve(chan);
+ else
+ x = reserved;
+ //if ((x = park_slot_reserve(chan)) < 0)
+ // return FEATURE_RETURN_PASSDIGITS;
+
+ snprintf(pu->parkingexten, sizeof(pu->parkingexten), "%d", x);
chan->appl = "Parked Call";
chan->data = NULL;
@@ -452,7 +475,7 @@
}
}
- ast_mutex_unlock(&parking_lock);
+ //ast_mutex_unlock(&parking_lock);
/* Wake up the (presumably select()ing) thread */
pthread_kill(parking_thread, SIGURG);
@@ -481,14 +504,18 @@
after these channels too */
int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout)
{
- return park_call_full(chan, peer, timeout, extout, NULL);
+ return park_call_full(chan, peer, timeout, extout, NULL, -1);
}
static int masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout, int play_announcement, const char *orig_chan_name)
{
struct ast_channel *chan;
struct ast_frame *f;
+ int x;
int park_status;
+
+ if ((x = park_slot_reserve(rchan)) < 0)
+ return FEATURE_RETURN_PARKFAILED;
/* Make a new, fake channel that we'll use to masquerade in the real one */
if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) {
@@ -517,7 +544,7 @@
orig_chan_name = ast_strdupa(chan->name);
}
- park_status = park_call_full(chan, peer, timeout, extout, orig_chan_name);
+ park_status = park_call_full(chan, peer, timeout, extout, orig_chan_name, x);
if (park_status == 1) {
/* would be nice to play: "invalid parking extension" */
ast_hangup(chan);
@@ -536,12 +563,6 @@
{
return masq_park_call(rchan, peer, timeout, extout, 1, orig_chan_name);
}
-#define FEATURE_RETURN_HANGUP -1
-#define FEATURE_RETURN_SUCCESSBREAK 0
-#define FEATURE_RETURN_PASSDIGITS 21
-#define FEATURE_RETURN_STOREDIGITS 22
-#define FEATURE_RETURN_SUCCESS 23
-#define FEATURE_RETURN_KEEPTRYING 24
#define FEATURE_SENSE_CHAN (1 << 0)
#define FEATURE_SENSE_PEER (1 << 1)
@@ -588,8 +609,8 @@
res = ast_safe_sleep(chan, 1000);
if (!res) { /* one direction used to call park_call.... */
- masq_park_call_announce(parkee, parker, 0, NULL, orig_chan_name);
- res = 0; /* PBX should hangup zombie channel */
+ res = masq_park_call_announce(parkee, parker, 0, NULL, orig_chan_name);
+ /* PBX should hangup zombie channel if a masquerade actually occurred (res=0) */
}
ast_module_user_remove(u);
@@ -1171,7 +1192,11 @@
!ast_strlen_zero(builtin_features[x].exten)) {
/* Feature is up for consideration */
if (!strcmp(builtin_features[x].exten, code)) {
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "Feature detected: fname=%s sname=%s exten=%s\n", builtin_features[x].fname, builtin_features[x].sname, builtin_features[x].exten);
+ }
res = builtin_features[x].operation(chan, peer, config, code, sense, NULL);
+ast_log(LOG_DEBUG, "jpeeler: res = %d\n", res);
feature_detected = 1;
break;
} else if (!strncmp(builtin_features[x].exten, code, strlen(code))) {
More information about the asterisk-commits
mailing list