[svn-commits] branch oej/metermaids-trunk r35093 - in /team/oej/metermaids-trunk: channels/...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Jun 20 05:44:08 MST 2006


Author: oej
Date: Tue Jun 20 07:44:07 2006
New Revision: 35093

URL: http://svn.digium.com/view/asterisk?rev=35093&view=rev
Log:
Actually add the metermaids code adapted to svn trunk

Modified:
    team/oej/metermaids-trunk/channels/chan_iax2.c
    team/oej/metermaids-trunk/channels/chan_sip.c
    team/oej/metermaids-trunk/include/asterisk/features.h
    team/oej/metermaids-trunk/res/res_features.c

Modified: team/oej/metermaids-trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/channels/chan_iax2.c?rev=35093&r1=35092&r2=35093&view=diff
==============================================================================
--- team/oej/metermaids-trunk/channels/chan_iax2.c (original)
+++ team/oej/metermaids-trunk/channels/chan_iax2.c Tue Jun 20 07:44:07 2006
@@ -5505,6 +5505,9 @@
 			} else
 				ast_context_remove_extension(regcontext, ext, 1, NULL);
 		}
+
+		/* Notify local watcher about extension changes */
+		local_watcher(ext, regcontext);
 	}
 }
 static void prune_peers(void);

Modified: team/oej/metermaids-trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/channels/chan_sip.c?rev=35093&r1=35092&r2=35093&view=diff
==============================================================================
--- team/oej/metermaids-trunk/channels/chan_sip.c (original)
+++ team/oej/metermaids-trunk/channels/chan_sip.c Tue Jun 20 07:44:07 2006
@@ -2203,14 +2203,17 @@
 				ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
 				continue;
 			}
-		} else {
+		} else 
 			context = global_regcontext;
-		}
-		if (onoff)
+		
+		if (onoff) {
 			ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
 				 ast_strdup(peer->name), free, "SIP");
-		else
+		} else
 			ast_context_remove_extension(context, ext, 1, NULL);
+
+		/* Notify local channel about device state change */
+		local_watcher(ext, context);
 	}
 }
 

Modified: team/oej/metermaids-trunk/include/asterisk/features.h
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/include/asterisk/features.h?rev=35093&r1=35092&r2=35093&view=diff
==============================================================================
--- team/oej/metermaids-trunk/include/asterisk/features.h (original)
+++ team/oej/metermaids-trunk/include/asterisk/features.h Tue Jun 20 07:44:07 2006
@@ -97,12 +97,20 @@
  	or remove parking extensions in the dial plan 
 		
  */
-int ast_park_metermaid_add(void (*maid)(char *exten, char *context), char *context);
+int ast_park_metermaid_add(void (*maid)(const char *exten, const char *context), const char *context);
 
-/*! Remove parking watcher 
+/*! \brief 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);
 
+/*! \brief Watcher callback for extension state changes (metermaids) 
+	Will notify about a device state change for local/ devices
+	based on exten and context
+	\param exten	Extension
+	\param context	Context
+*/
+void local_watcher(const char *exten, const char *context);
+
 #endif /* _AST_FEATURES_H */

Modified: team/oej/metermaids-trunk/res/res_features.c
URL: http://svn.digium.com/view/asterisk/team/oej/metermaids-trunk/res/res_features.c?rev=35093&r1=35092&r2=35093&view=diff
==============================================================================
--- team/oej/metermaids-trunk/res/res_features.c (original)
+++ team/oej/metermaids-trunk/res/res_features.c Tue Jun 20 07:44:07 2006
@@ -56,6 +56,7 @@
 #include "asterisk/manager.h"
 #include "asterisk/utils.h"
 #include "asterisk/adsi.h"
+#include "asterisk/devicestate.h"
 #include "asterisk/monitor.h"
 
 #ifdef __AST_DEBUG_MALLOC
@@ -73,6 +74,18 @@
 #define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000
 
 #define AST_MAX_WATCHERS 256
+
+/*! \brief List of meter maids (parking lot watchers) */
+struct features_parkwatch {
+        void (*callback)(const char *exten, const 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";
 
@@ -81,6 +94,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 automatically */
 static int parking_start;                                  /*!< First available extension for parking */
 static int parking_stop;                                   /*!< Last available extension for parking */
 
@@ -265,6 +279,85 @@
 	return adsi_print(chan, message, justify, 1);
 }
 
+/*! \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)(const char *exten, const char *context), const char *context)
+{
+	struct features_parkwatch *newmaid;
+	struct features_parkwatch *maids = metermaids;
+
+	newmaid = ast_calloc(1, sizeof(struct features_parkwatch));
+	if (!newmaid) {
+		ast_log(LOG_ERROR, "Can't allocate parking watcher, out of memory.\n");
+		return -1;
+	}
+
+	/* 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;
+}
+
+/*! \brief 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;
+}
+
+/*! \brief 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;
+}
+
+
 /*! \brief Park a call 
  	We put the user in the parking list, then wake up the parking thread to be sure it looks
 	after these channels too */
@@ -360,7 +453,8 @@
 	}
 	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))
+			notify_metermaids(exten, parking_con);
 	}
 	if (peer) 
 		ast_say_digits(peer, pu->parkingnum, "", peer->language);
@@ -1510,6 +1604,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);
@@ -1549,6 +1645,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);
@@ -1657,6 +1755,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");
 
@@ -1963,17 +2063,31 @@
 }
 
 /*! \brief Watcher callback for extension state changes (metermaids) */
-void local_watcher(char *exten, char *context) {
+void local_watcher(const char *exten, const 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;
+}
+
+/*! \brief Add parking hints for all defined parking lots */
+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;
@@ -1997,6 +2111,7 @@
 	parking_stop = 750;
 	parkfindnext = 0;
 	adsipark = 0;
+	parkaddhints = 0;
 
 	transferdigittimeout = DEFAULT_TRANSFER_DIGIT_TIMEOUT;
 	featuredigittimeout = DEFAULT_FEATURE_DIGIT_TIMEOUT;
@@ -2024,6 +2139,8 @@
 				}
 			} else if (!strcasecmp(var->name, "findslot")) {
 				parkfindnext = (!strcasecmp(var->value, "next"));
+			} else if (!strcasecmp(var->name, "parkinghints")) {
+				parkaddhints = ast_true(var->value);
 			} else if (!strcasecmp(var->name, "adsipark")) {
 				adsipark = ast_true(var->value);
 			} else if (!strcasecmp(var->name, "transferdigittimeout")) {
@@ -2143,7 +2260,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);
 		if (option_debug)
 			ast_log(LOG_DEBUG, "Removed old parking extension %s@%s\n", old_parking_ext, old_parking_con);
 	}
@@ -2152,7 +2270,13 @@
 		ast_log(LOG_ERROR, "Parking context '%s' does not exist and unable to create\n", parking_con);
 		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;
+
 }
 
 static int reload(void *mod)



More information about the svn-commits mailing list