Skip to content

Commit

Permalink
Merge pull request #113 from manchoz/manchoz_file_utils
Browse files Browse the repository at this point in the history
Add support for SARA U2 Filesystem
  • Loading branch information
aentinger authored Jun 26, 2020
2 parents 031723d + 93fc09c commit 5e913f1
Show file tree
Hide file tree
Showing 9 changed files with 997 additions and 0 deletions.
217 changes: 217 additions & 0 deletions examples/Tools/FileUtilsHttpDownload/FileUtilsHttpDownload.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/*
Download large file and store it into the GSM module filesystem.
This sketch connects to a website through a MKR GSM 1400 board and
downloads a large file and stores it into the filesystem of the GSM
module.
The file is processed in blocks of 512 bytes in order to save RAM.
A block of data is read from the GSM module and the appended to a
file created by the sketch.
Circuit:
* MKR GSM 1400 board
* Antenna
* SIM card with a data plan
created 19 June 2020
by Giampaolo Mancini
*/

// libraries
#include <MKRGSM.h>

GSMFileUtils fileUtils(false);

#include "Helpers.h"

#include "arduino_secrets.h"
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[] = SECRET_PINNUMBER;
// APN data
const char GPRS_APN[] = SECRET_GPRS_APN;
const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN;
const char GPRS_PASSWORD[] = SECRET_GPRS_PASSWORD;

// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess;

// URL, path and port (for example: example.org)

void setup()
{
// initialize serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

Serial.println("Starting Arduino web client.");

fileUtils.begin();

// List files on the GSM module's filesystem
auto numberOfFiles = fileUtils.fileCount();
Serial.print("Number of Files: ");
Serial.println(numberOfFiles);
Serial.println();

printFiles(fileUtils);

auto server = promptAndReadLine("Please, enter server name:", "arduino.cc");
auto port = promptAndReadInt("Please, enter server port:", 80);
auto filename = promptAndReadLine("Please, enter file name:", "asciilogo.txt");
auto filesize = promptAndReadInt("Please, enter file size:", 2263);
Serial.println("Connecting...");

// connection state
bool connected = false;

// After starting the modem with GSM.begin()
// attach the shield to the GPRS network with the APN, login and password
while (!connected) {
if ((gsmAccess.begin(PINNUMBER) == GSM_READY) && (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
connected = true;
} else {
Serial.println("Not connected");
delay(1000);
}
}

// if you get a connection, report back via serial:
if (client.connect(server.c_str(), port)) {
Serial.println("connected");
// Make a HTTP request:
client.print("GET /");
client.print(filename);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Connection: close");
client.println();
} else {
// if you didn't get a connection to the server:
Serial.println("Connection failed");
}

// Download and store block-by-block
storeFileBuffered(filename, filesize);

auto updateBinSize = fileUtils.listFile(filename);
Serial.print(filename);
Serial.print(" downloaded size: ");
Serial.println(updateBinSize);

numberOfFiles = fileUtils.fileCount();
Serial.print("Number of Files: ");
Serial.println(numberOfFiles);
Serial.println();

printFiles(fileUtils);

}

void loop()
{
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char r = client.read();
if (r < 16)
Serial.print(0);
Serial.print(r, HEX);

}

// if the server's disconnected, stop the client:
if (!client.available() && !client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();

// do nothing forevermore:
for (;;)
;
}
}

void storeFileBuffered(String filename, uint32_t totalLen)
{
Serial.print("Ready to download \"");
Serial.print(filename);
Serial.print("\" - len: ");
Serial.print(totalLen);
Serial.println(" bytes.");

constexpr uint32_t len { 512 };

uint32_t cycles = totalLen / len;
uint32_t spares = totalLen % len;

int totalRead { 0 };

fileUtils.deleteFile(filename);

Serial.print("Saving file in ");
Serial.print(cycles + 1);
Serial.print(" blocks. [");
Serial.print(cycles);
Serial.print(' ');
Serial.print(len);
Serial.print(" -bytes blocks and ");
Serial.print(spares);
Serial.println(" bytes].");

bool is_header_complete = false;
String http_header;

// Skip the HTTP header
while (!is_header_complete) {
while (client.available()) {
const char c = client.read();
http_header += c;
if (http_header.endsWith("\r\n\r\n")) {
Serial.println("Header Complete");
is_header_complete = true;
break;
}
}
}

// Define download and save lambda
auto downloadAndSaveTrunk = [filename](uint32_t len) {
char buf[len] { 0 };
uint32_t written { 0 };

if (client.available())
written = client.readBytes(buf, len);

fileUtils.appendFile(filename, buf, written);
return written;
};

// Define wrapper function
auto saveTrunk = [&totalRead, downloadAndSaveTrunk](size_t iter, uint32_t len) {
Serial.print("Block ");
if (iter < 10) Serial.print(' '); if (iter < 100) Serial.print(' ');
Serial.print(iter);

totalRead += downloadAndSaveTrunk(len);

Serial.print(": ");
Serial.print(len);
Serial.print(" - ");
Serial.print(totalRead);
Serial.println();
};

// Download and save complete trunks + spares
for (auto c = 0; c <= cycles; c++)
saveTrunk(c, len);

Serial.println();

}
124 changes: 124 additions & 0 deletions examples/Tools/FileUtilsHttpDownload/Helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#pragma once
#include <Arduino.h>

String readLine()
{
String line;

while (1)
{
if (Serial.available())
{
char c = Serial.read();

if (c == '\r')
{
// ignore
}
else if (c == '\n')
{
break;
}

line += c;
}
}

line.trim();

return line;
}

String promptAndReadLine(const char* prompt, const char* defaultValue) {
Serial.print(prompt);
Serial.print(" [");
Serial.print(defaultValue);
Serial.print("]: ");

String s = readLine();

if (s.length() == 0) {
s = defaultValue;
}

Serial.println(s);

return s;
}

int promptAndReadInt(const char* prompt, const int defaultValue) {
Serial.print(prompt);
Serial.print(" [");
Serial.print(defaultValue);
Serial.print("]: ");

String s = readLine();
int r;

if (s.length() == 0) {
r = defaultValue;
} else {
r = s.toInt();
}

Serial.println(r);

return r;
}

String promptAndReadLine(const char *prompt)
{
Serial.print(prompt);
String s = readLine();
Serial.println(s);

return s;
}

int promptAndReadInt(const char *prompt)
{
Serial.print(prompt);
String s = readLine();
Serial.println(s);

return s.toInt();
}


String toHex(char c)
{
String hex;

hex = "0x";
if (c < 16)
hex += "0";
hex += String(c, HEX);

return hex;
}

void printHex(const String& buf, const unsigned int cols)
{
for (size_t i = 0; i < buf.length(); i++) {
String hex = toHex(buf[i]);
hex += " ";
Serial.print(hex);
if (i % cols == (cols - 1))
Serial.println();
}
Serial.println();
}

void printHex(const uint8_t* buf, const size_t len, const unsigned int cols)
{
for (size_t i = 0; i < len; i++) {
// Serial.print("0x");
if (buf[i] < 16)
Serial.print(0);
Serial.print(buf[i], HEX);
// if (i != len - 1) Serial.print(", ");
if (i % cols == (cols - 1))
Serial.println();
}
Serial.println();
}
4 changes: 4 additions & 0 deletions examples/Tools/FileUtilsHttpDownload/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define SECRET_PINNUMBER ""
#define SECRET_GPRS_APN "GPRS_APN" // replace your GPRS APN
#define SECRET_GPRS_LOGIN "login" // replace with your GPRS login
#define SECRET_GPRS_PASSWORD "password" // replace with your GPRS password
Loading

0 comments on commit 5e913f1

Please sign in to comment.