Skip to content

Commit 5e913f1

Browse files
authored
Merge pull request #113 from manchoz/manchoz_file_utils
Add support for SARA U2 Filesystem
2 parents 031723d + 93fc09c commit 5e913f1

File tree

9 files changed

+997
-0
lines changed

9 files changed

+997
-0
lines changed
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/*
2+
Download large file and store it into the GSM module filesystem.
3+
4+
This sketch connects to a website through a MKR GSM 1400 board and
5+
downloads a large file and stores it into the filesystem of the GSM
6+
module.
7+
8+
The file is processed in blocks of 512 bytes in order to save RAM.
9+
A block of data is read from the GSM module and the appended to a
10+
file created by the sketch.
11+
12+
Circuit:
13+
* MKR GSM 1400 board
14+
* Antenna
15+
* SIM card with a data plan
16+
17+
created 19 June 2020
18+
by Giampaolo Mancini
19+
*/
20+
21+
// libraries
22+
#include <MKRGSM.h>
23+
24+
GSMFileUtils fileUtils(false);
25+
26+
#include "Helpers.h"
27+
28+
#include "arduino_secrets.h"
29+
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
30+
// PIN Number
31+
const char PINNUMBER[] = SECRET_PINNUMBER;
32+
// APN data
33+
const char GPRS_APN[] = SECRET_GPRS_APN;
34+
const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN;
35+
const char GPRS_PASSWORD[] = SECRET_GPRS_PASSWORD;
36+
37+
// initialize the library instance
38+
GSMClient client;
39+
GPRS gprs;
40+
GSM gsmAccess;
41+
42+
// URL, path and port (for example: example.org)
43+
44+
void setup()
45+
{
46+
// initialize serial communications and wait for port to open:
47+
Serial.begin(9600);
48+
while (!Serial) {
49+
; // wait for serial port to connect. Needed for native USB port only
50+
}
51+
52+
Serial.println("Starting Arduino web client.");
53+
54+
fileUtils.begin();
55+
56+
// List files on the GSM module's filesystem
57+
auto numberOfFiles = fileUtils.fileCount();
58+
Serial.print("Number of Files: ");
59+
Serial.println(numberOfFiles);
60+
Serial.println();
61+
62+
printFiles(fileUtils);
63+
64+
auto server = promptAndReadLine("Please, enter server name:", "arduino.cc");
65+
auto port = promptAndReadInt("Please, enter server port:", 80);
66+
auto filename = promptAndReadLine("Please, enter file name:", "asciilogo.txt");
67+
auto filesize = promptAndReadInt("Please, enter file size:", 2263);
68+
Serial.println("Connecting...");
69+
70+
// connection state
71+
bool connected = false;
72+
73+
// After starting the modem with GSM.begin()
74+
// attach the shield to the GPRS network with the APN, login and password
75+
while (!connected) {
76+
if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
77+
connected = true;
78+
} else {
79+
Serial.println("Not connected");
80+
delay(1000);
81+
}
82+
}
83+
84+
// if you get a connection, report back via serial:
85+
if (client.connect(server.c_str(), port)) {
86+
Serial.println("connected");
87+
// Make a HTTP request:
88+
client.print("GET /");
89+
client.print(filename);
90+
client.println(" HTTP/1.1");
91+
client.print("Host: ");
92+
client.println(server);
93+
client.println("Connection: close");
94+
client.println();
95+
} else {
96+
// if you didn't get a connection to the server:
97+
Serial.println("Connection failed");
98+
}
99+
100+
// Download and store block-by-block
101+
storeFileBuffered(filename, filesize);
102+
103+
auto updateBinSize = fileUtils.listFile(filename);
104+
Serial.print(filename);
105+
Serial.print(" downloaded size: ");
106+
Serial.println(updateBinSize);
107+
108+
numberOfFiles = fileUtils.fileCount();
109+
Serial.print("Number of Files: ");
110+
Serial.println(numberOfFiles);
111+
Serial.println();
112+
113+
printFiles(fileUtils);
114+
115+
}
116+
117+
void loop()
118+
{
119+
// if there are incoming bytes available
120+
// from the server, read them and print them:
121+
if (client.available()) {
122+
char r = client.read();
123+
if (r < 16)
124+
Serial.print(0);
125+
Serial.print(r, HEX);
126+
127+
}
128+
129+
// if the server's disconnected, stop the client:
130+
if (!client.available() && !client.connected()) {
131+
Serial.println();
132+
Serial.println("disconnecting.");
133+
client.stop();
134+
135+
// do nothing forevermore:
136+
for (;;)
137+
;
138+
}
139+
}
140+
141+
void storeFileBuffered(String filename, uint32_t totalLen)
142+
{
143+
Serial.print("Ready to download \"");
144+
Serial.print(filename);
145+
Serial.print("\" - len: ");
146+
Serial.print(totalLen);
147+
Serial.println(" bytes.");
148+
149+
constexpr uint32_t len { 512 };
150+
151+
uint32_t cycles = totalLen / len;
152+
uint32_t spares = totalLen % len;
153+
154+
int totalRead { 0 };
155+
156+
fileUtils.deleteFile(filename);
157+
158+
Serial.print("Saving file in ");
159+
Serial.print(cycles + 1);
160+
Serial.print(" blocks. [");
161+
Serial.print(cycles);
162+
Serial.print(' ');
163+
Serial.print(len);
164+
Serial.print(" -bytes blocks and ");
165+
Serial.print(spares);
166+
Serial.println(" bytes].");
167+
168+
bool is_header_complete = false;
169+
String http_header;
170+
171+
// Skip the HTTP header
172+
while (!is_header_complete) {
173+
while (client.available()) {
174+
const char c = client.read();
175+
http_header += c;
176+
if (http_header.endsWith("\r\n\r\n")) {
177+
Serial.println("Header Complete");
178+
is_header_complete = true;
179+
break;
180+
}
181+
}
182+
}
183+
184+
// Define download and save lambda
185+
auto downloadAndSaveTrunk = [filename](uint32_t len) {
186+
char buf[len] { 0 };
187+
uint32_t written { 0 };
188+
189+
if (client.available())
190+
written = client.readBytes(buf, len);
191+
192+
fileUtils.appendFile(filename, buf, written);
193+
return written;
194+
};
195+
196+
// Define wrapper function
197+
auto saveTrunk = [&totalRead, downloadAndSaveTrunk](size_t iter, uint32_t len) {
198+
Serial.print("Block ");
199+
if (iter < 10) Serial.print(' '); if (iter < 100) Serial.print(' ');
200+
Serial.print(iter);
201+
202+
totalRead += downloadAndSaveTrunk(len);
203+
204+
Serial.print(": ");
205+
Serial.print(len);
206+
Serial.print(" - ");
207+
Serial.print(totalRead);
208+
Serial.println();
209+
};
210+
211+
// Download and save complete trunks + spares
212+
for (auto c = 0; c <= cycles; c++)
213+
saveTrunk(c, len);
214+
215+
Serial.println();
216+
217+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#pragma once
2+
#include <Arduino.h>
3+
4+
String readLine()
5+
{
6+
String line;
7+
8+
while (1)
9+
{
10+
if (Serial.available())
11+
{
12+
char c = Serial.read();
13+
14+
if (c == '\r')
15+
{
16+
// ignore
17+
}
18+
else if (c == '\n')
19+
{
20+
break;
21+
}
22+
23+
line += c;
24+
}
25+
}
26+
27+
line.trim();
28+
29+
return line;
30+
}
31+
32+
String promptAndReadLine(const char* prompt, const char* defaultValue) {
33+
Serial.print(prompt);
34+
Serial.print(" [");
35+
Serial.print(defaultValue);
36+
Serial.print("]: ");
37+
38+
String s = readLine();
39+
40+
if (s.length() == 0) {
41+
s = defaultValue;
42+
}
43+
44+
Serial.println(s);
45+
46+
return s;
47+
}
48+
49+
int promptAndReadInt(const char* prompt, const int defaultValue) {
50+
Serial.print(prompt);
51+
Serial.print(" [");
52+
Serial.print(defaultValue);
53+
Serial.print("]: ");
54+
55+
String s = readLine();
56+
int r;
57+
58+
if (s.length() == 0) {
59+
r = defaultValue;
60+
} else {
61+
r = s.toInt();
62+
}
63+
64+
Serial.println(r);
65+
66+
return r;
67+
}
68+
69+
String promptAndReadLine(const char *prompt)
70+
{
71+
Serial.print(prompt);
72+
String s = readLine();
73+
Serial.println(s);
74+
75+
return s;
76+
}
77+
78+
int promptAndReadInt(const char *prompt)
79+
{
80+
Serial.print(prompt);
81+
String s = readLine();
82+
Serial.println(s);
83+
84+
return s.toInt();
85+
}
86+
87+
88+
String toHex(char c)
89+
{
90+
String hex;
91+
92+
hex = "0x";
93+
if (c < 16)
94+
hex += "0";
95+
hex += String(c, HEX);
96+
97+
return hex;
98+
}
99+
100+
void printHex(const String& buf, const unsigned int cols)
101+
{
102+
for (size_t i = 0; i < buf.length(); i++) {
103+
String hex = toHex(buf[i]);
104+
hex += " ";
105+
Serial.print(hex);
106+
if (i % cols == (cols - 1))
107+
Serial.println();
108+
}
109+
Serial.println();
110+
}
111+
112+
void printHex(const uint8_t* buf, const size_t len, const unsigned int cols)
113+
{
114+
for (size_t i = 0; i < len; i++) {
115+
// Serial.print("0x");
116+
if (buf[i] < 16)
117+
Serial.print(0);
118+
Serial.print(buf[i], HEX);
119+
// if (i != len - 1) Serial.print(", ");
120+
if (i % cols == (cols - 1))
121+
Serial.println();
122+
}
123+
Serial.println();
124+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#define SECRET_PINNUMBER ""
2+
#define SECRET_GPRS_APN "GPRS_APN" // replace your GPRS APN
3+
#define SECRET_GPRS_LOGIN "login" // replace with your GPRS login
4+
#define SECRET_GPRS_PASSWORD "password" // replace with your GPRS password

0 commit comments

Comments
 (0)