[asterisk-commits] branch oej/metermaids - r7879 in
/team/oej/metermaids: channels/ configs/ inc...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Jan 9 07:32:25 CST 2006
Author: oej
Date: Mon Jan 9 07:32:21 2006
New Revision: 7879
URL: http://svn.digium.com/view/asterisk?rev=7879&view=rev
Log:
Adding patch from bug 5779
Modified:
team/oej/metermaids/channels/chan_local.c
team/oej/metermaids/configs/features.conf.sample
team/oej/metermaids/include/asterisk/features.h
team/oej/metermaids/res/res_features.c
Modified: team/oej/metermaids/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids/channels/chan_local.c?rev=7879&r1=7878&r2=7879&view=diff
==============================================================================
--- team/oej/metermaids/channels/chan_local.c (original)
+++ team/oej/metermaids/channels/chan_local.c Mon Jan 9 07:32:21 2006
@@ -59,17 +59,21 @@
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"
+#include "asterisk/devicestate.h"
+#include "asterisk/features.h"
static const char desc[] = "Local Proxy Channel";
static const char type[] = "Local";
static const char tdesc[] = "Local Proxy Channel Driver";
+static int watchid;
+
static int usecnt =0;
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
#define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
-/* Protect the interface list (of sip_pvt's) */
+/* Protect the interface list (of local_pvt's) */
AST_MUTEX_DEFINE_STATIC(locallock);
static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
@@ -82,6 +86,7 @@
static int local_indicate(struct ast_channel *ast, int condition);
static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
+static int local_devicestate(void *data);
/* PBX interface structure for channel registration */
static const struct ast_channel_tech local_tech = {
@@ -99,6 +104,7 @@
.indicate = local_indicate,
.fixup = local_fixup,
.send_html = local_sendhtml,
+ .devicestate = local_devicestate,
};
static struct local_pvt {
@@ -115,6 +121,37 @@
struct ast_channel *chan; /* Outbound channel */
struct local_pvt *next; /* Next entity */
} *locals = NULL;
+
+/* Watcher callback for extension state changes in res_features */
+void local_watcher(char *exten, char *context) {
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "Got notification of state change for %s@%s\n", exten, context);
+ ast_device_state_changed("local/%s@%s", exten, context);
+ return;
+}
+
+/*! Adds devicestate to extensions (for parking mostly)
+*/
+static int local_devicestate(void *data)
+{
+ char *exten;
+ char *context;
+
+ int res = AST_DEVICE_INVALID;
+
+ exten = ast_strdupa(data);
+ if ((context = strchr(exten, '@'))) {
+ *context = '\0';
+ context = context + 1;
+ }
+ if (option_debug > 2)
+ ast_log(LOG_DEBUG, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
+ res = ast_exists_extension(NULL, context, exten, 1, NULL);
+ if (!res)
+ return AST_EXTENSION_UNAVAILABLE;
+ else
+ return AST_EXTENSION_NOT_INUSE;
+}
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
{
@@ -612,6 +649,10 @@
return -1;
}
ast_cli_register(&cli_show_locals);
+
+ /* Register watcher for parking lots in res_features */
+ ast_log(LOG_DEBUG, "Adding metermaid watcher...\n");
+ watchid = ast_park_metermaid_add(&local_watcher, NULL);
return 0;
}
@@ -628,6 +669,7 @@
/* First, take us out of the channel loop */
ast_cli_unregister(&cli_show_locals);
+ ast_park_metermaid_remove(watchid);
ast_channel_unregister(&local_tech);
if (!ast_mutex_lock(&locallock)) {
/* Hangup all interfaces if they have an owner */
Modified: team/oej/metermaids/configs/features.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids/configs/features.conf.sample?rev=7879&r1=7878&r2=7879&view=diff
==============================================================================
--- team/oej/metermaids/configs/features.conf.sample (original)
+++ team/oej/metermaids/configs/features.conf.sample Mon Jan 9 07:32:21 2006
@@ -8,6 +8,7 @@
context => parkedcalls ; Which context parked calls are in
;parkingtime => 45 ; Number of seconds a call can be parked for
; (default is 45 seconds)
+;parkhints=yes ; Automatically add hints for all parking extensions (default no)
;transferdigittimeout => 3 ; Number of seconds to wait between digits when transfering a call
;courtesytone = beep ; Sound file to play to the parked caller
; when someone dials a parked call
Modified: team/oej/metermaids/include/asterisk/features.h
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids/include/asterisk/features.h?rev=7879&r1=7878&r2=7879&view=diff
==============================================================================
--- team/oej/metermaids/include/asterisk/features.h (original)
+++ team/oej/metermaids/include/asterisk/features.h Mon Jan 9 07:32:21 2006
@@ -92,4 +92,17 @@
\param feature the ast_call_feature object which was registered before*/
extern void ast_unregister_feature(struct ast_call_feature *feature);
+
+/*! \brief Add parking watcher (metermaid) to list. These will be notified when we create
+ or remove parking extensions in the dial plan
+
+ */
+int ast_park_metermaid_add(void (*maid)(char *exten, char *context), char *context);
+
+/*! Remove parking watcher
+ \param id Watcher ID returned by ast_park_metermaid_add()
+ \return -1 on error (ID not found), otherwise 0
+*/
+int ast_park_metermaid_remove(int id);
+
#endif /* _AST_FEATURES_H */
Modified: team/oej/metermaids/res/res_features.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids/res/res_features.c?rev=7879&r1=7878&r2=7879&view=diff
==============================================================================
--- team/oej/metermaids/res/res_features.c (original)
+++ team/oej/metermaids/res/res_features.c Mon Jan 9 07:32:21 2006
@@ -73,6 +73,18 @@
#define AST_MAX_WATCHERS 256
+/*! List of meter maids (parking lot watchers) */
+struct features_parkwatch {
+ void (*callback)(char *exten, char *context); /*! Callback for notification */
+ int id; /*! Meter maid ID */
+ char *context; /*! Watched context */
+ struct features_parkwatch *next; /*! Next in this simple list */
+};
+
+/*! Metermaid ID */
+struct features_parkwatch *metermaids;
+int metermaidid = 0;
+
static char *parkedcall = "ParkedCall";
static int parkingtime = DEFAULT_PARK_TIME; /*!< No more than 45 seconds parked before you do something with them */
@@ -80,6 +92,7 @@
static char parking_con_dial[AST_MAX_EXTENSION]; /*!< Context for dialback for parking (KLUDGE) */
static char parking_ext[AST_MAX_EXTENSION]; /*!< Extension you type to park the call */
static char pickup_ext[AST_MAX_EXTENSION]; /*!< Call pickup extension */
+static int parkaddhints = 0; /*!< Add parking hints to dial plan automatically */
static int parking_start; /*!< First available extension for parking */
static int parking_stop; /*!< Last available extension for parking */
@@ -252,6 +265,87 @@
return res;
}
return adsi_print(chan, message, justify, 1);
+}
+
+/*! Add parking watcher (metermaid) to list. These will be notified when we create
+ or remove parking extensions in the dial plan
+ */
+int ast_park_metermaid_add(void (*maid)(char *exten, char *context), char *context)
+{
+ struct features_parkwatch *newmaid;
+ struct features_parkwatch *maids = metermaids;
+
+ newmaid = malloc(sizeof(struct features_parkwatch));
+ if (!newmaid) {
+ ast_log(LOG_ERROR, "Can't allocate parking watcher, out of memory.\n");
+ return -1;
+ }
+ memset(newmaid, 0, sizeof(struct features_parkwatch));
+
+ /* Spool till end of list */
+ while(maids && maids->next) {
+ maids = maids->next;
+ }
+
+ newmaid->callback = maid;
+ if (context)
+ newmaid->context = strdup(context);
+ newmaid->id = metermaidid;
+
+ /* Generate new ID */
+ metermaidid++;
+
+ /* Link the new object to the list */
+ if (maids)
+ maids->next = newmaid;
+ else
+ metermaids = newmaid;
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "Added metermaid # %d\n", metermaidid);
+ return metermaidid;
+}
+
+/*! Remove parking watcher */
+int ast_park_metermaid_remove(int id)
+{
+ struct features_parkwatch *maids = metermaids;
+ struct features_parkwatch *prev = NULL;
+ struct features_parkwatch *kill = NULL;
+
+ while (maids && !kill) {
+ if (maids->id == id) {
+ if (prev) {
+ prev->next = maids->next;
+ } else {
+ metermaids = maids->next;
+ }
+ kill = maids;
+ }
+ prev = maids;
+ maids = maids->next;
+ }
+ if (!kill)
+ return -1; /* Did not find id */
+ if (kill->context)
+ free(kill->context);
+ free(kill);
+ return 0;
+}
+
+/*! Notify metermaids that we've changed an extension */
+static void notify_metermaids(char *exten, char *context)
+{
+ struct features_parkwatch *maid = metermaids;
+ if (!maid)
+ return;
+ while (maid) {
+ if (!maid->context || !strcmp(context, maid->context))
+ maid->callback(exten, context);
+ maid = maid->next;
+ }
+ if (option_debug > 3)
+ ast_log(LOG_DEBUG, "Notification of state change to metermaids %s@%s\n", exten, context);
+ return;
}
/*--- ast_park_call: Park a call */
@@ -367,7 +461,9 @@
}
if (con) {
snprintf(exten, sizeof(exten), "%d", x);
- ast_add_extension2(con, 1, exten, 1, NULL, NULL, parkedcall, strdup(exten), FREE, registrar);
+
+ if (ast_add_extension2(con, 1, exten, 1, NULL, NULL, parkedcall, strdup(exten), FREE, registrar) == 0)
+ notify_metermaids(exten, parking_con); /* Notify watchers */
}
if (peer)
ast_say_digits(peer, pu->parkingnum, "", peer->language);
@@ -1556,6 +1652,8 @@
snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
if (ast_context_remove_extension2(con, exten, 1, NULL))
ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
+ else
+ notify_metermaids(exten, parking_con); /* Notify watchers */
} else
ast_log(LOG_WARNING, "Whoa, no parking context?\n");
free(pt);
@@ -1598,6 +1696,8 @@
snprintf(exten, sizeof(exten), "%d", pt->parkingnum);
if (ast_context_remove_extension2(con, exten, 1, NULL))
ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
+ else
+ notify_metermaids(exten, parking_con);
} else
ast_log(LOG_WARNING, "Whoa, no parking context?\n");
free(pt);
@@ -1705,6 +1805,8 @@
snprintf(exten, sizeof(exten), "%d", pu->parkingnum);
if (ast_context_remove_extension2(con, exten, 1, NULL))
ast_log(LOG_WARNING, "Whoa, failed to remove the extension!\n");
+ else
+ notify_metermaids(exten, parking_con);
} else
ast_log(LOG_WARNING, "Whoa, no parking context?\n");
@@ -1968,9 +2070,22 @@
return res;
}
+static void park_add_hints(char *context, int start, int stop)
+{
+ int numext;
+ char device[AST_MAX_EXTENSION];
+ char exten[10];
+ for (numext = start; numext <= stop; numext++) {
+ snprintf(exten, sizeof(exten), "%d", numext);
+ snprintf(device, sizeof(device), "Local/%s@%s", exten, context);
+ ast_add_extension(context, 1, exten, PRIORITY_HINT, NULL, NULL, device, NULL, NULL, registrar);
+ }
+}
+
static int load_config(void)
{
int start = 0, end = 0;
+ int res;
struct ast_context *con = NULL;
struct ast_config *cfg = NULL;
struct ast_variable *var = NULL;
@@ -1993,6 +2108,7 @@
parking_start = 701;
parking_stop = 750;
parkfindnext = 0;
+ parkaddhints = 0;
transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
@@ -2025,6 +2141,8 @@
}
} else if (!strcasecmp(var->name, "findslot")) {
parkfindnext = (!strcasecmp(var->value, "next"));
+ } else if (!strcasecmp(var->name, "parkhints")) {
+ parkaddhints = ast_true(var->value);
} else if (!strcasecmp(var->name, "adsipark")) {
adsipark = ast_true(var->value);
} else if (!strcasecmp(var->name, "transferdigittimeout")) {
@@ -2140,7 +2258,8 @@
/* Remove the old parking extension */
if (!ast_strlen_zero(old_parking_con) && (con = ast_context_find(old_parking_con))) {
- ast_context_remove_extension2(con, old_parking_ext, 1, registrar);
+ if(!ast_context_remove_extension2(con, old_parking_ext, 1, registrar))
+ notify_metermaids(old_parking_ext, old_parking_con);
ast_log(LOG_DEBUG, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
}
@@ -2150,7 +2269,12 @@
return -1;
}
}
- return ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), FREE, registrar);
+ res = ast_add_extension2(con, 1, ast_parking_ext(), 1, NULL, NULL, parkcall, strdup(""), FREE, registrar);
+ if (parkaddhints)
+ park_add_hints(parking_con, parking_start, parking_stop);
+ if (!res)
+ notify_metermaids(ast_parking_ext(), parking_con);
+ return res;
}
int reload(void) {
More information about the asterisk-commits
mailing list