# HG changeset patch # User Mychaela Falconia # Date 1520214438 0 # Node ID 89fe66cb60f68dca73b187abc5f38a8bbc07eee1 # Parent ae2556e256a4162c84b0216f88e42b523016e8bd fcup-smsend program put together, compiles diff -r ae2556e256a4 -r 89fe66cb60f6 .hgignore --- 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$ diff -r ae2556e256a4 -r 89fe66cb60f6 uptools/atcmd/Makefile --- 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} diff -r ae2556e256a4 -r 89fe66cb60f6 uptools/atcmd/smsend_basic.c --- /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 +#include +#include +#include +#include +#include +#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); +} diff -r ae2556e256a4 -r 89fe66cb60f6 uptools/atcmd/smsend_cmgw.c --- /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 +#include +#include +#include +#include +#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); +} diff -r ae2556e256a4 -r 89fe66cb60f6 uptools/atcmd/smsend_pdu.c --- /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 +#include + +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); +} diff -r ae2556e256a4 -r 89fe66cb60f6 uptools/atcmd/smsend_text.c --- /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 +#include + +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); +}