[asterisk-commits] coreyfarrell: branch group/media_formats-reviewed-trunk r417771 - in /team/gr...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jul 2 16:14:32 CDT 2014


Author: coreyfarrell
Date: Wed Jul  2 16:14:25 2014
New Revision: 417771

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417771
Log:
Merge /trunk at 417768

Added:
    team/group/media_formats-reviewed-trunk/contrib/ast-db-manage/config/versions/51f8cb66540e_add_further_dtls_options.py   (with props)
    team/group/media_formats-reviewed-trunk/tests/test_channel_feature_hooks.c   (with props)
Modified:
    team/group/media_formats-reviewed-trunk/   (props changed)
    team/group/media_formats-reviewed-trunk/CHANGES
    team/group/media_formats-reviewed-trunk/UPGRADE.txt
    team/group/media_formats-reviewed-trunk/apps/app_jack.c
    team/group/media_formats-reviewed-trunk/apps/app_voicemail.c
    team/group/media_formats-reviewed-trunk/channels/chan_dahdi.c
    team/group/media_formats-reviewed-trunk/channels/chan_pjsip.c
    team/group/media_formats-reviewed-trunk/channels/chan_sip.c
    team/group/media_formats-reviewed-trunk/channels/chan_skinny.c
    team/group/media_formats-reviewed-trunk/channels/sig_pri.c
    team/group/media_formats-reviewed-trunk/channels/sig_pri.h
    team/group/media_formats-reviewed-trunk/channels/sip/include/sip.h
    team/group/media_formats-reviewed-trunk/configs/ari.conf.sample
    team/group/media_formats-reviewed-trunk/configs/pjsip.conf.sample
    team/group/media_formats-reviewed-trunk/configs/sip.conf.sample
    team/group/media_formats-reviewed-trunk/contrib/scripts/refcounter.py
    team/group/media_formats-reviewed-trunk/include/asterisk/bridge_features.h
    team/group/media_formats-reviewed-trunk/include/asterisk/channel.h
    team/group/media_formats-reviewed-trunk/include/asterisk/http_websocket.h
    team/group/media_formats-reviewed-trunk/include/asterisk/netsock.h
    team/group/media_formats-reviewed-trunk/include/asterisk/res_pjsip.h
    team/group/media_formats-reviewed-trunk/include/asterisk/res_pjsip_pubsub.h
    team/group/media_formats-reviewed-trunk/include/asterisk/res_pjsip_session.h
    team/group/media_formats-reviewed-trunk/include/asterisk/rtp_engine.h
    team/group/media_formats-reviewed-trunk/include/asterisk/sdp_srtp.h
    team/group/media_formats-reviewed-trunk/main/astobj2.c
    team/group/media_formats-reviewed-trunk/main/astobj2_container.c
    team/group/media_formats-reviewed-trunk/main/bridge.c
    team/group/media_formats-reviewed-trunk/main/bridge_channel.c
    team/group/media_formats-reviewed-trunk/main/cel.c
    team/group/media_formats-reviewed-trunk/main/channel.c
    team/group/media_formats-reviewed-trunk/main/core_unreal.c
    team/group/media_formats-reviewed-trunk/main/event.c
    team/group/media_formats-reviewed-trunk/main/netsock.c
    team/group/media_formats-reviewed-trunk/main/rtp_engine.c
    team/group/media_formats-reviewed-trunk/main/say.c
    team/group/media_formats-reviewed-trunk/main/sdp_srtp.c
    team/group/media_formats-reviewed-trunk/main/udptl.c
    team/group/media_formats-reviewed-trunk/main/utils.c
    team/group/media_formats-reviewed-trunk/res/ari/ari_websockets.c
    team/group/media_formats-reviewed-trunk/res/ari/config.c
    team/group/media_formats-reviewed-trunk/res/ari/internal.h
    team/group/media_formats-reviewed-trunk/res/res_ari.c
    team/group/media_formats-reviewed-trunk/res/res_http_websocket.c
    team/group/media_formats-reviewed-trunk/res/res_http_websocket.exports.in
    team/group/media_formats-reviewed-trunk/res/res_pjsip.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip/config_transport.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip/pjsip_configuration.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_exten_state.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_mwi.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_outbound_registration.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_pidf_body_generator.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_pubsub.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_pubsub.exports.in
    team/group/media_formats-reviewed-trunk/res/res_pjsip_registrar.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_sdp_rtp.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_transport_websocket.c
    team/group/media_formats-reviewed-trunk/res/res_pjsip_xpidf_body_generator.c
    team/group/media_formats-reviewed-trunk/res/res_rtp_asterisk.c
    team/group/media_formats-reviewed-trunk/tests/test_cel.c

Propchange: team/group/media_formats-reviewed-trunk/
------------------------------------------------------------------------------
Binary property 'branch-12-merged' - no diff available.

Modified: team/group/media_formats-reviewed-trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/CHANGES?view=diff&rev=417771&r1=417770&r2=417771
==============================================================================
--- team/group/media_formats-reviewed-trunk/CHANGES (original)
+++ team/group/media_formats-reviewed-trunk/CHANGES Wed Jul  2 16:14:25 2014
@@ -23,6 +23,11 @@
  * New AMI action LoggerRotate reloads and rotates logger in the same manner
    as CLI command 'logger rotate'
 
+CEL
+------------------
+ * The "bridge_technology" extra field key has been added to BRIDGE_ENTER
+   and BRIDGE_EXIT events.
+
 chan_dahdi
 ------------------
  * SS7 support now requires libss7 v2.0 or later.
@@ -34,6 +39,41 @@
 
  * Added several SS7 config option parameters described in
    chan_dahdi.conf.sample.
+
+Features
+------------------
+ * The ast_channel_feature_hooks* functions have been added to allow features
+   such as DTMF hooks, interval hooks, and bridge event hooks to be made
+   available to a channel when the channel is bridged. Previously, these
+   features were provided exclusively by the caller of ast_bridge_join()
+   outside of "basic" type bridges.
+
+JACK_HOOK
+------------------
+ * The JACK_HOOK function now supports audio with a sample rate higher than
+   8kHz.
+
+Say
+------------------
+ * The 'say' family of dialplan applications now support the Japanese
+   language. The 'language' parameter in say.conf now recognizes a setting of
+   'ja', which will enable Japanese language specific mechanisms for playing
+   back numbers, dates, and other items.
+
+VoiceMail
+------------------
+ * VoiceMail and VoiceMailMain now support the Japanese language. The
+   'language' parameter in voicemail.conf now recognizes a setting of 'ja',
+   which will enable prompts to be played back using a Japanese grammatical
+   structure. Additional prompts are necessary for this functionality,
+   including:
+   - jb-arimasu: there is
+   - jb-arimasen: there is not
+   - jb-oshitekudasai: please press
+   - jb-ni: article ni
+   - jb-ga: article ga
+   - jb-wa: article wa
+   - jb-wo: article wo
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 12.3.0 to Asterisk 12.4.0 ------------

Modified: team/group/media_formats-reviewed-trunk/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/UPGRADE.txt?view=diff&rev=417771&r1=417770&r2=417771
==============================================================================
--- team/group/media_formats-reviewed-trunk/UPGRADE.txt (original)
+++ team/group/media_formats-reviewed-trunk/UPGRADE.txt Wed Jul  2 16:14:25 2014
@@ -225,5 +225,13 @@
  - The refcounter program has been removed in favor of the refcounter.py script
    in contrib/scripts.
 
-===========================================================
-===========================================================
+WebSockets:
+ - Added a compatibility option for ari, chan_sip, and chan_pjsip
+   'websocket_write_timeout'. When a websocket connection exists where Asterisk
+   writes a substantial amount of data to the connected client, and the connected
+   client is slow to process the received data, the socket may be disconnected.
+   In such cases, it may be necessary to adjust this value. Default is 100 ms.
+
+
+===========================================================
+===========================================================

Modified: team/group/media_formats-reviewed-trunk/apps/app_jack.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/apps/app_jack.c?view=diff&rev=417771&r1=417770&r2=417771
==============================================================================
--- team/group/media_formats-reviewed-trunk/apps/app_jack.c (original)
+++ team/group/media_formats-reviewed-trunk/apps/app_jack.c Wed Jul  2 16:14:25 2014
@@ -62,7 +62,8 @@
 
 #define RESAMPLE_QUALITY 1
 
-#define RINGBUFFER_SIZE 16384
+/* The number of frames the ringbuffers can store. The actual size is RINGBUFFER_FRAME_CAPACITY * jack_data->frame_datalen */
+#define RINGBUFFER_FRAME_CAPACITY 100
 
 /*! \brief Common options between the Jack() app and JACK_HOOK() function */
 #define COMMON_OPTIONS \
@@ -129,6 +130,9 @@
 	jack_port_t *output_port;
 	jack_ringbuffer_t *input_rb;
 	jack_ringbuffer_t *output_rb;
+	struct ast_format *audiohook_format;
+	unsigned int audiohook_rate;
+	unsigned int frame_datalen;
 	void *output_resampler;
 	double output_resample_factor;
 	void *input_resampler;
@@ -202,10 +206,8 @@
 
 	jack_srate = jack_get_sample_rate(jack_data->client);
 
-	/* XXX Hard coded 8 kHz */
-
-	to_srate = input ? 8000.0 : jack_srate;
-	from_srate = input ? jack_srate : 8000.0;
+	to_srate = input ? jack_data->audiohook_rate : jack_srate;
+	from_srate = input ? jack_srate : jack_data->audiohook_rate;
 
 	resample_factor = input ? &jack_data->input_resample_factor :
 		&jack_data->output_resample_factor;
@@ -290,7 +292,7 @@
 
 	res = jack_ringbuffer_write(jack_data->input_rb, (const char *) s_buf, write_len);
 	if (res != write_len) {
-		ast_debug(2, "Tried to write %d bytes to the ringbuffer, but only wrote %d\n",
+		ast_log(LOG_WARNING, "Tried to write %d bytes to the ringbuffer, but only wrote %d\n",
 			(int) sizeof(s_buf), (int) res);
 	}
 }
@@ -392,6 +394,28 @@
 	const char *client_name;
 	jack_status_t status = 0;
 	jack_options_t jack_options = JackNullOption;
+
+	struct ast_format *format_slin;
+	unsigned int channel_rate;
+
+	unsigned int ringbuffer_size;
+
+	/* Deducing audiohook sample rate from channel format
+	   ATTENTION: Might be problematic, if channel has different sampling than used by audiohook!
+	*/
+	channel_rate = ast_format_get_sample_rate(ast_channel_readformat(chan));
+	jack_data->audiohook_format = ast_format_cache_get_slin_by_rate(channel_rate);
+
+	format_slin = ao2_bump(jack_data->audiohook_format_id);
+	jack_data->audiohook_rate = ast_format_get_sample_rate(&format_slin);
+
+	/* Guessing frame->datalen assuming a ptime of 20ms */
+	jack_data->frame_datalen = jack_data->audiohook_rate / 50;
+
+	ringbuffer_size = jack_data->frame_datalen * RINGBUFFER_FRAME_CAPACITY;
+
+	ast_debug(1, "Audiohook parameters: slin-format:%s, rate:%d, frame-len:%d, ringbuffer_size: %d\n",
+	    ast_format_get_name(format_slin), jack_data->audiohook_rate, jack_data->frame_datalen, ringbuffer_size);
 
 	if (!ast_strlen_zero(jack_data->client_name)) {
 		client_name = jack_data->client_name;
@@ -401,10 +425,10 @@
 		ast_channel_unlock(chan);
 	}
 
-	if (!(jack_data->output_rb = jack_ringbuffer_create(RINGBUFFER_SIZE)))
-		return -1;
-
-	if (!(jack_data->input_rb = jack_ringbuffer_create(RINGBUFFER_SIZE)))
+	if (!(jack_data->output_rb = jack_ringbuffer_create(ringbuffer_size)))
+		return -1;
+
+	if (!(jack_data->input_rb = jack_ringbuffer_create(ringbuffer_size)))
 		return -1;
 
 	if (jack_data->no_start_server)
@@ -574,10 +598,9 @@
 
 	res = jack_ringbuffer_write(jack_data->output_rb, (const char *) f_buf, f_buf_used * sizeof(float));
 	if (res != (f_buf_used * sizeof(float))) {
-		ast_debug(2, "Tried to write %d bytes to the ringbuffer, but only wrote %d\n",
+		ast_log(LOG_WARNING, "Tried to write %d bytes to the ringbuffer, but only wrote %d\n",
 			(int) (f_buf_used * sizeof(float)), (int) res);
 	}
-
 	return 0;
 }
 
@@ -603,10 +626,10 @@
 static void handle_jack_audio(struct ast_channel *chan, struct jack_data *jack_data,
 	struct ast_frame *out_frame)
 {
-	short buf[160];
+	short buf[jack_data->frame_datalen];
 	struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.format = ast_format_slin,
+		.subclass.format = jack_data->audiohook_format,
 		.src = "JACK",
 		.data.ptr = buf,
 		.datalen = sizeof(buf),
@@ -756,12 +779,12 @@
 		return -1;
 	}
 
-	if (ast_set_read_format(chan, ast_format_slin)) {
+	if (ast_set_read_format(chan, jack_data->audiohook_format)) {
 		destroy_jack_data(jack_data);
 		return -1;
 	}
 
-	if (ast_set_write_format(chan, ast_format_slin)) {
+	if (ast_set_write_format(chan, jack_data->audiohook_format)) {
 		destroy_jack_data(jack_data);
 		return -1;
 	}
@@ -827,12 +850,6 @@
 	if (frame->frametype != AST_FRAME_VOICE)
 		return 0;
 
-	if (ast_format_cmp(frame->subclass.format, ast_format_slin) != AST_FORMAT_CMP_EQUAL) {
-		ast_log(LOG_WARNING, "Expected frame in SLINEAR for the audiohook, but got format %s\n",
-			ast_format_get_name(frame->subclass.format));
-		return 0;
-	}
-
 	ast_channel_lock(chan);
 
 	if (!(datastore = ast_channel_datastore_find(chan, &jack_hook_ds_info, NULL))) {
@@ -842,6 +859,13 @@
 	}
 
 	jack_data = datastore->data;
+
+	if (ast_format_cmp(frame->subclass.format, jack_data->audiohook_format) == AST_FORMAT_CMP_NOT_EQUAL) {
+		ast_log(LOG_WARNING, "Expected frame in %s for the audiohook, but got format %s\n",
+		    ast_format_get_name(jack_data->audiohook_format), ast_format_get_name(&frame->subclass.format));
+		ast_channel_unlock(chan);
+		return 0;
+	}
 
 	queue_voice_frame(jack_data, frame);
 
@@ -889,7 +913,7 @@
 		goto return_error;
 
 	jack_data->has_audiohook = 1;
-	ast_audiohook_init(&jack_data->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "JACK_HOOK", 0);
+	ast_audiohook_init(&jack_data->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "JACK_HOOK", AST_AUDIOHOOK_MANIPULATE_ALL_RATES);
 	jack_data->audiohook.manipulate_callback = jack_hook_callback;
 
 	datastore->data = jack_data;

Modified: team/group/media_formats-reviewed-trunk/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/apps/app_voicemail.c?view=diff&rev=417771&r1=417770&r2=417771
==============================================================================
--- team/group/media_formats-reviewed-trunk/apps/app_voicemail.c (original)
+++ team/group/media_formats-reviewed-trunk/apps/app_voicemail.c Wed Jul  2 16:14:25 2014
@@ -756,6 +756,15 @@
 \arg \b vm-vecchio	old
 \arg \b vm-vecchi	old plural
 
+Japanese requires the following additional soundfile:
+\arg \b jp-arimasu          there is
+\arg \b jp-arimasen         there is not
+\arg \b jp-oshitekudasai    please press
+\arg \b jp-ni               article ni
+\arg \b jp-ga               article ga
+\arg \b jp-wa               article wa
+\arg \b jp-wo               article wo
+
 Chinese (Taiwan) requires the following additional soundfile:
 \arg \b vm-tong		A class-word for call (tong1)
 \arg \b vm-ri		A class-word for day (ri4)
@@ -7583,6 +7592,34 @@
 	return d;
 }
 
+/* Japanese Syntax */
+static int get_folder_ja(struct ast_channel *chan, int start)
+{
+        int x;
+        int d;
+        char fn[256];
+        for (x = start; x< 5; x++) {    /* For all folders */
+                if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL))) {
+                        return d;
+		}
+		snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x));     /* Folder name */
+		d = vm_play_folder_name(chan, fn);
+		if (d) {
+                        return d;
+		}
+                d = ast_waitfordigit(chan, 500);
+                if (d) {
+                        return d;
+		}
+        }
+        d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
+        if (d) {
+                return d;
+	}
+        d = ast_waitfordigit(chan, 4000);
+        return d;
+}
+
 /*!
  * \brief plays a prompt and waits for a keypress.
  * \param chan
@@ -7604,7 +7641,12 @@
 	while (((res < '0') || (res > '9')) &&
 			(res != '#') && (res >= 0) &&
 			loops < 4) {
-		res = get_folder(chan, 0);
+                /* res = get_folder(chan, 0); */
+                if (!strcasecmp(ast_channel_language(chan),"ja")) {   /* Japanese syntax */
+                      res = get_folder_ja(chan, 0);
+                } else { /* Default syntax */
+		      res = get_folder(chan, 0);
+		}
 		loops++;
 	}
 	if (loops == 4) { /* give up */
@@ -8330,6 +8372,8 @@
 		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q  H 'digits/kai' M ", NULL);
 	} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) {     /* ITALIAN syntax */
 		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL);
+	} else if (!strcasecmp(ast_channel_language(chan),"ja")) {     /* Japanese syntax */
+		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "PHM q 'jp-ni' 'vm-received'", NULL);
 	} else if (!strncasecmp(ast_channel_language(chan), "nl", 2)) {     /* DUTCH syntax */
 		res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/nl-om' HM", NULL);
 	} else if (!strncasecmp(ast_channel_language(chan), "no", 2)) {     /* NORWEGIAN syntax */
@@ -8895,6 +8939,19 @@
 	}
 }
 
+static int vm_play_folder_name_ja(struct ast_channel *chan, char *box)
+{
+        int cmd;
+
+        if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) {
+                cmd = ast_play_and_wait(chan, box);
+                return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
+        } else {
+                cmd = ast_play_and_wait(chan, box);
+                return cmd;
+        }
+}
+
 static int vm_play_folder_name_pl(struct ast_channel *chan, char *box)
 {
 	int cmd;
@@ -8937,6 +8994,8 @@
 		return vm_play_folder_name_gr(chan, box);
 	} else if (!strncasecmp(ast_channel_language(chan), "he", 2)) {  /* Hebrew syntax */
 		return ast_play_and_wait(chan, box);
+        } else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {  /* Japanese syntax */
+                return vm_play_folder_name_ja(chan, box);
 	} else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) {
 		return vm_play_folder_name_pl(chan, box);
 	} else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) {  /* Ukrainian syntax */
@@ -9160,6 +9219,45 @@
 	}
 	return res;
 }
+
+/* Japanese syntax */
+static int vm_intro_ja(struct ast_channel *chan,struct vm_state *vms)
+{
+      /* Introduce messages they have */
+      int res;
+      if (vms->newmessages) {
+              res = ast_play_and_wait(chan, "vm-INBOX");
+              if (!res)
+                      res = ast_play_and_wait(chan, "vm-message");
+              if (!res)
+                      res = ast_play_and_wait(chan, "jp-ga");
+              if (!res)
+                      res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan));
+              if (vms->oldmessages && !res)
+                      res = ast_play_and_wait(chan, "silence/1");
+
+      }
+      if (vms->oldmessages) {
+              res = ast_play_and_wait(chan, "vm-Old");
+              if (!res)
+                      res = ast_play_and_wait(chan, "vm-message");
+              if (!res)
+                      res = ast_play_and_wait(chan, "jp-ga");
+              if (!res)
+                      res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan));
+      }
+      if (!vms->oldmessages && !vms->newmessages) {
+              res = ast_play_and_wait(chan, "vm-messages");
+              if (!res)
+                      res = ast_play_and_wait(chan, "jp-wa");
+              if (!res)
+                      res = ast_play_and_wait(chan, "jp-arimasen");
+      }
+      else {
+              res = ast_play_and_wait(chan, "jp-arimasu");
+      }
+      return res;
+} /* Japanese */
 	
 /* Default English syntax */
 static int vm_intro_en(struct ast_channel *chan, struct vm_state *vms)
@@ -9884,6 +9982,8 @@
 		return vm_intro_he(chan, vms);
 	} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) {  /* ITALIAN syntax */
 		return vm_intro_it(chan, vms);
+	} else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {  /* JAPANESE syntax */
+		return vm_intro_ja(chan, vms);
 	} else if (!strncasecmp(ast_channel_language(chan), "nl", 2)) {  /* DUTCH syntax */
 		return vm_intro_nl(chan, vms);
 	} else if (!strncasecmp(ast_channel_language(chan), "no", 2)) {  /* NORWEGIAN syntax */
@@ -9997,6 +10097,102 @@
 	return res;
 }
 
+static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms,  int skipadvanced, int in_urgent)
+{
+        int res = 0;
+        /* Play instructions and wait for new command */
+        while (!res) {
+                if (vms->starting) {
+                        if (vms->lastmsg > -1) {
+                                res = vm_play_folder_name(chan, vms->vmbox);
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "jp-wa");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "digits/1");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "jp-wo");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "silence/1");
+                        }
+                        if (!res)
+                                res = ast_play_and_wait(chan, "vm-opts");
+                } else {
+                        /* Added for additional help */
+                        if (skipadvanced) {
+                                res = vm_play_folder_name(chan, vms->vmbox);
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "jp-wa");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "digits/1");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "jp-wo");
+                                if (!res)
+                                        res = ast_play_and_wait(chan, "silence/1");
+                                res = ast_play_and_wait(chan, "vm-opts-full");
+                        }
+                        /* Logic:
+                         * If the current message is not the first OR
+                         * if we're listening to the first new message and there are
+                         * also urgent messages, then prompt for navigation to the
+                         * previous message
+                         */
+                        if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) {
+                                res = ast_play_and_wait(chan, "vm-prev");
+                        }
+                        if (!res && !skipadvanced)
+                                res = ast_play_and_wait(chan, "vm-advopts");
+                        if (!res)
+                                res = ast_play_and_wait(chan, "vm-repeat");
+                        /* Logic:
+                         * If we're not listening to the last message OR
+                         * we're listening to the last urgent message and there are
+                         * also new non-urgent messages, then prompt for navigation
+                         * to the next message
+                         */
+                        if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) ||
+                                (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) {
+                                res = ast_play_and_wait(chan, "vm-next");
+                        }
+                        if (!res) {
+                                int curmsg_deleted;
+#ifdef IMAP_STORAGE
+                                ast_mutex_lock(&vms->lock);
+#endif
+                                curmsg_deleted = vms->deleted[vms->curmsg];
+#ifdef IMAP_STORAGE
+                                ast_mutex_unlock(&vms->lock);
+#endif
+                                if (!curmsg_deleted) {
+                                        res = ast_play_and_wait(chan, "vm-delete");
+                                } else {
+                                        res = ast_play_and_wait(chan, "vm-undelete");
+                                }
+                                if (!res) {
+                                        res = ast_play_and_wait(chan, "vm-toforward");
+                                }
+                                if (!res) {
+                                        res = ast_play_and_wait(chan, "vm-savemessage");
+                                }
+                        }
+                }
+
+		if (!res) {
+			res = ast_play_and_wait(chan, "vm-helpexit");
+		}
+		if (!res)
+			res = ast_waitfordigit(chan, 6000);
+		if (!res) {
+			vms->repeats++;
+			if (vms->repeats > 2) {
+				res = 't';
+			}
+		}
+
+	}
+
+        return res;
+}
+
 static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms,  int skipadvanced, int in_urgent)
 {
 	int res = 0;
@@ -10023,7 +10219,9 @@
 
 static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
 {
-	if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */
+        if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* Japanese syntax */
+                return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent);
+        } else if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */
 		return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent);
 	} else {					/* Default to ENGLISH */
 		return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
@@ -10444,6 +10642,33 @@
 	return cmd;
 }
 
+/*!
+ * \brief Japanese syntax for 'You have N messages' greeting.
+ * \param chan
+ * \param vms
+ * \param vmu
+ *
+ * \return zero on success, -1 on error.
+ */
+static int vm_browse_messages_ja(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
+{
+        int cmd = 0;
+
+        if (vms->lastmsg > -1) {
+                cmd = play_message(chan, vmu, vms);
+        } else {
+                snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
+                cmd = ast_play_and_wait(chan, vms->fn);
+                if (!cmd)
+                        cmd = ast_play_and_wait(chan, "vm-messages");
+                if (!cmd)
+                        cmd = ast_play_and_wait(chan, "jp-wa");
+                if (!cmd)
+                        cmd = ast_play_and_wait(chan, "jp-arimasen");
+        }
+        return cmd;
+}
+
 /*! 
  * \brief Spanish syntax for 'You have N messages' greeting.
  * \param chan
@@ -10569,6 +10794,8 @@
 		return vm_browse_messages_he(chan, vms, vmu);
 	} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) {  /* ITALIAN */
 		return vm_browse_messages_it(chan, vms, vmu);
+        } else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {  /* JAPANESE */
+                return vm_browse_messages_ja(chan, vms, vmu);
 	} else if (!strncasecmp(ast_channel_language(chan), "pt", 2)) {  /* PORTUGUESE */
 		return vm_browse_messages_pt(chan, vms, vmu);
 	} else if (!strncasecmp(ast_channel_language(chan), "vi", 2)) {  /* VIETNAMESE */
@@ -11514,6 +11741,22 @@
 			break;
 		case '*': /* Help */
 			if (!vms.starting) {
+                                if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {
+                                        cmd = vm_play_folder_name(chan, vms.vmbox);
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "jp-wa");
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "digits/1");
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "jp-wo");
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "silence/1");
+                                        if (!cmd)
+                                                cmd = ast_play_and_wait(chan, "vm-opts");
+                                        if (!cmd)
+                                                cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);
+                                        break;
+                                }
 				cmd = ast_play_and_wait(chan, "vm-onefor");
 				if (!strncasecmp(ast_channel_language(chan), "he", 2)) {
 					cmd = ast_play_and_wait(chan, "vm-for");
@@ -12096,9 +12339,7 @@
 		} else if (!strncasecmp(arg.attribute, "pager", 5)) {
 			ast_copy_string(buf, vmu->pager, len);
 		} else if (!strncasecmp(arg.attribute, "language", 8)) {
-			const char *lang = S_OR(vmu->language, chan ?
-				ast_channel_language(chan) : ast_defaultlanguage);
-			ast_copy_string(buf, lang, len);
+			ast_copy_string(buf, S_OR(vmu->language, ast_channel_language(chan)), len);
 		} else if (!strncasecmp(arg.attribute, "locale", 6)) {
 			ast_copy_string(buf, vmu->locale, len);
 		} else if (!strncasecmp(arg.attribute, "tz", 2)) {

Modified: team/group/media_formats-reviewed-trunk/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/channels/chan_dahdi.c?view=diff&rev=417771&r1=417770&r2=417771
==============================================================================
--- team/group/media_formats-reviewed-trunk/channels/chan_dahdi.c (original)
+++ team/group/media_formats-reviewed-trunk/channels/chan_dahdi.c Wed Jul  2 16:14:25 2014
@@ -781,6 +781,14 @@
 static struct dahdi_pvt *ifend = NULL;	/*!< Main interface list end */
 
 #if defined(HAVE_PRI)
+struct doomed_pri {
+	struct sig_pri_span *pri;
+	AST_LIST_ENTRY(doomed_pri) list;
+};
+static AST_LIST_HEAD_STATIC(doomed_pris, doomed_pri);
+
+static void pri_destroy_span(struct sig_pri_span *pri);
+
 static struct dahdi_parms_pseudo {
 	int buf_no;					/*!< Number of buffers */
 	int buf_policy;				/*!< Buffer policy */
@@ -1112,6 +1120,69 @@
 
 	return index;
 }
+
+/*!
+ * \internal
+ * \brief release all members on the doomed pris list
+ * \since 13.0
+ *
+ * Called priodically by the monitor threads to release spans marked for
+ * removal.
+ */
+static void release_doomed_pris(void)
+{
+#ifdef HAVE_PRI
+	struct doomed_pri *entry;
+
+	AST_LIST_LOCK(&doomed_pris);
+	while ((entry = AST_LIST_REMOVE_HEAD(&doomed_pris, list))) {
+		/* The span destruction must be done with this lock not held */
+		AST_LIST_UNLOCK(&doomed_pris);
+		ast_debug(4, "Destroying span %d from doomed queue.\n",
+				entry->pri->span);
+		pri_destroy_span(entry->pri);
+		ast_free(entry);
+		AST_LIST_LOCK(&doomed_pris);
+	}
+	AST_LIST_UNLOCK(&doomed_pris);
+#endif
+}
+
+#ifdef HAVE_PRI
+/*!
+ * \brief Queue a span for destruction
+ * \since 13.0
+ *
+ * \param pri the span to destroy
+ *
+ * Add a span to the list of spans to be destroyed later on
+ * by the monitor thread. Allows destroying a span while holding its
+ * lock.
+ */
+static void pri_queue_for_destruction(struct sig_pri_span *pri)
+{
+	struct doomed_pri *entry;
+
+	AST_LIST_LOCK(&doomed_pris);
+	AST_LIST_TRAVERSE(&doomed_pris, entry, list) {
+		if (entry->pri == pri) {
+			AST_LIST_UNLOCK(&doomed_pris);
+			return;
+		}
+	}
+	entry = ast_calloc(sizeof(struct doomed_pri), 1);
+	if (!entry) {
+		/* Nothing useful to do here. Panic? */
+		ast_log(LOG_WARNING, "Failed allocating memory for a doomed_pri.\n");
+		AST_LIST_UNLOCK(&doomed_pris);
+		return;
+	}
+	entry->pri = pri;
+	ast_debug(4, "Queue span %d for destruction.\n", pri->span);
+	AST_LIST_INSERT_TAIL(&doomed_pris, entry, list);
+	AST_LIST_UNLOCK(&doomed_pris);
+}
+#endif
 
 /*!
  * \internal
@@ -2653,8 +2724,6 @@
 #endif	/* defined(HAVE_PRI) */
 
 #if defined(HAVE_PRI)
-static void pri_destroy_span(struct sig_pri_span *pri);
-
 static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
 {
 	int x;
@@ -2683,7 +2752,7 @@
 		pri_event_noalarm(pri, index, 0);
 		break;
 	case DAHDI_EVENT_REMOVED:
-		pri_destroy_span(pri);
+		pri_queue_for_destruction(pri);
 		break;
 	default:
 		break;
@@ -2966,6 +3035,7 @@
 	.dial_digits = my_pri_dial_digits,
 	.open_media = my_pri_ss7_open_media,
 	.ami_channel_event = my_ami_channel_event,
+	.destroy_later = pri_queue_for_destruction,
 };
 #endif	/* defined(HAVE_PRI) */
 
@@ -11455,6 +11525,7 @@
 			}
 		}
 		ast_mutex_unlock(&iflock);
+		release_doomed_pris();
 	}
 	/* Never reached */
 	pthread_cleanup_pop(1);
@@ -14203,6 +14274,7 @@
 	for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
 		ast_debug(4, "closing pri_fd %d\n", i);
 		dahdi_close_pri_fd(dahdi_pri, i);
+		dahdi_pri->dchannels[i] = 0;
 	}
 	sig_pri_init_pri(pri);
 	ast_debug(1, "PRI span %d destroyed\n", pri->span);

Modified: team/group/media_formats-reviewed-trunk/channels/chan_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/channels/chan_pjsip.c?view=diff&rev=417771&r1=417770&r2=417771
==============================================================================
--- team/group/media_formats-reviewed-trunk/channels/chan_pjsip.c (original)
+++ team/group/media_formats-reviewed-trunk/channels/chan_pjsip.c Wed Jul  2 16:14:25 2014
@@ -61,6 +61,7 @@
 #include "asterisk/threadstorage.h"
 #include "asterisk/features_config.h"
 #include "asterisk/pickup.h"
+#include "asterisk/test.h"
 
 #include "asterisk/res_pjsip.h"
 #include "asterisk/res_pjsip_session.h"
@@ -1159,7 +1160,9 @@
 					ao2_cleanup(channel->session);
 				}
 			}
+			ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
 		} else {
+			ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Failure");
 			res = -1;
 		}
 		break;

Modified: team/group/media_formats-reviewed-trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/media_formats-reviewed-trunk/channels/chan_sip.c?view=diff&rev=417771&r1=417770&r2=417771
==============================================================================
--- team/group/media_formats-reviewed-trunk/channels/chan_sip.c (original)
+++ team/group/media_formats-reviewed-trunk/channels/chan_sip.c Wed Jul  2 16:14:25 2014
@@ -1251,7 +1251,7 @@
 static int process_sdp_a_image(const char *a, struct sip_pvt *p);
 static void add_ice_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a_buf);
 static void add_dtls_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a_buf);
-static void start_ice(struct ast_rtp_instance *instance);
+static void start_ice(struct ast_rtp_instance *instance, int offer);
 static void add_codec_to_sdp(const struct sip_pvt *p, struct ast_format *codec,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size, int *max_packet_size);
@@ -2661,6 +2661,10 @@
 	int res;
 
 	if (ast_websocket_set_nonblock(session)) {
+		goto end;
+	}
+
+	if (ast_websocket_set_timeout(session, sip_cfg.websocket_write_timeout)) {
 		goto end;
 	}
 
@@ -10187,12 +10191,21 @@
 
 			if (process_sdp_a_dtls(value, p, p->rtp)) {
 				processed = TRUE;
+				if (p->srtp) {
+					ast_set_flag(p->srtp, AST_SRTP_CRYPTO_OFFER_OK);
+				}
 			}
 			if (process_sdp_a_dtls(value, p, p->vrtp)) {
 				processed = TRUE;
+				if (p->vsrtp) {
+					ast_set_flag(p->vsrtp, AST_SRTP_CRYPTO_OFFER_OK);
+				}
 			}
 			if (process_sdp_a_dtls(value, p, p->trtp)) {
 				processed = TRUE;
+				if (p->tsrtp) {
+					ast_set_flag(p->tsrtp, AST_SRTP_CRYPTO_OFFER_OK);
+				}
 			}
 
 			break;
@@ -10600,7 +10613,11 @@
 					if (process_sdp_a_ice(value, p, p->rtp)) {
 						processed = TRUE;
 					} else if (process_sdp_a_dtls(value, p, p->rtp)) {
+						processed_crypto = TRUE;
 						processed = TRUE;
+						if (p->srtp) {
+							ast_set_flag(p->srtp, AST_SRTP_CRYPTO_OFFER_OK);
+						}
 					} else if (process_sdp_a_sendonly(value, &sendonly)) {
 						processed = TRUE;
 					} else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) {
@@ -10615,7 +10632,11 @@
 					if (process_sdp_a_ice(value, p, p->vrtp)) {
 						processed = TRUE;
 					} else if (process_sdp_a_dtls(value, p, p->vrtp)) {
+						processed_crypto = TRUE;
 						processed = TRUE;
+						if (p->vsrtp) {
+							ast_set_flag(p->vsrtp, AST_SRTP_CRYPTO_OFFER_OK);
+						}
 					} else if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) {
 						processed_crypto = TRUE;
 						processed = TRUE;
@@ -10775,7 +10796,7 @@
 	/* Setup audio address and port */
 	if (p->rtp) {
 		if (sa && portno > 0) {
-			start_ice(p->rtp);
+			start_ice(p->rtp, (req->method != SIP_RESPONSE) ? 0 : 1);
 			ast_sockaddr_set_port(sa, portno);
 			ast_rtp_instance_set_remote_address(p->rtp, sa);
 			if (debug) {
@@ -10823,7 +10844,7 @@
 	/* Setup video address and port */
 	if (p->vrtp) {
 		if (vsa && vportno > 0) {
-			start_ice(p->vrtp);
+			start_ice(p->vrtp, (req->method != SIP_RESPONSE) ? 0 : 1);
 			ast_sockaddr_set_port(vsa, vportno);
 			ast_rtp_instance_set_remote_address(p->vrtp, vsa);
 			if (debug) {
@@ -10841,7 +10862,7 @@
 	/* Setup text address and port */
 	if (p->trtp) {
 		if (tsa && tportno > 0) {
-			start_ice(p->trtp);
+			start_ice(p->trtp, (req->method != SIP_RESPONSE) ? 0 : 1);
 			ast_sockaddr_set_port(tsa, tportno);
 			ast_rtp_instance_set_remote_address(p->trtp, tsa);
 			if (debug) {
@@ -11179,7 +11200,7 @@
 {
 	struct ast_rtp_engine_dtls *dtls;
 	int found = FALSE;
-	char value[256], hash[6];
+	char value[256], hash[32];
 
 	if (!instance || !p->dtls_cfg.enabled || !(dtls = ast_rtp_instance_get_dtls(instance))) {
 		return found;
@@ -11211,11 +11232,13 @@
 			ast_log(LOG_WARNING, "Unsupported connection attribute value '%s' received on dialog '%s'\n",
 				value, p->callid);
 		}
-	} else if (sscanf(a, "fingerprint: %5s %255s", hash, value) == 2) {
+	} else if (sscanf(a, "fingerprint: %31s %255s", hash, value) == 2) {
 		found = TRUE;
 
 		if (!strcasecmp(hash, "sha-1")) {
 			dtls->set_fingerprint(instance, AST_RTP_DTLS_HASH_SHA1, value);
+		} else if (!strcasecmp(hash, "sha-256")) {
+			dtls->set_fingerprint(instance, AST_RTP_DTLS_HASH_SHA256, value);
 		} else {
 			ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s' received on dialog '%s'\n",
 				hash, p->callid);
@@ -11348,7 +11371,7 @@
 			if (debug)
 				ast_verbose("Discarded description format %s for ID %u\n", mimeSubtype, codec);
 		}
-	} else if (sscanf(a, "fmtp: %30u %255s", &codec, fmtp_string) == 2) {
+	} else if (sscanf(a, "fmtp: %30u %255[^\t\n]", &codec, fmtp_string) == 2) {
 		struct ast_format *format;
 
 		if ((format = ast_rtp_codecs_get_payload_format(newvideortp, codec))) {
@@ -12853,7 +12876,7 @@
 }
 
 /*! \brief Start ICE negotiation on an RTP instance */
-static void start_ice(struct ast_rtp_instance *instance)
+static void start_ice(struct ast_rtp_instance *instance, int offer)
 {
 	struct ast_rtp_engine_ice *ice = ast_rtp_instance_get_ice(instance);
 
@@ -12861,6 +12884,8 @@
 		return;
 	}
 
+	/* If we are the offerer then we are the controlling agent, otherwise they are */
+	ice->set_role(instance, offer ? AST_RTP_ICE_ROLE_CONTROLLING : AST_RTP_ICE_ROLE_CONTROLLED);
 	ice->start(instance);
 }
 
@@ -12868,6 +12893,7 @@

[... 6720 lines stripped ...]



More information about the asterisk-commits mailing list