Index: channels/chan_vpb.cc
===================================================================
--- channels/chan_vpb.cc	(revision 104388)
+++ channels/chan_vpb.cc	(working copy)
@@ -33,6 +33,8 @@
 	<depend>vpbapi</depend>
  ***/
 
+#include <vpbapi.h>
+
 extern "C" {
 
 #include "asterisk.h"
@@ -58,7 +60,6 @@
 #include <sys/ioctl.h>
 #include <ctype.h>
 
-#include <vpbapi.h>
 #include <assert.h>
 
 #ifdef pthread_create
@@ -171,7 +172,7 @@
 static int break_for_dtmf=1;
 
 /* Set EC suppression threshold */
-static int ec_supp_threshold=-1;
+static short ec_supp_threshold=-1;
 
 /* Inter Digit Delay for collecting DTMF's */
 static int dtmf_idd = 3000;
@@ -181,26 +182,26 @@
 #define TIMER_PERIOD_RING 4000
 static int timer_period_ring = TIMER_PERIOD_RING;
 	  
-#define VPB_EVENTS_ALL (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \
-			|VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
+#define VPB_EVENTS_ALL (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP \
+			|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
 			|VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH)
-#define VPB_EVENTS_NODROP (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \
-			|VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
+#define VPB_EVENTS_NODROP (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP \
+			|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
 			|VPB_MRING_OFF|VPB_MSTATION_FLASH)
-#define VPB_EVENTS_NODTMF (VPB_MRING|VPB_MDIGIT|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \
-			|VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
+#define VPB_EVENTS_NODTMF (VPB_MRING|VPB_MDIGIT|VPB_MTONEDETECT|VPB_MTIMEREXP \
+			|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
 			|VPB_MRING_OFF|VPB_MDROP|VPB_MSTATION_FLASH)
-#define VPB_EVENTS_STAT (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP|VPB_MPLAY_UNDERFLOW \
-			|VPB_MRECORD_OVERFLOW|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
+#define VPB_EVENTS_STAT (VPB_MRING|VPB_MDIGIT|VPB_MDTMF|VPB_MTONEDETECT|VPB_MTIMEREXP \
+			|VPB_MSTATION_OFFHOOK|VPB_MSTATION_ONHOOK \
 			|VPB_MRING_OFF|VPB_MSTATION_FLASH)
 
 
 /* Dialing parameters for Australia */
 /* #define DIAL_WITH_CALL_PROGRESS */
-VPB_TONE_MAP DialToneMap[] = { 	{ VPB_BUSY_AUST, VPB_CALL_DISCONNECT, 0 },
+VPB_TONE_MAP DialToneMap[] = { 	{ VPB_BUSY, VPB_CALL_DISCONNECT, 0 },
   				{ VPB_DIAL, VPB_CALL_DIALTONE, 0 },
-				{ VPB_RINGBACK_308, VPB_CALL_RINGBACK, 0 },
-				{ VPB_BUSY_AUST, VPB_CALL_BUSY, 0 },
+				{ VPB_RINGBACK, VPB_CALL_RINGBACK, 0 },
+				{ VPB_BUSY, VPB_CALL_BUSY, 0 },
 				{ VPB_GRUNT, VPB_CALL_GRUNT, 0 },
 				{ 0, 0, 1 } };
 #define VPB_DIALTONE_WAIT 2000 /* Wait up to 2s for a dialtone */
@@ -328,7 +329,7 @@
 
 } *iflist = NULL;
 
-static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, char *context);
+static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, const char *context);
 static void *do_chanreads(void *pvt);
 static struct ast_channel *vpb_request(const char *type, int format, void *data, int *cause);
 static int vpb_digit_begin(struct ast_channel *ast, char digit);
@@ -361,13 +362,19 @@
 	send_html: NULL,
 	exception: NULL,
 	bridge: ast_vpb_bridge,
+	early_bridge: NULL,
 	indicate: vpb_indicate,
 	fixup: vpb_fixup,
 	setoption: NULL,
 	queryoption: NULL,
 	transfer: NULL,
 	write_video: NULL,
-	bridged_channel: NULL
+	write_text: NULL,
+	bridged_channel: NULL,
+	func_channel_read: NULL,
+	func_channel_write: NULL,
+	get_base_channel: NULL,
+	set_base_channel: NULL
 };
 
 static struct ast_channel_tech vpb_tech_indicate = {
@@ -389,13 +396,19 @@
 	send_html: NULL,
 	exception: NULL,
 	bridge: ast_vpb_bridge,
+	early_bridge: NULL,
 	indicate: NULL,
 	fixup: vpb_fixup,
 	setoption: NULL,
 	queryoption: NULL,
 	transfer: NULL,
 	write_video: NULL,
-	bridged_channel: NULL
+	write_text: NULL,
+	bridged_channel: NULL,
+	func_channel_read: NULL,
+	func_channel_write: NULL,
+	get_base_channel: NULL,
+	set_base_channel: NULL
 };
 
 /* Can't get ast_vpb_bridge() working on v4pci without either a horrible 
@@ -513,7 +526,7 @@
 
 	#else
 
-	res = vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_ON, i+1 /* resource 1 & 2 only for V4PCI*/ );
+	res = vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_ON);
 	if (res == VPB_OK) {
 		/* pthread_cond_wait(&bridges[i].cond, &bridges[i].lock);*/ /* Wait for condition signal. */
 		while( !bridges[i].endbridge ) {
@@ -577,7 +590,7 @@
 			cs[0] = cs[1];
 			cs[1] = cs[2];
 		};
-		vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_OFF, i+1 /* resource 1 & 2 only for V4PCI*/ ); 
+		vpb_bridge(p0->handle, p1->handle, VPB_BRIDGE_OFF); 
 	}
 
 	#endif
@@ -690,7 +703,7 @@
 			}
 
 		} else {
-			ast_log(LOG_ERROR, "CID record - Failed to decode caller id on %s - %s\n", p->dev, vpb_strerror(rc) );
+			ast_log(LOG_ERROR, "CID record - Failed to decode caller id on %s - %d\n", p->dev, rc );
 			strncpy(p->callerid,"unknown", sizeof(p->callerid) - 1);
 		}
 		delete cli_struct;
@@ -981,7 +994,7 @@
 			}
 			break;
 
-		case VPB_PLAY_UNDERFLOW:
+/*		case VPB_PLAY_UNDERFLOW:
 			f.frametype = AST_FRAME_NULL;
 			vpb_reset_play_fifo_alarm(p->handle);
 			break;
@@ -990,7 +1003,7 @@
 			f.frametype = AST_FRAME_NULL;
 			vpb_reset_record_fifo_alarm(p->handle);
 			break;
-
+*/
 		default:
 			f.frametype = AST_FRAME_NULL;
 			break;
@@ -1057,9 +1070,9 @@
 	 * Problem is that hangup holds p->owner->lock
 	 */
 	if ((f.frametype >= 0)&& (f.frametype != AST_FRAME_NULL)&&(p->owner)) {
-		if (ast_mutex_trylock(&p->owner->lock)==0)  {
+		if (ast_channel_trylock(p->owner)==0)  {
 			ast_queue_frame(p->owner, &f);
-			ast_mutex_unlock(&p->owner->lock);
+			ast_channel_unlock(p->owner);
 			ast_verb(4, "%s: handled_owned: Queued Frame to [%s]\n", p->dev,p->owner->name);
 		} else {
 			ast_verbose("%s: handled_owned: Missed event %d/%d \n",
@@ -1253,7 +1266,7 @@
 				}
 			} else if (!ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)){
 				if (ast_exists_extension(NULL, "default", p->ext, 1, p->callerid)) {
-					vpb_new(p,AST_STATE_UP, "default");	      
+					vpb_new(p,AST_STATE_UP, "default");
 				} else if (!ast_canmatch_extension(NULL, "default", p->ext, 1, p->callerid)) {
 					ast_verb(4, "%s: handle_notowned: can't match anything in %s or default\n", p->dev, p->context);
 					playtone(p->handle, &Busytone);
@@ -1307,8 +1320,8 @@
 		}
 
 		if (res != VPB_OK) {
-			ast_log(LOG_ERROR,"Monitor get event error %s\n", vpb_strerror(res) );
-			ast_verbose("Monitor get event error %s\n", vpb_strerror(res) );
+			ast_log(LOG_ERROR,"Monitor get event error %d\n", res );
+			ast_verbose("Monitor get event error %d\n", res );
 			continue;
 		}
 
@@ -1408,7 +1421,7 @@
 				/* Why do other drivers kill the thread? No need says I, simply awake thread with event. */
 				VPB_EVENT e;
 				e.handle = 0;
-				e.type = VPB_NULL_EVENT;
+				e.type = VPB_EVT_NONE;
 				e.data = 0;
 
 				ast_verb(4, "Trying to reawake monitor\n");
@@ -1438,7 +1451,7 @@
 	if(!bridges) {
 		if(model==vpb_model_v4pci) 
 			max_bridges = MAX_BRIDGES_V4PCI;
-		bridges = ast_calloc(1, max_bridges * sizeof(vpb_bridge_t));
+		bridges = (vpb_bridge_t *)ast_calloc(1, max_bridges * sizeof(vpb_bridge_t));
 		if(!bridges) 
 			ast_log(LOG_ERROR, "Failed to initialize bridges\n");
 		else {
@@ -1461,11 +1474,7 @@
 			vpb_echo_canc_enable();
 			ast_log(LOG_NOTICE, "Voicetronix echo cancellation ON\n");
 			if (ec_supp_threshold > -1){
-				#ifdef VPB_PRI
-				vpb_echo_canc_set_sup_thresh(0,(short *)&ec_supp_threshold);
-				#else
-				vpb_echo_canc_set_sup_thresh((short *)&ec_supp_threshold);
-				#endif
+				vpb_echo_canc_set_sup_thresh(0, &ec_supp_threshold);
 				ast_log(LOG_NOTICE, "Voicetronix EC Sup Thres set\n");
 			}
 		}
@@ -1482,7 +1491,7 @@
 	struct vpb_pvt *tmp;
 	char buf[64];
 
-	tmp = ast_calloc(1, sizeof(*tmp));
+	tmp = (vpb_pvt *)ast_calloc(1, sizeof(*tmp));
 
 	if (!tmp)
 		return NULL;
@@ -1581,7 +1590,7 @@
 	}
 
 	tmp->vpb_model = vpb_model_unknown;
-	if( vpb_get_model(buf) == VPB_OK ) {
+	if( vpb_get_model(tmp->handle, buf) == VPB_OK ) {
 		if(strcmp(buf,"V12PCI")==0) 
 			tmp->vpb_model = vpb_model_v12pci;
 		else if(strcmp(buf,"VPB4")==0) 
@@ -1802,7 +1811,7 @@
 static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
 {
 	struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
-	int res = 0,i;
+	int res = 0, i;
 	char *s = strrchr(dest, '/');
 	char dialstring[254] = "";
 	int tmp = 0;
@@ -1824,7 +1833,7 @@
 			dialstring[i] = ',';
 		else if ((dialstring[i] == 'f') || (dialstring[i] == 'F'))
 			dialstring[i] = '&';
-	}	
+	}
 
 	if (ast->_state != AST_STATE_DOWN && ast->_state != AST_STATE_RESERVED) {
 		ast_log(LOG_WARNING, "vpb_call on %s neither down nor reserved!\n", ast->name);
@@ -1835,7 +1844,7 @@
 		return -1;
 	}
 	if (p->mode != MODE_FXO)  /* Station port, ring it. */
-		res = vpb_ring_station_async(p->handle, VPB_RING_STATION_ON,0);       
+		vpb_ring_station_async(p->handle, 2);
 	else {
 		VPB_CALL call;
 
@@ -1882,16 +1891,16 @@
 		#endif
 
 		if (res != VPB_OK) {
-			ast_debug(1, "Call on %s to %s failed: %s\n", ast->name, s, vpb_strerror(res));	      
+			ast_debug(1, "Call on %s to %s failed: %d\n", ast->name, s, res);
 			res = -1;
-		} else 
+		} else
 			res = 0;
 	}
 
 	ast_verb(3, "%s: VPB Calling %s [t=%d] on %s returned %d\n",p->dev , s, timeout, ast->name, res);
 	if (res == 0) {
 		ast_setstate(ast, AST_STATE_RINGING);
-		ast_queue_control(ast,AST_CONTROL_RINGING);		
+		ast_queue_control(ast,AST_CONTROL_RINGING);
 	}
 
 	if (!p->readthread){
@@ -1965,7 +1974,7 @@
 
 	if (p->mode != MODE_FXO) {
 		/* station port. */
-		vpb_ring_station_async(p->handle, VPB_RING_STATION_OFF,0);	
+		vpb_ring_station_async(p->handle, 0);
 		if(p->state!=VPB_STATE_ONHOOK){
 			/* This is causing a "dial end" "play tone" loop
 			playtone(p->handle, &Busytone); 
@@ -2095,7 +2104,7 @@
 	return &f;
 }
 
-static inline int ast2vpbformat(int ast_format)
+static inline AudioCompress ast2vpbformat(int ast_format)
 {
 	switch(ast_format) {
 		case AST_FORMAT_ALAW:
@@ -2107,11 +2116,11 @@
 		case AST_FORMAT_ADPCM:
 			return VPB_OKIADPCM;
 		default:
-			return -1;
+			return VPB_RAW;
 	}
 }
 
-static inline char * ast2vpbformatname(int ast_format)
+static inline const char * ast2vpbformatname(int ast_format)
 {
 	switch(ast_format) {
 		case AST_FORMAT_ALAW:
@@ -2139,7 +2148,7 @@
 			return 4;
 		default:
 			return 8;
-	}   
+	}
 }
 
 int a_gain_vector(float g, short *v, int n) 
@@ -2161,7 +2170,8 @@
 static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
 {
 	struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt; 
-	int res = 0, fmt = 0;
+	int res = 0;
+	AudioCompress fmt = VPB_RAW;
 	struct timeval play_buf_time_start;
 	int tdiff;
 
@@ -2258,7 +2268,8 @@
 	struct ast_frame *fr = &p->fr;
 	char *readbuf = ((char *)p->buf) + AST_FRIENDLY_OFFSET;
 	int bridgerec = 0;
-	int afmt, readlen, res, fmt, trycnt=0;
+	int afmt, readlen, res,trycnt=0;
+	AudioCompress fmt;
 	int ignore_dtmf;
 	const char * getdtmf_var = NULL;
 
@@ -2370,7 +2381,7 @@
 
 		if (p->lastinput == -1) {
 			vpb_record_buf_start(p->handle, fmt);
-			vpb_reset_record_fifo_alarm(p->handle);
+/*			vpb_reset_record_fifo_alarm(p->handle); */
 			p->lastinput = fmt;
 			ast_verb(2, "%s: Starting record mode (codec=%d)[%s]\n",p->dev,fmt,ast2vpbformatname(afmt));
 			continue;
@@ -2419,12 +2430,12 @@
 			if (p->owner && !p->stopreads ) {
 				ast_verb(6, "%s: chanreads: queueing buffer on read frame q (state[%d])\n", p->dev,p->owner->_state);
 				do {
-					res = ast_mutex_trylock(&p->owner->lock);
+					res = ast_channel_trylock(p->owner);
 					trycnt++;
 				} while((res !=0)&&(trycnt<300));
 				if (res==0)  {
 					ast_queue_frame(p->owner, fr);
-					ast_mutex_unlock(&p->owner->lock);
+					ast_channel_unlock(p->owner);
 				} else {
 					ast_verb(5, "%s: chanreads: Couldnt get lock after %d tries!\n", p->dev,trycnt);
 				}
@@ -2477,7 +2488,7 @@
 	return NULL;
 }
 
-static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state state, char *context)
+static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state state, const char *context)
 {
 	struct ast_channel *tmp; 
 	char cid_num[256];
@@ -2518,11 +2529,11 @@
 		tmp->tech_pvt = me;
 		
 		strncpy(tmp->context, context, sizeof(tmp->context)-1);
-		if (strlen(me->ext))
-			strncpy(tmp->exten, me->ext, sizeof(tmp->exten)-1);
+		if (!ast_strlen_zero(me->ext))
+			ast_copy_string(tmp->exten, me->ext, sizeof(tmp->exten));
 		else
-			strncpy(tmp->exten, "s",  sizeof(tmp->exten) - 1);
-		if (strlen(me->language))
+			strcpy(tmp->exten, "s");
+		if (!ast_strlen_zero(me->language))
 			ast_string_field_set(tmp, language, me->language);
 
 		me->owner = tmp;
@@ -2558,7 +2569,7 @@
 	int oldformat;
 	struct vpb_pvt *p;
 	struct ast_channel *tmp = NULL;
-	char *name = ast_strdup(data ? (char *)data : "");
+	char emptystring[] = "";
 	char *s, *sepstr;
 	int group=-1;
 
@@ -2569,13 +2580,15 @@
 		return NULL;
 	}
 
+	char *name = strdup(data ? (char *)data : emptystring);
+
 	sepstr = name;
 	s = strsep(&sepstr, "/"); /* Handle / issues */
-	if (!s) 
-		s = "";
+	if (!s)
+		s = emptystring;
 	/* Check if we are looking for a group */
 	if (toupper(name[0]) == 'G' || toupper(name[0])=='R') {
-		group=atoi(name+1);	
+		group=atoi(name+1);
 	}
 	/* Search for an unowned channel */
 	ast_mutex_lock(&iflock); {
@@ -2608,7 +2621,7 @@
 	return tmp;
 }
 
-static float parse_gain_value(char *gain_type, char *value)
+static float parse_gain_value(const char *gain_type, const char *value)
 {
 	float gain;
 
@@ -2680,20 +2693,22 @@
 		iflist = NULL;
 	} ast_mutex_unlock(&iflock);
 
-	ast_mutex_lock(&bridge_lock); {
-		memset(bridges, 0, sizeof bridges);	     
-	} ast_mutex_unlock(&bridge_lock);
-	ast_mutex_destroy(&bridge_lock);
-	for(int i = 0; i < max_bridges; i++ ) {
-		ast_mutex_destroy(&bridges[i].lock);
-		ast_cond_destroy(&bridges[i].cond);
+	if (bridges) {
+		ast_mutex_lock(&bridge_lock); {
+			memset(bridges, 0, sizeof bridges);
+		} ast_mutex_unlock(&bridge_lock);
+		ast_mutex_destroy(&bridge_lock);
+		for(int i = 0; i < max_bridges; i++ ) {
+			ast_mutex_destroy(&bridges[i].lock);
+			ast_cond_destroy(&bridges[i].cond);
+		}
+		ast_free(bridges);
 	}
-	ast_free(bridges);
 
 	return 0;
 }
 
-static int load_module()
+static enum ast_module_load_result load_module()
 {
 	struct ast_config *cfg;
 	struct ast_variable *v;
@@ -2708,7 +2723,7 @@
 	int got_gain=0;
 	int first_channel = 1;
 	int echo_cancel = DEFAULT_ECHO_CANCEL;
-	int error = 0; /* Error flag */
+	enum ast_module_load_result error = AST_MODULE_LOAD_SUCCESS; /* Error flag */
 	int bal1 = -1; /* Special value - means do not set */
 	int bal2 = -1; 
 	int bal3 = -1;
@@ -2722,8 +2737,6 @@
 		return AST_MODULE_LOAD_DECLINE;
 	}  
 
-	vpb_seterrormode(VPB_ERROR_CODE);
-
 	ast_mutex_lock(&iflock); {
 		v = ast_variable_browse(cfg, "general");
 		while (v){
@@ -2759,7 +2772,7 @@
 				timer_period_ring = atoi(v->value);
 			}
 			else if (strcasecmp(v->name, "ecsuppthres") ==0) {
-				ec_supp_threshold = atoi(v->value);
+				ec_supp_threshold = (short)atoi(v->value);
 			}
 			else if (strcasecmp(v->name, "dtmfidd") ==0) {
 				dtmf_idd = atoi(v->value);
@@ -2797,7 +2810,7 @@
 					iflist = tmp;
 				} else {
 					ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
-					error = -1;
+					error = AST_MODULE_LOAD_FAILURE;
 					goto done;
 				}
 			} else if (strcasecmp(v->name, "language") == 0) {
@@ -2863,18 +2876,18 @@
 	ast_config_destroy(cfg);
 
 	if (use_ast_ind == 1){
-		if (!error && ast_channel_register(&vpb_tech_indicate) != 0) {
+		if (error == AST_MODULE_LOAD_SUCCESS && ast_channel_register(&vpb_tech_indicate) != 0) {
 			ast_log(LOG_ERROR, "Unable to register channel class 'vpb'\n");
-			error = -1;
+			error = AST_MODULE_LOAD_FAILURE;
 		}
 		else {
 			ast_log(LOG_NOTICE,"VPB driver Registered (w/AstIndication)\n");
 		}
 	}
 	else {
-		if (!error && ast_channel_register(&vpb_tech) != 0) {
+		if (error == AST_MODULE_LOAD_SUCCESS && ast_channel_register(&vpb_tech) != 0) {
 			ast_log(LOG_ERROR, "Unable to register channel class 'vpb'\n");
-			error = -1;
+			error = AST_MODULE_LOAD_FAILURE;
 		}
 		else {
 			ast_log(LOG_NOTICE,"VPB driver Registered )\n");
@@ -2882,7 +2895,7 @@
 	}
 
 
-	if (error)
+	if (error != AST_MODULE_LOAD_SUCCESS)
 		unload_module();
 	else 
 		restart_monitor(); /* And start the monitor for the first time */
@@ -2896,4 +2909,13 @@
 #endif
 /**/
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "VoiceTronix API driver");
+static int reload_module()
+{
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Voicetronix API driver",
+		load_module,
+		unload_module,
+		reload_module
+);
