[asterisk-commits] moy: branch moy/mfcr2 r157227 - /team/moy/mfcr2/channels/chan_dahdi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Nov 15 16:01:43 CST 2008


Author: moy
Date: Sat Nov 15 16:01:43 2008
New Revision: 157227

URL: http://svn.digium.com/view/asterisk?view=rev&rev=157227
Log:
removed artificial limit in the number of R2 links

Modified:
    team/moy/mfcr2/channels/chan_dahdi.c

Modified: team/moy/mfcr2/channels/chan_dahdi.c
URL: http://svn.digium.com/view/asterisk/team/moy/mfcr2/channels/chan_dahdi.c?view=diff&rev=157227&r1=157226&r2=157227
==============================================================================
--- team/moy/mfcr2/channels/chan_dahdi.c (original)
+++ team/moy/mfcr2/channels/chan_dahdi.c Sat Nov 15 16:01:43 2008
@@ -215,7 +215,7 @@
 	#if defined(HAVE_PRI) || defined(HAVE_SS7)
 	" & MFC/R2"
 	#else
-	"MFCR2"
+	"MFC/R2"
 	#endif
 #endif
 ;
@@ -241,7 +241,7 @@
 #define SIG_BRI		(0x2000000 | DAHDI_SIG_CLEAR)
 #define SIG_BRI_PTMP	(0X4000000 | DAHDI_SIG_CLEAR)
 #define SIG_SS7		(0x1000000 | DAHDI_SIG_CLEAR)
-#define SIG_MFCR2	DAHDI_SIG_CAS
+#define SIG_MFCR2   	DAHDI_SIG_CAS
 #define	SIG_SF		DAHDI_SIG_SF
 #define SIG_SFWINK 	(0x0100000 | DAHDI_SIG_SF)
 #define SIG_SF_FEATD	(0x0200000 | DAHDI_SIG_SF)
@@ -439,49 +439,37 @@
 #endif /* HAVE_SS7 */
 
 #ifdef HAVE_OPENR2
-
-struct dahdi_mf_tx_state {
-	openr2_chan_t *r2chan;
-	int forward;
-	int signal;
-	int generate;
-};
-
-struct dahdi_mf_rx_state {
-	struct ast_dsp *detector;
-	int signal;
-	struct ast_frame fr;
-};
-
 struct dahdi_mfcr2 {
-	pthread_t master;		       /*!< Thread of master */
+	pthread_t r2master;		       /*!< Thread of master */
 	openr2_context_t *protocol_context;    /*!< OpenR2 context handle */ 
 	struct dahdi_pvt *pvts[MAX_CHANNELS];     /*!< Member channel pvt structs */
 	int numchans;                          /*!< Number of channels in this R2 block */
 	int monitored_count;                   /*!< Number of channels being monitored */
 	ast_mutex_t monitored_count_lock;      /*!< lock access to the counter */ 
 	ast_cond_t do_monitor;                 /*!< Condition to wake up the monitor thread when there's work to do */
+
 };
-
-static struct dahdi_mfcr2 r2links[NUM_SPANS];
-static openr2_variant_t mfcr2_cur_variant = OR2_VAR_UNKNOWN;
-static int mfcr2_cur_mfback_timeout = -1;
-static int mfcr2_cur_metering_pulse_timeout = -1;
-static int mfcr2_cur_max_ani = 10;
-static int mfcr2_cur_max_dnis = 4;
-static int mfcr2_cur_get_ani_first = -1;
-static int mfcr2_cur_context_index = 0;
-static int mfcr2_cur_call_files = 0;
-static int mfcr2_cur_allow_collect_calls = 0; 
-static int mfcr2_cur_charge_calls = 1; 
-static int mfcr2_cur_forced_release = 0; 
-static int mfcr2_cur_double_answer = 0; 
-static int mfcr2_cur_immediate_accept = -1;
-static char mfcr2_cur_logdir[OR2_MAX_LOGDIR];
-static char mfcr2_cur_r2proto_file[OR2_MAX_LOGDIR];
-static openr2_log_level_t mfcr2_cur_loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING;
-static openr2_calling_party_category_t mfcr2_cur_category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
-
+struct dahdi_mfcr2_conf {
+	openr2_variant_t variant;
+	int mfback_timeout;
+	int metering_pulse_timeout;
+	int max_ani;
+	int max_dnis;
+	int get_ani_first;
+	int call_files;
+	int allow_collect_calls;
+	int charge_calls;
+	int forced_release;
+	int double_answer;
+	int immediate_accept;
+	char logdir[OR2_MAX_PATH];
+	char r2proto_file[OR2_MAX_PATH];
+	openr2_log_level_t loglevel;
+	openr2_calling_party_category_t category;
+};
+static struct dahdi_mfcr2 **r2links = NULL; // malloc'd r2links
+static int r2links_count = 0; // how many r2links have been malloc'd
+static int r2links_index = 0; // current link when configuring
 #endif /* HAVE_OPENR2 */
 
 #ifdef HAVE_PRI
@@ -845,8 +833,6 @@
 	openr2_chan_t *r2chan;
 	openr2_calling_party_category_t mfcr2_recvd_category;
 	openr2_calling_party_category_t mfcr2_category;
-	struct dahdi_mf_tx_state mf_tx_state;
-	struct dahdi_mf_rx_state mf_rx_state;
 	int mfcr2_charge_calls;
 	int mfcr2_allow_collect_calls;
 	int mfcr2_forced_release;
@@ -877,6 +863,10 @@
 #ifdef HAVE_SS7
 	struct dahdi_ss7 ss7;
 #endif
+
+#ifdef HAVE_OPENR2
+	struct dahdi_mfcr2_conf mfcr2;
+#endif
 	struct dahdi_params timing;
 	int is_sig_auto; /*!< Use channel signalling from DAHDI? */
 
@@ -916,6 +906,26 @@
 			.nationalprefix = "",
 			.subscriberprefix = "",
 			.unknownprefix = ""
+		},
+#endif
+#ifdef HAVE_OPENR2
+		.mfcr2 = {
+			.variant = OR2_VAR_ITU,
+			.mfback_timeout = -1,
+			.metering_pulse_timeout = -1,
+			.max_ani = 10,
+			.max_dnis = 4,
+			.get_ani_first = -1,
+			.call_files = 0,
+			.allow_collect_calls = 0,
+			.charge_calls = 1,
+			.forced_release = 0,
+			.double_answer = 0,
+			.immediate_accept = -1,
+			.logdir = "",
+			.r2proto_file = "",
+			.loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
+			.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
 		},
 #endif
 		.chan = {
@@ -1199,32 +1209,6 @@
 
 static struct ast_channel *dahdi_new(struct dahdi_pvt *, int, int, int, int, int);
 #ifdef HAVE_OPENR2
-
-static void init_mfcr2_globals(void)
-{
-	mfcr2_cur_context_index = 0;
-	mfcr2_cur_variant = OR2_VAR_UNKNOWN;
-	mfcr2_cur_mfback_timeout = -1;
-	mfcr2_cur_metering_pulse_timeout = -1;
-	mfcr2_cur_max_ani = 10;
-	mfcr2_cur_max_dnis = 4;
-	mfcr2_cur_get_ani_first = -1;
-	mfcr2_cur_call_files = 0;
-	mfcr2_cur_allow_collect_calls = 0;
-	mfcr2_cur_forced_release = 0;
-	mfcr2_cur_double_answer = 0;
-	mfcr2_cur_immediate_accept = -1;
-	mfcr2_cur_loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING;
-	mfcr2_cur_category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
-	memset(mfcr2_cur_logdir, 0, sizeof(mfcr2_cur_logdir));
-	memset(mfcr2_cur_r2proto_file, 0, sizeof(mfcr2_cur_r2proto_file));
-	memset(r2links, 0, sizeof(r2links));
-	int r;
-	for (r = 0; r < NUM_SPANS; r++) {
-		r2links[r].master = AST_PTHREADT_NULL;
-	}
-}
-
 static openr2_calling_party_category_t dahdi_r2_get_channel_category(struct ast_channel *c)
 {
 	openr2_calling_party_category_t cat;
@@ -1243,155 +1227,6 @@
 	ast_log(LOG_DEBUG, "Using category %s\n", catstr);
 	return cat;
 }
-
-static void *dahdi_r2_mf_tx_init(struct dahdi_mf_tx_state *handle, int forward_signals)
-{
-	struct dahdi_dialoperation dahdi_operation = {
-		.op = DAHDI_DIAL_OP_REPLACE
-	};
-	int res;
-	/* choose either fOrward or Reverse signals */
-	ast_copy_string(dahdi_operation.dialstr, forward_signals ? "O" : "R", sizeof(dahdi_operation.dialstr));
-	res = ioctl(openr2_chan_get_fd(handle->r2chan), DAHDI_DIAL, &dahdi_operation);
-	if (-1 == res) {
-		ast_log(LOG_ERROR, "Failed to init MF tx state: %s, we will not be able to make or receive calls!.\n", strerror(errno));
-		return NULL;
-	}
-	handle->forward = forward_signals;
-	handle->generate = 0;
-	return handle;
-}
-
-static const char dahdi_r2_mf_names[] = "123456789ABCDEF";
-static int dahdi_r2_mf_tx_put(struct dahdi_mf_tx_state *handle, char signal)
-{
-	int res;
-	struct dahdi_pvt *p;
-	/* OpenR2 0 signal is A signal in Zaptel */
-	signal = (signal == '0') ? 'A' : signal;
-	if (signal && strchr(dahdi_r2_mf_names, signal)) {
-		handle->signal = handle->forward ? (DAHDI_TONE_MFR2_FWD_BASE + (signal - dahdi_r2_mf_names[0])) 
-			                         : (DAHDI_TONE_MFR2_REV_BASE + (signal - dahdi_r2_mf_names[0]));
-		if (signal >= 'A') {
-			handle->signal -= 7;
-		}
-		handle->generate = 1;
-	} else if (!signal){
-		/* mute the tone as soon as possible, dont wait until dahdi_r2_mf_tx gets called.
-		   In fact, since OpenR2 was designed for user space tone generation, this could
-		   be our last chance to mute it */
-		handle->signal = -1;
-		res = ioctl(openr2_chan_get_fd(handle->r2chan), DAHDI_SENDTONE, &handle->signal);
-		if (-1 == res) {
-			ast_log(LOG_ERROR, "Failed to mute MF signal, something will likely fail.\n");
-			return -1;
-		}
-		handle->generate = 0;
-		p = openr2_chan_get_client_data(handle->r2chan);
-		p->dialing = 0;
-	} else {
-		ast_log(LOG_ERROR, "Asked to prepare invalid signal '%c', call setup will likely fail.\n", signal);
-		return -1;
-	}
-	return 0;
-}
-
-static int dahdi_r2_mf_tx(struct dahdi_mf_tx_state *handle, int16_t buffer[], int samples)
-{
-	/* OpenR2 passes a buffer in case the MF implementation wants to put the 
-	   signal in a buffer, but zaptel generates the signal directly on the kernel
-	   hence we ignore buffer and samples and return 0 to indicate no samples were generated */
-	int res;
-	struct dahdi_pvt *p = openr2_chan_get_client_data(handle->r2chan);
-	if (handle->signal == -1) {
-		return 0;
-	}
-	p->dialing = 1;
-	res = ioctl(openr2_chan_get_fd(handle->r2chan), DAHDI_SENDTONE, &handle->signal);
-	if (-1 == res) {
-		ast_log(LOG_ERROR, "Failed to generate tone %X with ZT_SENDTONE in fd %d: %s\n", 
-				handle->signal, openr2_chan_get_fd(handle->r2chan), strerror(errno));
-		return -1;
-	}
-	handle->generate = 0;
-	return 0;
-}
-
-static int dahdi_r2_mf_want_generate(struct dahdi_mf_tx_state *handle, int signal)
-{
-	return handle->generate;
-}
-
-static void *dahdi_r2_mf_rx_init(struct dahdi_mf_rx_state *handle, int forward_signals)
-{
-	if (handle->detector) {
-		ast_dsp_free(handle->detector);
-	} else {
-		handle->fr.frametype = AST_FRAME_VOICE;
-		handle->fr.subclass = AST_FORMAT_SLINEAR;
-		handle->fr.offset = 0;
-		handle->fr.datalen = OR2_CHAN_READ_SIZE * 2;
-		handle->fr.samples = OR2_CHAN_READ_SIZE;
-		handle->fr.data.ptr = NULL;
-		handle->fr.src = __FUNCTION__;
-		handle->fr.mallocd = 0;
-	}
-	handle->detector = ast_dsp_new();
-	if (!handle->detector) {
-		ast_log(LOG_ERROR, "Failed to init MF rx state: %s, we will not be able to make or receive calls!.\n", strerror(errno));
-		return NULL;
-	}
-	ast_dsp_set_features(handle->detector, DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_SILENCE_SUPPRESS);
-	ast_dsp_set_digitmode(handle->detector, forward_signals ? DSP_DIGITMODE_MFR2_FWD : DSP_DIGITMODE_MFR2_REV);
-	return handle;
-}
-
-static void dahdi_r2_mf_rx_dispose(struct dahdi_mf_rx_state *handle)
-{
-	if (handle->detector) {
-		ast_dsp_free(handle->detector);
-		handle->detector = NULL;
-	}
-}
-
-static int dahdi_r2_mf_rx(struct dahdi_mf_rx_state *handle, int16_t buffer[], int samples)
-{
-	struct ast_frame *f;
-	handle->fr.data.ptr = buffer;
-	f = ast_dsp_process(NULL, handle->detector, &handle->fr);
-	if (f && f->frametype == AST_FRAME_DTMF_BEGIN) {
-		handle->signal = f->subclass;
-	} else if (f && f->frametype == AST_FRAME_NULL) {
-		if (handle->signal != 0) {
-			/* a better way must exists to 
-			   be able to detect tone x, silence, tone x */
-			ast_dsp_digitreset(handle->detector);
-		}
-		handle->signal = 0;
-	} 
-	/* OpenR2 A signal is represented as 0 */
-	return (handle->signal == 'A') ? '0' : handle->signal;
-}
-
-static openr2_mflib_interface_t dahdi_r2_mf_iface = {
-	/*(openr2_mf_read_init_func)dahdi_r2_mf_rx_init,*/
-	NULL,
-	/*(openr2_mf_write_init_func)dahdi_r2_mf_tx_init,*/
-	NULL,
-
-	/*(openr2_mf_detect_tone_func)dahdi_r2_mf_rx,*/
-	NULL,
-	/*(openr2_mf_generate_tone_func)dahdi_r2_mf_tx, */
-
-	/*(openr2_mf_select_tone_func)dahdi_r2_mf_tx_put, */
-	NULL,
-
-	/*(openr2_mf_want_generate_func)dahdi_r2_mf_want_generate,*/
-	NULL,
-	/*(openr2_mf_read_dispose_func)dahdi_r2_mf_rx_dispose,*/
-	NULL,
-	NULL
-};
 
 static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
 {
@@ -1512,7 +1347,7 @@
 	if (increment) {
 		mfcr2->monitored_count++;
 		if (mfcr2->monitored_count == 1) {
-			ast_log(LOG_DEBUG, "At least one device needs monitoring, let's wake up that lazy bastard.\n");
+			ast_log(LOG_DEBUG, "At least one device needs monitoring, let's wake up the monitor thread.\n");
 			ast_cond_signal(&mfcr2->do_monitor);
 		}
 	} else {
@@ -1535,7 +1370,7 @@
 		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, 0);
 		if (c) {
 			dahdi_r2_update_monitor_count(p->mfcr2, 0);
-			/* chan_zap will take care of reading from now on, tell the library to forget about it */
+			/* chan_dahdi will take care of reading from now on, tell the library to forget about it */
 			openr2_chan_disable_read(r2chan);
 		} else {
 			ast_log(LOG_WARNING, "Unable to start PBX on chan %d\n", p->channel);
@@ -1547,7 +1382,7 @@
 		ast_log(LOG_NOTICE, "Call accepted on forward channel %d\n", p->channel);
 		p->subs[SUB_REAL].needringing = 1;
 		p->dialing = 0;
-		/* chan_zap will take care of reading from now on, tell the library to forget about it */
+		/* chan_dahdi will take care of reading from now on, tell the library to forget about it */
 		openr2_chan_disable_read(r2chan);
 	}	
 }
@@ -1561,7 +1396,7 @@
 
 static void dahdi_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf, int buflen)
 {
-	/*ast_log(LOG_DEBUG, "Read data from zap channel %d\n", openr2_chan_get_number(r2chan));*/
+	/*ast_log(LOG_DEBUG, "Read data from dahdi channel %d\n", openr2_chan_get_number(r2chan));*/
 }
 
 static int dahdi_r2_cause_to_ast_cause(openr2_call_disconnect_cause_t cause)
@@ -1702,7 +1537,7 @@
 	p->exten[p->mfcr2_dnis_index] = 0;
 	p->rdnis[p->mfcr2_dnis_index] = 0;
 	/*
-	ast_log(LOG_DEBUG, "Got digit %c in zap, dnis so far: %s\n", digit, p->exten);
+	ast_log(LOG_DEBUG, "Got digit %c in dahdi, dnis so far: %s\n", digit, p->exten);
 	int ret;
 	ret = ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num);
 	ast_log(LOG_DEBUG, "ast_exists_extension(%s, %s, 1, %s) = %d\n", p->context, p->exten, p->cid_num, ret);
@@ -9139,16 +8974,47 @@
 #endif /* HAVE_SS7 */
 
 #ifdef HAVE_OPENR2
-
-static struct dahdi_mfcr2 *mfcr2_get_context(int id)
-{
-	if ((id < 0) || (id >= (sizeof(r2links)/sizeof(r2links[0])))) {
-		ast_log(LOG_ERROR, "No more R2 links available!.\n");
-		return NULL;
-	}
-	return &r2links[id];
-}
-
+static void dahdi_r2_destroy_links(void)
+{
+	if (!r2links) {
+		return;
+	}
+	int i = 0;
+	for (; i < r2links_count; i++) {
+		if (r2links[i]->r2master != AST_PTHREADT_NULL) {
+			pthread_cancel(r2links[i]->r2master);
+			pthread_join(r2links[i]->r2master, NULL);
+			openr2_context_delete(r2links[i]->protocol_context);
+		}
+		ast_free(r2links[i]);
+	}
+	ast_free(r2links);
+	r2links = NULL;
+	r2links_count = 0;
+	r2links_index = 0;
+}		
+
+static struct dahdi_mfcr2 *dahdi_r2_get_link(void)
+{
+	if (r2links_index == r2links_count) {
+		struct dahdi_mfcr2 *new_r2link = ast_calloc(1, sizeof(**r2links));
+		if (!new_r2link) {
+			ast_log(LOG_ERROR, "Cannot allocate another R2 link!\n");
+			return NULL;
+		}
+		struct dahdi_mfcr2 **new_r2links = ast_realloc(r2links, ((r2links_count + 1) * sizeof(*r2links)));
+		if (!new_r2links) {
+			ast_log(LOG_ERROR, "Cannot allocate another R2 link!\n");
+			ast_free(new_r2link);
+			return NULL;
+		}
+		r2links = new_r2links;
+		new_r2links->r2master = AST_PTHREADT_NULL;
+		r2links[r2links_index] = new_r2link;
+		r2links_count++;
+	}
+	return r2links[r2links_index];
+}
 #endif
 
 /* converts a DAHDI sigtype to signalling as can be configured from
@@ -9303,60 +9169,61 @@
 #endif
 #ifdef HAVE_OPENR2
 			if (chan_sig == SIG_MFCR2 && reloading != 1) {
-				char logdir[OR2_MAX_LOGDIR];
-				struct dahdi_mfcr2 *zap_r2;
+				char logdir[OR2_MAX_PATH];
+				struct dahdi_mfcr2 *r2_link;
 				int threshold = 0;
 				int snres = 0;
-				zap_r2 = mfcr2_get_context(mfcr2_cur_context_index);
-				if (!zap_r2) {
-					ast_log(LOG_WARNING, "Cannot get another R2 zap context!\n");
-				} else if (!zap_r2->protocol_context){
+				r2_link = dahdi_r2_get_link();
+				if (!r2_link) {
+					ast_log(LOG_WARNING, "Cannot get another R2 DAHDI context!\n");
+				} else if (!r2_link->protocol_context) {
 					char tmplogdir[] = "/tmp";
-					zap_r2->protocol_context = openr2_context_new(&dahdi_r2_mf_iface, &dahdi_r2_event_iface, 
-							&dahdi_r2_transcode_iface, mfcr2_cur_variant, mfcr2_cur_max_ani, mfcr2_cur_max_dnis);
-					if (!zap_r2->protocol_context) {
+					r2_link->protocol_context = openr2_context_new(NULL, &dahdi_r2_event_iface, 
+							&dahdi_r2_transcode_iface, conf->mfcr2.variant, conf->mfcr2.max_ani, 
+							conf->mfcr2.max_dnis);
+					if (!r2_link->protocol_context) {
 						ast_log(LOG_ERROR, "Cannot create OpenR2 protocol context.\n");
 						destroy_dahdi_pvt(&tmp);
 						return NULL;
 					} 
-					openr2_context_set_log_level(zap_r2->protocol_context, mfcr2_cur_loglevel);
-					openr2_context_set_ani_first(zap_r2->protocol_context, mfcr2_cur_get_ani_first);
-					openr2_context_set_mf_threshold(zap_r2->protocol_context, threshold);
-					openr2_context_set_mf_back_timeout(zap_r2->protocol_context, mfcr2_cur_mfback_timeout);
-					openr2_context_set_metering_pulse_timeout(zap_r2->protocol_context, mfcr2_cur_metering_pulse_timeout);
-					openr2_context_set_double_answer(zap_r2->protocol_context, mfcr2_cur_double_answer);
-					openr2_context_set_immediate_accept(zap_r2->protocol_context, mfcr2_cur_immediate_accept);
-					if (ast_strlen_zero(mfcr2_cur_logdir)) {
-						if (openr2_context_set_log_directory(zap_r2->protocol_context, tmplogdir)) {
+					openr2_context_set_log_level(r2_link->protocol_context, conf->mfcr2.loglevel);
+					openr2_context_set_ani_first(r2_link->protocol_context, conf->mfcr2.get_ani_first);
+					openr2_context_set_mf_threshold(r2_link->protocol_context, threshold);
+					openr2_context_set_mf_back_timeout(r2_link->protocol_context, conf->mfcr2.mfback_timeout);
+					openr2_context_set_metering_pulse_timeout(r2_link->protocol_context, conf->mfcr2.metering_pulse_timeout);
+					openr2_context_set_double_answer(r2_link->protocol_context, conf->mfcr2.double_answer);
+					openr2_context_set_immediate_accept(r2_link->protocol_context, conf->mfcr2.immediate_accept);
+					if (ast_strlen_zero(conf->mfcr2.logdir)) {
+						if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
 							ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir);
 						}
 					} else {
-						snres = snprintf(logdir, sizeof(logdir), "%s/%s/%s", ast_config_AST_LOG_DIR, "mfcr2", mfcr2_cur_logdir);
+						snres = snprintf(logdir, sizeof(logdir), "%s/%s/%s", ast_config_AST_LOG_DIR, "mfcr2", conf->mfcr2.logdir);
 						if (snres >= sizeof(logdir)) {
 							ast_log(LOG_ERROR, "MFC/R2 logging directory truncated, using %s\n", tmplogdir);
-							if (openr2_context_set_log_directory(zap_r2->protocol_context, tmplogdir)) {
+							if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
 								ast_log(LOG_ERROR, "Failed setting default MFC/R2 log directory %s\n", tmplogdir);
 							}
 						} else {
-							if (openr2_context_set_log_directory(zap_r2->protocol_context, logdir)) {
+							if (openr2_context_set_log_directory(r2_link->protocol_context, logdir)) {
 								ast_log(LOG_ERROR, "Failed setting MFC/R2 log directory %s\n", logdir);
 							}
 						}
 					}
-					if (!ast_strlen_zero(mfcr2_cur_r2proto_file)) {
-						if (openr2_context_configure_from_advanced_file(zap_r2->protocol_context, mfcr2_cur_r2proto_file)) {
-							ast_log(LOG_ERROR, "Failed to configure r2context from advanced configuration file %s\n", mfcr2_cur_r2proto_file);
+					if (!ast_strlen_zero(conf->mfcr2.r2proto_file)) {
+						if (openr2_context_configure_from_advanced_file(r2_link->protocol_context, conf->mfcr2.r2proto_file)) {
+							ast_log(LOG_ERROR, "Failed to configure r2context from advanced configuration file %s\n", conf->mfcr2.r2proto_file);
 						}
 					}
-					ast_cond_init(&zap_r2->do_monitor, NULL);
-					ast_mutex_init(&zap_r2->monitored_count_lock);
-					zap_r2->monitored_count = 0;
+					ast_cond_init(&r2_link->do_monitor, NULL);
+					ast_mutex_init(&r2_link->monitored_count_lock);
+					r2_link->monitored_count = 0;
 				} 
-				if (zap_r2) {
-					/* TODO: should we check numchans overflow, or is it already done by zap? */
-					zap_r2->pvts[zap_r2->numchans++] = tmp;
-					tmp->r2chan = openr2_chan_new_from_fd(zap_r2->protocol_context, tmp->subs[SUB_REAL].dfd, 
-							&tmp->mf_tx_state, NULL);
+				if (r2_link) {
+					/* TODO: should we check numchans overflow, or is it already done by dahdi? */
+					r2_link->pvts[r2_link->numchans++] = tmp;
+					tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context, tmp->subs[SUB_REAL].dfd, 
+							NULL, NULL);
 					if (!tmp->r2chan) {
 						ast_log(LOG_ERROR, "Cannot create OpenR2 channel.\n");
 						destroy_dahdi_pvt(&tmp);
@@ -9364,20 +9231,19 @@
 					}
 					openr2_chan_set_client_data(tmp->r2chan, tmp);
 					openr2_chan_set_logging_func(tmp->r2chan, dahdi_r2_on_chan_log);
-					openr2_chan_set_log_level(tmp->r2chan, mfcr2_cur_loglevel);
-					if (mfcr2_cur_call_files) {
+					openr2_chan_set_log_level(tmp->r2chan, conf->mfcr2.loglevel);
+					if (conf->mfcr2.call_files) {
 						openr2_chan_enable_call_files(tmp->r2chan);
 					} 
-					tmp->mf_tx_state.r2chan = tmp->r2chan;
-					tmp->mfcr2_category = mfcr2_cur_category;
-					tmp->mfcr2 = zap_r2;
+					tmp->mfcr2_category = conf->mfcr2.category;
+					tmp->mfcr2 = r2_link;
 					tmp->mfcr2call = 0;
-					tmp->mfcr2_charge_calls = mfcr2_cur_charge_calls;
+					tmp->mfcr2_charge_calls = conf->mfcr2.charge_calls;
 					tmp->mfcr2_dnis_index = 0;
 					tmp->mfcr2_ani_index = 0;
-					tmp->mfcr2_allow_collect_calls = mfcr2_cur_allow_collect_calls;
-					tmp->mfcr2_forced_release = mfcr2_cur_forced_release;
-					zap_r2->monitored_count++;
+					tmp->mfcr2_allow_collect_calls = conf->mfcr2.allow_collect_calls;
+					tmp->mfcr2_forced_release = conf->mfcr2.forced_release;
+					r2_link->monitored_count++;
 				}
 			}
 #endif
@@ -13013,7 +12879,7 @@
 		e->command = "mfcr2 show channels [group|context]";
 		e->usage = 
 			"Usage: mfcr2 show channels [group <group> | context <context>]\n"
-			"       Shows the zap channels configured with MFC/R2 signaling.\n";
+			"       Shows the DAHDI channels configured with MFC/R2 signaling.\n";
 		return NULL;
 	case CLI_GENERATE:
 		return NULL;
@@ -13296,7 +13162,7 @@
 	return CLI_SUCCESS;
 }
 
-static struct ast_cli_entry zap_mfcr2_cli[] = {
+static struct ast_cli_entry dahdi_mfcr2_cli[] = {
 	AST_CLI_DEFINE(handle_mfcr2_version, "Show OpenR2 library version"),
 	AST_CLI_DEFINE(handle_mfcr2_show_variants, "Show supported MFC/R2 variants"),
 	AST_CLI_DEFINE(handle_mfcr2_show_channels, "Show MFC/R2 channels"),
@@ -13372,16 +13238,7 @@
 	dahdi_softhangup_all();
 	ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n");
 #ifdef HAVE_OPENR2
-	int r;
-	for (r = 0; r < NUM_SPANS; r++) {
-		if (r2links[r].master != AST_PTHREADT_NULL) {
-			ast_log(LOG_DEBUG, "Killing MFC/R2 monitor thread %p\n", &r2links[r].master);
-			pthread_cancel(r2links[r].master);
-			pthread_join(r2links[r].master, NULL);
-			openr2_context_delete(r2links[r].protocol_context);
-		}
-	}
-	init_mfcr2_globals();
+	dahdi_r2_destroy_links();
 #endif
 
 #if defined(HAVE_PRI)
@@ -13768,7 +13625,7 @@
 			}
 #ifdef HAVE_OPENR2
 			if (tmp->mfcr2) {
-				char calldir[OR2_MAX_LOGDIR];
+				char calldir[OR2_MAX_PATH];
 				openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
 				openr2_variant_t r2variant = openr2_context_get_variant(r2context);
 				ast_cli(a->fd, "MFC/R2 MF State: %s\n", openr2_proto_get_mf_state_string(tmp->r2chan));
@@ -14859,9 +14716,6 @@
 #if defined(HAVE_PRI) || defined(HAVE_SS7)
 	int i, j;
 #endif
-#if defined(HAVE_OPENR2)
-	int k;
-#endif
 
 #ifdef HAVE_PRI
 	for (i = 0; i < NUM_SPANS; i++) {
@@ -14882,13 +14736,8 @@
 	ast_cli_unregister_multiple(dahdi_ss7_cli, sizeof(dahdi_ss7_cli) / sizeof(struct ast_cli_entry));
 #endif
 #if defined(HAVE_OPENR2)
-	for (k = 0; k < NUM_SPANS; k++) {
-		if (r2links[k].master != AST_PTHREADT_NULL) {
-			pthread_cancel(r2links[k].master);
-			pthread_join(r2links[k].master, NULL);
-		}
-	}
-	ast_cli_unregister_multiple(zap_mfcr2_cli, sizeof(zap_mfcr2_cli) / sizeof(zap_mfcr2_cli[0]));
+	dahdi_r2_destroy_links();
+	ast_cli_unregister_multiple(dahdi_mfcr2_cli, sizeof(dahdi_mfcr2_cli) / sizeof(dahdi_mfcr2_cli[0]));
 #endif
 
 	ast_cli_unregister_multiple(dahdi_cli, sizeof(dahdi_cli) / sizeof(struct ast_cli_entry));
@@ -14939,14 +14788,6 @@
 		}
 	}
 #endif
-#ifdef HAVE_OPENR2
-	for (k = 0; k < NUM_SPANS; k++) {
-		if (r2links[k].protocol_context) {
-			openr2_context_delete(r2links[k].protocol_context);
-		}
-	}
-#endif
-
 	ast_cond_destroy(&ss_thread_complete);
 	return 0;
 }
@@ -15051,8 +14892,8 @@
 			}
 		}
 #ifdef HAVE_OPENR2
-		if (reload != 1 && r2links[mfcr2_cur_context_index].protocol_context) {
-			mfcr2_cur_context_index++;
+		if ((reload != 1) && (r2links_index < r2links_count) && r2links[r2links_index]->protocol_context) {
+			r2links_index++;
 		}
 #endif
 	}
@@ -15807,56 +15648,57 @@
 #endif /* HAVE_SS7 */
 #ifdef HAVE_OPENR2
 			} else if (!strcasecmp(v->name, "mfcr2_advanced_protocol_file")) {
-				ast_copy_string(mfcr2_cur_r2proto_file, v->value, sizeof(mfcr2_cur_r2proto_file));
-				ast_log(LOG_WARNING, "MFC/R2 Protocol file '%s' will be used, you only should use this if you *REALLY KNOW WHAT YOU ARE DOING*.\n", mfcr2_cur_r2proto_file);
+				ast_copy_string(confp->mfcr2.r2proto_file, v->value, sizeof(confp->mfcr2.r2proto_file));
+				ast_log(LOG_WARNING, "MFC/R2 Protocol file '%s' will be used, you only should use this if you *REALLY KNOW WHAT YOU ARE DOING*.\n", confp->mfcr2.r2proto_file);
 			} else if (!strcasecmp(v->name, "mfcr2_logdir")) {
-				ast_copy_string(mfcr2_cur_logdir, v->value, sizeof(mfcr2_cur_logdir));
+				ast_copy_string(confp->mfcr2.logdir, v->value, sizeof(confp->mfcr2.logdir));
 			} else if (!strcasecmp(v->name, "mfcr2_variant")) {
-				mfcr2_cur_variant = openr2_proto_get_variant(v->value);
-				if (OR2_VAR_UNKNOWN == mfcr2_cur_variant) {
-					ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d.\n", v->value, v->lineno);
+				confp->mfcr2.variant = openr2_proto_get_variant(v->value);
+				if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) {
+					ast_log(LOG_WARNING, "Unknown MFC/R2 variant '%s' at line %d, defaulting to ITU.\n", v->value, v->lineno);
+					confp->mfcr2.variant = OR2_VAR_ITU;
 				}
 			} else if (!strcasecmp(v->name, "mfcr2_mfback_timeout")) {
-				mfcr2_cur_mfback_timeout = atoi(v->value);
-				if (!mfcr2_cur_mfback_timeout) {
+				confp->mfcr2.mfback_timeout = atoi(v->value);
+				if (!confp->mfcr2.mfback_timeout) {
 					ast_log(LOG_WARNING, "MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
-					mfcr2_cur_mfback_timeout = -1;
-				} else if (mfcr2_cur_mfback_timeout > 0 && mfcr2_cur_mfback_timeout < 500) {
+					confp->mfcr2.mfback_timeout = -1;
+				} else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) {
 					ast_log(LOG_WARNING, "MF timeout less than 500ms is not recommended, you have been warned!\n");
 				}
 			} else if (!strcasecmp(v->name, "mfcr2_metering_pulse_timeout")) {
-				mfcr2_cur_metering_pulse_timeout = atoi(v->value);
-				if (mfcr2_cur_metering_pulse_timeout > 500) {
+				confp->mfcr2.metering_pulse_timeout = atoi(v->value);
+				if (confp->mfcr2.metering_pulse_timeout > 500) {
 					ast_log(LOG_WARNING, "Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n");
 				}
 			} else if (!strcasecmp(v->name, "mfcr2_get_ani_first")) {
-				mfcr2_cur_get_ani_first = ast_true(v->value);
+				confp->mfcr2.get_ani_first = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_double_answer")) {
-				mfcr2_cur_double_answer = ast_true(v->value);
+				confp->mfcr2.double_answer = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_charge_calls")) {
-				mfcr2_cur_charge_calls = ast_true(v->value);
+				confp->mfcr2.charge_calls = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_allow_collect_calls")) {
-				mfcr2_cur_allow_collect_calls = ast_true(v->value);
+				confp->mfcr2.allow_collect_calls = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_forced_release")) {
-				mfcr2_cur_forced_release = ast_true(v->value);
+				confp->mfcr2.forced_release = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_immediate_accept")) {
-				mfcr2_cur_immediate_accept = ast_true(v->value);
+				confp->mfcr2.immediate_accept = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_call_files")) {
-				mfcr2_cur_call_files = ast_true(v->value);
+				confp->mfcr2.call_files = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "mfcr2_max_ani")) {
-				mfcr2_cur_max_ani = atoi(v->value);
-				if (mfcr2_cur_max_ani >= AST_MAX_EXTENSION){
-					mfcr2_cur_max_ani = AST_MAX_EXTENSION - 1;
+				confp->mfcr2.max_ani = atoi(v->value);
+				if (confp->mfcr2.max_ani >= AST_MAX_EXTENSION){
+					confp->mfcr2.max_ani = AST_MAX_EXTENSION - 1;
 				}
 			} else if (!strcasecmp(v->name, "mfcr2_max_dnis")) {
-				mfcr2_cur_max_dnis = atoi(v->value);
-				if (mfcr2_cur_max_dnis >= AST_MAX_EXTENSION){
-					mfcr2_cur_max_dnis = AST_MAX_EXTENSION - 1;
+				confp->mfcr2.max_dnis = atoi(v->value);
+				if (confp->mfcr2.max_dnis >= AST_MAX_EXTENSION){
+					confp->mfcr2.max_dnis = AST_MAX_EXTENSION - 1;
 				}
 			} else if (!strcasecmp(v->name, "mfcr2_category")) {
-				mfcr2_cur_category = openr2_proto_get_category(v->value);
-				if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == mfcr2_cur_category) {
-					mfcr2_cur_category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
+				confp->mfcr2.category = openr2_proto_get_category(v->value);
+				if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) {
+					confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
 					ast_log(LOG_WARNING, "Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n", 
 							v->value, v->lineno);
 				}
@@ -15869,15 +15711,15 @@
 				if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
 					ast_log(LOG_WARNING, "Invalid MFC/R2 logging level '%s' at line %d.\n", v->value, v->lineno);
 				} else if (OR2_LOG_NOTHING == tmplevel) {
-					mfcr2_cur_loglevel = tmplevel;
+					confp->mfcr2.loglevel = tmplevel;
 				} else {
-					mfcr2_cur_loglevel |= tmplevel;
+					confp->mfcr2.loglevel |= tmplevel;
 					while ((toklevel = strtok_r(NULL, ",", &saveptr))) {
 						if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
 							ast_log(LOG_WARNING, "Ignoring invalid logging level: '%s' at line %d.\n", toklevel, v->lineno);
 							continue;
 						}
-						mfcr2_cur_loglevel |= tmplevel;
+						confp->mfcr2.loglevel |= tmplevel;
 					}
 				}
 #endif /* HAVE_OPENR2 */
@@ -16254,14 +16096,12 @@
 #ifdef HAVE_OPENR2
 	if (reload != 1) {
 		int x;
-		for (x = 0; x < NUM_SPANS; x++) {
-			if (r2links[x].protocol_context) {
-				if (ast_pthread_create(&r2links[x].master, NULL, mfcr2_monitor, &r2links[x])) {
-					ast_log(LOG_ERROR, "Unable to start R2 context on span %d\n", x + 1);
-					return -1;
-				} else {
-					ast_verb(2, "Starting R2 context on span %d\n", x + 1);
-				}
+		for (x = 0; x < r2links_count; x++) {
+			if (ast_pthread_create(&r2links[x]->r2master, NULL, mfcr2_monitor, r2links[x])) {
+				ast_log(LOG_ERROR, "Unable to start R2 monitor on channel group %d\n", x + 1);
+				return -1;
+			} else {
+				ast_verb(2, "Starting R2 monitor on channel group %d\n", x + 1);
 			}
 		}
 	}
@@ -16305,9 +16145,6 @@
 	ss7_set_error(dahdi_ss7_error);
 	ss7_set_message(dahdi_ss7_message);
 #endif /* HAVE_SS7 */
-#ifdef HAVE_OPENR2
-	init_mfcr2_globals();
-#endif
 	res = setup_dahdi(0);
 	/* Make sure we can register our DAHDI channel type */
 	if (res)
@@ -16326,7 +16163,7 @@
 	ast_cli_register_multiple(dahdi_ss7_cli, ARRAY_LEN(dahdi_ss7_cli));
 #endif
 #ifdef HAVE_OPENR2
-	ast_cli_register_multiple(zap_mfcr2_cli, sizeof(zap_mfcr2_cli)/sizeof(zap_mfcr2_cli[0]));
+	ast_cli_register_multiple(dahdi_mfcr2_cli, sizeof(dahdi_mfcr2_cli)/sizeof(dahdi_mfcr2_cli[0]));
 #endif
 
 	ast_cli_register_multiple(dahdi_cli, ARRAY_LEN(dahdi_cli));




More information about the asterisk-commits mailing list