Skip to content

Commit 103ac38

Browse files
committed
Add GSMFilesystem APIs
1 parent 47e64f0 commit 103ac38

File tree

2 files changed

+295
-0
lines changed

2 files changed

+295
-0
lines changed

src/GSMFileUtils.cpp

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
#include "Modem.h"
2+
3+
#include "GSMFileUtils.h"
4+
5+
GSMFileUtils::GSMFileUtils(bool debug):
6+
_count(0),
7+
_files(""),
8+
_fileTags{"USER", "FOAT", "PROFILE"}
9+
{
10+
if (debug) {
11+
MODEM.debug();
12+
}
13+
}
14+
15+
void GSMFileUtils::begin(unsigned long int timeout)
16+
{
17+
int status;
18+
19+
MODEM.begin();
20+
21+
for (unsigned long start = millis(); (millis() - start) < timeout;) {
22+
status = _getFileList();
23+
if (status == 1) {
24+
_countFiles();
25+
return;
26+
}
27+
MODEM.poll();
28+
}
29+
30+
Serial.println("Unable to read files.");
31+
while(true) {}
32+
}
33+
34+
int GSMFileUtils::_getFileList()
35+
{
36+
String response;
37+
38+
MODEM.send("AT+ULSTFILE");
39+
int status = MODEM.waitForResponse(5000, &response);
40+
if (!response.length())
41+
return -1;
42+
43+
if (status) {
44+
String list = response.substring(11);
45+
list.trim();
46+
_files = list;
47+
}
48+
49+
return status;
50+
}
51+
52+
void GSMFileUtils::_countFiles()
53+
{
54+
String list = _files;
55+
size_t len = 0;
56+
57+
if (list.length() > 0) {
58+
for(int index = list.indexOf(','); index != -1; index = list.indexOf(',')) {
59+
list.remove(0, index + 1);
60+
++len;
61+
}
62+
++len;
63+
}
64+
_count = len;
65+
}
66+
67+
void GSMFileUtils::listFiles(String files[]) const
68+
{
69+
String list = _files;
70+
int index;
71+
72+
if (_count == 0)
73+
return;
74+
75+
size_t n = 0;
76+
77+
for(index = list.indexOf(','); index != -1; index = list.indexOf(',')) {
78+
String file = list.substring(1, index - 1);
79+
files[n++] = file;
80+
list.remove(0, index + 1);
81+
}
82+
files[n++] = list.substring(1, list.lastIndexOf("\""));
83+
}
84+
85+
void GSMFileUtils::downloadFile(const String filename, const char buf[], size_t size, GSM_fileTags_t tag, const bool binary, const bool append)
86+
{
87+
String response;
88+
bool fileExists = listFile(filename) > 0;
89+
90+
if (fileExists && !append)
91+
deleteFile(filename);
92+
93+
if (binary) {
94+
MODEM.send("ATE0");
95+
MODEM.waitForResponse();
96+
}
97+
98+
MODEM.sendf("AT+UDWNFILE=\"%s\",%d,\"%s\"", filename.c_str(), size, _fileTags[tag]);
99+
MODEM.waitForPrompt(20000);
100+
101+
for (size_t i = 0; i < size; i++)
102+
MODEM.write(buf[i]);
103+
104+
int status = MODEM.waitForResponse(1000, &response);
105+
106+
if (status && !append) {
107+
if (_count == 0)
108+
_files.concat("\"" + filename + "\"");
109+
else
110+
_files.concat(",\"" + filename + "\"");
111+
_count++;
112+
}
113+
114+
if (binary) {
115+
MODEM.send("ATE1");
116+
MODEM.waitForResponse();
117+
}
118+
}
119+
120+
void GSMFileUtils::fwUpdate() {
121+
// TODO: check if there is a FW with FOAT tag
122+
MODEM.sendf("AT+UFWINSTALL");
123+
MODEM.waitForPrompt(60000);
124+
}
125+
126+
size_t GSMFileUtils::readFile(const String filename, String *content, const bool binary)
127+
{
128+
String response;
129+
130+
if (!listFile(filename)){
131+
Serial.println("File does not exist.");
132+
return 0;
133+
}
134+
135+
if (binary)
136+
MODEM.binary();
137+
138+
MODEM.sendf("AT+URDFILE=\"%s\"", filename.c_str());
139+
MODEM.waitForResponse(1000, &response);
140+
141+
size_t skip = 10;
142+
String _content = response.substring(skip);
143+
int commaIndex = _content.indexOf(',');
144+
skip += commaIndex;
145+
146+
_content = _content.substring(commaIndex + 1);
147+
commaIndex = _content.indexOf(',');
148+
skip += commaIndex;
149+
150+
String sizePart = _content.substring(0, commaIndex);
151+
size_t size = sizePart.toInt();
152+
skip += 3;
153+
154+
if (binary) {
155+
(*content).reserve(size);
156+
*content = "";
157+
for (size_t i = 0; i < size; i++) {
158+
*content += response[skip + i];
159+
}
160+
} else {
161+
_content = _content.substring(commaIndex + 2);
162+
*content = _content.substring(0, size);
163+
}
164+
165+
if (binary)
166+
MODEM.noBinary();
167+
return size;
168+
}
169+
170+
int GSMFileUtils::deleteFile(const String filename)
171+
{
172+
String response;
173+
174+
int start = _files.indexOf(filename);
175+
int count = filename.length();
176+
if (start == 1) {
177+
start = 0;
178+
count += 3;
179+
} else {
180+
start -= 2;
181+
count += 3;
182+
}
183+
184+
MODEM.sendf("AT+UDELFILE=\"%s\"", filename.c_str());
185+
if (MODEM.waitForResponse(100, &response)){
186+
_files.remove(start, count);
187+
_count--;
188+
return 1;
189+
}
190+
return 0;
191+
}
192+
193+
int GSMFileUtils::deleteFiles()
194+
{
195+
int n = 0;
196+
String files[_count];
197+
198+
listFiles(files);
199+
200+
while (_count > 0) {
201+
n += deleteFile(files[_count - 1]);
202+
}
203+
204+
return n;
205+
}
206+
207+
size_t GSMFileUtils::listFile(const String filename)
208+
{
209+
String response;
210+
int res;
211+
size_t size = 0;
212+
213+
MODEM.sendf("AT+ULSTFILE=2,\"%s\"", filename.c_str());
214+
res = MODEM.waitForResponse(100, &response);
215+
if (res == 1) {
216+
String content = response.substring(11);
217+
size = content.toInt();
218+
}
219+
220+
return size;
221+
}
222+
223+
size_t GSMFileUtils::freeSpace()
224+
{
225+
String response;
226+
int res;
227+
size_t size = 0;
228+
229+
MODEM.send("AT+ULSTFILE=1");
230+
res = MODEM.waitForResponse(100, &response);
231+
if (res == 1) {
232+
String content = response.substring(11);
233+
size = content.toInt();
234+
}
235+
236+
return size;
237+
}
238+
239+
void listFiles(const GSMFileUtils fu)
240+
{
241+
// TODO: Print files sizes
242+
243+
int count = fu.fileCount();
244+
String files[count];
245+
246+
Serial.println(String(count) + " files found.");
247+
fu.listFiles(files);
248+
for (int i = 0; i < count; i++)
249+
Serial.println("File " + String(i + 1) + ": " + files[i]);
250+
}

src/GSMFileUtils.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ifndef _GSM_FILEUTILS_H_INCLUDED
2+
#define _GSM_FILEUTILS_H_INCLUDED
3+
4+
#include <Arduino.h>
5+
6+
enum GSM_fileTags_t {
7+
USER = 0,
8+
FOAT = 1,
9+
PROFILE = 2
10+
};
11+
12+
class GSMFileUtils {
13+
public:
14+
GSMFileUtils(bool debug = false);
15+
16+
void begin(unsigned long timeout = 10000);
17+
size_t fileCount() const { return _count; };
18+
void listFiles(String list[]) const;
19+
size_t listFile(const String filename);
20+
21+
void downloadFile(const String filename, const char buf[], const size_t size, const GSM_fileTags_t tag = USER, const bool binary = false, const bool append = false);
22+
void downloadFile(const String filename, const String &buf, const GSM_fileTags_t tag = USER, const bool binary = false, const bool append = false) { downloadFile(filename, buf.c_str(), buf.length(), tag, binary, append); }
23+
void downloadBinary(const String filename, const char buf[], const size_t size, const GSM_fileTags_t tag = USER, const bool append = false) { downloadFile(filename, buf, size, tag, true, append); }
24+
void downloadBinary(const String filename, const String &buf, const GSM_fileTags_t tag = USER, const bool append = false) { downloadFile(filename, buf.c_str(), buf.length(), tag, true, append); }
25+
26+
int deleteFile(const String filename);
27+
int deleteFiles();
28+
29+
size_t readFile(const String filename, String *content, const bool binary = false);
30+
size_t readBinary(const String filename, String *content) { return readFile(filename, content, true); }
31+
32+
void fwUpdate();
33+
size_t freeSpace();
34+
35+
private:
36+
int _count;
37+
String _files;
38+
const char *_fileTags[3];
39+
void _countFiles();
40+
int _getFileList();
41+
};
42+
43+
void listFiles(const GSMFileUtils fileUtils);
44+
45+
#endif

0 commit comments

Comments
 (0)