changeset 223:f11c3e40c87a

new program smpp-send
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 05 Aug 2023 12:24:31 -0800
parents 9d6e8d99d2b1
children 62184b971c8e
files .hgignore Makefile smpp-send/Makefile smpp-send/build_pdu.c smpp-send/error.h smpp-send/hexdump.c smpp-send/input.c smpp-send/main.c smpp-send/msg_cmd.c smpp-send/settings.c
diffstat 10 files changed, 562 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Aug 03 21:13:41 2023 -0800
+++ b/.hgignore	Sat Aug 05 12:24:31 2023 -0800
@@ -16,6 +16,8 @@
 
 ^sip-out/themwi-sip-out$
 
+^smpp-send/smpp-send$
+
 ^smpp-trx-sa/smpp-trx-sa$
 
 ^utils/rtp-alloc-test$
--- a/Makefile	Thu Aug 03 21:13:41 2023 -0800
+++ b/Makefile	Sat Aug 05 12:24:31 2023 -0800
@@ -1,7 +1,8 @@
 CC=	gcc
 CFLAGS=	-O2
 
-PROGDIR=mgw mncc mtctest rtp-mgr sip-in sip-manual-out sip-out smpp-trx-sa utils
+PROGDIR=mgw mncc mtctest rtp-mgr sip-in sip-manual-out sip-out smpp-send \
+	smpp-trx-sa utils
 LIBDIR=	libnumdb liboutrt librtpalloc libsip libutil
 SUBDIR=	${PROGDIR} ${LIBDIR}
 
@@ -14,6 +15,7 @@
 sip-in:		libnumdb libsip libutil
 sip-manual-out:	librtpalloc libsip libutil
 sip-out:	liboutrt libsip libutil
+smpp-send:	libutil
 smpp-trx-sa:	libutil
 utils:		libnumdb librtpalloc libsip libutil
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smpp-send/Makefile	Sat Aug 05 12:24:31 2023 -0800
@@ -0,0 +1,17 @@
+CC=	gcc
+CFLAGS=	-O2
+PROG=	smpp-send
+OBJS=	build_pdu.o hexdump.o input.o main.o msg_cmd.o settings.o
+LIBS=	../libutil/libutil.a
+INSTBIN=/usr/local/bin
+
+all:	${PROG}
+
+${PROG}: ${OBJS} ${LIBS}
+	${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS}
+
+install:
+	install -c -o bin -g bin -m 755 ${PROG} ${INSTBIN}
+
+clean:
+	rm -f *.o ${PROG} errs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smpp-send/build_pdu.c	Sat Aug 05 12:24:31 2023 -0800
@@ -0,0 +1,90 @@
+/*
+ * The function in this module constructs SMPP submit_sm PDUs
+ * from input messages.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "error.h"
+
+extern char src_addr[21], dest_addr[21];
+extern u_char src_ton, src_npi, dest_ton, dest_npi;
+extern u_char esm_class, pid_byte, dcs_byte;
+extern u_char prio_flag, reg_deliv, replace_flag;
+
+extern int input_lineno;
+
+void
+build_submit_sm(payload, payload_len, udhi)
+	u_char *payload;
+	unsigned payload_len;
+{
+	u_char pdu[512], *dp, esm_class_inst;
+	unsigned pdu_len, slen;
+
+	/* sanity checks first */
+	if (!src_addr[0]) {
+		fprintf(stderr, ERR_PREFIX "src address is not set\n",
+			input_lineno);
+		exit(1);
+	}
+	if (!dest_addr[0]) {
+		fprintf(stderr, ERR_PREFIX "dest address is not set\n",
+			input_lineno);
+		exit(1);
+	}
+	/* proceed */
+	dp = pdu + 4;		/* length will be filled last */
+	/* command_id */
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0x04;		/* submit_sm */
+	/* empty command_status */
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	/* dummy sequence_number (will be overwritten by smpp-trx-sa) */
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	*dp++ = 0;
+	/* mandatory params */
+	*dp++ = 0;		/* empty service_type */
+	*dp++ = src_ton;
+	*dp++ = src_npi;
+	slen = strlen(src_addr) + 1;
+	bcopy(src_addr, dp, slen);
+	dp += slen;
+	*dp++ = dest_ton;
+	*dp++ = dest_npi;
+	slen = strlen(dest_addr) + 1;
+	bcopy(dest_addr, dp, slen);
+	dp += slen;
+	esm_class_inst = esm_class;
+	if (udhi)
+		esm_class_inst |= 0x40;
+	*dp++ = esm_class_inst;
+	*dp++ = pid_byte;
+	*dp++ = prio_flag;
+	*dp++ = 0;		/* empty schedule_delivery_time */
+	*dp++ = 0;		/* empty validity_period */
+	*dp++ = reg_deliv;
+	*dp++ = replace_flag;
+	*dp++ = dcs_byte;
+	*dp++ = 0;		/* no canned messages */
+	*dp++ = payload_len;
+	bcopy(payload, dp, payload_len);
+	dp += payload_len;
+	pdu_len = dp - pdu;
+	pdu[0] = pdu_len >> 24;
+	pdu[1] = pdu_len >> 16;
+	pdu[2] = pdu_len >> 8;
+	pdu[3] = pdu_len;
+	/* local datagram socket output to be implemented */
+	hex_dump_output(pdu, pdu_len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smpp-send/error.h	Sat Aug 05 12:24:31 2023 -0800
@@ -0,0 +1,3 @@
+/* some definitions for error handling */
+
+#define	ERR_PREFIX	"smpp-send input line %d: "
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smpp-send/hexdump.c	Sat Aug 05 12:24:31 2023 -0800
@@ -0,0 +1,39 @@
+/*
+ * This module implements debug hex dump output of SMPP submit_sm PDUs
+ * constructed by our smpp-send program.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+
+void
+hex_dump_output(pdu, pdulen)
+	u_char *pdu;
+	unsigned pdulen;
+{
+	unsigned off, chunk;
+	int i, c;
+
+	printf("Constructed PDU of %u bytes:\n", pdulen);
+	for (off = 0; off < pdulen; off += chunk) {
+		printf("%04X:  ", off);
+		chunk = pdulen - off;
+		if (chunk > 16)
+			chunk = 16;
+		for (i = 0; i < 16; i++) {
+			if (i < chunk)
+				printf("%02X ", pdu[off + i]);
+			else
+				fputs("   ", stdout);
+			if (i == 7 || i == 15)
+				putchar(' ');
+		}
+		for (i = 0; i < chunk; i++) {
+			c = pdu[off + i];
+			if (c < ' ' || c > '~')
+				c = '.';
+			putchar(c);
+		}
+		putchar('\n');
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smpp-send/input.c	Sat Aug 05 12:24:31 2023 -0800
@@ -0,0 +1,125 @@
+/*
+ * This module implements input handling for smpp-send.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "error.h"
+
+extern char input_line[];
+extern int input_lineno;
+
+extern void set_src_addr();
+extern void set_src_ton();
+extern void set_src_npi();
+extern void set_dest_addr();
+extern void set_dest_ton();
+extern void set_dest_npi();
+extern void set_pid_byte();
+extern void set_dcs_byte();
+extern void set_esm_class();
+extern void set_priority();
+extern void set_reg_deliv();
+extern void set_replace_flag();
+extern void cmd_msg_plain();
+extern void cmd_msg_udh();
+
+static struct cmdtab {
+	char *cmd;
+	int minargs;
+	int maxargs;
+	void (*func)();
+} cmdtab[] = {
+	{"src", 1, 1, set_src_addr},
+	{"src-ton", 1, 1, set_src_ton},
+	{"src-npi", 1, 1, set_src_npi},
+	{"dest", 1, 1, set_src_addr},
+	{"dest-ton", 1, 1, set_src_ton},
+	{"dest-npi", 1, 1, set_src_npi},
+	{"pid", 1, 1, set_pid_byte},
+	{"dcs", 1, 2, set_dcs_byte},
+	{"esm-class", 1, 1, set_esm_class},
+	{"priority", 1, 1, set_priority},
+	{"reg-deliv", 1, 1, set_reg_deliv},
+	{"replace-flag", 1, 1, set_replace_flag},
+	{"msg", 1, 1, cmd_msg_plain},
+	{"msg-udh", 1, 1, cmd_msg_udh},
+	/* table search terminator */
+	{0, 0, 0, 0}
+};
+
+void
+process_input_line()
+{
+	char *argv[10];
+	char *cp, **ap;
+	struct cmdtab *tp;
+
+	cp = index(input_line, '\n');
+	if (!cp) {
+		fprintf(stderr, ERR_PREFIX "missing newline\n", input_lineno);
+		exit(1);
+	}
+	for (cp = input_line; isspace(*cp); cp++)
+		;
+	if (*cp == '\0' || *cp == '#')
+		return;
+	argv[0] = cp;
+	while (*cp && !isspace(*cp))
+		cp++;
+	if (*cp)
+		*cp++ = '\0';
+	for (tp = cmdtab; tp->cmd; tp++)
+		if (!strcmp(tp->cmd, argv[0]))
+			break;
+	if (!tp->func) {
+		fprintf(stderr, ERR_PREFIX "invalid command \"%s\"\n",
+			input_lineno, argv[0]);
+		exit(1);
+	}
+	for (ap = argv + 1; ; ) {
+		while (isspace(*cp))
+			cp++;
+		if (!*cp || *cp == '#')
+			break;
+		if (ap - argv - 1 >= tp->maxargs) {
+			fprintf(stderr, ERR_PREFIX "too many arguments\n",
+				input_lineno);
+			exit(1);
+		}
+		if (*cp == '"') {
+			*ap++ = ++cp;
+			for (;;) {
+				if (!*cp) {
+unterm_qstring:				fprintf(stderr, ERR_PREFIX
+						"unterminated quoted string\n",
+						input_lineno);
+					exit(1);
+				}
+				if (*cp == '"')
+					break;
+				if (*cp++ == '\\') {
+					if (!*cp)
+						goto unterm_qstring;
+					cp++;
+				}
+			}
+			*cp++ = '\0';
+		} else {
+			*ap++ = cp;
+			while (*cp && !isspace(*cp))
+				cp++;
+			if (*cp)
+				*cp++ = '\0';
+		}
+	}
+	if (ap - argv - 1 < tp->minargs) {
+		fprintf(stderr, ERR_PREFIX "too few arguments\n", input_lineno);
+		exit(1);
+	}
+	*ap = 0;
+	tp->func(ap - argv, argv);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smpp-send/main.c	Sat Aug 05 12:24:31 2023 -0800
@@ -0,0 +1,32 @@
+/*
+ * This C file is the main module for smpp-send test program.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char *trx_socket;
+
+char src_addr[21], dest_addr[21];
+u_char src_ton = 1, src_npi = 1, dest_ton = 1, dest_npi = 1;
+u_char esm_class, pid_byte, dcs_byte;
+u_char prio_flag, reg_deliv, replace_flag;
+
+char input_line[512];
+int input_lineno;
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc > 2) {
+		fprintf(stderr, "usage: %s [trx-local-socket]\n", argv[0]);
+		exit(1);
+	}
+	if (argc > 1)
+		trx_socket = argv[1];
+	for (input_lineno = 1; fgets(input_line, sizeof input_line, stdin);
+	     input_lineno++)
+		process_input_line();
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smpp-send/msg_cmd.c	Sat Aug 05 12:24:31 2023 -0800
@@ -0,0 +1,69 @@
+/*
+ * This module implements msg and msg-udh input commands,
+ * after all settings have been captured.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "error.h"
+
+extern int input_lineno;
+
+static int
+decode_hex_digit(c)
+{
+	if (c >= '0' && c <= '9')
+		return(c - '0');
+	if (c >= 'A' && c <= 'F')
+		return(c - 'A' + 10);
+	if (c >= 'a' && c <= 'f')
+		return(c - 'a' + 10);
+	return(-1);
+}
+
+static void
+cmd_msg_common(arg, udhi)
+	char *arg;
+{
+	u_char input[160];
+	unsigned input_len;
+
+	for (input_len = 0; ; input_len++) {
+		while (isspace(*arg))
+			arg++;
+		if (!*arg)
+			break;
+		if (!isxdigit(arg[0]) || !isxdigit(arg[1])) {
+			fprintf(stderr, ERR_PREFIX "invalid hex string\n",
+				input_lineno);
+			exit(1);
+		}
+		if (input_len >= 160) {
+			fprintf(stderr, ERR_PREFIX "hex string is too long\n",
+				input_lineno);
+			exit(1);
+		}
+		input[input_len] = (decode_hex_digit(arg[0]) << 4) |
+				    decode_hex_digit(arg[1]);
+		arg += 2;
+	}
+	build_submit_sm(input, input_len, udhi);
+}
+
+void
+cmd_msg_plain(argc, argv)
+	char **argv;
+{
+	cmd_msg_common(argv[1], 0);
+}
+
+void
+cmd_msg_udh(argc, argv)
+	char **argv;
+{
+	cmd_msg_common(argv[1], 1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smpp-send/settings.c	Sat Aug 05 12:24:31 2023 -0800
@@ -0,0 +1,182 @@
+/*
+ * This module implements functions for various settings that come before
+ * msg or msg-udh lines.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "error.h"
+
+extern char src_addr[21], dest_addr[21];
+extern u_char src_ton, src_npi, dest_ton, dest_npi;
+extern u_char esm_class, pid_byte, dcs_byte;
+extern u_char prio_flag, reg_deliv, replace_flag;
+
+extern int input_lineno;
+
+void
+set_src_addr(argc, argv)
+	char **argv;
+{
+	if (strlen(argv[1]) > 20) {
+		fprintf(stderr, ERR_PREFIX
+			"phone number argument is too long\n", input_lineno);
+		exit(1);
+	}
+	strcpy(src_addr, argv[1]);
+}
+
+void
+set_src_ton(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	src_ton = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_src_npi(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	src_npi = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_dest_addr(argc, argv)
+	char **argv;
+{
+	if (strlen(argv[1]) > 20) {
+		fprintf(stderr, ERR_PREFIX
+			"phone number argument is too long\n", input_lineno);
+		exit(1);
+	}
+	strcpy(dest_addr, argv[1]);
+}
+
+void
+set_dest_ton(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	dest_ton = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_dest_npi(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	dest_npi = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_pid_byte(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	pid_byte = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_dcs_byte(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	dcs_byte = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_esm_class(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	esm_class = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_priority(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	prio_flag = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_reg_deliv(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	reg_deliv = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}
+
+void
+set_replace_flag(argc, argv)
+	char **argv;
+{
+	char *endp;
+
+	replace_flag = strtoul(argv[1], &endp, 0);
+	if (*endp) {
+		fprintf(stderr, ERR_PREFIX "invalid byte value argument\n",
+			input_lineno);
+		exit(1);
+	}
+}