comparison 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
comparison
equal deleted inserted replaced
351:f0e9bb28b4d6 352:02d6c8469535
1 /*
2 * This utility retrieves a dump of all stored SMS records in PDU mode.
3 */
4
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <strings.h>
10 #include <unistd.h>
11 #include "../../rvinterf/include/exitcodes.h"
12 #include "resp_parse.h"
13
14 extern char at_response[];
15
16 int pdu_state;
17 char *msgtype;
18 u_char pbname_gsm[40];
19 unsigned pbname_len, header_len;
20 u_char pdu_bin[176];
21
22 validate_pbname_7bit()
23 {
24 unsigned n;
25
26 for (n = 0; n < pbname_len; n++)
27 if (pbname_gsm[n] & 0x80)
28 return(-1);
29 return(0);
30 }
31
32 cmgl_header()
33 {
34 struct resp_field fields[4];
35 int cc;
36
37 /* skip empty lines */
38 if (!at_response[1])
39 return;
40 /* if not empty, it MUST be +CMGL */
41 if (strncmp(at_response+1, "+CMGL: ", 7)) {
42 fprintf(stderr, "error: response from target is not +CMGL\n");
43 exit(ERROR_TARGET);
44 }
45 if (parse_structured_response(at_response+8, fields, 4) != 4) {
46 malformed: fprintf(stderr, "error: malformed +CMGL response\n");
47 exit(ERROR_TARGET);
48 }
49 if (fields[0].type != RESP_FIELD_NUMBER ||
50 fields[1].type != RESP_FIELD_NUMBER ||
51 fields[3].type != RESP_FIELD_NUMBER)
52 goto malformed;
53 if (fields[2].type != RESP_FIELD_STRING &&
54 fields[2].type != RESP_FIELD_EMPTY)
55 goto malformed;
56 /* we'll handle the message number when we add delete after dump */
57 switch (fields[1].num) {
58 case 0:
59 case 1:
60 msgtype = "Received";
61 break;
62 case 2:
63 msgtype = "Stored unsent";
64 break;
65 case 3:
66 msgtype = "Sent";
67 break;
68 default:
69 fprintf(stderr,
70 "error: invalid message status code in +CMGL response\n");
71 exit(ERROR_TARGET);
72 }
73 if (fields[2].type == RESP_FIELD_STRING) {
74 cc = decode_hex_line(fields[2].str, pbname_gsm,
75 sizeof pbname_gsm);
76 if (cc >= 1) {
77 pbname_len = cc;
78 if (validate_pbname_7bit() < 0)
79 pbname_len = 0;
80 } else
81 pbname_len = 0;
82 } else
83 pbname_len = 0;
84 header_len = fields[3].num;
85 pdu_state = 1;
86 }
87
88 emit_pb_name()
89 {
90 u_char decoded_name[81];
91
92 gsm7_to_ascii_or_ext(pbname_gsm, pbname_len, decoded_name, 0, 0, 0, 0);
93 printf("Phonebook-Name: %s\n", decoded_name);
94 }
95
96 cmgl_pdu()
97 {
98 int cc;
99 unsigned sca_len;
100
101 cc = decode_hex_line(at_response+1, pdu_bin, sizeof pdu_bin);
102 if (cc < 1) {
103 fprintf(stderr, "error: expected PDU not received\n");
104 exit(ERROR_TARGET);
105 }
106 sca_len = pdu_bin[0];
107 if (1 + sca_len + header_len != cc) {
108 fprintf(stderr, "error: PDU length mismatch\n");
109 exit(ERROR_TARGET);
110 }
111 printf("%s message:\n", msgtype);
112 if (pbname_len)
113 emit_pb_name();
114 puts(at_response+1);
115 putchar('\n');
116 pdu_state = 0;
117 }
118
119 cmgl_callback()
120 {
121 if (pdu_state)
122 cmgl_pdu();
123 else
124 cmgl_header();
125 }
126
127 main(argc, argv)
128 char **argv;
129 {
130 int c;
131 extern int optind;
132
133 while ((c = getopt(argc, argv, "B:np:RX:")) != EOF)
134 if (!atinterf_cmdline_opt(c)) {
135 /* error msg already printed */
136 exit(ERROR_USAGE);
137 }
138 if (argc != optind) {
139 fprintf(stderr, "usage: %s [options]\n", argv[0]);
140 exit(ERROR_USAGE);
141 }
142 atinterf_init();
143 /* put the 07.05 modem in PDU mode */
144 atinterf_exec_cmd_needok("AT+CMGF=0", 0, 0);
145 /* HEX charset for phonebook names */
146 atinterf_exec_cmd_needok("AT+CSCS=\"HEX\"", 0, 0);
147 /* main command */
148 atinterf_exec_cmd_needok("AT+CMGL=4", 0, cmgl_callback);
149 if (pdu_state) {
150 fprintf(stderr, "error: wrong state at the end of +CMGL\n");
151 exit(ERROR_TARGET);
152 }
153 /* delete-after-dump will go here */
154 exit(0);
155 }