FreeCalypso > hg > osmo-playpen
changeset 12:7543aa173634
proto-smsc-sendmt program written, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 27 Aug 2023 16:36:28 -0800 |
parents | 44148d13283c |
children | 2c35aad69fea |
files | .hgignore smsc-sendmt/Makefile smsc-sendmt/hexdecode.c smsc-sendmt/imsi_entry.c smsc-sendmt/main.c smsc-sendmt/read_pdu.c smsc-sendmt/smsc_addr.c |
diffstat | 7 files changed, 247 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Sun Aug 27 13:39:51 2023 -0800 +++ b/.hgignore Sun Aug 27 16:36:28 2023 -0800 @@ -5,3 +5,5 @@ ^euse-demo/osmo-euse-demo$ ^smsc-daemon/proto-smsc-daemon$ + +^smsc-sendmt/proto-smsc-sendmt$
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smsc-sendmt/Makefile Sun Aug 27 16:36:28 2023 -0800 @@ -0,0 +1,13 @@ +CC= gcc +CFLAGS= -O2 -pthread -I/opt/osmocni2/include -I/usr/include/samba-4.0 +PROG= proto-smsc-sendmt +OBJS= hexdecode.o imsi_entry.o main.o read_pdu.o smsc_addr.o +OSMOLIB=-L/opt/osmocni2/lib -Wl,-rpath,/opt/osmocni2/lib -losmogsm -losmocore + +all: ${PROG} + +${PROG}: ${OBJS} + ${CC} -o $@ ${OBJS} ${OSMOLIB} + +clean: + rm -f *.o ${PROG}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smsc-sendmt/hexdecode.c Sun Aug 27 16:36:28 2023 -0800 @@ -0,0 +1,34 @@ +/* + * This library module implements decoding of long hex strings, + * such as SMS PDUs. + */ + +#include <ctype.h> +#include <stdint.h> + +int decode_hex_line(const char *inbuf, uint8_t *outbuf, unsigned outmax) +{ + const char *inp = inbuf; + uint8_t *outp = outbuf; + unsigned outcnt = 0; + int c, d[2], i; + + while (*inp) { + if (!isxdigit(inp[0]) || !isxdigit(inp[1])) + return(-1); + if (outcnt >= outmax) + break; + for (i = 0; i < 2; i++) { + c = *inp++; + if (isdigit(c)) + d[i] = c - '0'; + else if (isupper(c)) + d[i] = c - 'A' + 10; + else + d[i] = c - 'a' + 10; + } + *outp++ = (d[0] << 4) | d[1]; + outcnt++; + } + return outcnt; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smsc-sendmt/imsi_entry.c Sun Aug 27 16:36:28 2023 -0800 @@ -0,0 +1,53 @@ +/* + * The library function implemented in this module supports IMSI entry + * at UI level, either in the standard form (long string of digits) + * or in the shorthand notation introduced in fc-sim-tools. + */ + +#include <ctype.h> +#include <string.h> + +int grok_imsi_user_arg(const char *arg, char *dest) +{ + const char *cp; + char *dp; + int n, tail_len, remain; + + if (!isdigit(*arg)) + return(-1); + cp = arg; + dp = dest; + n = 0; + while (isdigit(*cp)) { + if (n >= 15) + return(-1); + *dp++ = *cp++; + n++; + } + if (!*cp) { + if (n < 6) + return(-1); + *dp = '\0'; + return(0); + } + if (*cp != '-') + return(-1); + cp++; + tail_len = strlen(cp); + if (!tail_len) + return(-1); + remain = 15 - n; + if (remain < tail_len + 1) + return(-1); + while (remain > tail_len) { + *dp++ = '0'; + remain--; + } + while (*cp) { + if (!isdigit(*cp)) + return(-1); + *dp++ = *cp++; + } + *dp = '\0'; + return(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smsc-sendmt/main.c Sun Aug 27 16:36:28 2023 -0800 @@ -0,0 +1,87 @@ +/* + * This C module is the main for proto-smsc-sendmt, a command line utility + * that constructs an MT-forwardSM.req GSUP message and shoots it over to + * proto-smsc-daemon for feeding to OsmoHLR. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <ctype.h> +#include <string.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +#include <osmocom/core/msgb.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/socket.h> + +#include <osmocom/gsm/gsup.h> + +extern void parse_smsc_addr_arg(const char *arg); +extern void encode_smsc_addr(struct osmo_gsup_message *gmsg); +extern int grok_imsi_user_arg(const char *arg, char *dest); +extern void read_pdu_from_stdin(void); + +extern uint8_t tpdu_buf[]; +extern unsigned tpdu_len; + +static const uint8_t sm_rp_mr = 0xFF; + +int main(int argc, char **argv) +{ + struct osmo_gsup_message gmsg; + struct msgb *msgb; + int rc, sock; + + if (argc != 4) { + fprintf(stderr, "usage: %s smsc-addr imsi socket-path\n", + argv[0]); + exit(1); + } + parse_smsc_addr_arg(argv[1]); + memset(&gmsg, 0, sizeof(gmsg)); + rc = grok_imsi_user_arg(argv[2], gmsg.imsi); + if (rc < 0) { + fprintf(stderr, "error: invalid IMSI argument\n"); + exit(1); + } + read_pdu_from_stdin(); + + /* fill out the rest of GSUP msg */ + gmsg.message_type = OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST; + gmsg.message_class = OSMO_GSUP_MESSAGE_CLASS_SMS; + gmsg.sm_rp_mr = &sm_rp_mr; + gmsg.sm_rp_da_type = OSMO_GSUP_SMS_SM_RP_ODA_NULL; + gmsg.sm_rp_oa_type = OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR; + encode_smsc_addr(&gmsg); + gmsg.sm_rp_ui = tpdu_buf; + gmsg.sm_rp_ui_len = tpdu_len; + + /* pack it into an msgb */ + msgb = msgb_alloc_headroom(4000, 64, "sendmt"); + if (!msgb) { + fprintf(stderr, "error: unable to allocate msgb\n"); + exit(1); + } + rc = osmo_gsup_encode(msgb, &gmsg); + if (rc < 0) { + fprintf(stderr, "error: osmo_gsup_encode() failed\n"); + exit(1); + } + + /* send it off via UNIX socket */ + sock = osmo_sock_unix_init(SOCK_DGRAM, 0, argv[3], OSMO_SOCK_F_CONNECT); + if (sock < 0) { + fprintf(stderr, "error connecting to %s\n", argv[3]); + exit(1); + } + rc = send(sock, msgb->data, msgb->len, 0); + if (rc < 0) { + perror("sending dgram on socket"); + exit(1); + } + exit(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smsc-sendmt/read_pdu.c Sun Aug 27 16:36:28 2023 -0800 @@ -0,0 +1,38 @@ +/* + * This module implements the reading of hex-encoded SMS-DELIVER TPDU + * from stdin. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +extern int decode_hex_line(const char *inbuf, uint8_t *outbuf, unsigned outmax); + +uint8_t tpdu_buf[176]; +unsigned tpdu_len; + +void read_pdu_from_stdin(void) +{ + char linebuf[512], *nl; + int rc; + + if (!fgets(linebuf, sizeof(linebuf), stdin)) { + fprintf(stderr, "error: empty stdin is not acceptable\n"); + exit(1); + } + nl = strchr(linebuf, '\n'); + if (!nl) { + fprintf(stderr, + "error: stdin line is too long or unterminated\n"); + exit(1); + } + *nl = '\0'; + rc = decode_hex_line(linebuf, tpdu_buf, sizeof(tpdu_buf)); + if (rc <= 0) { + fprintf(stderr, "error: stdin line is not a valid hex PDU\n"); + exit(1); + } + tpdu_len = rc; +}
--- a/smsc-sendmt/smsc_addr.c Sun Aug 27 13:39:51 2023 -0800 +++ b/smsc-sendmt/smsc_addr.c Sun Aug 27 16:36:28 2023 -0800 @@ -1,21 +1,25 @@ /* - * This C module is being stashed here temporarily until we figure out - * where this function ultimately needs to go. The parsing of the SMSC - * address is being moved out of proto-smsc-daemon to proto-smsc-sendmt, - * but we haven't started putting together the latter program yet. + * This module handles the parsing and GSUP encoding of our SMSC address, + * which we need to send to the MSC and ultimately to the MS as SM-RP-OA. */ #include <ctype.h> #include <string.h> #include <stdio.h> +#include <stdint.h> #include <stdlib.h> -char smsc_addr_num[21]; /* maximum of 20 digits per GSM 04.11 */ -uint8_t smsc_addr_ton_npi; +#include <osmocom/gsm/gsm48_ie.h> +#include <osmocom/gsm/gsup.h> -void parse_smsc_addr_arg(char *arg) +static char smsc_addr_num[21]; /* maximum of 20 digits per GSM 04.11 */ +static uint8_t smsc_addr_ton_npi; +static uint8_t smsc_addr_bcd[12]; + +void parse_smsc_addr_arg(const char *arg) { - char *cp, *dp, *endp; + const char *cp; + char *dp, *endp; unsigned ndig; cp = arg; @@ -49,3 +53,11 @@ if (*endp) goto invalid; } + +void encode_smsc_addr(struct osmo_gsup_message *gmsg) +{ + gsm48_encode_bcd_number(smsc_addr_bcd, 11, 1, smsc_addr_num); + smsc_addr_bcd[1] = smsc_addr_ton_npi; + gmsg->sm_rp_oa = smsc_addr_bcd + 1; + gmsg->sm_rp_oa_len = smsc_addr_bcd[0]; +}