[asterisk-commits] rizzo: trunk r48598 - /trunk/apps/app_sms.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Dec 19 16:56:08 MST 2006


Author: rizzo
Date: Tue Dec 19 17:56:08 2006
New Revision: 48598

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48598
Log:
formatting and code cleanup.
Still a lot of copy&pasted code here...


Modified:
    trunk/apps/app_sms.c

Modified: trunk/apps/app_sms.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_sms.c?view=diff&rev=48598&r1=48597&r2=48598
==============================================================================
--- trunk/apps/app_sms.c (original)
+++ trunk/apps/app_sms.c Tue Dec 19 17:56:08 2006
@@ -46,8 +46,7 @@
 #include "asterisk/alaw.h"
 #include "asterisk/callerid.h"
 
-/* output using Alaw rather than linear */
-/* #define OUTALAW */
+/* #define OUTALAW */ /* enable this to output Alaw rather than linear */
 
 /* ToDo */
 /* Add full VP support */
@@ -97,6 +96,13 @@
 
 #ifdef OUTALAW
 static unsigned char wavea[80];
+typedef unsigned char output_t;
+static const output_t *wave_out = wavea;	/* outgoing samples */
+#define __OUT_FMT AST_FORMAT_ALAW;
+#else
+typedef signed short output_t;
+static const output_t *wave_out = wave;	/* outgoing samples */
+#define __OUT_FMT AST_FORMAT_SLINEAR
 #endif
 
 
@@ -158,17 +164,17 @@
 	unsigned char obytep;        /*!< byte in data */
 	unsigned char obyten;        /*!< bytes in data */
 	unsigned char omsg[256];     /*!< data buffer (out) */
-	unsigned char imsg[200];     /*!< data buffer (in) */
+	unsigned char imsg[250];     /*!< data buffer (in) */
 	signed long long ims0,
 		imc0,
 		ims1,
 		imc1;                      /*!< magnitude averages sin/cos 0/1 */
 	unsigned int idle;
 	unsigned short imag;         /*!< signal level */
-	unsigned char ips0,
-		ips1,
-		ipc0,
-		ipc1;                      /*!< phase sin/cos 0/1 */
+	unsigned char ips0;	     /*!< phase sin for bit 0, start at  0 inc by 21 mod 80 */
+	unsigned char ips1;	     /*!< phase cos for bit 0, start at 20 inc by 21 mod 80 */
+	unsigned char ipc0;	     /*!< phase sin for bit 1, start at  0 inc by 13 mod 80 */
+	unsigned char ipc1;	     /*!< phase cos for bit 1, start at 20 inc by 13 mod 80 */
 	unsigned char ibitl;         /*!< last bit */
 	unsigned char ibitc;         /*!< bit run length count */
 	unsigned char iphasep;       /*!< bit phase (0-79) for 1200 bps */
@@ -680,22 +686,19 @@
 {
 	char line[1000];
 	FILE *s;
-	char dcsset = 0;				 /* if DSC set */
+	char dcsset = 0;		/* if DSC set */
 	ast_log (LOG_EVENT, "Sending %s\n", fn);
 	h->rx = h->udl = *h->oa = *h->da = h->pid = h->srr = h->udhi = h->rp = h->vp = h->udhl = 0;
 	h->mr = -1;
-	h->dcs = 0xF1;					/* normal messages class 1 */
+	h->dcs = 0xF1;			/* normal messages class 1 */
 	h->scts = time (0);
 	s = fopen (fn, "r");
-	if (s)
-	{
-		if (unlink (fn))
-		{								 /* concurrent access, we lost */
+	if (s) {
+		if (unlink (fn)) {	/* concurrent access, we lost */
 			fclose (s);
 			return;
 		}
-		while (fgets (line, sizeof (line), s))
-		{								 /* process line in file */
+		while (fgets (line, sizeof (line), s)) {	/* process line in file */
 			char *p;
 			void *pp = &p;
 			for (p = line; *p && *p != '\n' && *p != '\r'; p++);
@@ -703,26 +706,22 @@
 			p = line;
 			if (!*p || *p == ';')
 				continue;			  /* blank line or comment, ignore */
-			while (isalnum (*p))
-			{
+			while (isalnum (*p)) {
 				*p = tolower (*p);
 				p++;
 			}
 			while (isspace (*p))
 				*p++ = 0;
-			if (*p == '=')
-			{
+			if (*p == '=') {
 				*p++ = 0;
-				if (!strcmp (line, "ud"))
-				{						 /* parse message (UTF-8) */
+				if (!strcmp (line, "ud")) {						 /* parse message (UTF-8) */
 					unsigned char o = 0;
 					while (*p && o < SMSLEN)
 						h->ud[o++] = utf8decode(pp);
 					h->udl = o;
 					if (*p)
 						ast_log (LOG_WARNING, "UD too long in %s\n", fn);
-				} else
-				{
+				} else {
 					while (isspace (*p))
 						p++;
 					if (!strcmp (line, "oa") && strlen (p) < sizeof (h->oa))
@@ -731,8 +730,7 @@
 						numcpy (h->da, p);
 					else if (!strcmp (line, "pid"))
 						h->pid = atoi (p);
-					else if (!strcmp (line, "dcs"))
-					{
+					else if (!strcmp (line, "dcs")) {
 						h->dcs = atoi (p);
 						dcsset = 1;
 					} else if (!strcmp (line, "mr"))
@@ -743,16 +741,14 @@
 						h->vp = atoi (p);
 					else if (!strcmp (line, "rp"))
 						h->rp = (atoi (p) ? 1 : 0);
-					else if (!strcmp (line, "scts"))
-					{					 /* get date/time */
+					else if (!strcmp (line, "scts")) {	/* get date/time */
 						int Y,
 						  m,
 						  d,
 						  H,
 						  M,
 						  S;
-						if (sscanf (p, "%d-%d-%dT%d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6)
-						{
+						if (sscanf (p, "%d-%d-%dT%d:%d:%d", &Y, &m, &d, &H, &M, &S) == 6) {
 							struct tm t;
 							t.tm_year = Y - 1900;
 							t.tm_mon = m - 1;
@@ -768,19 +764,14 @@
 					} else
 						ast_log (LOG_WARNING, "Cannot parse in %s: %s=%si\n", fn, line, p);
 				}
-			} else if (*p == '#')
-			{							 /* raw hex format */
+			} else if (*p == '#') {		/* raw hex format */
 				*p++ = 0;
-				if (*p == '#')
-				{
+				if (*p == '#') {
 					p++;
-					if (!strcmp (line, "ud"))
-					{					 /* user data */
+					if (!strcmp (line, "ud")) {	/* user data */
 						int o = 0;
-						while (*p && o < SMSLEN)
-						{
-							if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3]))
-							{
+						while (*p && o < SMSLEN) {
+							if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3])) {
 								h->ud[o++] =
 									(((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 12) +
 									(((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
@@ -794,13 +785,10 @@
 							ast_log (LOG_WARNING, "UD too long / invalid UCS-2 hex in %s\n", fn);
 					} else
 						ast_log (LOG_WARNING, "Only ud can use ## format, %s\n", fn);
-				} else if (!strcmp (line, "ud"))
-				{						 /* user data */
+				} else if (!strcmp (line, "ud")) {	/* user data */
 					int o = 0;
-					while (*p && o < SMSLEN)
-					{
-						if (isxdigit (*p) && isxdigit (p[1]))
-						{
+					while (*p && o < SMSLEN) {
+						if (isxdigit (*p) && isxdigit (p[1])) {
 							h->ud[o++] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
 							p += 2;
 						} else
@@ -809,14 +797,11 @@
 					h->udl = o;
 					if (*p)
 						ast_log (LOG_WARNING, "UD too long / invalid UCS-1 hex in %s\n", fn);
-				} else if (!strcmp (line, "udh"))
-				{						 /* user data header */
+				} else if (!strcmp (line, "udh")) {	/* user data header */
 					unsigned char o = 0;
 					h->udhi = 1;
-					while (*p && o < SMSLEN)
-					{
-						if (isxdigit (*p) && isxdigit (p[1]))
-						{
+					while (*p && o < SMSLEN) {
+						if (isxdigit (*p) && isxdigit (p[1])) {
 							h->udh[o] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
 							o++;
 							p += 2;
@@ -832,19 +817,15 @@
 				ast_log (LOG_WARNING, "Cannot parse in %s: %s\n", fn, line);
 		}
 		fclose (s);
-		if (!dcsset && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
-		{
-			if (packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
-			{
+		if (!dcsset && packsms7 (0, h->udhl, h->udh, h->udl, h->ud) < 0) {
+			if (packsms8 (0, h->udhl, h->udh, h->udl, h->ud) < 0) {
 				if (packsms16 (0, h->udhl, h->udh, h->udl, h->ud) < 0)
 					ast_log (LOG_WARNING, "Invalid UTF-8 message even for UCS-2 (%s)\n", fn);
-				else
-				{
+				else {
 					h->dcs = 0x08;	/* default to 16 bit */
 					ast_log (LOG_WARNING, "Sending in 16 bit format (%s)\n", fn);
 				}
-			} else
-			{
+			} else {
 				h->dcs = 0xF5;		/* default to 8 bit */
 				ast_log (LOG_WARNING, "Sending in 8 bit format (%s)\n", fn);
 			}
@@ -1032,11 +1013,13 @@
 	char fn[100 + NAME_MAX] = "";
 	DIR *d;
 	char more = 0;
+
+	*h->da = *h->oa = '\0';			/* clear destinations */
 	ast_copy_string (fn, spool_dir, sizeof (fn));
-	mkdir (fn, 0777);				/* ensure it exists */
-	h->rx = 0;						 /* outgoing message */
+	mkdir(fn, 0777);			/* ensure it exists */
+	h->rx = 0;			 	/* outgoing message */
 	snprintf (fn + strlen (fn), sizeof (fn) - strlen (fn), "/%s", h->smsc ? "mttx" : "motx");
-	mkdir (fn, 0777);				/* ensure it exists */
+	mkdir (fn, 0777);			/* ensure it exists */
 	d = opendir (fn);
 	if (d) {
 		struct dirent *f = readdirqueue (d, h->queue);
@@ -1184,12 +1167,7 @@
 {
 	struct ast_frame f = { 0 };
 #define MAXSAMPLES (800)
-#ifdef OUTALAW
-	unsigned char *buf;
-#else
-	short *buf;
-#endif
-#define SAMPLE2LEN sizeof(*buf)
+	output_t *buf;
 	sms_t *h = data;
 	int i;
 
@@ -1198,16 +1176,12 @@
 			 MAXSAMPLES, samples);
 		samples = MAXSAMPLES;
 	}
-	len = samples * SAMPLE2LEN + AST_FRIENDLY_OFFSET;
+	len = samples * sizeof(*buf) + AST_FRIENDLY_OFFSET;
 	buf = alloca(len);
 
 	f.frametype = AST_FRAME_VOICE;
-#ifdef OUTALAW
-	f.subclass = AST_FORMAT_ALAW;
-#else
-	f.subclass = AST_FORMAT_SLINEAR;
-#endif
-	f.datalen = samples * SAMPLE2LEN;
+	f.subclass = __OUT_FMT;
+	f.datalen = samples * sizeof(*buf);
 	f.offset = AST_FRIENDLY_OFFSET;
 	f.mallocd = 0;
 	f.data = buf;
@@ -1215,27 +1189,20 @@
 	f.src = "app_sms";
 	/* create a buffer containing the digital sms pattern */
 	for (i = 0; i < samples; i++) {
-#ifdef OUTALAW
-		buf[i] = wavea[0];
-#else
-		buf[i] = wave[0];
-#endif
+		buf[i] = wave_out[0];	/* default is silence */
+
 		if (h->opause)
 			h->opause--;
-		else if (h->obyten || h->osync) {								 /* sending data */
-#ifdef OUTALAW
-			buf[i] = wavea[h->ophase];
-#else
-			buf[i] = wave[h->ophase];
-#endif
-			if ((h->ophase += ((h->obyte & 1) ? 13 : 21)) >= 80)
+		else if (h->obyten || h->osync) {		/* sending data */
+			buf[i] = wave_out[h->ophase];
+			h->ophase += (h->obyte & 1) ? 13 : 21;	/* compute next phase */
+			if (h->ophase >= 80)
 				h->ophase -= 80;
-			if ((h->ophasep += 12) >= 80) {							 /* next bit */
+			if ((h->ophasep += 12) >= 80) {		/* time to send the next bit */
 				h->ophasep -= 80;
-				if (h->osync)
+				if (h->osync) {
 					h->osync--;		/* sending sync bits */
-				else {
-					h->obyte >>= 1;
+				} else {
 					h->obitp++;
 					if (h->obitp == 1)
 						h->obyte = 0; /* start bit; */
@@ -1249,7 +1216,8 @@
 							h->obytep = h->obyten = 0; /* sent */
 							h->osync = 10;	  /* trailing marks */
 						}
-					}
+					} else
+						h->obyte >>= 1;
 				}
 			}
 		}
@@ -1259,10 +1227,21 @@
 		return -1;
 	}
 	return 0;
-#undef SAMPLE2LEN
 #undef MAXSAMPLES
 }
 
+/*!
+ * Process an incoming frame, trying to detect the carrier and
+ * decode the message. The two frequencies are 1300 and 2100 Hz.
+ * The decoder detects the amplitude of the signal over the last
+ * few samples, filtering the absolute values with a lowpass filter.
+ * If the magnitude (h->imag) is large enough, multiply the signal
+ * by the two carriers, and compute the amplitudes m0 and m1.
+ * Record the current sample as '0' or '1' depending on which one is greater.
+ * The last 3 bits are stored in h->ibith, with the count of '1'
+ * bits in h->ibitt.
+ * XXX the rest is to be determined.
+ */
 static void sms_process (sms_t * h, int samples, signed short *data)
 {
 	if (h->obyten || h->osync)
@@ -1275,12 +1254,17 @@
 			h->imag = h->imag * 7 / 8;
 		if (h->imag > 500) {
 			h->idle = 0;
+
+			/* multiply signal by the two carriers. */
 			h->ims0 = (h->ims0 * 6 + *data * wave[h->ips0]) / 7;
 			h->imc0 = (h->imc0 * 6 + *data * wave[h->ipc0]) / 7;
 			h->ims1 = (h->ims1 * 6 + *data * wave[h->ips1]) / 7;
 			h->imc1 = (h->imc1 * 6 + *data * wave[h->ipc1]) / 7;
+			/* compute the amplitudes */
 			m0 = h->ims0 * h->ims0 + h->imc0 * h->imc0;
 			m1 = h->ims1 * h->ims1 + h->imc1 * h->imc1;
+
+			/* advance the sin/cos pointers */
 			if ((h->ips0 += 21) >= 80)
 				h->ips0 -= 80;
 			if ((h->ipc0 += 21) >= 80)
@@ -1291,6 +1275,8 @@
 				h->ipc1 -= 80;
 			{
 				char bit;
+
+				/* set new bit to 1 or 0 depending on which value is stronger */
 				h->ibith <<= 1;
 				if (m1 > m0)
 					h->ibith |= 1;
@@ -1344,7 +1330,8 @@
 				h->hangup = 1;
 				h->err = 1;
 			}
-			if (h->ierr) {							 /* error */
+			if (h->ierr) {		/* error */
+				/* Protocol 1 */
 				h->err = 1;
 				h->omsg[0] = 0x92;  /* error */
 				h->omsg[1] = 1;
@@ -1479,11 +1466,7 @@
 	if (chan->_state != AST_STATE_UP)
 		ast_answer (chan);
 
-#ifdef OUTALAW
-	res = ast_set_write_format (chan, AST_FORMAT_ALAW);
-#else
-	res = ast_set_write_format (chan, AST_FORMAT_SLINEAR);
-#endif
+	res = ast_set_write_format (chan, __OUT_FMT);
 	if (res >= 0)
 		res = ast_set_read_format (chan, AST_FORMAT_SLINEAR);
 	if (res < 0) {
@@ -1510,8 +1493,10 @@
 			break;
 		}
 		f = ast_read (chan);
-		if (!f)
+		if (!f) {
+			ast_log(LOG_NOTICE, "ast_read failed\n");
 			break;
+		}
 		if (f->frametype == AST_FRAME_VOICE) {
 			sms_process (&h, f->samples, f->data);
 		}



More information about the asterisk-commits mailing list