Sending and reception of big data file (1kB example)

Dependencies:   modem_ref_helper CRC DebouncedInterrupt

Revision:
15:9a9cfb0c3c4e
Parent:
14:a0241090f967
Child:
16:2990b7d21ca2
--- a/main.cpp	Thu May 28 09:08:51 2020 +0000
+++ b/main.cpp	Wed Feb 17 11:11:23 2021 +0000
@@ -2,31 +2,20 @@
 // @date: 2017-12-14
 
 #include "DebouncedInterrupt.h"
-#include "modem_ref_helper.h"
+#include "modem_d7a.h"
 #include "modem_callbacks.h"
 #include "files.h"
 #include "crc.h"
 
-#define MIN(a,b)                ((a<b)?a:b)
-
 #define CHUNK_SIZE              128
 
 Semaphore button_user(0);
 Semaphore modem_ready(0);
-Queue<void, 8> modem_resp[MAX_USER_NB];
 Queue<touch_t, 8> g_file_modified;
 
-enum {
-    MODEM_RESP_NO,
-    MODEM_RESP_TERMINAL,
-    MODEM_RESP_ERROR,
-    MODEM_RESP_ACK,
-    MODEM_RESP_TIMEOUT,
-};
-
 // This describe the upload interface
 // Do not modify uncommented parameters
-alp_itf_d7a_cfg_t my_itf = {
+alp_itf_d7a_cfg_t report_itf = {
     .type                           = ALP_ITF_TYPE_D7A,
     .cfg.to.byte                    = D7A_CTF_ENCODE(0),
     .cfg.te.byte                    = D7A_CTF_ENCODE(0),
@@ -38,31 +27,6 @@
     .cfg.addressee.id[0]            = D7A_CTF_ENCODE(4),
 };
 
-// Response Callback
-void my_response_callback(uint8_t terminal, int8_t err, uint8_t id)
-{    
-    if (ALP_ERR_NONE > err)
-    {
-        modem_print_error(ALP_ITF_TYPE_D7A, err);
-    }
-    
-    if (terminal)
-    {
-        modem_resp[id].put((void*)MODEM_RESP_TERMINAL);
-    }
-    else
-    {
-        if (ALP_ERR_NONE == err)
-        {
-            modem_resp[id].put((void*)MODEM_RESP_ACK);
-        }
-        else if (ALP_ERR_NONE > err)
-        {
-            modem_resp[id].put((void*)MODEM_RESP_ERROR);
-        }
-    }
-}
-
 // Interrupt Service Routine on button press.
 void button_push_isr( void )
 {
@@ -73,15 +37,39 @@
 void button_user_thread()
 {
     osEvent evt;
-    uint32_t resp;
-    d7a_sp_res_t istat;
     output_file_t* output;
     uint32_t sent = 0;
-
-    uint8_t id = modem_get_id(my_response_callback);
+    int err;
+    alp_payload_t* alp;
+    alp_payload_t* rsp;
+    
+    PRINT("Register Files\n");
+    ram_fs_new(FID_OUTPUT_FILE, (uint8_t*)&h_output_file, (uint8_t*)&f_output_file);
+    ram_fs_new(FID_INPUT_FILE, (uint8_t*)&h_input_file, (uint8_t*)&f_input_file);
+    
+    modem_declare_file(FID_OUTPUT_FILE, (alp_file_header_t*)&h_output_file);
+    modem_declare_file(FID_INPUT_FILE, (alp_file_header_t*)&h_input_file);
+    
+    PRINT("Enable D7A interface\n");
+    modem_d7a_enable_itf();
+    
+    // Host revision file is in the modem. Update it.
+    PRINT("Update host revision\n");
+    modem_write_file(FID_HOST_REV, &f_rev, 0, sizeof(revision_t));
+    
+    // Retrieve modem revision
+    PRINT("Send revision\n");
+    revision_t rev;
+    modem_read_file(FID_WM_REV, &rev, 0, sizeof(revision_t));
+    
+    // Send both to the server
+    // Build payload
+    alp = NULL;
+    alp = alp_payload_rsp_f_data(alp, FID_WM_REV, &rev, 0, sizeof(revision_t));
+    alp = alp_payload_rsp_f_data(alp, FID_HOST_REV, &f_rev, 0, sizeof(revision_t));
+    // Send
+    modem_remote_raw_alp((void*)&report_itf, alp, NULL, 10000);
         
-    memset(&istat, 0, sizeof(d7a_sp_res_t));
-    
     // Directly get data pointer to avoid reading file
     output = (output_file_t*)ram_fs_get_data(FID_OUTPUT_FILE);
     
@@ -96,7 +84,8 @@
 
         // Wait for button press
         PRINT("Press user button to send file. (%d bytes)\n", output_length);
-        button_user.acquire();
+        //button_user.acquire();
+        osDelay(5000);
         
         // Update file CRC (Calculate CRC on string without end of string)
         output->crc = crc32((char*)output->data, output_length - 1);
@@ -108,53 +97,39 @@
         while (sent < output_length)
         {
             is_ok = false;
-            uint32_t chunk_size = MIN(CHUNK_SIZE, output_length - sent);
+            uint32_t chunk_size = min_u32(CHUNK_SIZE, output_length - sent);
             uint32_t chunk_offset = sent;
             
             PRINT("Sending chunk %4d/%4d (%3d bytes)... ", chunk_offset, output_length, chunk_size);
             FLUSH();
-            modem_send_file_content((uint8_t*)&my_itf, D7_ITF_SIZE(&my_itf), (void*)&istat, FID_OUTPUT_FILE, &(output->data[chunk_offset]), chunk_offset, chunk_size, id);
+            
+            // Build payload
+            alp = NULL;
+            alp = alp_payload_rsp_f_data(alp, FID_OUTPUT_FILE, &(output->data[chunk_offset]), chunk_offset, chunk_size);
             
-            do
+            // Send
+            err = modem_remote_raw_alp((void*)&report_itf, alp, &rsp, 60000);
+        
+            if (ALP_ERR_UNKNOWN == err)
             {
-                evt = modem_resp[id].get(3000);
-                resp = (evt.status == osEventMessage)? (uint32_t)evt.value.p : MODEM_RESP_TIMEOUT;
-                
-                if (MODEM_RESP_ACK == resp)
-                {
-                    //PRINT_DATA("ACK UID:", "%02X", istat.addressee.id, 8, " ");
-                    //PRINT("SNR: %ddB RXLEV: %ddBm LB: %ddB\n", istat.snr, -istat.rxlev, istat.lb);
-                    
-                    //PRINT("ACK.\n");
-                    is_ok = true;
-                }
-                else if (MODEM_RESP_TIMEOUT == resp)
-                {
-                    PRINT("WAITING...\n");
-                }
-                else if (MODEM_RESP_ERROR == resp)
-                {
-                    //PRINT("ERROR.\n");
-                    break;
-                }
-                else if (MODEM_RESP_TERMINAL == resp)
-                {
-                    //PRINT("DONE.\n");
-                }
-                
-                memset(&istat, 0, sizeof(d7a_sp_res_t));
-            } while (MODEM_RESP_TERMINAL != resp);
-            
-            if (is_ok)
-            {
-                sent += chunk_size;
-                PRINT("OK.\n");
+                PRINT("TIMEOUT.\n");
             }
             else
             {
-                PRINT("FAILED.\n");
-                break;
+                err = alp_payload_get_err(rsp);
+                if (ALP_ERR_NONE <= err)
+                {
+                    sent += chunk_size;
+                    is_ok = true;
+                    PRINT("OK.\n");
+                }
+                else
+                {
+                    modem_print_error(report_itf.type, err);
+                }
             }
+            
+            alp_payload_free(rsp);
         }
         
         double time_s = tim.read();
@@ -166,35 +141,32 @@
         if (is_ok)
         {
             // Send CRC
-            PRINT("Sendind CRC 0x%08X\n", output->crc);
-            modem_send_file_content((uint8_t*)&my_itf, D7_ITF_SIZE(&my_itf), (void*)&istat, FID_OUTPUT_FILE, &(output->crc), offsetof(output_file_t, crc), sizeof_field(output_file_t, crc), id);
+            PRINT("Sendind CRC 0x%08X... ", output->crc);
+            
+            alp = NULL;
+            alp = alp_payload_rsp_f_data(alp, FID_OUTPUT_FILE, &(output->crc), offsetof(output_file_t, crc), sizeof_field(output_file_t, crc));
             
-            do
+            // Send
+            err = modem_remote_raw_alp((void*)&report_itf, alp, &rsp, 60000);
+            
+            if (ALP_ERR_UNKNOWN == err)
             {
-                evt = modem_resp[id].get(3000);
-                resp = (evt.status == osEventMessage)? (uint32_t)evt.value.p : MODEM_RESP_TIMEOUT;
-                
-                if (MODEM_RESP_ACK == resp)
-                {
-                    PRINT_DATA("ACK UID:", "%02X", istat.addressee.id, 8, " ");
-                    PRINT("SNR: %ddB RXLEV: %ddBm LB: %ddB\n", istat.snr, -istat.rxlev, istat.lb);
-                }
-                else if (MODEM_RESP_TIMEOUT == resp)
+                PRINT("TIMEOUT.\n");
+            }
+            else
+            {
+                err = alp_payload_get_err(rsp);
+                if (ALP_ERR_NONE <= err)
                 {
-                    PRINT("WAITING...\n");
-                }
-                else if (MODEM_RESP_ERROR == resp)
-                {
-                    PRINT("ERROR.\n");
-                    break;
+                    PRINT("OK.\n");
                 }
-                else if (MODEM_RESP_TERMINAL == resp)
+                else
                 {
-                    PRINT("DONE.\n");
+                    modem_print_error(report_itf.type, err);
                 }
-                
-                memset(&istat, 0, sizeof(d7a_sp_res_t));
-            } while (MODEM_RESP_TERMINAL != resp);
+            }
+            
+            alp_payload_free(rsp);
         }
     }
 }
@@ -203,11 +175,9 @@
 {
     touch_t* touch;
     osEvent evt;
-    uint32_t resp;
-    d7a_sp_res_t istat;
     uint8_t chunk[CHUNK_SIZE];
-    
-    uint8_t id = modem_get_id(my_response_callback);
+    int err;
+    alp_payload_t* alp;
     
     while (true)
     {
@@ -257,39 +227,26 @@
                     
                     // Send CRC as confirmation
                     PRINT("COMFIRM CRC 0x%08X\n", input->crc);
-                    modem_send_file_content((uint8_t*)&my_itf, D7_ITF_SIZE(&my_itf), (void*)&istat, FID_INPUT_FILE, &(input->crc), offsetof(input_file_t, crc), sizeof_field(input_file_t, crc), id);
+                    
+                    alp = NULL;
+                    alp = alp_payload_rsp_f_data(alp, FID_INPUT_FILE, &(input->crc), offsetof(input_file_t, crc), sizeof_field(input_file_t, crc));
                     
-                    do
+                    // Send
+                    err = modem_remote_raw_alp((void*)&report_itf, alp, NULL, 3000);
+                    
+                    if (ALP_ERR_NONE <= err)
                     {
-                        evt = modem_resp[id].get(3000);
-                        resp = (evt.status == osEventMessage)? (uint32_t)evt.value.p : MODEM_RESP_TIMEOUT;
-                        
-                        if (MODEM_RESP_ACK == resp)
-                        {
-                            PRINT_DATA("ACK UID:", "%02X", istat.addressee.id, 8, " ");
-                            PRINT("SNR: %ddB RXLEV: %ddBm LB: %ddB\n", istat.snr, -istat.rxlev, istat.lb);
-                        }
-                        else if (MODEM_RESP_TIMEOUT == resp)
-                        {
-                            PRINT("WAITING...\n");
-                        }
-                        else if (MODEM_RESP_ERROR == resp)
-                        {
-                            PRINT("ERROR.\n");
-                            break;
-                        }
-                        else if (MODEM_RESP_TERMINAL == resp)
-                        {
-                            PRINT("DONE.\n");
-                        }
-                        
-                        memset(&istat, 0, sizeof(d7a_sp_res_t));
-                    } while (MODEM_RESP_TERMINAL != resp);
+                        PRINT("OK.\n");
+                    }
+                    else
+                    {
+                        modem_print_error(report_itf.type, err);
+                    }
                 }
                 else
                 {                    
                     PRINT("Got chunk %4d/%4d (%3d bytes)\n", touch->offset, sizeof_field(input_file_t, data), touch->length);
-                    ram_fs_read(touch->fid, touch->offset, touch->length, chunk);
+                    ram_fs_read(touch->fid, chunk, touch->offset, touch->length);
                     //PRINT("%s\n", chunk);
                     //PRINT_DATA("chunk end:", "%02X", &(chunk[touch->length-4]), 4, "\n");
                 
@@ -305,7 +262,7 @@
     }
 }
 
-modem_callbacks_t callbacks = {
+modem_ref_callbacks_t callbacks = {
     .read       = my_read,
     .write      = my_write,
     .read_fprop = my_read_fprop,
@@ -319,19 +276,6 @@
     .busy       = my_busy,
 };
 
-// Callback
-void my_main_callback(uint8_t terminal, int8_t err, uint8_t id)
-{    
-    if (ALP_ERR_NONE != err)
-    {
-        modem_print_error(ALP_ITF_TYPE_D7A, err);
-    }
-    
-    if (terminal)
-    {
-        modem_ready.release();
-    }
-}
 
 /*** Main function ------------------------------------------------------------- ***/
 int main() {
@@ -346,36 +290,10 @@
           "------------- Demo Big File -------------\n"
           "-----------------------------------------\n");
               
-    modem_helper_open(&callbacks);
-    
-    uint8_t id = modem_get_id(my_main_callback);
-    
-    // Put modem to listen to downlink access class
-    d7a_xcl_t xcl = { .bf.s = 0, .bf.m = 0x1 };
-    modem_write_file(D7A_FID_DLL_CFG, (void*)&xcl, offsetof(d7a_dll_cfg_t, xcl), sizeof(d7a_xcl_t), id);
-    modem_ready.acquire();
-    
-    PRINT("Register Files\n");
-    modem_update_file(FID_OUTPUT_FILE, (alp_file_header_t*)&h_output_file, (uint8_t*)&f_output_file);
-    modem_update_file(FID_INPUT_FILE, (alp_file_header_t*)&h_input_file, (uint8_t*)&f_input_file);
-    
-    PRINT("Start D7A Stack\n");
-    modem_activate_itf(ALP_ITF_TYPE_D7A, 24, 0, ALP_D7A_ISTAT_RESP | ALP_D7A_ISTAT_UNS | ALP_D7A_ISTAT_EOP, true, id);
-    modem_ready.acquire();
-    
-    PRINT("Notify Modem Version\n");
-    modem_notify_file(D7A_FID_FIRMWARE_VERSION, 0, SIZE_HOST_REV, id);
-    modem_ready.acquire();
-    
-    PRINT("Notify Host Version\n");
-    uint8_t default_root_key[] = DEFAULT_ROOT_KEY;
-    modem_notify_host_rev(&f_rev, &h_rev, default_root_key);
-    
-    // id no longer needed
-    modem_free_id(id);
+    modem_open(&callbacks);
     
     // Start file modified thread
-    Thread th_file_modified(osPriorityNormal, 1024, NULL);
+    Thread th_file_modified(osPriorityNormal, 4096, NULL);
     osStatus status = th_file_modified.start(thread_file_modified);
     ASSERT(status == osOK, "Failed to start thread_file_modified (err: %d)\r\n", status);