changeset 362:89fe66cb60f6

fcup-smsend program put together, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 05 Mar 2018 01:47:18 +0000
parents ae2556e256a4
children 46cf847781bd
files .hgignore uptools/atcmd/Makefile uptools/atcmd/smsend_basic.c uptools/atcmd/smsend_cmgw.c uptools/atcmd/smsend_pdu.c uptools/atcmd/smsend_text.c
diffstat 6 files changed, 303 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Mar 04 23:11:51 2018 +0000
+++ b/.hgignore	Mon Mar 05 01:47:18 2018 +0000
@@ -62,5 +62,6 @@
 
 ^uptools/atcmd/fcup-at$
 ^uptools/atcmd/fcup-smdump$
+^uptools/atcmd/fcup-smsend$
 ^uptools/atinterf/fcup-atinterf$
 ^uptools/sms-pdu-decode/sms-pdu-decode$
--- a/uptools/atcmd/Makefile	Sun Mar 04 23:11:51 2018 +0000
+++ b/uptools/atcmd/Makefile	Mon Mar 05 01:47:18 2018 +0000
@@ -1,6 +1,6 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	fcup-at fcup-smdump
+PROGS=	fcup-at fcup-smdump fcup-smsend
 INSTBIN=/opt/freecalypso/bin
 
 LIBCODING=	../libcoding/libcoding.a
@@ -9,6 +9,9 @@
 
 SMDUMP_OBJS=	atinterf.o resp_parse.o smdump.o ${LIBCODING}
 
+SMSEND_OBJS=	atinterf.o resp_parse.o smsend_basic.o smsend_cmgw.o \
+		smsend_pdu.o smsend_text.o ${LIBCODING}
+
 all:	${PROGS}
 
 fcup-at:	${ATCMD_OBJS}
@@ -17,6 +20,9 @@
 fcup-smdump:	${SMDUMP_OBJS}
 	${CC} ${CFLAGS} -o $@ ${SMDUMP_OBJS}
 
+fcup-smsend:	${SMSEND_OBJS}
+	${CC} ${CFLAGS} -o $@ ${SMSEND_OBJS}
+
 install:	${PROGS}
 	mkdir -p ${INSTBIN}
 	install -c ${PROGS} ${INSTBIN}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uptools/atcmd/smsend_basic.c	Mon Mar 05 01:47:18 2018 +0000
@@ -0,0 +1,131 @@
+/*
+ * This is the main module for the basic fcup-smsend utility.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include "../../rvinterf/include/exitcodes.h"
+
+int sms_write_mode, text_mode, utf8_input;
+u_char dest_addr[12];
+char msgtext[322];
+u_char msgtext_gsm7[160];
+unsigned msgtext_gsmlen;
+
+process_cmdline(argc, argv)
+	char **argv;
+{
+	int c;
+	extern int optind;
+
+	while ((c = getopt(argc, argv, "B:np:RtuwWX:")) != EOF) {
+		if (atinterf_cmdline_opt(c))
+			continue;
+		switch (c) {
+		case 't':
+			text_mode = 1;
+			continue;
+		case 'u':
+			utf8_input = 1;
+			continue;
+		case 'w':
+			sms_write_mode = 1;
+			continue;
+		case 'W':
+			sms_write_mode = 2;
+			continue;
+		default:
+			/* error msg already printed */
+			exit(ERROR_USAGE);
+		}
+	}
+	if (argc > optind + 2) {
+		fprintf(stderr, "usage: %s [options] dest-addr [message]\n",
+			argv[0]);
+		exit(ERROR_USAGE);
+	}
+	if (!argv[optind] || !argv[optind][0]) {
+		if (sms_write_mode == 2) {
+			dest_addr[0] = 0;
+			dest_addr[1] = 0x80;
+		} else {
+			fprintf(stderr,
+			"error: destination address must be specified\n");
+			exit(ERROR_USAGE);
+		}
+	} else if (parse_and_encode_dest_addr(argv[optind], dest_addr) < 0) {
+		fprintf(stderr,
+			"error: destination address argument is invalid\n");
+		exit(ERROR_USAGE);
+	}
+	if (!argv[optind+1])
+		return(0);
+	if (strlen(argv[optind+1]) > 320) {
+		fprintf(stderr, "error: message argument is too long\n");
+		exit(ERROR_USAGE);
+	}
+	strcpy(msgtext, argv[optind+1]);
+	return(1);
+}
+
+read_msgtext_from_stdin()
+{
+	char *nl;
+
+	if (!fgets(msgtext, sizeof msgtext, stdin)) {
+		fprintf(stderr, "error reading message from stdin\n");
+		exit(ERROR_USAGE);
+	}
+	nl = index(msgtext, '\n');
+	if (!nl) {
+		fprintf(stderr,
+		"error: message on stdin is too long or unterminated\n");
+		exit(ERROR_USAGE);
+	}
+	*nl = '\0';
+}
+
+main(argc, argv)
+	char **argv;
+{
+	int rc;
+
+	if (!process_cmdline(argc, argv))
+		read_msgtext_from_stdin();
+	if (utf8_input && utf8_to_latin1(msgtext) < 0) {
+		fprintf(stderr, "error: invalid UTF-8 message\n");
+		exit(ERROR_USAGE);
+	}
+	if (text_mode) {
+		if (strlen(msgtext) > 160) {
+toolong:		fprintf(stderr, "error: message exceeds 160 chars\n");
+			exit(ERROR_USAGE);
+		}
+	} else {
+		rc = latin1_to_gsm7(msgtext, msgtext_gsm7, 160,
+				    &msgtext_gsmlen);
+		if (rc == -1) {
+			fprintf(stderr,
+				"error: message not valid for GSM7 charset\n");
+			exit(ERROR_USAGE);
+		}
+		if (rc == -2)
+			goto toolong;
+	}
+	/* get to work */
+	atinterf_init();
+	if (text_mode) {
+		prep_for_text_mode();
+		send_in_text_mode(dest_addr, msgtext);
+	} else {
+		prep_for_pdu_mode();
+		send_in_pdu_mode(dest_addr, msgtext_gsm7, msgtext_gsmlen, 0, 0);
+	}
+	if (sms_write_mode == 1)
+		sendafterwr_process();
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uptools/atcmd/smsend_cmgw.c	Mon Mar 05 01:47:18 2018 +0000
@@ -0,0 +1,84 @@
+/*
+ * The handling of +CMGW responses and send-after-write for fcup-smsend
+ * family is implemented here.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "../../rvinterf/include/exitcodes.h"
+#include "resp_parse.h"
+
+extern char at_response[];
+extern int sms_write_mode;
+
+struct saw_rec {
+	unsigned	msgid;
+	struct saw_rec	*next;
+};
+
+struct saw_rec *sendafterwr_head, **sendafterwr_tail = &sendafterwr_head;
+
+add_sendafterwr_record(msgid)
+	unsigned msgid;
+{
+	struct saw_rec *rec;
+
+	rec = malloc(sizeof(struct saw_rec));
+	if (!rec) {
+		perror("malloc for send-after-write record");
+		exit(ERROR_UNIX);
+	}
+	rec->msgid = msgid;
+	rec->next = 0;
+	*sendafterwr_tail = rec;
+	sendafterwr_tail = &rec->next;
+}
+
+cmgw_callback()
+{
+	struct resp_field fields[1];
+	int cc;
+
+	/* skip empty lines */
+	if (!at_response[1])
+		return;
+	/* if not empty, it MUST be +CMGW */
+	if (strncmp(at_response+1, "+CMGW: ", 7)) {
+		fprintf(stderr, "error: response from target is not +CMGW\n");
+		exit(ERROR_TARGET);
+	}
+	if (sms_write_mode == 2) {
+		puts(at_response+1);
+		return;
+	}
+	if (parse_structured_response(at_response+8, fields, 1) != 1) {
+malformed:	fprintf(stderr, "error: malformed +CMGW response\n");
+		exit(ERROR_TARGET);
+	}
+	if (fields[0].type != RESP_FIELD_NUMBER)
+		goto malformed;
+	add_sendafterwr_record(fields[0].num);
+}
+
+sendafterwr_process()
+{
+	struct saw_rec *rec;
+	char cmss_cmd[32];
+
+	if (!sendafterwr_head) {
+		fprintf(stderr,
+			"error: no +CMGW response received from target\n");
+		exit(ERROR_TARGET);
+	}
+	if (sendafterwr_head->next)
+		atinterf_exec_cmd_needok("AT+CMMS=1", 0, 0);
+	for (rec = sendafterwr_head; rec; rec = rec->next) {
+		sprintf(cmss_cmd, "AT+CMSS=%u", rec->msgid);
+		atinterf_exec_cmd_needok(cmss_cmd, 0, 0);
+	}
+	if (sendafterwr_head->next)
+		atinterf_exec_cmd_needok("AT+CMMS=0", 0, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uptools/atcmd/smsend_pdu.c	Mon Mar 05 01:47:18 2018 +0000
@@ -0,0 +1,40 @@
+/*
+ * This module implements SMS sending/writing in PDU mode.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+
+extern void cmgw_callback();
+
+extern int sms_write_mode;
+
+prep_for_pdu_mode()
+{
+	atinterf_exec_cmd_needok("AT+CMGF=0", 0, 0);
+}
+
+send_in_pdu_mode(da, textsrc, textlen, udh, udhl)
+	u_char *da, *textsrc, *udh;
+	unsigned textlen, udhl;
+{
+	char *cmdname;
+	void (*callback)();
+	u_char pdu[158];
+	unsigned pdulen;
+	char pduhex[317];
+	char send_cmd[32];
+
+	pdu[0] = 0;
+	pdulen = make_sms_submit_pdu(da, textsrc, textlen, udh, udhl, pdu + 1);
+	make_hex_string(pdu, pdulen + 1, pduhex);
+	if (sms_write_mode) {
+		cmdname = "CMGW";
+		callback = cmgw_callback;
+	} else {
+		cmdname = "CMGS";
+		callback = 0;
+	}
+	sprintf(send_cmd, "AT+%s=%u", cmdname, pdulen + 1);
+	atinterf_exec_cmd_needok(send_cmd, pduhex, callback);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uptools/atcmd/smsend_text.c	Mon Mar 05 01:47:18 2018 +0000
@@ -0,0 +1,40 @@
+/*
+ * This module implements SMS sending/writing in text mode.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+
+extern void cmgw_callback();
+
+extern int sms_write_mode;
+
+prep_for_text_mode()
+{
+	atinterf_exec_cmd_needok("AT+CMGF=1", 0, 0);
+	atinterf_exec_cmd_needok("AT+CSCS=\"8859-1\"", 0, 0);
+	atinterf_exec_cmd_needok("AT+CSMP=1,,0,0", 0, 0);
+}
+
+send_in_text_mode(binda, textstr)
+	u_char *binda;
+	char *textstr;
+{
+	char *cmdname;
+	void (*callback)();
+	char send_cmd[64], digits[21];
+
+	if (sms_write_mode) {
+		cmdname = "CMGW";
+		callback = cmgw_callback;
+	} else {
+		cmdname = "CMGS";
+		callback = 0;
+	}
+	if (binda[0]) {
+		decode_address_digits(binda + 2, digits, binda[0]);
+		sprintf(send_cmd, "AT+%s=\"%s\",%u", cmdname, digits, binda[1]);
+	} else
+		sprintf(send_cmd, "AT+%s", cmdname);
+	atinterf_exec_cmd_needok(send_cmd, textstr, callback);
+}