FreeCalypso > hg > freecalypso-tools
view 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 source
/* * 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); }