[asterisk-commits] oej: branch oej/calleridutf8 r89567 - in /team/oej/calleridutf8: ./ channels/...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Nov 25 15:13:17 CST 2007


Author: oej
Date: Sun Nov 25 15:13:17 2007
New Revision: 89567

URL: http://svn.digium.com/view/asterisk?view=rev&rev=89567
Log:
Update to trunk, resolve conflicts

Modified:
    team/oej/calleridutf8/   (props changed)
    team/oej/calleridutf8/CHANGES
    team/oej/calleridutf8/channels/chan_sip.c
    team/oej/calleridutf8/configs/res_odbc.conf.sample
    team/oej/calleridutf8/configs/sip.conf.sample
    team/oej/calleridutf8/include/asterisk/channel.h
    team/oej/calleridutf8/include/asterisk/res_odbc.h
    team/oej/calleridutf8/res/res_config_odbc.c
    team/oej/calleridutf8/res/res_odbc.c

Propchange: team/oej/calleridutf8/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/oej/calleridutf8/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sun Nov 25 15:13:17 2007
@@ -1,1 +1,1 @@
-/trunk:1-89551
+/trunk:1-89565

Modified: team/oej/calleridutf8/CHANGES
URL: http://svn.digium.com/view/asterisk/team/oej/calleridutf8/CHANGES?view=diff&rev=89567&r1=89566&r2=89567
==============================================================================
--- team/oej/calleridutf8/CHANGES (original)
+++ team/oej/calleridutf8/CHANGES Sun Nov 25 15:13:17 2007
@@ -89,8 +89,14 @@
   * SIP now adds a header to the CANCEL if the call was answered by another phone
      in the same dial command, or if the new c option in dial() is used.
   * The new default is that 100 Trying is not sent on REGISTER attempts as the RFC specifically
-     states it is not needed. For phones, however, that do require it the registertrying option
+     states it is not needed. For phones, however, that do require it the "registertrying" option
      has been added so it can be enabled. 
+  * The "call-limit" option is marked as deprecated. It still works in this version of
+    Asterisk, but will be removed in the following version. Please use the groupcount functions
+    in the dialplan to enforce call limits.
+  * A new option called "callcounter" (global/peer/user level) enables call counters needed
+    for better status reports needed for queues and SIP subscriptions. (Call-Limit was previously
+    used to enable this functionality).
 
 IAX2 changes
 ------------

Modified: team/oej/calleridutf8/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/calleridutf8/channels/chan_sip.c?view=diff&rev=89567&r1=89566&r2=89567
==============================================================================
--- team/oej/calleridutf8/channels/chan_sip.c (original)
+++ team/oej/calleridutf8/channels/chan_sip.c Sun Nov 25 15:13:17 2007
@@ -239,14 +239,6 @@
 	INV_CANCELLED = 7,	/*!< Transaction cancelled by client or server in non-terminated state */
 };
 
-/* Do _NOT_ make any changes to this enum, or the array following it;
-   if you think you are doing the right thing, you are probably
-   not doing the right thing. If you think there are changes
-   needed, get someone else to review them first _before_
-   submitting a patch. If these two lists do not match properly
-   bad things will happen.
-*/
-
 enum xmittype {
 	XMIT_CRITICAL = 2,              /*!< Transmit critical SIP message reliably, with re-transmits.
                                               If it fails, it's critical and will cause a teardown of the session */
@@ -269,6 +261,11 @@
 	MWI_NOTIFICATION
 };
 
+/*! \brief Subscription types that we support. We support
+   - dialoginfo updates (really device status, not dialog info as was the original intent of the standard)
+   - SIMPLE presence used for device status
+   - Voicemail notification subscriptions
+*/
 static const struct cfsubscription_types {
 	enum subscriptiontype type;
 	const char * const event;
@@ -284,26 +281,6 @@
 	{ MWI_NOTIFICATION,	"message-summary", "application/simple-message-summary", "mwi" } /* RFC 3842: Mailbox notification */
 };
 
-/*! \brief SIP Request methods known by Asterisk */
-enum sipmethod {
-	SIP_UNKNOWN,		/* Unknown response */
-	SIP_RESPONSE,		/* Not request, response to outbound request */
-	SIP_REGISTER,
-	SIP_OPTIONS,
-	SIP_NOTIFY,
-	SIP_INVITE,
-	SIP_ACK,
-	SIP_PRACK,		/* Not supported at all */
-	SIP_BYE,
-	SIP_REFER,
-	SIP_SUBSCRIBE,
-	SIP_MESSAGE,
-	SIP_UPDATE,		/* We can send UPDATE; but not accept it */
-	SIP_INFO,
-	SIP_CANCEL,
-	SIP_PUBLISH,		/* Not supported at all */
-	SIP_PING,		/* Not supported at all, no standard but still implemented out there */
-};
 
 /*! \brief Authentication types - proxy or www authentication 
 	\note Endpoints, like Asterisk, should always use WWW authentication to
@@ -324,7 +301,7 @@
 	AUTH_CHALLENGE_SENT = 1,
 	AUTH_SECRET_FAILED = -1,
 	AUTH_USERNAME_MISMATCH = -2,
-	AUTH_NOT_FOUND = -3,	/* returned by register_verify */
+	AUTH_NOT_FOUND = -3,	/*!< returned by register_verify */
 	AUTH_FAKE_AUTH = -4,
 	AUTH_UNKNOWN_DOMAIN = -5,
 	AUTH_PEER_NOT_DYNAMIC = -6,
@@ -379,13 +356,47 @@
 	/* Room for a SRV record chain based on the name */
 };
 
+/*! \brief States whether a SIP message can create a dialog in Asterisk. */
 enum can_create_dialog {
 	CAN_NOT_CREATE_DIALOG,
 	CAN_CREATE_DIALOG,
 	CAN_CREATE_DIALOG_UNSUPPORTED_METHOD,
 };
 
-/*! XXX Note that sip_methods[i].id == i must hold or the code breaks */
+/*! \brief SIP Request methods known by Asterisk 
+
+   \note Do _NOT_ make any changes to this enum, or the array following it;
+   if you think you are doing the right thing, you are probably
+   not doing the right thing. If you think there are changes
+   needed, get someone else to review them first _before_
+   submitting a patch. If these two lists do not match properly
+   bad things will happen.
+*/
+
+enum sipmethod {
+	SIP_UNKNOWN,		/*!< Unknown response */
+	SIP_RESPONSE,		/*!< Not request, response to outbound request */
+	SIP_REGISTER,		/*!< Registration to the mothership, tell us where you are located */
+	SIP_OPTIONS,		/*!< Check capabilities of a device, used for "ping" too */
+	SIP_NOTIFY,		/*!< Status update, Part of the event package standard, result of a SUBSCRIBE or a REFER */
+	SIP_INVITE,		/*!< Set up a session */
+	SIP_ACK,		/*!< End of a three-way handshake started with INVITE. */
+	SIP_PRACK,		/*!< Reliable pre-call signalling. Not supported in Asterisk. */
+	SIP_BYE,		/*!< End of a session */
+	SIP_REFER,		/*!< Refer to another URI (transfer) */
+	SIP_SUBSCRIBE,		/*!< Subscribe for updates (voicemail, session status, device status, presence) */
+	SIP_MESSAGE,		/*!< Text messaging */
+	SIP_UPDATE,		/*!< Update a dialog. We can send UPDATE; but not accept it */
+	SIP_INFO,		/*!< Information updates during a session */
+	SIP_CANCEL,		/*!< Cancel an INVITE */
+	SIP_PUBLISH,		/*!< Not supported in Asterisk */
+	SIP_PING,		/*!< Not supported at all, no standard but still implemented out there */
+};
+
+/*! \brief The core structure to setup dialogs. We parse incoming messages by using
+	structure and then route the messages according to the type.
+
+      \note Note that sip_methods[i].id == i must hold or the code breaks */
 static const struct  cfsip_methods { 
 	enum sipmethod id;
 	int need_rtp;		/*!< when this is the 'primary' use for a pvt structure, does it need RTP? */
@@ -424,6 +435,7 @@
 #define SUPPORTED		1
 #define NOT_SUPPORTED		0
 
+/* SIP options */
 #define SIP_OPT_REPLACES	(1 << 0)
 #define SIP_OPT_100REL		(1 << 1)
 #define SIP_OPT_TIMER		(1 << 2)
@@ -488,7 +500,10 @@
 };
 
 
-/*! \brief SIP Methods we support */
+/*! \brief SIP Methods we support 
+	\todo This string should be set dynamically. We only support REFER and SUBSCRIBE is we have
+	allowsubscribe and allowrefer on in sip.conf.
+*/
 #define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY"
 
 /*! \brief SIP Extensions we support */
@@ -503,8 +518,9 @@
  * we do not support this feature at the moment.
  */
 
-/* Default values, set and reset in reload_config before reading configuration */
-/* These are default values in the source. There are other recommended values in the
+/*! \brief Default values, set and reset in reload_config before reading configuration 
+
+   These are default values in the source. There are other recommended values in the
    sip.conf.sample for new installations. These may differ to keep backwards compatibility,
    yet encouraging new behaviour on new installations 
  */
@@ -515,6 +531,7 @@
 #define DEFAULT_CALLERID 	"asterisk"
 #define DEFAULT_NOTIFYMIME 	"application/simple-message-summary"
 #define DEFAULT_ALLOWGUEST	TRUE
+#define DEFAULT_CALLCOUNTER	FALSE
 #define DEFAULT_SRVLOOKUP	TRUE		/*!< Recommended setting is ON */
 #define DEFAULT_COMPACTHEADERS	FALSE
 #define DEFAULT_TOS_SIP         0               /*!< Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions. */
@@ -584,6 +601,9 @@
 static int global_reg_timeout;	
 static int global_regattempts_max;	/*!< Registration attempts before giving up */
 static int global_allowguest;		/*!< allow unauthenticated users/peers to connect? */
+static int global_callcounter;		/*!< Enable call counters for all devices. This is currently enabled by setting the peer
+						call-limit to 999. When we remove the call-limit from the code, we can make it
+						with just a boolean flag in the device structure */
 static int global_allowsubscribe;	/*!< Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE 
 					    the global setting is in globals_flags[1] */
 static unsigned int global_tos_sip;		/*!< IP type of service for SIP packets */
@@ -826,7 +846,8 @@
 #define SIP_PAGE2_RTAUTOCLEAR		(1 << 2)	/*!< GP: Should we clean memory from peers after expiry? */
 /* Space for addition of other realtime flags in the future */
 
-#define SIP_PAGE2_VIDEOSUPPORT		(1 << 15)	/*!< DP: Video supported if offered? */
+#define SIP_PAGE2_VIDEOSUPPORT		(1 << 14)	/*!< DP: Video supported if offered? */
+#define SIP_PAGE2_TEXTSUPPORT		(1 << 15)	/*!< GDP: Global text enable */
 #define SIP_PAGE2_ALLOWSUBSCRIBE	(1 << 16)	/*!< GP: Allow subscriptions from this peer? */
 #define SIP_PAGE2_ALLOWOVERLAP		(1 << 17)	/*!< DP: Allow overlap dialing ? */
 #define SIP_PAGE2_SUBSCRIBEMWIONLY	(1 << 18)	/*!< GP: Only issue MWI notification if subscribed to */
@@ -843,7 +864,6 @@
 
 #define SIP_PAGE2_RFC2833_COMPENSATE    (1 << 25)	/*!< DP: Compensate for buggy RFC2833 implementations */
 #define SIP_PAGE2_BUGGY_MWI		(1 << 26)	/*!< DP: Buggy CISCO MWI fix */
-#define SIP_PAGE2_TEXTSUPPORT		(1 << 28)	/*!< GDP: Global text enable */
 #define SIP_PAGE2_REGISTERTRYING        (1 << 29)       /*!< DP: Send 100 Trying on REGISTER attempts */
 
 #define SIP_PAGE2_FLAGS_TO_COPY \
@@ -11725,6 +11745,7 @@
 	ast_cli(a->fd, "  MatchAuthUsername:      %s\n", cli_yesno(global_match_auth_username));
 	ast_cli(a->fd, "  Allow unknown access:   %s\n", cli_yesno(global_allowguest));
 	ast_cli(a->fd, "  Allow subscriptions:    %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
+	ast_cli(a->fd, "  Enable call counters:   %s\n", cli_yesno(global_callcounter));
 	ast_cli(a->fd, "  Allow overlap dialing:  %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)));
 	ast_cli(a->fd, "  Promsic. redir:         %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR)));
 	ast_cli(a->fd, "  SIP domain support:     %s\n", cli_yesno(!AST_LIST_EMPTY(&domain_list)));
@@ -17483,6 +17504,8 @@
 	user->allowtransfer = global_allowtransfer;
 	user->maxcallbitrate = default_maxcallbitrate;
 	user->autoframing = global_autoframing;
+	if (global_callcounter)
+		user->call_limit=999;
 	user->prefs = default_prefs;
 	/* set default context */
 	strcpy(user->context, default_context);
@@ -17530,6 +17553,8 @@
 			ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest));
 		} else if (!strcasecmp(v->name, "accountcode")) {
 			ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
+		} else if (!strcasecmp(v->name, "callcounter")) {
+			user->call_limit = ast_true(v->value) ? 999 : 0;
 		} else if (!strcasecmp(v->name, "call-limit")) {
 			user->call_limit = atoi(v->value);
 			if (user->call_limit < 0)
@@ -17599,6 +17624,8 @@
 	peer->rtpkeepalive = global_rtpkeepalive;
 	peer->allowtransfer = global_allowtransfer;
 	peer->autoframing = global_autoframing;
+	if (global_callcounter)
+		peer->call_limit=999;
 	strcpy(peer->vmexten, default_vmexten);
 	peer->secret[0] = '\0';
 	peer->md5secret[0] = '\0';
@@ -17824,6 +17851,8 @@
 			ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
 		} else if (!strcasecmp(v->name, "callbackextension")) {
 			ast_copy_string(callback, v->value, sizeof(callback));
+		} else if (!strcasecmp(v->name, "callcounter")) {
+			peer->call_limit = ast_true(v->value) ? 999 : 0;
 		} else if (!strcasecmp(v->name, "call-limit")) {
 			peer->call_limit = atoi(v->value);
 			if (peer->call_limit < 0)
@@ -18071,6 +18100,7 @@
 	autocreatepeer = DEFAULT_AUTOCREATEPEER;
 	global_autoframing = 0;
 	global_allowguest = DEFAULT_ALLOWGUEST;
+	global_callcounter = DEFAULT_CALLCOUNTER;
 	global_match_auth_username = FALSE;		/*!< Match auth username if available instead of From: Default off. */
 	global_rtptimeout = 0;
 	global_rtpholdtimeout = 0;
@@ -18126,6 +18156,8 @@
 			ast_copy_string(default_context, v->value, sizeof(default_context));
 		} else if (!strcasecmp(v->name, "subscribecontext")) {
 			ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext));
+  		} else if (!strcasecmp(v->name, "callcounter")) {
+			global_callcounter = ast_true(v->value) ? 1 : 0;
   		} else if (!strcasecmp(v->name, "allowguest")) {
 			global_allowguest = ast_true(v->value) ? 1 : 0;
 		} else if (!strcasecmp(v->name, "realm")) {

Modified: team/oej/calleridutf8/configs/res_odbc.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/calleridutf8/configs/res_odbc.conf.sample?view=diff&rev=89567&r1=89566&r2=89567
==============================================================================
--- team/oej/calleridutf8/configs/res_odbc.conf.sample (original)
+++ team/oej/calleridutf8/configs/res_odbc.conf.sample Sun Nov 25 15:13:17 2007
@@ -40,6 +40,9 @@
 password => thegrouch
 pre-connect => yes
 sanitysql => select count(*) from systables
+; Many databases have a default of '\' to escape special characters.  MS SQL
+; Server does not.
+backslash_is_escape => no
 
 
 

Modified: team/oej/calleridutf8/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/calleridutf8/configs/sip.conf.sample?view=diff&rev=89567&r1=89566&r2=89567
==============================================================================
--- team/oej/calleridutf8/configs/sip.conf.sample (original)
+++ team/oej/calleridutf8/configs/sip.conf.sample Sun Nov 25 15:13:17 2007
@@ -22,6 +22,15 @@
 ;   sip reload			Reload configuration file
 ;				Active SIP peers will not be reconfigured
 ;
+
+; ** Deprecated options **
+; The "call-limit" configuation option is deprecated. It still works in
+; this version of Asterisk, but will disappear in the next version.
+; You are encouraged to use the dialplan groupcount functionality
+; to enforce call limits instead of using this channel-specific method.
+;
+; You can still set limits per device in sip.conf or in a database by using 
+; "setvar" to set variables that can be used in the dialplan for various limits.
 
 [general]
 context=default			; Default context for incoming calls
@@ -206,14 +215,11 @@
 ; (See extensions.conf.sample for examples)
 ; chan_sip support two major formats for notifications: dialog-info and SIMPLE 
 ;
-; You will get more detailed reports (busy etc) if you have a call limit set
-; for a device. When the call limit is filled, we will indicate busy. Note that
-; you need at least 2 in order to be able to do attended transfers.
-;
-; If you set the busylevel in addition to the call limit, we will indicate busy
-; when we have a number of calls that matches busylevel, but still allow calls
-; up to the call-limit. This allows for transfers while still having blinking
-; lamps and queues understanding that a device is busy.
+; You will get more detailed reports (busy etc) if you have a call counter enabled
+; for a device. 
+;
+; If you set the busylevel, we will indicate busy when we have a number of calls that 
+; matches the busylevel treshold.
 ;
 ; For queues, you will need this level of detail in status reporting, regardless
 ; if you use SIP subscriptions. Queues and manager use the same internal interface
@@ -230,12 +236,14 @@
 ;notifyhold = yes		; Notify subscriptions on HOLD state (default: no)
 				; Turning on notifyringing and notifyhold will add a lot
 				; more database transactions if you are using realtime.
-;limitonpeer = yes		; Apply call limits on peers only. This will improve 
+;limitonpeer = yes		; Apply call counting on peers only. This will improve 
 				; status notification when you are using type=friend
 				; Inbound calls, that really apply to the user part
 				; of a friend will now be added to and compared with
-				; the peer limit instead of applying two call limits,
+				; the peer counter instead of applying two call counters,
 				; one for the peer and one for the user.
+;callcounter = yes		; Enable call counters on devices. This can be set per
+				; device too.
 
 ;----------------------------------------- T.38 FAX PASSTHROUGH SUPPORT -----------------------
 ;
@@ -561,7 +569,8 @@
 ; setvar                      setvar
 ; callerid		      callerid
 ; amaflags		      amaflags
-; call-limit		      call-limit
+; call-limit		      call-limit	(deprecated)
+; callcounter                 callcounter
 ; allowoverlap		      allowoverlap
 ; allowsubscribe	      allowsubscribe
 ; allowtransfer	      	      allowtransfer
@@ -603,9 +612,7 @@
 ;fromdomain=provider.sip.domain	
 ;host=box.provider.com
 ;usereqphone=yes			; This provider requires ";user=phone" on URI
-;call-limit=5				; permit only 5 simultaneous outgoing calls to this peer
-					; Call-limits will not be enforced on real-time peers,
-					; since they are not stored in-memory
+;callcounter=yes			; Enable call counter
 ;busylevel=2				; Signal busy at 2 or more calls
 ;outboundproxy=proxy.provider.domain	; send outbound signaling to this proxy, not directly to the peer
 ;port=80				; The port number we want to connect to on the remote side
@@ -690,11 +697,10 @@
 ;canreinvite=yes		; allow RTP voice traffic to bypass Asterisk
 ;dtmfmode=info			; either RFC2833 or INFO for the BudgeTone
 ;call-limit=1			; permit only 1 outgoing call and 1 incoming call at a time
-				; from the phone to asterisk
+				; from the phone to asterisk (deprecated)
 				; 1 for the explicit peer, 1 for the explicit user,
 				; remember that a friend equals 1 peer and 1 user in
 				; memory
-				; This will affect your subscriptions as well.
 				; There is no combined call counter for a "friend"
 				; so there's currently no way in sip.conf to limit
 				; to one inbound or outbound call per phone. Use

Modified: team/oej/calleridutf8/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/oej/calleridutf8/include/asterisk/channel.h?view=diff&rev=89567&r1=89566&r2=89567
==============================================================================
--- team/oej/calleridutf8/include/asterisk/channel.h (original)
+++ team/oej/calleridutf8/include/asterisk/channel.h Sun Nov 25 15:13:17 2007
@@ -720,8 +720,8 @@
  * \param data data to pass to the channel requester
  * \param timeout maximum amount of time to wait for an answer
  * \param reason why unsuccessful (if unsuccessful)
- * \param cidnum Caller-ID Number
- * \param cidname Caller-ID Name (ascii)
+ * \param cid_num Caller-ID Number
+ * \param cid_name Caller-ID Name (ascii)
  * \param cid_utf8name Caller-ID Name (utf8)
  * \param cid_domain Caller-ID domain
  * \return Returns an ast_channel on success or no answer, NULL on failure.  Check the value of chan->_state
@@ -730,6 +730,20 @@
 struct ast_channel *ast_request_and_dial(const char *type, int format, void *data,
 	int timeout, int *reason, const char *cid_num, const char *cid_name, const char *cid_utf8name, const char *cid_domain);
 
+/*!
+ * \brief Request a channel of a given type, with data as optional information used 
+ * by the low level module and attempt to place a call on it
+ * \param type type of channel to request
+ * \param format requested channel format
+ * \param data data to pass to the channel requester
+ * \param timeout maximum amount of time to wait for an answer
+ * \param reason why unsuccessful (if unsuccessful)
+ * \param cid_num Caller-ID Number
+ * \param cid_name Caller-ID Name (ascii)
+ * \param oh Outgoing helper
+ * \return Returns an ast_channel on success or no answer, NULL on failure.  Check the value of chan->_state
+ * to know if the call was answered or not.
+ */
 struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data,
 	int timeout, int *reason, const char *cidnum, const char *cid_name, const char *cid_utf8name, const char *cid_domain, struct outgoing_helper *oh);
 
@@ -1211,7 +1225,7 @@
 void ast_deactivate_generator(struct ast_channel *chan);
 
 /*! Set caller ID data */
-void ast_set_callerid(struct ast_channel *chan, const char *cidnum, const char *cidname, const char *cidutf8name, const char *ciddomain, const char *ani);
+void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_utf8name, const char *cid_domain, const char *cid_ani);
 
 /*! Set the file descriptor on the channel */
 void ast_channel_set_fd(struct ast_channel *chan, int which, int fd);

Modified: team/oej/calleridutf8/include/asterisk/res_odbc.h
URL: http://svn.digium.com/view/asterisk/team/oej/calleridutf8/include/asterisk/res_odbc.h?view=diff&rev=89567&r1=89566&r2=89567
==============================================================================
--- team/oej/calleridutf8/include/asterisk/res_odbc.h (original)
+++ team/oej/calleridutf8/include/asterisk/res_odbc.h Sun Nov 25 15:13:17 2007
@@ -93,6 +93,12 @@
  */
 int ast_odbc_sanity_check(struct odbc_obj *obj);
 
+/*! \brief Checks if the database natively supports backslash as an escape character.
+ * \param obj The ODBC object
+ * \return Returns 1 if an ESCAPE clause is needed to support '\', 0 otherwise
+ */
+int ast_odbc_backslash_is_escape(struct odbc_obj *obj);
+
 /*! \brief Executes an non prepared statement and returns the resulting
  * statement handle.
  * \param obj The ODBC object

Modified: team/oej/calleridutf8/res/res_config_odbc.c
URL: http://svn.digium.com/view/asterisk/team/oej/calleridutf8/res/res_config_odbc.c?view=diff&rev=89567&r1=89566&r2=89567
==============================================================================
--- team/oej/calleridutf8/res/res_config_odbc.c (original)
+++ team/oej/calleridutf8/res/res_config_odbc.c Sun Nov 25 15:13:17 2007
@@ -142,11 +142,12 @@
 		return NULL;
 	newval = va_arg(aq, const char *);
 	op = !strchr(newparam, ' ') ? " =" : "";
-	snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?", table, newparam, op);
+	snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?%s", table, newparam, op,
+		strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
 	while((newparam = va_arg(aq, const char *))) {
 		op = !strchr(newparam, ' ') ? " =" : "";
 		snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", newparam, op,
-			strcasestr(newparam, "LIKE") ? " ESCAPE '\\'" : "");
+			strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
 		newval = va_arg(aq, const char *);
 	}
 	va_end(aq);
@@ -290,11 +291,11 @@
 	newval = va_arg(aq, const char *);
 	op = !strchr(newparam, ' ') ? " =" : "";
 	snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?%s", table, newparam, op,
-		strcasestr(newparam, "LIKE") ? " ESCAPE '\\'" : "");
+		strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
 	while((newparam = va_arg(aq, const char *))) {
 		op = !strchr(newparam, ' ') ? " =" : "";
 		snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?%s", newparam, op,
-			strcasestr(newparam, "LIKE") ? " ESCAPE '\\'" : "");
+			strcasestr(newparam, "LIKE") && !ast_odbc_backslash_is_escape(obj) ? " ESCAPE '\\'" : "");
 		newval = va_arg(aq, const char *);
 	}
 	if (initfield)

Modified: team/oej/calleridutf8/res/res_odbc.c
URL: http://svn.digium.com/view/asterisk/team/oej/calleridutf8/res/res_odbc.c?view=diff&rev=89567&r1=89566&r2=89567
==============================================================================
--- team/oej/calleridutf8/res/res_odbc.c (original)
+++ team/oej/calleridutf8/res/res_odbc.c Sun Nov 25 15:13:17 2007
@@ -60,6 +60,7 @@
 	unsigned int limit:10;          /* Gives a limit of 1023 maximum */
 	unsigned int count:10;          /* Running count of pooled connections */
 	unsigned int delme:1;			/* Purge the class */
+	unsigned int backslash_is_escape:1;	/* On this database, the backslash is a native escape sequence */
 	AST_LIST_HEAD(, odbc_obj) odbc_obj;
 };
 
@@ -227,7 +228,7 @@
 	struct ast_variable *v;
 	char *cat;
 	const char *dsn, *username, *password, *sanitysql;
-	int enabled, pooling, limit;
+	int enabled, pooling, limit, bse;
 	int connect = 0, res = 0;
 	struct ast_flags config_flags = { 0 };
 
@@ -251,6 +252,7 @@
 			connect = 0;
 			pooling = 0;
 			limit = 0;
+			bse = 1;
 			for (v = ast_variable_browse(config, cat); v; v = v->next) {
 				if (!strcasecmp(v->name, "pooling")) {
 					if (ast_true(v->value))
@@ -277,6 +279,8 @@
 					password = v->value;
 				} else if (!strcasecmp(v->name, "sanitysql")) {
 					sanitysql = v->value;
+				} else if (!strcasecmp(v->name, "backslash_is_escape")) {
+					bse = ast_true(v->value);
 				}
 			}
 
@@ -317,6 +321,8 @@
 						new->limit = 5;
 					}
 				}
+
+				new->backslash_is_escape = bse ? 1 : 0;
 
 				odbc_register_class(new, connect);
 				ast_log(LOG_NOTICE, "Registered ODBC class '%s' dsn->[%s]\n", cat, dsn);
@@ -422,6 +428,11 @@
 	obj->used = 0;
 }
 
+int ast_odbc_backslash_is_escape(struct odbc_obj *obj)
+{
+	return obj->parent->backslash_is_escape;
+}
+
 struct odbc_obj *ast_odbc_request_obj(const char *name, int check)
 {
 	struct odbc_obj *obj = NULL;
@@ -577,7 +588,7 @@
 	struct ast_variable *v;
 	char *cat;
 	const char *dsn, *username, *password, *sanitysql;
-	int enabled, pooling, limit;
+	int enabled, pooling, limit, bse;
 	int connect = 0, res = 0;
 	struct ast_flags config_flags = { CONFIG_FLAG_FILEUNCHANGED };
 
@@ -605,6 +616,7 @@
 				connect = 0;
 				pooling = 0;
 				limit = 0;
+				bse = 1;
 				for (v = ast_variable_browse(config, cat); v; v = v->next) {
 					if (!strcasecmp(v->name, "pooling")) {
 						pooling = 1;
@@ -630,6 +642,8 @@
 						password = v->value;
 					} else if (!strcasecmp(v->name, "sanitysql")) {
 						sanitysql = v->value;
+					} else if (!strcasecmp(v->name, "backslash_is_escape")) {
+						bse = ast_true(v->value);
 					}
 				}
 
@@ -686,6 +700,8 @@
 						}
 					}
 
+					new->backslash_is_escape = bse;
+
 					if (class) {
 						ast_log(LOG_NOTICE, "Refreshing ODBC class '%s' dsn->[%s]\n", cat, dsn);
 					} else {




More information about the asterisk-commits mailing list