[asterisk-commits] rizzo: branch rizzo/astobj2 r48542 - /team/rizzo/astobj2/channels/chan_sip.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sun Dec 17 05:19:51 MST 2006


Author: rizzo
Date: Sun Dec 17 06:19:51 2006
New Revision: 48542

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48542
Log:
+ define (locally to the function) a macro CO_SF to wrap some
  common operations performed in handle_common_options()

+ introduce a generic structure _map_x_s to map between
  strings and integers. This is a functionality widely used
  for e.g. translating configuration options.

+ use the above to map dtmf mode strings.

On passing, note that the SIPDtmfMode() dialplan function
does not accept "auto" as an option, despite this is supported
elsewhere. Put an XXX mark so we can review this later.


Modified:
    team/rizzo/astobj2/channels/chan_sip.c

Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=48542&r1=48541&r2=48542
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Sun Dec 17 06:19:51 2006
@@ -10168,20 +10168,42 @@
 	ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
 }
 
+/*!
+ * generic struct to map between strings and integers.
+ * Must be terminated by s = NULL;
+ */
+struct _map_x_s {
+	int x;
+	const char *s;
+};
+
+/*! \brief mapping between dtmf flags and strings */
+static struct _map_x_s dtmfstr[] = {
+	{ SIP_DTMF_RFC2833,	"rfc2833" },
+	{ SIP_DTMF_INFO,	"info" },
+	{ SIP_DTMF_INBAND,	"inband" },
+	{ SIP_DTMF_AUTO,	"auto" },
+	{ 0,			NULL }, /* terminator */
+};
+
 /*! \brief Convert DTMF mode to printable string */
 static const char *dtmfmode2str(int mode)
 {
-	switch (mode) {
-	case SIP_DTMF_RFC2833:
-		return "rfc2833";
-	case SIP_DTMF_INFO:
-		return "info";
-	case SIP_DTMF_INBAND:
-		return "inband";
-	case SIP_DTMF_AUTO:
-		return "auto";
-	}
+	struct _map_x_s *cur;
+	for (cur = dtmfstr; cur->s; cur++)
+		if (mode == cur->x)
+			return cur->s;
 	return "<error>";
+}
+
+/*! \brief maps a string to dtmfmode, returns -1 on error */
+static int str2dtmfmode(const char *str)
+{
+	struct _map_x_s *cur;
+	for (cur = dtmfstr; cur->s; cur++)
+		if (!strcasecmp(str, cur->s))
+			return cur->x;
+	return -1;
 }
 
 /*! \brief Convert Insecure setting to printable string */
@@ -16053,36 +16075,35 @@
   \param mask array of two struct ast_flags
   \param v linked list of config variables to process
   \returns non-zero if any config options were handled, zero otherwise
+ *
+ * Most of these options set a flag in mask[x] and conditionally
+ * on the value, a corresponding one in flags[x].
+ * We define a macro __CO_SF(x, flag) to help
 */
 static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 {
+#define CO_SF(x, flag)	 do {						\
+		ast_set_flag(&mask[x], flag);				\
+		ast_set2_flag(&flags[x], ast_true(v->value), flag);	\
+	} while (0)
+
 	if (!strcasecmp(v->name, "trustrpid")) {
-		ast_set_flag(&mask[0], SIP_TRUSTRPID);
-		ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
+		CO_SF(0, SIP_TRUSTRPID);
 	} else if (!strcasecmp(v->name, "sendrpid")) {
-		ast_set_flag(&mask[0], SIP_SENDRPID);
-		ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
+		CO_SF(0, SIP_SENDRPID);
 	} else if (!strcasecmp(v->name, "g726nonstandard")) {
-		ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
-		ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
+		CO_SF(0, SIP_G726_NONSTANDARD);
 	} else if (!strcasecmp(v->name, "useclientcode")) {
-		ast_set_flag(&mask[0], SIP_USECLIENTCODE);
-		ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
+		CO_SF(0, SIP_USECLIENTCODE);
 	} else if (!strcasecmp(v->name, "dtmfmode")) {
+		int i = str2dtmfmode(v->value);
 		ast_set_flag(&mask[0], SIP_DTMF);
 		ast_clear_flag(&flags[0], SIP_DTMF);
-		if (!strcasecmp(v->value, "inband"))
-			ast_set_flag(&flags[0], SIP_DTMF_INBAND);
-		else if (!strcasecmp(v->value, "rfc2833"))
-			ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
-		else if (!strcasecmp(v->value, "info"))
-			ast_set_flag(&flags[0], SIP_DTMF_INFO);
-		else if (!strcasecmp(v->value, "auto"))
-			ast_set_flag(&flags[0], SIP_DTMF_AUTO);
-		else {
+		if (i == -1) {	/* error */
 			ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
-			ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
-		}
+			i = SIP_DTMF_RFC2833;
+		}
+		ast_set_flag(&flags[0], i);
 	} else if (!strcasecmp(v->name, "nat")) {
 		ast_set_flag(&mask[0], SIP_NAT);
 		ast_clear_flag(&flags[0], SIP_NAT);
@@ -16141,35 +16162,28 @@
 		else if (strcasecmp(v->value, "never"))
 			ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
 	} else if (!strcasecmp(v->name, "promiscredir")) {
-		ast_set_flag(&mask[0], SIP_PROMISCREDIR);
-		ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
+		CO_SF(0, SIP_PROMISCREDIR);
 	} else if (!strcasecmp(v->name, "videosupport")) {
-		ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
-		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
+		CO_SF(1, SIP_PAGE2_VIDEOSUPPORT);
 	} else if (!strcasecmp(v->name, "allowoverlap")) {
-		ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
-		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
+		CO_SF(1, SIP_PAGE2_ALLOWOVERLAP);
 	} else if (!strcasecmp(v->name, "allowsubscribe")) {
-		ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
-		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
+		CO_SF(1, SIP_PAGE2_ALLOWSUBSCRIBE);
 	} else if (!strcasecmp(v->name, "t38pt_udptl")) {
-		ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL);
-		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL);
+		CO_SF(1, SIP_PAGE2_T38SUPPORT_UDPTL);
 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
 	} else if (!strcasecmp(v->name, "t38pt_rtp")) {
-		ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP);
-		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP);
+		CO_SF(1, SIP_PAGE2_T38SUPPORT_RTP);
 	} else if (!strcasecmp(v->name, "t38pt_tcp")) {
-		ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP);
-		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP);
+		CO_SF(1, SIP_PAGE2_T38SUPPORT_TCP);
 #endif
 	} else if (!strcasecmp(v->name, "rfc2833compensate")) {
-		ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
-		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
+		CO_SF(1, SIP_PAGE2_RFC2833_COMPENSATE);
 	} else
 		return 0;	/* not found */
 
 	return 1;
+#undef __CO_SF
 }
 
 /*! \brief Add SIP domain to list of domains we are responsible for */
@@ -17420,6 +17434,7 @@
 {
 	struct sip_pvt *p;
 	char *mode = data;
+	int i;
 
 	if (!data) {
 		ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
@@ -17437,17 +17452,14 @@
 		return 0;
 	}
 	sip_pvt_lock(p);
-	if (!strcasecmp(mode,"info")) {
+	i = str2dtmfmode(mode);
+	if (i == -1 || i == SIP_DTMF_AUTO)	/* XXX should we filter this out ? */
+		ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode);
+	else {
 		ast_clear_flag(&p->flags[0], SIP_DTMF);
-		ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
-	} else if (!strcasecmp(mode,"rfc2833")) {
-		ast_clear_flag(&p->flags[0], SIP_DTMF);
-		ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
-	} else if (!strcasecmp(mode,"inband")) { 
-		ast_clear_flag(&p->flags[0], SIP_DTMF);
-		ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
-	} else
-		ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode);
+		ast_set_flag(&p->flags[0], i);
+	}
+	/* XXX shouldn't it also look for a change in the mode ? */
 	if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
 		if (!p->vad) {
 			p->vad = ast_dsp_new();



More information about the asterisk-commits mailing list