FreeCalypso > hg > freecalypso-tools
diff uptools/atcmd/smdump.c @ 352:02d6c8469535
fcup-smdump implemented, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 05 Feb 2018 08:47:45 +0000 |
parents | |
children | 3bcc56883b17 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uptools/atcmd/smdump.c Mon Feb 05 08:47:45 2018 +0000 @@ -0,0 +1,155 @@ +/* + * This utility retrieves a dump of all stored SMS records in PDU mode. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include "../../rvinterf/include/exitcodes.h" +#include "resp_parse.h" + +extern char at_response[]; + +int pdu_state; +char *msgtype; +u_char pbname_gsm[40]; +unsigned pbname_len, header_len; +u_char pdu_bin[176]; + +validate_pbname_7bit() +{ + unsigned n; + + for (n = 0; n < pbname_len; n++) + if (pbname_gsm[n] & 0x80) + return(-1); + return(0); +} + +cmgl_header() +{ + struct resp_field fields[4]; + int cc; + + /* skip empty lines */ + if (!at_response[1]) + return; + /* if not empty, it MUST be +CMGL */ + if (strncmp(at_response+1, "+CMGL: ", 7)) { + fprintf(stderr, "error: response from target is not +CMGL\n"); + exit(ERROR_TARGET); + } + if (parse_structured_response(at_response+8, fields, 4) != 4) { +malformed: fprintf(stderr, "error: malformed +CMGL response\n"); + exit(ERROR_TARGET); + } + if (fields[0].type != RESP_FIELD_NUMBER || + fields[1].type != RESP_FIELD_NUMBER || + fields[3].type != RESP_FIELD_NUMBER) + goto malformed; + if (fields[2].type != RESP_FIELD_STRING && + fields[2].type != RESP_FIELD_EMPTY) + goto malformed; + /* we'll handle the message number when we add delete after dump */ + switch (fields[1].num) { + case 0: + case 1: + msgtype = "Received"; + break; + case 2: + msgtype = "Stored unsent"; + break; + case 3: + msgtype = "Sent"; + break; + default: + fprintf(stderr, + "error: invalid message status code in +CMGL response\n"); + exit(ERROR_TARGET); + } + if (fields[2].type == RESP_FIELD_STRING) { + cc = decode_hex_line(fields[2].str, pbname_gsm, + sizeof pbname_gsm); + if (cc >= 1) { + pbname_len = cc; + if (validate_pbname_7bit() < 0) + pbname_len = 0; + } else + pbname_len = 0; + } else + pbname_len = 0; + header_len = fields[3].num; + pdu_state = 1; +} + +emit_pb_name() +{ + u_char decoded_name[81]; + + gsm7_to_ascii_or_ext(pbname_gsm, pbname_len, decoded_name, 0, 0, 0, 0); + printf("Phonebook-Name: %s\n", decoded_name); +} + +cmgl_pdu() +{ + int cc; + unsigned sca_len; + + cc = decode_hex_line(at_response+1, pdu_bin, sizeof pdu_bin); + if (cc < 1) { + fprintf(stderr, "error: expected PDU not received\n"); + exit(ERROR_TARGET); + } + sca_len = pdu_bin[0]; + if (1 + sca_len + header_len != cc) { + fprintf(stderr, "error: PDU length mismatch\n"); + exit(ERROR_TARGET); + } + printf("%s message:\n", msgtype); + if (pbname_len) + emit_pb_name(); + puts(at_response+1); + putchar('\n'); + pdu_state = 0; +} + +cmgl_callback() +{ + if (pdu_state) + cmgl_pdu(); + else + cmgl_header(); +} + +main(argc, argv) + char **argv; +{ + int c; + extern int optind; + + while ((c = getopt(argc, argv, "B:np:RX:")) != EOF) + if (!atinterf_cmdline_opt(c)) { + /* error msg already printed */ + exit(ERROR_USAGE); + } + if (argc != optind) { + fprintf(stderr, "usage: %s [options]\n", argv[0]); + exit(ERROR_USAGE); + } + atinterf_init(); + /* put the 07.05 modem in PDU mode */ + atinterf_exec_cmd_needok("AT+CMGF=0", 0, 0); + /* HEX charset for phonebook names */ + atinterf_exec_cmd_needok("AT+CSCS=\"HEX\"", 0, 0); + /* main command */ + atinterf_exec_cmd_needok("AT+CMGL=4", 0, cmgl_callback); + if (pdu_state) { + fprintf(stderr, "error: wrong state at the end of +CMGL\n"); + exit(ERROR_TARGET); + } + /* delete-after-dump will go here */ + exit(0); +}