Index: configs/unistim.conf.sample
===================================================================
--- configs/unistim.conf.sample	(revision 411700)
+++ configs/unistim.conf.sample	(working copy)
@@ -57,7 +57,7 @@
 ;maintext0="you can insert"  ; default = "Welcome", 24 characters max
 ;maintext1="a custom text"   ; default = the name of the device, 24 characters max
 ;maintext2="(main page)"     ; default = the public IP of the phone, 24 characters max
-;dateformat=1                ; 0 = month/day, 1 (default) = day/month
+;dateformat=0                ; 0 (default) = 31Jan, 1 = Jan31, 3 = month/day, 3 = day/month
 ;timeformat=1                ; 0 = 0:00am ; 1 (default) = 0h00, 2 = 0:00
 ;contrast=8                  ; define the contrast of the LCD. From 0 to 15. Default = 8
 ;country=us                  ; country (ccTLD) for dial tone frequency. See README, default = us
@@ -66,6 +66,7 @@
 ;cwvolume=2                  ; ring volume : 0,1,2,3, default = 0
 ;cwstyle=3                   ; ring style : 0 to 7, default = 2
 ;sharpdial=1                 ; dial number by pressing #, default = 0
+;dtmf_duration=0	     ; DTMF playback duration (in milliseconds) 0..150 (0 = off (default), 150 = maximum)
 ;interdigit_timer=4000       ; timer for automatic dial after several digits of number entered (in ms, 0 is off)
 ;callhistory=1               ; 0 = disable, 1 = enable call history, default = 1
 ;callerid="Customer Support" <555-234-5678>
Index: channels/chan_unistim.c
===================================================================
--- channels/chan_unistim.c	(revision 411700)
+++ channels/chan_unistim.c	(working copy)
@@ -405,6 +405,7 @@
 	char cwvolume;			/*!< Ring volume on call waiting */
 	char cwstyle;			 /*!< Ring melody on call waiting */
 	int interdigit_timer;		/*!< Interdigit timer for dialing number by timeout */
+	int dtmfduration;		/*!< DTMF playback duration */
 	time_t nextdial;		/*!< Timer used for dial by timeout */
 	int rtp_port;			   /*!< RTP port used by the phone */
 	int rtp_method;			 /*!< Select the unistim data used to establish a RTP session */
@@ -547,9 +548,9 @@
 static const unsigned char packet_send_stream_based_tone_off[] =
 	{ 0x16, 0x05, 0x1c, 0x00, 0x00 };
 
-/* static const unsigned char packet_send_Mute[] = { 0x16, 0x05, 0x04, 0x00, 0x00 };
+static const unsigned char packet_send_Mute[] = { 0x16, 0x05, 0x04, 0x00, 0x00 };
 static const unsigned char packet_send_CloseAudioStreamRX[] = { 0x16, 0x05, 0x31, 0x00, 0xff };
-static const unsigned char packet_send_CloseAudioStreamTX[] = { 0x16, 0x05, 0x31, 0xff, 0x00 };*/
+static const unsigned char packet_send_CloseAudioStreamTX[] = { 0x16, 0x05, 0x31, 0xff, 0x00 };
 static const unsigned char packet_send_stream_based_tone_on[] =
 	{ 0x16, 0x06, 0x1b, 0x00, 0x00, 0x05 };
 static const unsigned char packet_send_stream_based_tone_single_freq[] =
@@ -558,6 +559,7 @@
 	{ 0x16, 0x08, 0x1d, 0x00, 0x01, 0xb8, 0x01, 0x5e };
 static const unsigned char packet_send_select_output[] =
 	{ 0x16, 0x06, 0x32, 0xc0, 0x01, 0x00 };
+
 static const unsigned char packet_send_ring[] =
 	{ 0x16, 0x06, 0x32, 0xdf, 0x00, 0xff, 0x16, 0x05, 0x1c, 0x00, 0x00, 0x16,
 	0x04, 0x1a, 0x01, 0x16, 0x05, 0x12, 0x13 /* Ring type 10 to 17 */ , 0x18, 0x16, 0x04, 0x18,     /* volume 00, 10, 20... */
@@ -616,15 +618,19 @@
 	{ 0x17, 0x04, 0x24, /*Contrast */ 0x08 };
 static const unsigned char packet_send_start_timer[] =
 	{ 0x17, 0x05, 0x0b, /*Timer option*/0x05, /* Timer ID */0x00, 0x17, 0x08, 0x16,
-	/* Text */ 0x44, 0x75, 0x72, 0xe9, 0x65 };
+	/* Text */ 0x54, 0x69, 0x6d, 0x65, 0x72 }; /* Changed Duree to Timer */
 static const unsigned char packet_send_stop_timer[] = { 0x17, 0x05, 0x0b, 0x02, 0x00 };
 static const unsigned char packet_send_icon[] = { 0x17, 0x05, 0x14, /*pos */ 0x00, /*icon */ 0x25 };      /* display an icon in front of the text zone */
 static const unsigned char packet_send_S7[] = { 0x17, 0x06, 0x0f, 0x30, 0x07, 0x07 };
 static const unsigned char packet_send_set_pos_cursor[] =
 	{ 0x17, 0x06, 0x10, 0x81, 0x04, /*pos */ 0x20 };
 
-/*static unsigned char packet_send_MonthLabelsDownload[] =
-  { 0x17, 0x0a, 0x15,  Month (3 char)  0x46, 0x65, 0x62, 0x4d, 0xe4, 0x72, 0x20 }; */
+static unsigned char monthlabels[] =
+  { 0x4a,0x61,0x6e, 0x46,0x65,0x62, 0x4d,0x61,0x72, 0x41,0x70,0x72,
+    0x4d,0x61,0x79, 0x4a,0x75,0x6e, 0x4a,0x75,0x6c, 0x41,0x75,0x67,
+    0x53,0x65,0x70, 0x4f,0x63,0x74, 0x4e,0x6f,0x76, 0x44,0x65,0x63 ,0x4a,0x61,0x6e};
+static unsigned char packet_send_MonthLabelsDownload[] =
+  { 0x17, 0x0a, 0x15,  	0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d, 0x20};
 static const unsigned char packet_send_favorite[] =
 	{ 0x17, 0x0f, 0x19, 0x10, /*pos */ 0x01, /*name */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 0x20, 0x20, 0x20, 0x20, /*end_name */ 0x19,
@@ -1596,6 +1602,21 @@
 	send_client(SIZE_HEADER + sizeof(packet_send_led_update), buffsend, pte);
 }
 
+static void send_mute(struct unistimsession *pte, unsigned char mute)
+{
+/*
+	00 = unmute TX 01 = mute TX
+	20 = unmute TX 21 = mute RX
+*/
+	BUFFSEND;
+	if (unistimdebug) {
+		ast_verb(0, "Sending mute packet (%x)\n", mute);
+	}
+	memcpy(buffsend + SIZE_HEADER, packet_send_Mute, sizeof(packet_send_Mute));
+	buffsend[9] = mute;
+	send_client(SIZE_HEADER + sizeof(packet_send_Mute), buffsend, pte);
+}
+
 /* output = OUTPUT_HANDSET, OUTPUT_HEADPHONE or OUTPUT_SPEAKER
  * volume = VOLUME_LOW, VOLUME_NORMAL, VOLUME_INSANELY_LOUD
  * mute = MUTE_OFF, MUTE_ON */
@@ -1618,16 +1639,20 @@
 	}
 	buffsend[10] = volume;
 	if (mute == MUTE_ON_DISCRET) {
-		buffsend[11] = MUTE_ON;
-	} else {
-		buffsend[11] = mute;
+/*		buffsend[11] = MUTE_ON; */
+		send_mute (pte,0x01);
+	} else { 
+		send_mute (pte,(mute&0x01));
+/*		buffsend[11] = mute; */
 	}
+
 	send_client(SIZE_HEADER + sizeof(packet_send_select_output), buffsend, pte);
 	if (mute == MUTE_OFF) {
 		send_led_update(pte, 0x18);
 	} else if (mute == MUTE_ON) {
 		send_led_update(pte, 0x19);
 	}
+
 	pte->device->mute = mute;
 	if (output == OUTPUT_HANDSET) {
 		if (mute == MUTE_ON) {
@@ -1714,6 +1739,26 @@
 	send_text(TEXT_LINE0, TEXT_NORMAL, pte, "");
 }
 
+static void send_month_labels(struct unistimsession *pte, int month)
+{
+        BUFFSEND;
+	month = month*3;
+ 
+        if (unistimdebug) {
+                ast_verb(0, "Sending Month Labels\n");
+        }
+        memcpy(buffsend + SIZE_HEADER, packet_send_MonthLabelsDownload, sizeof(packet_send_MonthLabelsDownload));
+	buffsend[9] = monthlabels[month];
+	buffsend[10] = monthlabels[month+1];
+	buffsend[11] = monthlabels[month+2];
+	buffsend[12] = monthlabels[month+3];
+	buffsend[13] = monthlabels[month+4];
+	buffsend[14] = monthlabels[month+5];
+
+        send_client(SIZE_HEADER + sizeof(packet_send_MonthLabelsDownload), buffsend, pte);
+}
+
+
 static void send_date_time(struct unistimsession *pte)
 {
 	BUFFSEND;
@@ -1730,6 +1775,7 @@
 	buffsend[12] = (unsigned char) atm.tm_hour;
 	buffsend[13] = (unsigned char) atm.tm_min;
 	send_client(SIZE_HEADER + sizeof(packet_send_date_time), buffsend, pte);
+	send_month_labels(pte, atm.tm_mon); 
 }
 
 static void send_date_time2(struct unistimsession *pte)
@@ -2859,10 +2905,10 @@
 		ind = ast_strdupa(ts->data);
 		s = strsep(&ind, ",");
 		ast_tone_zone_part_parse(s, &tone_data);
-		if (tone_data.modulate) {
+/*		if (tone_data.modulate) {
 			tone_data.freq2 = 0;
 		}
-		send_tone(pte, tone_data.freq1, tone_data.freq2);
+*/		send_tone(pte, tone_data.freq1, tone_data.freq2);
 		if (unistimdebug) {
 			ast_verb(0, "Country code found (%s), freq1=%d freq2=%d\n",
 							pte->device->tz->country, tone_data.freq1, tone_data.freq2);
@@ -3270,27 +3316,28 @@
 
 	/* Send DTMF indication _before_ playing sounds */
 	ast_queue_frame(sub->owner, &f);
-
 	if (unistimdebug) {
-		ast_verb(0, "Send Digit %c\n", digit);
+		ast_verb(0, "Send Digit %c (%i ms)\n", digit, pte->device->dtmfduration);
 	}
-	row = (digit - '1') % 3;
-	col = (digit - '1' - row) / 3;
-	if (digit >= '1' && digit <='9') {
-		send_tone(pte, dtmf_row[row], dtmf_col[col]);
-	} else if (digit >= 'A' && digit <= 'D') {
-		send_tone(pte, dtmf_row[digit-'A'], dtmf_col[3]);
-	} else if (digit == '*') {
-		send_tone(pte, dtmf_row[3], dtmf_col[0]);
-	} else if (digit == '0') {
-		send_tone(pte, dtmf_row[3], dtmf_col[1]);
-	} else if (digit == '#') {
-		send_tone(pte, dtmf_row[3], dtmf_col[2]);
-	} else {
-		send_tone(pte, 500, 2000);
+	if (pte->device->dtmfduration > 0) {
+		row = (digit - '1') % 3;
+		col = (digit - '1' - row) / 3;
+		if (digit >= '1' && digit <='9') {
+			send_tone(pte, dtmf_row[row], dtmf_col[col]);
+		} else if (digit >= 'A' && digit <= 'D') {
+			send_tone(pte, dtmf_row[digit-'A'], dtmf_col[3]);
+		} else if (digit == '*') {
+			send_tone(pte, dtmf_row[3], dtmf_col[0]);
+		} else if (digit == '0') {
+			send_tone(pte, dtmf_row[3], dtmf_col[1]);
+		} else if (digit == '#') {
+			send_tone(pte, dtmf_row[3], dtmf_col[2]);
+		} else {
+			send_tone(pte, 500, 2000);
+		}
+		usleep(pte->device->dtmfduration*1000);	 /* Less than perfect, blocking an important thread is not a good idea */
+		send_tone(pte, 0, 0);
 	}
-	usleep(150000);			 /* XXX Less than perfect, blocking an important thread is not a good idea */
-	send_tone(pte, 0, 0);
 	return 0;
 }
 
@@ -6352,6 +6399,7 @@
 		d->height = DEFAULTHEIGHT;
 		d->selected = -1;
 		d->interdigit_timer = DEFAULT_INTERDIGIT_TIMER;
+		d->dtmfduration=0;
 	} else {
 		/* Delete existing line information */
 		AST_LIST_LOCK(&d->lines);
@@ -6382,6 +6430,7 @@
 	cwstyle = 2;
 	nbsoftkey = 0;
 	linecnt = 0;
+	d->dtmfduration=0;
 	while (v) {
 		if (!strcasecmp(v->name, "rtp_port")) {
 			d->rtp_port = atoi(v->value);
@@ -6433,6 +6482,9 @@
 			sharpdial = ast_true(v->value) ? 1 : 0;
 		} else if (!strcasecmp(v->name, "interdigit_timer")) {
 			d->interdigit_timer = atoi(v->value);
+		} else if (!strcasecmp(v->name, "dtmf_duration")) {
+			d->dtmfduration = atoi(v->value);
+			if (d->dtmfduration > 150) {d->dtmfduration = 150;}
 		} else if (!strcasecmp(v->name, "callerid")) {
 			if (!strcasecmp(v->value, "asreceived")) {
 				lt->cid_num[0] = '\0';
@@ -6570,7 +6622,7 @@
 		ast_log(LOG_WARNING, "Country '%s' was not found in indications.conf\n",
 				d->country);
 	}
-	d->datetimeformat = 56 + (dateformat * 4);
+	d->datetimeformat = 48 + (dateformat * 4);
 	d->datetimeformat += timeformat;
 	if ((autoprovisioning == AUTOPROVISIONING_TN) &&
 		(!ast_strlen_zero(d->extension_number))) {
