view uptools/atcmd/smdump.c @ 873:2b5f4736079c
doc/Buzzer-melodies: update for fc-pwt-comp and Tourmaline BUZM
author |
Mychaela Falconia <falcon@freecalypso.org> |
date |
Tue, 29 Mar 2022 07:49:05 +0000 (2022-03-29) |
parents |
da724c67159d |
children |
|
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[];
struct delafter {
unsigned msgid;
struct delafter *next;
};
int delete_after_flag;
struct delafter *delafter_head, **delafter_tail = &delafter_head;
int pdu_state;
char *msgtype;
u_char pbname_gsm[40];
unsigned pbname_len, header_len;
u_char pdu_bin[176];
add_delafter_record(msgid)
unsigned msgid;
{
struct delafter *rec;
rec = malloc(sizeof(struct delafter));
if (!rec)
return;
rec->msgid = msgid;
rec->next = 0;
*delafter_tail = rec;
delafter_tail = &rec->next;
}
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;
if (delete_after_flag)
add_delafter_record(fields[0].num);
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()
{
fputs("Phonebook-Name: ", stdout);
print_gsm7_string_to_file(pbname_gsm, pbname_len, stdout);
putchar('\n');
}
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();
}
delete_after_process()
{
struct delafter *rec;
char cmgd_cmd[32];
for (rec = delafter_head; rec; rec = rec->next) {
sprintf(cmgd_cmd, "AT+CMGD=%u", rec->msgid);
atinterf_exec_cmd_needok(cmgd_cmd, (char *) 0, (void *) 0);
}
}
main(argc, argv)
char **argv;
{
int c;
extern int optind;
while ((c = getopt(argc, argv, "B:dnp:RX:")) != EOF) {
if (atinterf_cmdline_opt(c))
continue;
else if (c == 'd')
delete_after_flag = 1;
else {
/* error msg already printed */
exit(ERROR_USAGE);
}
}
if (argc != optind) {
fprintf(stderr, "usage: %s [options]\n", argv[0]);
exit(ERROR_USAGE);
}
atinterf_init();
/* enable verbose error messages */
atinterf_exec_cmd_needok("AT+CMEE=2", (char *) 0, (void *) 0);
/* put the 07.05 modem in PDU mode */
atinterf_exec_cmd_needok("AT+CMGF=0", (char *) 0, (void *) 0);
/* HEX charset for phonebook names */
atinterf_exec_cmd_needok("AT+CSCS=\"HEX\"", (char *) 0, (void *) 0);
/* main command */
atinterf_exec_cmd_needok("AT+CMGL=4", (char *) 0, cmgl_callback);
if (pdu_state) {
fprintf(stderr, "error: wrong state at the end of +CMGL\n");
exit(ERROR_TARGET);
}
if (delete_after_flag)
delete_after_process();
/* be nice and restore IRA charset for manual AT command users */
atinterf_exec_cmd_needok("AT+CSCS=\"IRA\"", (char *) 0, (void *) 0);
exit(0);
}