Skip to content

Commit 7d0ecb4

Browse files
committed
SFU support for OTA on SaraU210 module
Added new core librares to manage Sara flash support, by useing new MKRGSM's API to write and read from sara module for retrive file during OTA's procedure
1 parent 6e049f7 commit 7d0ecb4

File tree

19 files changed

+3845
-1
lines changed

19 files changed

+3845
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
#include "Modem.h"
2+
3+
#include "GSMFileUtils.h"
4+
5+
GSMFileUtils::GSMFileUtils(bool debug)
6+
: _count(0)
7+
, _files("")
8+
, _debug(debug)
9+
{
10+
}
11+
12+
bool GSMFileUtils::begin(const unsigned long timeout)
13+
{
14+
int status;
15+
16+
MODEM.begin();
17+
18+
if (_debug) {
19+
MODEM.debug();
20+
MODEM.send("AT+CMEE=2");
21+
MODEM.waitForResponse();
22+
}
23+
MODEM.send("AT+CMEE=2");
24+
MODEM.waitForResponse();
25+
26+
for (unsigned long start = millis(); (millis() - start) < timeout;) {
27+
status = _getFileList();
28+
if (status == 1) {
29+
_countFiles();
30+
return true;
31+
}
32+
MODEM.poll();
33+
}
34+
return false;
35+
}
36+
37+
int GSMFileUtils::_getFileList()
38+
{
39+
String response;
40+
41+
MODEM.send("AT+ULSTFILE=0");
42+
int status = MODEM.waitForResponse(5000, &response);
43+
if (!response.length())
44+
return -1;
45+
46+
if (status) {
47+
String list = response.substring(11);
48+
list.trim();
49+
_files = list;
50+
}
51+
52+
return status;
53+
}
54+
55+
void GSMFileUtils::_countFiles()
56+
{
57+
String list = _files;
58+
size_t len = 0;
59+
60+
if (list.length() > 0) {
61+
for (int index = list.indexOf(','); index != -1; index = list.indexOf(',')) {
62+
list.remove(0, index + 1);
63+
++len;
64+
}
65+
++len;
66+
}
67+
_count = len;
68+
}
69+
70+
size_t GSMFileUtils::listFiles(String files[]) const
71+
{
72+
String list = _files;
73+
int index;
74+
75+
if (_count == 0)
76+
return 0;
77+
78+
size_t n = 0;
79+
80+
for (index = list.indexOf(','); index != -1; index = list.indexOf(',')) {
81+
String file = list.substring(1, index - 1);
82+
files[n++] = file;
83+
list.remove(0, index + 1);
84+
}
85+
files[n++] = list.substring(1, list.lastIndexOf("\""));
86+
87+
return n;
88+
}
89+
90+
void GSMFileUtils::downloadFile(const String filename, const char buf[], uint32_t size, const bool append)
91+
{
92+
String response;
93+
94+
if (!append)
95+
deleteFile(filename);
96+
97+
MODEM.sendf("AT+UDWNFILE=\"%s\",%d", filename.c_str(), size * 2);
98+
MODEM.waitForPrompt(20000);
99+
100+
char hex[size * 2] { 0 };
101+
102+
for (auto i = 0; i < size; i++) {
103+
byte b = buf[i];
104+
105+
byte n1 = (b >> 4) & 0x0f;
106+
byte n2 = (b & 0x0f);
107+
108+
hex[i * 2] = (char)(n1 > 9 ? 'A' + n1 - 10 : '0' + n1);
109+
hex[i * 2 + 1] = (char)(n2 > 9 ? 'A' + n2 - 10 : '0' + n2);
110+
}
111+
for (auto h: hex)
112+
MODEM.write(h);
113+
114+
int status = MODEM.waitForResponse(1000, &response);
115+
116+
auto fileExists = _files.indexOf(filename) > 0;
117+
if (status && !fileExists) {
118+
_getFileList();
119+
_countFiles();
120+
}
121+
}
122+
123+
uint32_t GSMFileUtils::readFile(const String filename, String* content)
124+
{
125+
String response;
126+
127+
if (!listFile(filename)) {
128+
return 0;
129+
}
130+
131+
MODEM.sendf("AT+URDFILE=\"%s\"", filename.c_str());
132+
MODEM.waitForResponse(1000, &response);
133+
134+
size_t skip = 10;
135+
String _content = response.substring(skip);
136+
137+
int commaIndex = _content.indexOf(',');
138+
skip += commaIndex;
139+
140+
_content = _content.substring(commaIndex + 1);
141+
commaIndex = _content.indexOf(',');
142+
skip += commaIndex;
143+
144+
String sizePart = _content.substring(0, commaIndex);
145+
uint32_t size = sizePart.toInt() / 2;
146+
skip += 3;
147+
148+
String * _data = content;
149+
(*_data).reserve(size);
150+
151+
for (auto i = 0; i < size; i++) {
152+
byte n1 = response[skip + i * 2];
153+
byte n2 = response[skip + i * 2 + 1];
154+
155+
if (n1 > '9') {
156+
n1 = (n1 - 'A') + 10;
157+
} else {
158+
n1 = (n1 - '0');
159+
}
160+
161+
if (n2 > '9') {
162+
n2 = (n2 - 'A') + 10;
163+
} else {
164+
n2 = (n2 - '0');
165+
}
166+
167+
(*_data) += (char)((n1 << 4) | n2);
168+
}
169+
170+
return (*_data).length();
171+
}
172+
173+
uint32_t GSMFileUtils::readFile(const String filename, uint8_t* content)
174+
{
175+
String response;
176+
177+
if (listFile(filename) == 0) {
178+
return 0;
179+
}
180+
181+
MODEM.sendf("AT+URDFILE=\"%s\"", filename.c_str());
182+
MODEM.waitForResponse(1000, &response);
183+
184+
size_t skip = 10;
185+
String _content = response.substring(skip);
186+
187+
int commaIndex = _content.indexOf(',');
188+
skip += commaIndex;
189+
190+
_content = _content.substring(commaIndex + 1);
191+
commaIndex = _content.indexOf(',');
192+
skip += commaIndex;
193+
194+
String sizePart = _content.substring(0, commaIndex);
195+
uint32_t size = sizePart.toInt() / 2;
196+
skip += 3;
197+
198+
for (auto i = 0; i < size; i++) {
199+
byte n1 = response[skip + i * 2];
200+
byte n2 = response[skip + i * 2 + 1];
201+
202+
if (n1 > '9') {
203+
n1 = (n1 - 'A') + 10;
204+
} else {
205+
n1 = (n1 - '0');
206+
}
207+
208+
if (n2 > '9') {
209+
n2 = (n2 - 'A') + 10;
210+
} else {
211+
n2 = (n2 - '0');
212+
}
213+
214+
content[i] = (n1 << 4) | n2;
215+
}
216+
217+
return size;
218+
}
219+
220+
uint32_t GSMFileUtils::readBlock(const String filename, const uint32_t offset, const uint32_t len, uint8_t* content)
221+
{
222+
String response;
223+
224+
if (listFile(filename) == 0) {
225+
return 0;
226+
}
227+
228+
MODEM.sendf("AT+URDBLOCK=\"%s\",%d,%d", filename.c_str(), offset * 2, len * 2);
229+
MODEM.waitForResponse(1000, &response);
230+
231+
size_t skip = 10;
232+
String _content = response.substring(skip);
233+
234+
int commaIndex = _content.indexOf(',');
235+
skip += commaIndex;
236+
237+
_content = _content.substring(commaIndex + 1);
238+
commaIndex = _content.indexOf(',');
239+
skip += commaIndex;
240+
241+
String sizePart = _content.substring(0, commaIndex);
242+
uint32_t size = sizePart.toInt() / 2;
243+
skip += 3;
244+
245+
for (auto i = 0; i < size; i++) {
246+
byte n1 = response[skip + i * 2];
247+
byte n2 = response[skip + i * 2 + 1];
248+
249+
if (n1 > '9') {
250+
n1 = (n1 - 'A') + 10;
251+
} else {
252+
n1 = (n1 - '0');
253+
}
254+
255+
if (n2 > '9') {
256+
n2 = (n2 - 'A') + 10;
257+
} else {
258+
n2 = (n2 - '0');
259+
}
260+
261+
content[i] = (n1 << 4) | n2;
262+
}
263+
264+
return size;
265+
}
266+
267+
bool GSMFileUtils::deleteFile(const String filename)
268+
{
269+
String response;
270+
271+
if (listFile(filename) == 0)
272+
return false;
273+
274+
MODEM.sendf("AT+UDELFILE=\"%s\"", filename.c_str());
275+
auto status = MODEM.waitForResponse(100, &response);
276+
277+
if (status == 0)
278+
return false;
279+
280+
_getFileList();
281+
_countFiles();
282+
283+
return true;
284+
}
285+
286+
int GSMFileUtils::deleteFiles()
287+
{
288+
int n = 0;
289+
String files[_count];
290+
291+
listFiles(files);
292+
293+
while (_count > 0) {
294+
n += deleteFile(files[_count - 1]);
295+
}
296+
297+
return n;
298+
}
299+
300+
uint32_t GSMFileUtils::listFile(const String filename) const
301+
{
302+
String response;
303+
int res;
304+
uint32_t size = 0;
305+
306+
MODEM.sendf("AT+ULSTFILE=2,\"%s\"", filename.c_str());
307+
res = MODEM.waitForResponse(100, &response);
308+
if (res == 1) {
309+
String content = response.substring(11);
310+
size = content.toInt();
311+
}
312+
313+
return size / 2;
314+
}
315+
316+
uint32_t GSMFileUtils::freeSpace()
317+
{
318+
String response;
319+
int res;
320+
uint32_t size = 0;
321+
322+
MODEM.send("AT+ULSTFILE=1");
323+
res = MODEM.waitForResponse(100, &response);
324+
if (res == 1) {
325+
String content = response.substring(11);
326+
size = content.toInt();
327+
}
328+
329+
return size;
330+
}
331+
332+
void printFiles(const GSMFileUtils fu)
333+
{
334+
auto count { fu.fileCount() };
335+
String files[count];
336+
337+
Serial.print(count);
338+
Serial.print(count == 1 ? " file" : " files");
339+
Serial.println(" found.");
340+
341+
fu.listFiles(files);
342+
343+
for (auto f : files) {
344+
Serial.print("File ");
345+
Serial.print(f);
346+
Serial.print(" - Size: ");
347+
Serial.print(fu.listFile(f));
348+
Serial.println();
349+
}
350+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include <Arduino.h>
4+
5+
6+
class GSMFileUtils {
7+
public:
8+
GSMFileUtils(bool debug = false);
9+
10+
bool begin(const unsigned long timeout);
11+
bool begin() { return begin(10000); };
12+
uint32_t fileCount() const { return _count; };
13+
size_t listFiles(String list[]) const;
14+
uint32_t listFile(const String filename) const;
15+
16+
void downloadFile(const String filename, const char buf[], const uint32_t size, const bool append);
17+
void downloadFile(const String filename, const char buf[], const uint32_t size) { downloadFile(filename, buf, size, false); };
18+
void downloadFile(const String filename, const String& buf) { downloadFile(filename, buf.c_str(), buf.length(), false); }
19+
20+
void appendFile(const String filename, const String& buf) { downloadFile(filename, buf.c_str(), buf.length(), true); }
21+
void appendFile(const String filename, const char buf[], const uint32_t size) { downloadFile(filename, buf, size, true); }
22+
23+
bool deleteFile(const String filename);
24+
int deleteFiles();
25+
26+
uint32_t readFile(const String filename, String* content);
27+
uint32_t readFile(const String filename, uint8_t* content);
28+
// size_t readBlock(const String filename, String* content, const bool binary = false);
29+
uint32_t readBlock(const String filename, const uint32_t offset, const uint32_t len, uint8_t* content);
30+
31+
uint32_t freeSpace();
32+
33+
private:
34+
int _count;
35+
String _files;
36+
37+
bool _debug;
38+
39+
void _countFiles();
40+
int _getFileList();
41+
42+
};
43+
44+
void printFiles(const GSMFileUtils fileUtils);

0 commit comments

Comments
 (0)