LoRa Basics Modem and LoRa Edge documentation

Component - Large File Upload

Introduction

The Large File Upload (LFU) service, available as part of the LoRa Cloud™ Device & Application Services, is a fragmentation and reassembly service that is useful when the device backhaul has a very low-throughput and can’t accept large amounts of data all at one time. It can also handle the variable MTU of LoRaWAN® networks, so it can be used with any adaptive data rate (ADR) strategy.

Once reassembled in the back-end LoRa Cloud Device & Application Services, the large file will be delivered to the application server through an API call. The LFU adds Forward Error Correction to the file to be transferred, which compensates for lost packets.

Prerequisites

Common:

  • The device is connected to its application server, typically over a LoRaWAN network

  • The application server forwards messages on a configured Device Management FPort (FPort 199 by default) to das.loracloud.com.

Prerequisites for LoRa Basics Modem:

  • Maximum file size is 8 KB

Prerequisites for LoRa Basics Modem-E:

  • Maximum file size is 2 KB

Step-by-Step Procedure

  1. Initiate the Large File Upload session via the UploadInit() command, specifying the following parameters:

    1. Select plain text or encrypted with the AppSKey. (The file will be processed as cipher text by the LoRa Cloud Device & Application Services if it is encrypted).

    2. Determine the FPort to send the file to.

    3. Set the size of the file in Bytes.

    4. Set a reasonable delay, in seconds, between transmitted frames (in accordance with your connectivity plan). Local duty-cycle restrictions will be enforced by the modem.

  2. Load the file to be transferred by invoking UploadData() with chunk(s) of 255 bytes or less.

  3. Launch the file upload with the UploadStart() command, providing the expected CRC.

  4. In the event of an error, the command will return one of the following codes.

    1. BadSize: indicates a file size other than that declared with UploadInit().

    2. BadSig: indicates that the file integrity could not be verified against the CRC provided.

    3. Busy : indicates that a file upload session is already in progress.

  5. The file upload starts. For details see In-depth Behavior.

  6. Once the upload completes:

    • The LoRa Cloud Device & Application Services will provide the reassembled file in the UPLINK_RESPONSE JSON object.

    • The modem generates an UploadDone event.

Note

  • The LFU FPort is an internal index to the file upload. It differs from the LoRaWAN FPort. All values [0:255] may be used. Data is still transmitted on the DM FPort (default: 199).

  • To cancel the current file upload session call UploadInit() again, using the same port but setting the size value to 0.

Sample code

End-Device Application

#include "lr1110_modem_lorawan.h"

// Initialize file upload
uint8_t data_to_send[300] = {0};
lr1110_modem_upload_init(
      &context,
      0,        // LFU internal port
      LR1110_MODEM_FILE_ENCRYPTION_DISABLE,
      300,      // File size
      5*60      // Delay between fragments (sec)
);

// Send all the data
lr1110_modem_upload_data( &context, data_to_send, 255 );
lr1110_modem_upload_data( &context, data_to_send + 255, 45 );

// Start the upload
uint32_t crc = compute_crc( data_to_send );
lr1110_modem_upload_start( &context, crc );

// Modem event call-back
customer_event_callback_upload_done(  ) {
   printf( "LFU completed\n" );
}

Application Server

Pseudocode to get a file after the LoRa Cloud Device & Application Services reassembles it:

# Call the LoRa Cloud Device & Application Services and get the answer to an uplink
res = call_das_device_send(uplink)  # /api/v1/device/send

# Extract file array, if any
if ( res["uplink"]["file"] != None ):
   file = res["uplink"]["file"]
   print( f'File port={file["port"]}  -  data: 0x{file["data"]}' )

Pseudocode to get the last eight (8) files stored in the LoRa Cloud Device & Application Services from the device_info API:

# Call the LoRa Cloud Device & Application Services to query device information
res = call_das_device_info( devEUI )  # /api/v1/device/info
res = res["result"][devEUI]

# Extract file array, if any
if ( res["result"]["file"] != None ):
   for file in res["result"]["uploaded_files"]:
      print( f'File port={file["port"]}  -  data: 0x{file["data"]}' )

Pseudocode to get the last eight (8) files stored in the LoRa Cloud Device & Application Services from the fetch file upload API. This API will also clear the file upload history on the server:

# Call the LoRa Cloud Device & Application Services to query device information
res = call_das_file_uploads_fetch( devEUI )  # /api/v1/uploads/fetch
res = res["result"][devEUI]

# Extract file array, if any
if ( res["file"] != None ):
   for file in res["result"]["uploaded_files"]:
      print( f'File port={file["port"]}  -  data: 0x{file["data"]}' )

In-depth Behavior

  1. The Forward Error Correction feature of the Large File Upload service eliminates the need for each fragment to be acknowledged.

  2. If a Large File Upload is being processed, this is indicated in the Upload flag of the modem status messages.

  3. When the upload stream stops, an UploadDone event is generated. This event carries a status byte indicating Success or Timeout.

  4. The Timeout status is issued when twice the number of uplink packets have been sent, which corresponds to a Forward Error Correction algorithm with a Code Rate equal to 1/2; in other words the data is repeated twice.

Note

If EncryptMode = 1, the file is delivered to the application server encrypted with the AppSKey of the LoRaWAN session. Otherwise, it is transferred as plain text.

@startumltitle Simplified Flow for\nLarge File Uploadskinparam linetype orthobox Deviceparticipant "End-Device\nApplication" as UC #99FF99participant "modem" as MODEMend boxbox Serversparticipant "Customer\nApplication Server" as AS #99FF99participant "LoRaCloud\nDAS" as DASend boxUC -> MODEM : UploadInit( lfu_port, plain/cyphered, size, delay)Loop Transfer file to modem    note right of UC: Until all 'size' bytes of the file are transferred    UC -> MODEM : UploadData( max 255 bytes by call )end== Start of a Successful Upload Session ==UC -> MODEM ++: UploadStart( fileCrc )Loop Modem sends file fragments    MODEM -> AS : Uplinks with file fragments    AS -> DAS : File fragmentsendDAS -> AS : Reconstructed file,\ndownlink for the modemAS -> MODEM: Downlink for the modemMODEM -> MODEM: Stop sending framentsreturn Notify the applicative MCU\nEvent upload done = 1== End of a Successful Upload Session ==== Start of a Failed Upload Session ==UC -> MODEM ++: UploadStart( fileCrc )Loop Modem sends file fragments    note right of MODEM: Twice the number of fragments are sent    MODEM -> AS : Uplinks with file fragments    AS -> DAS : File fragmentsendMODEM -> MODEM: Abort File Uploadreturn Notify the applicative MCU\nEvent upload done = 0== End of a Failed Upload Session ==@enduml

Used by

Applications

References