[asterisk-commits] murf: branch murf/bug11210 r97556 - in /team/murf/bug11210: ./ apps/ channels...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 9 12:33:42 CST 2008


Author: murf
Date: Wed Jan  9 12:33:41 2008
New Revision: 97556

URL: http://svn.digium.com/view/asterisk?view=rev&rev=97556
Log:
Merged revisions 97280-97282,97303,97305,97307,97309,97364-97365,97389-97390,97421,97449,97451,97488,97490,97495,97530-97533 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r97280 | rizzo | 2008-01-08 16:09:44 -0700 (Tue, 08 Jan 2008) | 11 lines

add support for textareas, used for various dialog windows on the gui.
The main code to implement the textarea is in console_board.c,
and uses a simple png image with the font, blitting characters
on the designated areas of the main screen.
Additionally we provide some annotations in the image used
as a skin to indicate which areas are used for text messages.
(images will be committed separately).
At the moment the dialog area is only used to display a running
counter, just as a proof of concept.


................
r97281 | rizzo | 2008-01-08 16:11:25 -0700 (Tue, 08 Jan 2008) | 5 lines

add a font suitable for use with the console GUI.
The background of this particular image is transparent so we
can preserve the original background when we draw strings.


................
r97282 | rizzo | 2008-01-08 16:14:48 -0700 (Tue, 08 Jan 2008) | 6 lines

Add the annotation for the textarea used for messages,
and also change the background from white to something
different to show that we can make use of fonts with transparent
background.


................
r97303 | rizzo | 2008-01-08 16:35:05 -0700 (Tue, 08 Jan 2008) | 4 lines

add copyright (most of this code was written by Marta Carbone),
remove some unused code, add/clarify some comments.


................
r97305 | tilghman | 2008-01-08 16:51:51 -0700 (Tue, 08 Jan 2008) | 6 lines

Add a new flag 'd' (with optional context) permitting any extension within
that context to be entered as a new extension during the playback of a
voicemail greeting.
Patch inspired by bluecrow76, by tilghman.
(Closes issue #7063)

................
r97307 | mmichelson | 2008-01-08 16:56:24 -0700 (Tue, 08 Jan 2008) | 13 lines

Merged revisions 97304 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97304 | mmichelson | 2008-01-08 17:49:11 -0600 (Tue, 08 Jan 2008) | 5 lines

Part 1 of N of adding doxygen comments to app_queue. I picked some of the most common functions
used (which also happen to be some the biggest/ugliest functions too) to document first. I'm pretty
new to doxygen so criticism is welcome.


........

................
r97309 | mmichelson | 2008-01-08 17:18:15 -0700 (Tue, 08 Jan 2008) | 11 lines

Merged revisions 97308 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97308 | mmichelson | 2008-01-08 18:17:40 -0600 (Tue, 08 Jan 2008) | 3 lines

use the \retval doxygen command properly


........

................
r97364 | tilghman | 2008-01-08 17:51:59 -0700 (Tue, 08 Jan 2008) | 13 lines

Merged revisions 97350 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97350 | tilghman | 2008-01-08 18:44:14 -0600 (Tue, 08 Jan 2008) | 5 lines

Allow filename completion on zero-length modules, remove a memory leak, remove
a file descriptor leak, and make filename completion thread-safe.
Patched and tested by tilghman.
(Closes issue #11681)

........

................
r97365 | tilghman | 2008-01-08 17:58:22 -0700 (Tue, 08 Jan 2008) | 2 lines

New option in trunk, needs strdupa to be safe, too

................
r97389 | rizzo | 2008-01-09 05:13:32 -0700 (Wed, 09 Jan 2008) | 4 lines

make get_video_desc() return the active console if
passed a null argument (channel).


................
r97390 | rizzo | 2008-01-09 05:23:18 -0700 (Wed, 09 Jan 2008) | 7 lines

implement the "console startgui" and "console stopgui"
commands so you can start and stop the gui even outside
of a call. This is convenient for testing, and also for
using the keypad to pick up a call, and to dial a number
(the latter not yet implemented, but should be close).


................
r97421 | kpfleming | 2008-01-09 08:31:56 -0700 (Wed, 09 Jan 2008) | 10 lines

Merged revisions 97410 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97410 | kpfleming | 2008-01-09 09:26:23 -0600 (Wed, 09 Jan 2008) | 2 lines

add error number output to ioctl failure messages to help with debugging

........

................
r97449 | kpfleming | 2008-01-09 08:45:34 -0700 (Wed, 09 Jan 2008) | 10 lines

Merged revisions 97448 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97448 | kpfleming | 2008-01-09 09:43:19 -0600 (Wed, 09 Jan 2008) | 2 lines

pass the right variable to get an error string... oops

........

................
r97451 | file | 2008-01-09 09:13:24 -0700 (Wed, 09 Jan 2008) | 14 lines

Merged revisions 97450 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97450 | file | 2008-01-09 12:11:17 -0400 (Wed, 09 Jan 2008) | 6 lines

Don't do conferencing totally in Zaptel if Monitor is running on the channel.
(closes issue #11709)
Reported by: BigJimmy
Patches:
      patch-meetmerec uploaded by BigJimmy (license 371)

........

................
r97488 | rizzo | 2008-01-09 09:44:20 -0700 (Wed, 09 Jan 2008) | 8 lines

Implement keyboard handling, and use it to enter
a number to dial in the 'message' area under the
keypad.

Now you can make calls using the keypad as a regular phone
(or the keyboard for chars not present on the keypad)


................
r97490 | phsultan | 2008-01-09 09:59:09 -0700 (Wed, 09 Jan 2008) | 15 lines

Merged revisions 97489 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97489 | phsultan | 2008-01-09 17:44:24 +0100 (Wed, 09 Jan 2008) | 7 lines

Set the caller id within the gtalk_alloc function.

As underlined in issue #10437 by Josh, we need to prevent a possible
memory leak. We only set the name part of the caller id, the number
part is not relevant when dealing with JIDs.

Closes issue #11549.
........

................
r97495 | kpfleming | 2008-01-09 10:30:13 -0700 (Wed, 09 Jan 2008) | 10 lines

Merged revisions 97491 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97491 | kpfleming | 2008-01-09 11:21:14 -0600 (Wed, 09 Jan 2008) | 2 lines

report the same message whether Zaptel does not have transcoder support loaded or no transcoders were found

........

................
r97530 | rizzo | 2008-01-09 11:03:40 -0700 (Wed, 09 Jan 2008) | 11 lines

Two changes:
- support scrolling of message window;
- simplify the code for creating a message window,
  and try it using a second one in the top of
  the keypad (where we echo the dialed number).

The 'skin' that supports these two windows will be
committed separately.

 

................
r97531 | russell | 2008-01-09 11:04:14 -0700 (Wed, 09 Jan 2008) | 10 lines

Merged revisions 97529 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r97529 | russell | 2008-01-09 12:02:08 -0600 (Wed, 09 Jan 2008) | 2 lines

Fix saying the parking space number to the caller doing the parking ...

........

................
r97532 | rizzo | 2008-01-09 11:04:17 -0700 (Wed, 09 Jan 2008) | 4 lines

add annotations for the two message windows
we use.


................
r97533 | rizzo | 2008-01-09 11:12:44 -0700 (Wed, 09 Jan 2008) | 3 lines

remove a wrong 'const'


................

Added:
    team/murf/bug11210/channels/console_board.c
      - copied unchanged from r97533, trunk/channels/console_board.c
    team/murf/bug11210/images/font.png
      - copied unchanged from r97533, trunk/images/font.png
Modified:
    team/murf/bug11210/   (props changed)
    team/murf/bug11210/apps/app_meetme.c
    team/murf/bug11210/apps/app_queue.c
    team/murf/bug11210/apps/app_voicemail.c
    team/murf/bug11210/channels/Makefile
    team/murf/bug11210/channels/chan_gtalk.c
    team/murf/bug11210/channels/chan_oss.c
    team/murf/bug11210/channels/chan_zap.c
    team/murf/bug11210/channels/console_gui.c
    team/murf/bug11210/channels/console_video.c
    team/murf/bug11210/channels/console_video.h
    team/murf/bug11210/codecs/codec_zap.c
    team/murf/bug11210/images/kpad2.jpg
    team/murf/bug11210/main/asterisk.c
    team/murf/bug11210/main/cli.c
    team/murf/bug11210/main/editline/readline.c
    team/murf/bug11210/res/res_features.c

Propchange: team/murf/bug11210/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/murf/bug11210/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Jan  9 12:33:41 2008
@@ -1,1 +1,1 @@
-/trunk:1-97275
+/trunk:1-97535

Modified: team/murf/bug11210/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/apps/app_meetme.c?view=diff&rev=97556&r1=97555&r2=97556
==============================================================================
--- team/murf/bug11210/apps/app_meetme.c (original)
+++ team/murf/bug11210/apps/app_meetme.c Wed Jan  9 12:33:41 2008
@@ -1796,7 +1796,7 @@
 		goto outrun;
 	}
 
-	retryzap = (strcasecmp(chan->tech->type, "Zap") || chan->audiohooks ? 1 : 0);
+	retryzap = (strcasecmp(chan->tech->type, "Zap") || (chan->audiohooks || chan->monitor) ? 1 : 0);
 	user->zapchannel = !retryzap;
 
  zapretry:
@@ -2240,14 +2240,14 @@
 				break;
 
 			if (c) {
-				if (c->fds[0] != origfd || (user->zapchannel && c->audiohooks)) {
+				if (c->fds[0] != origfd || (user->zapchannel && (c->audiohooks || c->monitor))) {
 					if (using_pseudo) {
 						/* Kill old pseudo */
 						close(fd);
 						using_pseudo = 0;
 					}
 					ast_debug(1, "Ooh, something swapped out under us, starting over\n");
-					retryzap = (strcasecmp(c->tech->type, "Zap") || c->audiohooks ? 1 : 0);
+					retryzap = (strcasecmp(c->tech->type, "Zap") || (c->audiohooks || c->monitor) ? 1 : 0);
 					user->zapchannel = !retryzap;
 					goto zapretry;
 				}

Modified: team/murf/bug11210/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/apps/app_queue.c?view=diff&rev=97556&r1=97555&r2=97556
==============================================================================
--- team/murf/bug11210/apps/app_queue.c (original)
+++ team/murf/bug11210/apps/app_queue.c Wed Jan  9 12:33:41 2008
@@ -2021,6 +2021,11 @@
 	return vars;
 }
 
+/*! \brief Part 2 of ring_one
+ *
+ * Does error checking before attempting to request a channel and call a member. This
+ * function is only called from ring_one
+ */
 static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
 {
 	int res;
@@ -2168,6 +2173,14 @@
 	return best;
 }
 
+/*! \brief Place a call to a queue member
+ *
+ * Once metrics have been calculated for each member, this function is used
+ * to place a call to the appropriate member (or members). The low-level
+ * channel-handling and error detection is handled in ring_entry
+ *
+ * Returns 1 if a member was called successfully, 0 otherwise
+ */
 static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
 {
 	int ret = 0;
@@ -2325,7 +2338,16 @@
 }
 
 #define AST_MAX_WATCHERS 256
-
+/*! \brief Wait for a member to answer the call
+ *
+ * \param[in] qe the queue_ent corresponding to the caller in the queue
+ * \param[in] outgoing the list of callattempts. Relevant ones will have their chan and stillgoing parameters non-zero
+ * \param[in] to the amount of time (in milliseconds) to wait for a response
+ * \param[out] digit if a user presses a digit to exit the queue, this is the digit the caller pressed
+ * \param[in] prebusies number of busy members calculated prior to calling wait_for_answer
+ * \param[in] caller_disconnect if the 'H' option is used when calling Queue(), this is used to detect if the caller pressed * to disconnect the call
+ * \param[in] forwardsallowed used to detect if we should allow call forwarding, based on the 'i' option to Queue()
+ */
 static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
 {
 	const char *queue = qe->parent->name;
@@ -2572,7 +2594,15 @@
 
 	return peer;
 }
-
+/*! \brief Check if we should start attempting to call queue members
+ *
+ * The behavior of this function is dependent first on whether autofill is enabled
+ * and second on whether the ring strategy is ringall. If autofill is not enabled,
+ * then return true if we're the head of the queue. If autofill is enabled, then
+ * we count the available members and see if the number of available members is enough
+ * that given our position in the queue, we would theoretically be able to connect to
+ * one of those available members
+ */
 static int is_our_turn(struct queue_ent *qe)
 {
 	struct queue_ent *ch;
@@ -2637,7 +2667,6 @@
 
 	return res;
 }
-
 static void update_qe_rule(struct queue_ent *qe)
 {
 	int max_penalty = qe->pr->max_relative ? qe->max_penalty + qe->pr->max_value : qe->pr->max_value;
@@ -2660,6 +2689,16 @@
 	qe->pr = AST_LIST_NEXT(qe->pr, list);
 }
 
+/*! \brief The waiting areas for callers who are not actively calling members
+ *
+ * This function is one large loop. This function will return if a caller
+ * either exits the queue or it becomes that caller's turn to attempt calling
+ * queue members. Inside the loop, we service the caller with periodic announcements,
+ * holdtime announcements, etc. as configured in queues.conf
+ *
+ * \retval  0 if the caller's turn has arrived
+ * \retval -1 if the caller should exit the queue.
+ */
 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
 {
 	int res = 0;
@@ -2762,6 +2801,12 @@
 	return 0;
 }
 
+/*! \brief Calculate the metric of each member in the outgoing callattempts
+ *
+ * A numeric metric is given to each member depending on the ring strategy used
+ * by the queue. Members with lower metrics will be called before members with
+ * higher metrics
+ */
 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
 {
 	if ((qe->max_penalty && (mem->penalty > qe->max_penalty)) || (qe->min_penalty && (mem->penalty < qe->min_penalty)))
@@ -2860,7 +2905,32 @@
 		(long)(callstart - qe->start), (long)(time(NULL) - callstart), reason,
 		qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
 }
-
+/*! \brief A large function which calls members, updates statistics, and bridges the caller and a member
+ * 
+ * Here is the process of this function
+ * 1. Process any options passed to the Queue() application. Options here mean the third argument to Queue()
+ * 2. Iterate trough the members of the queue, creating a callattempt corresponding to each member. During this
+ *    iteration, we also check the dialed_interfaces datastore to see if we have already attempted calling this
+ *    member. If we have, we do not create a callattempt. This is in place to prevent call forwarding loops. Also
+ *    during each iteration, we call calc_metric to determine which members should be rung when.
+ * 3. Call ring_one to place a call to the appropriate member(s)
+ * 4. Call wait_for_answer to wait for an answer. If no one answers, return.
+ * 5. Take care of any holdtime announcements, member delays, or other options which occur after a call has been answered.
+ * 6. Start the monitor or mixmonitor if the option is set
+ * 7. Remove the caller from the queue to allow other callers to advance
+ * 8. Bridge the call.
+ * 9. Do any post processing after the call has disconnected.
+ *
+ * \param[in] qe the queue_ent structure which corresponds to the caller attempting to reach members
+ * \param[in] options the options passed as the third parameter to the Queue() application
+ * \param[in] url the url passed as the fourth parameter to the Queue() application
+ * \param[in,out] tries the number of times we have tried calling queue members
+ * \param[out] noption set if the call to Queue() has the 'n' option set.
+ * \param[in] agi the agi passed as the fifth parameter to the Queue() application
+ * \param[in] macro the macro passed as the sixth parameter to the Queue() application
+ * \param[in] gosub the gosub passed as the seventh parameter to the Queue() application
+ * \param[in] ringing 1 if the 'r' option is set, otherwise 0
+ */
 static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *tries, int *noption, const char *agi, const char *macro, const char *gosub, int ringing)
 {
 	struct member *cur;
@@ -4140,6 +4210,18 @@
 	AST_LIST_UNLOCK(&rule_lists);
 }
 
+/*!\brief The starting point for all queue calls
+ *
+ * The process involved here is to 
+ * 1. Parse the options specified in the call to Queue()
+ * 2. Join the queue
+ * 3. Wait in a loop until it is our turn to try calling a queue member
+ * 4. Attempt to call a queue member
+ * 5. If 4. did not result in a bridged call, then check for between
+ *    call options such as periodic announcements etc.
+ * 6. Try 4 again uless some condition (such as an expiration time) causes us to 
+ *    exit the queue.
+ */
 static int queue_exec(struct ast_channel *chan, void *data)
 {
 	int res=-1;

Modified: team/murf/bug11210/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/apps/app_voicemail.c?view=diff&rev=97556&r1=97555&r2=97556
==============================================================================
--- team/murf/bug11210/apps/app_voicemail.c (original)
+++ team/murf/bug11210/apps/app_voicemail.c Wed Jan  9 12:33:41 2008
@@ -240,13 +240,15 @@
 	OPT_RECORDGAIN =       (1 << 3),
 	OPT_PREPEND_MAILBOX =  (1 << 4),
 	OPT_AUTOPLAY =         (1 << 6),
+	OPT_DTMFEXIT =         (1 << 7),
 } vm_option_flags;
 
 enum {
 	OPT_ARG_RECORDGAIN = 0,
 	OPT_ARG_PLAYFOLDER = 1,
+	OPT_ARG_DTMFEXIT   = 2,
 	/* This *must* be the last value in this enum! */
-	OPT_ARG_ARRAY_SIZE = 2,
+	OPT_ARG_ARRAY_SIZE = 3,
 } vm_option_args;
 
 AST_APP_OPTIONS(vm_app_options, {
@@ -254,6 +256,7 @@
 	AST_APP_OPTION('b', OPT_BUSY_GREETING),
 	AST_APP_OPTION('u', OPT_UNAVAIL_GREETING),
 	AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN),
+	AST_APP_OPTION_ARG('d', OPT_DTMFEXIT, OPT_ARG_DTMFEXIT),
 	AST_APP_OPTION('p', OPT_PREPEND_MAILBOX),
 	AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER),
 });
@@ -496,12 +499,14 @@
 	"               application. The possible values are:\n"
 	"               SUCCESS | USEREXIT | FAILED\n\n"
 	"  Options:\n"
-	"    b    - Play the 'busy' greeting to the calling party.\n"
-	"    g(#) - Use the specified amount of gain when recording the voicemail\n"
-	"           message. The units are whole-number decibels (dB).\n"
-	"    s    - Skip the playback of instructions for leaving a message to the\n"
-	"           calling party.\n"
-	"    u    - Play the 'unavailable' greeting.\n";
+	"    b      - Play the 'busy' greeting to the calling party.\n"
+	"    d([c]) - Accept digits for a new extension in context c, if played during\n"
+	"             the greeting.  Context defaults to the current context.\n"
+	"    g(#)   - Use the specified amount of gain when recording the voicemail\n"
+	"             message. The units are whole-number decibels (dB).\n"
+	"    s      - Skip the playback of instructions for leaving a message to the\n"
+	"             calling party.\n"
+	"    u      - Play the 'unavailable' greeting.\n";
 
 static char *synopsis_vmain = "Check Voicemail messages";
 
@@ -2952,6 +2957,7 @@
 struct leave_vm_options {
 	unsigned int flags;
 	signed char record_gain;
+	char *exitcontext;
 };
 
 static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
@@ -2983,11 +2989,11 @@
 	char ext_context[256] = "";
 	char fmt[80];
 	char *context;
-	char ecodes[16] = "#";
+	char ecodes[17] = "#";
 	char tmp[1024] = "", *tmpptr;
 	struct ast_vm_user *vmu;
 	struct ast_vm_user svm;
-	const char *category = NULL;
+	const char *category = NULL, *code, *alldtmf = "0123456789ABCD*#";
 
 	ast_copy_string(tmp, ext, sizeof(tmp));
 	ext = tmp;
@@ -3056,6 +3062,15 @@
 	else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
 		strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
 		ausemacro = 1;
+	}
+
+	if (ast_test_flag(options, OPT_DTMFEXIT)) {
+		for (code = alldtmf; *code; code++) {
+			char e[2] = "";
+			e[0] = *code;
+			if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num))
+				strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1);
+		}
 	}
 
 	/* Play the beginning intro if desired */
@@ -3102,7 +3117,7 @@
 		ast_stopstream(chan);
 	/* Check for a '*' here in case the caller wants to escape from voicemail to something
 	 other than the operator -- an automated attendant or mailbox login for example */
-	if (res == '*') {
+	if (!ast_strlen_zero(vmu->exit) && (res == '*')) {
 		chan->exten[0] = 'a';
 		chan->exten[1] = '\0';
 		if (!ast_strlen_zero(vmu->exit)) {
@@ -3117,7 +3132,7 @@
 	}
 
 	/* Check for a '0' here */
-	if (res == '0') {
+	if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') {
 	transfer:
 		if (ouseexten || ousemacro) {
 			chan->exten[0] = 'o';
@@ -3134,6 +3149,16 @@
 		}
 		return 0;
 	}
+
+	/* Allow all other digits to exit Voicemail and return to the dialplan */
+	if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) {
+		if (!ast_strlen_zero(options->exitcontext))
+			ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context));
+		free_user(vmu);
+		pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
+		return res;
+	}
+
 	if (res < 0) {
 		free_user(vmu);
 		pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
@@ -7400,7 +7425,7 @@
 		if (args.argc == 2) {
 			if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1))
 				return -1;
-			ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING);
+			ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_DTMFEXIT);
 			if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
 				int gain;
 
@@ -7410,6 +7435,10 @@
 				} else {
 					leave_options.record_gain = (signed char) gain;
 				}
+			}
+			if (ast_test_flag(&flags, OPT_DTMFEXIT)) {
+				if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT]))
+					leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT];
 			}
 		}
 	} else {

Modified: team/murf/bug11210/channels/Makefile
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/Makefile?view=diff&rev=97556&r1=97555&r2=97556
==============================================================================
--- team/murf/bug11210/channels/Makefile (original)
+++ team/murf/bug11210/channels/Makefile Wed Jan  9 12:33:41 2008
@@ -102,4 +102,4 @@
 
 chan_vpb.oo: ASTCFLAGS:=$(filter-out -Wdeclaration-after-statement,$(ASTCFLAGS))
 
-$(if $(filter chan_oss,$(EMBEDDED_MODS)),modules.link,chan_oss.so): console_video.o vgrabbers.o
+$(if $(filter chan_oss,$(EMBEDDED_MODS)),modules.link,chan_oss.so): console_video.o vgrabbers.o console_board.o

Modified: team/murf/bug11210/channels/chan_gtalk.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_gtalk.c?view=diff&rev=97556&r1=97555&r2=97556
==============================================================================
--- team/murf/bug11210/channels/chan_gtalk.c (original)
+++ team/murf/bug11210/channels/chan_gtalk.c Wed Jan  9 12:33:41 2008
@@ -896,6 +896,9 @@
 		return NULL;
 	}
 
+	/* Set CALLERID(name) to the full JID of the remote peer */
+	ast_copy_string(tmp->cid_name, tmp->them, sizeof(tmp->cid_name));
+
 	if(strchr(tmp->us, '/')) {
 		data = ast_strdupa(tmp->us);
 		exten = strsep(&data, "/");
@@ -917,7 +920,6 @@
 	int fmt;
 	int what;
 	const char *n2;
-	char *data = NULL, *cid = NULL;
 
 	if (title)
 		n2 = title;
@@ -981,20 +983,7 @@
 	ast_module_ref(ast_module_info->self);
 	ast_copy_string(tmp->context, client->context, sizeof(tmp->context));
 	ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
-	/* Don't use ast_set_callerid() here because it will
-	 * generate a needless NewCallerID event */
-	if (!strcasecmp(client->name, "guest")) {
-		data = ast_strdupa(i->them);
-		if (strchr(data, '/')) {
-			cid = strsep(&data, "/");
-		} else
-			cid = data;
-	} else {
-		data =  ast_strdupa(client->user);
-		cid = data;
-	}
-	cid = strsep(&cid, "@");
-	tmp->cid.cid_ani = ast_strdup(cid);
+
 	if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
 		tmp->cid.cid_dnid = ast_strdup(i->exten);
 	tmp->priority = 1;

Modified: team/murf/bug11210/channels/chan_oss.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_oss.c?view=diff&rev=97556&r1=97555&r2=97556
==============================================================================
--- team/murf/bug11210/channels/chan_oss.c (original)
+++ team/murf/bug11210/channels/chan_oss.c Wed Jan  9 12:33:41 2008
@@ -307,10 +307,12 @@
 /*! forward declaration */
 static struct chan_oss_pvt *find_desc(char *dev);
 
+static char *oss_active;	 /*!< the active device */
+
 /*! \brief return the pointer to the video descriptor */
 struct video_desc *get_video_desc(struct ast_channel *c)
 {
-	struct chan_oss_pvt *o = c->tech_pvt;
+	struct chan_oss_pvt *o = c ? c->tech_pvt : find_desc(oss_active);
 	return o ? o->env : NULL;
 }
 static struct chan_oss_pvt oss_default = {
@@ -327,7 +329,6 @@
 	.boost = BOOST_SCALE,
 };
 
-static char *oss_active;	 /*!< the active device */
 
 static int setformat(struct chan_oss_pvt *o, int mode);
 

Modified: team/murf/bug11210/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/chan_zap.c?view=diff&rev=97556&r1=97555&r2=97556
==============================================================================
--- team/murf/bug11210/channels/chan_zap.c (original)
+++ team/murf/bug11210/channels/chan_zap.c Wed Jan  9 12:33:41 2008
@@ -1647,7 +1647,7 @@
 			x = 1;
 			res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
 			if (res)
-				ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d\n", p->channel);
+				ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n", p->channel, strerror(errno));
 		}
 #if defined(HAVE_ZAPTEL_ECHOCANPARAMS)
 		res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL_PARAMS, &p->echocancel);
@@ -1656,7 +1656,7 @@
 		res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOCANCEL, &x);
 #endif
 		if (res)  {
-			ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
+			ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d (%s)\n", p->channel, strerror(errno));
 		} else {
 			p->echocanon = 1;
 			ast_debug(1, "Enabled echo cancellation on channel %d\n", p->channel);

Modified: team/murf/bug11210/channels/console_gui.c
URL: http://svn.digium.com/view/asterisk/team/murf/bug11210/channels/console_gui.c?view=diff&rev=97556&r1=97555&r2=97556
==============================================================================
--- team/murf/bug11210/channels/console_gui.c (original)
+++ team/murf/bug11210/channels/console_gui.c Wed Jan  9 12:33:41 2008
@@ -58,9 +58,6 @@
 #ifdef HAVE_SDL_IMAGE
 #include <SDL/SDL_image.h>      /* for loading images */
 #endif
-#ifdef HAVE_SDL_TTF
-#include <SDL/SDL_ttf.h>        /* render text on sdl surfaces */
-#endif
 
 enum kp_type { KP_NONE, KP_RECT, KP_CIRCLE };
 struct keypad_entry {
@@ -76,44 +73,31 @@
 	SDL_Overlay	*bmp;
 	SDL_Rect	rect;	/* location of the window */
 };
-#define GUI_BUFFER_LEN 256			/* buffer lenght used for input buffers */
-
-/* Where do we send the keyboard/keypad output */
-enum kb_output {
-	KO_NONE,
-	KO_INPUT,	/* the local input window */
-	KO_DIALED,	/* the 'dialed number' window */
-};
-
-enum drag_window {	/* which window are we dragging */
-	DRAG_NONE,
-	DRAG_LOCAL,	/* local video */
-	DRAG_REMOTE,	/* remote video */
-	DRAG_DIALED,	/* dialed number */
-	DRAG_INPUT,	/* input window */
-	DRAG_MESSAGE,	/* message window */
-};
-
-/*! \brief info related to the gui: button status, mouse coords, etc. */
+
 struct gui_info {
-	char			inbuf[GUI_BUFFER_LEN];	/* buffer for to-dial buffer */
-	int			inbuf_pos;	/* next free position in inbuf */
-	char			msgbuf[GUI_BUFFER_LEN];	/* buffer for text-message buffer */
-	int			msgbuf_pos;	/* next free position in msgbuf */
 	enum kb_output		kb_output;	/* where the keyboard output goes */
-	enum drag_window	drag_window;	/* which window are we dragging */
-	int			x_drag;		/* x coordinate where the drag starts */
-	int			y_drag;		/* y coordinate where the drag starts */
-#ifdef HAVE_SDL_TTF
-	TTF_Font                *font;          /* font to be used */ 
-#endif
+	struct drag_info	drag;		/* info on the window are we dragging */
 	/* support for display. */
 	SDL_Surface             *screen;	/* the main window */
 
 	int			outfd;		/* fd for output */
 	SDL_Surface		*keypad;	/* the skin for the keypad */
-
 	SDL_Rect		kp_rect;	/* portion of the skin to display - default all */
+	SDL_Surface		*font;		/* font to be used */ 
+	SDL_Rect		font_rects[96];	/* only printable chars */
+
+	/* each board has two rectangles,
+	 * [0] is the geometry relative to the keypad,
+	 * [1] is the geometry relative to the whole screen
+	 */
+	SDL_Rect		kp_msg[2];		/* incoming msg, relative to kpad */
+	struct board		*bd_msg;
+
+	SDL_Rect		kp_edit[2];	/* edit user input */
+	struct board		*bd_edit;
+
+	SDL_Rect		kp_dialed[2];	/* dialed number */
+	struct board		*bd_dialed;
 
 	/* variable-size array mapping keypad regions to functions */
 	int kp_size, kp_used;
@@ -132,17 +116,12 @@
 	if (gui == NULL)
 		return NULL;
 
-#ifdef HAVE_SDL_TTF
 	/* unload font file */ 
 	if (gui->font) {
-		TTF_CloseFont(gui->font);
+		SDL_FreeSurface(gui->font);
 		gui->font = NULL; 
 	}
 
-	/* uninitialize SDL_ttf library */
-	if ( TTF_WasInit() )
-		TTF_Quit();
-#endif
 	if (gui->outfd > -1)
 		close(gui->outfd);
 	if (gui->keypad)
@@ -234,13 +213,22 @@
 	KEY_SENDVIDEO = 132,
 	KEY_LOCALVIDEO = 133,
 	KEY_REMOTEVIDEO = 134,
-	KEY_WRITEMESSAGE = 135,
 	KEY_FLASH = 136,
+
+	/* sensitive areas for the various text windows */
+	KEY_MESSAGEBOARD = 140,
+	KEY_DIALEDBOARD = 141,
+	KEY_EDITBOARD = 142,
+
 	KEY_GUI_CLOSE = 199,		/* close gui */
-
-	/* regions of the skin - active area, fonts, etc. */
+	/* regions of the skin - displayed area, fonts, etc.
+	 * XXX NOTE these are not sensitive areas.
+	 */
 	KEY_KEYPAD = 200,		/* the keypad - default to the whole image */
-	KEY_FONT = 201,		/* the font */
+	KEY_FONT = 201,		/* the font. Maybe not really useful */
+	KEY_MESSAGE = 202,	/* area for incoming messages */
+	KEY_DIALED = 203,	/* area for dialed numbers */
+	KEY_EDIT = 204,		/* area for editing user input */
 
 	/* areas outside the keypad - simulated */
 	KEY_OUT_OF_KEYPAD = 241,
@@ -255,27 +243,6 @@
  * Handlers for the various keypad functions
  */
 
-/*! \brief append a character, or reset if  c = '\0' */
-static void append_char(char *str, int *str_pos, const char c)
-{
-	int i = *str_pos;
-	if (c == '\0')
-		i = 0;
-	else if (i < GUI_BUFFER_LEN - 1)
-		str[i++] = c;
-	else
-		i = GUI_BUFFER_LEN - 1; /* unnecessary, i think */
-	str = '\0';
-	*str_pos = i;
-}
-
-/*! \brief append string to a buffer */
-static void append_string(char *str, int *str_pos, const char *s)
-{
-	while (*s)
-		append_char(str, str_pos, *s++);
-}
-
 /* accumulate digits, possibly call dial if in connected mode */
 static void keypad_digit(struct video_desc *env, int digit)
 {	
@@ -285,7 +252,9 @@
 		f.subclass = digit;
 		ast_queue_frame(env->owner, &f);
 	} else {		/* no call, accumulate digits */
-		append_char(env->gui->inbuf, &env->gui->inbuf_pos, digit);
+		char buf[2] = { digit, '\0' };
+		if (env->gui->bd_msg) /* XXX not strictly necessary ... */
+			print_message(env->gui->bd_msg, buf);
 	}
 }
 
@@ -333,11 +302,17 @@
 
 	if (env->owner) { /* someone is calling us, just answer */
 		ast_cli_command(gui->outfd, "console answer");
-	} else if (gui->inbuf_pos) { /* we have someone to call */
-		ast_cli_command(gui->outfd, gui->inbuf);
-	}
-	append_char(gui->inbuf, &gui->inbuf_pos, '\0'); /* clear buffer */
-	append_string(gui->inbuf, &gui->inbuf_pos, "console dial ");
+	} else { /* we have someone to call */
+		char buf[160];
+		const char *who = ast_skip_blanks(read_message(gui->bd_msg));
+		buf[sizeof(buf) - 1] = '\0';
+		snprintf(buf, sizeof(buf) - 1, "console dial %s", who);
+		ast_log(LOG_WARNING, "doing <%s>\n", buf);
+		print_message(gui->bd_dialed, "\n");
+		print_message(gui->bd_dialed, who);
+		reset_board(gui->bd_msg);
+		ast_cli_command(gui->outfd, buf);
+	}
 }
 
 #if 0 /* still unused */
@@ -361,36 +336,20 @@
 /* Print given text on the gui */
 static int gui_output(struct video_desc *env, const char *text)
 {
-#ifndef HAVE_SDL_TTF
 	return 1;	/* error, not supported */
-#else
-	int x = 30, y = 20;	/* XXX change */
-	SDL_Surface *output = NULL;
-	SDL_Color color = {0, 0, 0};	/* text color */
-	struct gui_info *gui = env->gui;
-	SDL_Rect dest = {gui->win[WIN_KEYPAD].rect.x + x, y};
-
-	/* clean surface each rewrite */
-	SDL_BlitSurface(gui->keypad, NULL, gui->screen, &gui->win[WIN_KEYPAD].rect);
-
-	output = TTF_RenderText_Solid(gui->font, text, color);
-	if (output == NULL) {
-		ast_log(LOG_WARNING, "Cannot render text on gui - %s\n", TTF_GetError());
-		return 1;
-	}
-
-	SDL_BlitSurface(output, NULL, gui->screen, &dest);
-	
-	SDL_UpdateRects(gui->keypad, 1, &gui->win[WIN_KEYPAD].rect);
-	SDL_FreeSurface(output);
-	return 0;	/* success */
-#endif
 }
 #endif 
 
 static int video_geom(struct fbuf_t *b, const char *s);
 static void sdl_setup(struct video_desc *env);
 static int kp_match_area(const struct keypad_entry *e, int x, int y);
+
+static void set_drag(struct drag_info *drag, int x, int y, enum drag_window win)
+{
+	drag->x_start = x;
+	drag->y_start = y;
+	drag->drag_window = win;
+}
 
 /*
  * Handle SDL_MOUSEBUTTONDOWN type, finding the palette
@@ -408,7 +367,7 @@
 		button.x, button.y, gui->kp_used, gui->kp_size, gui->kp);
 #endif
 	/* for each mousedown we end previous drag */
-	gui->drag_window = DRAG_NONE;
+	gui->drag.drag_window = DRAG_NONE;
 
 	/* define keypad boundary */
 	if (button.x < env->rem_dpy.w)
@@ -453,17 +412,17 @@
 	case KEY_REMOTEVIDEO:
 		break;
 
+	case KEY_MESSAGEBOARD:
+		if (button.button == SDL_BUTTON_LEFT)
+			set_drag(&gui->drag, button.x, button.y, DRAG_MESSAGE);
+		break;
+
 	/* press outside the keypad. right increases size, center decreases, left drags */
 	case KEY_LOC_DPY:
 	case KEY_REM_DPY:
 		if (button.button == SDL_BUTTON_LEFT) {
-			if (index == KEY_LOC_DPY) {
-				/* store points where the drag start
-				* and switch in drag mode */
-				env->gui->x_drag = button.x;
-				env->gui->y_drag = button.y;
-				env->gui->drag_window = DRAG_LOCAL;
-			}
+			if (index == KEY_LOC_DPY)
+				set_drag(&gui->drag, button.x, button.y, DRAG_LOCAL);
 			break;
 		} else {
 			char buf[128];
@@ -490,64 +449,87 @@
  * depending on the text_mode variable value.
  *
  * key is the SDLKey structure corresponding to the key pressed.
- * XXX needs to be cleaned up when handling returns etc.
- */
-static void handle_keyboard_input(struct video_desc *env, SDLKey key)
-{
+ * Note that SDL returns modifiers (ctrl, shift, alt) as independent
+ * information so the key itself is not enough and we need to
+ * use a translation table, below - one line per entry,
+ * plain, shift, ctrl, ... using the first char as key.
+ */
+static const char *us_kbd_map[] = {
+	"`~", "1!", "2@", "3#", "4$", "5%", "6^",
+	"7&", "8*", "9(", "0)", "-_", "=+", "[{",
+	"]}", "\\|", ";:", "'\"", ",<", ".>", "/?",
+	"jJ\n",
+	NULL
+};
+
+static char map_key(SDL_keysym *ks)
+{
+	const char *s, **p = us_kbd_map;
+	int c = ks->sym;
+
+	if (c == '\r')	/* map cr into lf */
+		c = '\n';
+	if (c >= SDLK_NUMLOCK && c <= SDLK_COMPOSE)
+		return 0;	/* only a modifier */
+	if (ks->mod == 0)
+		return c;
+	while ((s = *p) && s[0] != c)
+		p++;
+	if (s) { /* see if we have a modifier and a chance to use it */
+		int l = strlen(s), mod = 0;
+		if (l > 1)
+			mod |= (ks->mod & KMOD_SHIFT) ? 1 : 0;
+		if (l > 2 + mod)
+			mod |= (ks->mod & KMOD_CTRL) ? 2 : 0;
+		if (l > 4 + mod)
+			mod |= (ks->mod & KMOD_ALT) ? 4 : 0;
+		c = s[mod];
+	}
+	if (ks->mod & (KMOD_CAPS|KMOD_SHIFT) && c >= 'a' && c <='z')
+		c += 'A' - 'a';
+	return c;
+}
+
+static void handle_keyboard_input(struct video_desc *env, SDL_keysym *ks)
+{
+	char buf[2] = { map_key(ks), '\0' };
 	struct gui_info *gui = env->gui;
+	if (buf[0] == 0)	/* modifier ? */
+		return;
 	switch (gui->kb_output) {
 	default:
 		break;
-	case KO_INPUT:
-		/* append in the text-message buffer */
-		if (key == SDLK_RETURN) {
-			/* send the text message and return in normal mode */
-			gui->kb_output = KO_NONE;
-			ast_cli_command(gui->outfd, gui->msgbuf);
-			append_char(gui->msgbuf, &gui->msgbuf_pos, '\0');
-		} else {
-			/* accumulate the key in the message buffer */
-			append_char(gui->msgbuf, &gui->msgbuf_pos, key);
-		}
-		break;
-	case KO_DIALED:
-		/* XXX actually, enter should be a 'console dial ' */
-		/* append in the dial buffer */
-		append_char(gui->inbuf, &gui->inbuf_pos, key);
+	case KO_INPUT:	/* to be completed */
+		break;
+	case KO_MESSAGE:
+		if (gui->bd_msg) {
+			print_message(gui->bd_msg, buf);
+			if (buf[0] == '\r' || buf[0] == '\n') {
+				keypad_pick_up(env);
+			}
+		}
+		break;
+
+	case KO_DIALED: /* to be completed */
 		break;
 	}
 
 	return;
 }
 
-/* implement superlinear acceleration on the movement */
-static int move_accel(int delta)
-{
-	int d1 = delta*delta / 100;
-	return (delta > 0) ? delta + d1 : delta - d1;
-}
-
 static void grabber_move(struct video_out_desc *, int dx, int dy);
-/*
- * Move the source of the captured video.
- *
- * x_final_drag and y_final_drag are the coordinates where the drag ends,
- * start coordinares are in the gui_info structure.
- */
-static void move_capture_source(struct video_desc *env, int x_final_drag, int y_final_drag)
-{
-	int dx, dy;
-
-	/* move the origin */
-#define POLARITY -1		/* +1 or -1 depending on the desired direction */
-	dx = POLARITY*move_accel(x_final_drag - env->gui->x_drag) * 3;
-	dy = POLARITY*move_accel(y_final_drag - env->gui->y_drag) * 3;
+
+int compute_drag(int *start, int end, int magnifier);
+int compute_drag(int *start, int end, int magnifier)
+{
+	int delta = end - *start;
+#define POLARITY -1
+	/* add a small quadratic term */
+	delta += delta * delta * (delta > 0 ? 1 : -1 )/100;
+	delta *= POLARITY * magnifier;
 #undef POLARITY
-	env->gui->x_drag = x_final_drag;	/* update origin */
-	env->gui->y_drag = y_final_drag;
-
-	grabber_move(&env->out, dx, dy);
-	return;
+	*start = end;
+	return delta;
 }
 
 /*
@@ -562,12 +544,14 @@
 static void eventhandler(struct video_desc *env, const char *caption)
 {
 	struct gui_info *gui = env->gui;
+	struct drag_info *drag;
 #define N_EVENTS	32
 	int i, n;
 	SDL_Event ev[N_EVENTS];
 
 	if (!gui)
 		return;
+	drag = &gui->drag;
 	if (caption)
 		SDL_WM_SetCaption(caption, NULL);
 
@@ -580,23 +564,27 @@
 #endif
 			switch (ev[i].type) {
 			case SDL_KEYDOWN:
-				handle_keyboard_input(env, ev[i].key.keysym.sym);
+				handle_keyboard_input(env, &ev[i].key.keysym);
 				break;
 			case SDL_MOUSEMOTION:
-				if (gui->drag_window == DRAG_LOCAL)
-					move_capture_source(env, ev[i].motion.x, ev[i].motion.y);
+			case SDL_MOUSEBUTTONUP:
+				if (drag->drag_window == DRAG_LOCAL) {
+					/* move the capture source */
+					int dx = compute_drag(&drag->x_start, ev[i].motion.x, 3);
+					int dy = compute_drag(&drag->y_start, ev[i].motion.y, 3);
+					grabber_move(&env->out, dx, dy);
+				} else if (drag->drag_window == DRAG_MESSAGE) {
+					/* scroll up/down the window */

[... 598 lines stripped ...]



More information about the asterisk-commits mailing list