Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Revision:
67:9ac9d109b80a
Parent:
65:ac3844adfe49
Child:
69:18852c154df9
--- a/src/d7a_alp.cpp	Fri Oct 21 15:31:45 2016 +0000
+++ b/src/d7a_alp.cpp	Wed Oct 26 10:01:26 2016 +0000
@@ -8,10 +8,11 @@
 #include "d7a_modem.h"
 #include "d7a_sys.h"
 #include "d7a_alp.h"
+#include "sha.h"
 
 typedef struct {
     uint8_t tag;
-    uint8_t buffer[100];
+    uint8_t buffer[256];
     Queue<d7a_com_rx_msg_t, 16> pkt_queue;
     Queue<d7a_com_rx_msg_t, 8> pl_queue;
     
@@ -48,20 +49,20 @@
     ASSERT(g_alp_ctx.pkt_queue.put(pkt) == osOK, "ALP queue full!\r\n");
 }
 
-void d7a_alp_new_pl(d7a_com_rx_msg_t* pl)
+static void d7a_alp_new_pl(d7a_com_rx_msg_t* pl)
 {
     FPRINT("\r\n");
     ASSERT(g_alp_ctx.pl_queue.put(pl) == osOK, "ALP OP queue full!\r\n");
 }
 
-d7a_com_rx_msg_t* d7a_alp_wait_pkt(uint32_t millisec)
+static d7a_com_rx_msg_t* d7a_alp_wait_pkt(uint32_t millisec)
 {
     FPRINT("\r\n");
     osEvent evt = g_alp_ctx.pkt_queue.get(millisec);
     return (evt.status == osEventMessage)? (d7a_com_rx_msg_t*)evt.value.p : NULL;
 }
 
-d7a_com_rx_msg_t* d7a_alp_wait_pl(uint32_t millisec)
+static d7a_com_rx_msg_t* d7a_alp_wait_pl(uint32_t millisec)
 {
     FPRINT("\r\n");
     osEvent evt = g_alp_ctx.pl_queue.get(millisec);
@@ -73,7 +74,7 @@
     return ((1 << (2*ctf.bf.exp)) * ctf.bf.mant);
 }
 
-uint32_t d7a_alp_encode_length(uint8_t* p, uint32_t len)
+static uint32_t d7a_alp_encode_length(uint8_t* p, uint32_t len)
 {
     if (len <= 0x3F)
     {
@@ -103,7 +104,7 @@
     }
 }
 
-uint32_t alp_decode_length(uint8_t* p, uint32_t* len)
+static uint32_t alp_decode_length(uint8_t* p, uint32_t* len)
 {
     uint32_t tmp = 0;
     switch ((*p) & 0xC0)
@@ -148,7 +149,7 @@
     return 0;
 }
 
-uint32_t d7a_alp_add(uint8_t* p, const uint8_t* data, uint32_t len)
+static uint32_t d7a_alp_add(uint8_t* p, const uint8_t* data, uint32_t len)
 {
     memcpy(p, data, len);
     
@@ -157,6 +158,8 @@
 
 void d7a_alp_free_msg(d7a_msg_t* msg)
 {
+    FPRINT("\r\n");
+    
     if (msg->data)
     {
         FREE(msg->data);
@@ -164,8 +167,10 @@
     FREE(msg);
 }
 
-d7a_msg_t* d7a_alp_new_msg(void)
+static d7a_msg_t* d7a_alp_new_msg(void)
 {
+    FPRINT("\r\n");
+    
     d7a_msg_t* msg = (d7a_msg_t*)MALLOC(sizeof(d7a_msg_t));
     memset(msg, 0, sizeof(d7a_msg_t));
     msg->err = D7A_ERR_NONE;
@@ -173,8 +178,10 @@
     return msg;
 }
 
-d7a_alp_rsp_t* d7a_alp_parse_pl(d7a_com_rx_msg_t* pkt)
-{    
+static d7a_alp_rsp_t* d7a_alp_parse_pl(d7a_com_rx_msg_t* pkt)
+{
+    FPRINT("\r\n");
+    
     if (pkt == NULL)
     {
         return NULL;
@@ -248,12 +255,12 @@
     }
     
     ASSERT((p - t) == len, "Payload wrong size: %d expected %d\r\n", (p - t), len);
-    
+
     return rsp;
 }
 
 
-uint32_t d7a_alp_tag(uint8_t* p, bool eop)
+static uint32_t d7a_alp_tag(uint8_t* p, bool eop)
 {
     uint8_t* t = p;
     
@@ -263,7 +270,7 @@
     return (uint32_t)(p - t);
 }
 
-uint32_t d7a_alp_forward_action(uint8_t* p, alp_d7a_itf_t* itf, bool resp)
+static uint32_t d7a_alp_forward_action(uint8_t* p, alp_d7a_itf_t* itf, bool resp)
 {
     uint8_t* t = p;
     
@@ -291,7 +298,7 @@
     return (uint32_t)(p - t);
 }
 
-uint32_t d7a_alp_write_action(uint8_t* p, const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* const buf, bool resp)
+static uint32_t d7a_alp_write_action(uint8_t* p, const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* const buf, bool resp)
 {
     uint8_t* t = p;
     
@@ -304,7 +311,7 @@
     return (uint32_t)(p - t);
 }
 
-uint32_t d7a_alp_read_action(uint8_t* p, const uint8_t file_id, const uint32_t offset, const uint32_t size, bool resp)
+static uint32_t d7a_alp_read_action(uint8_t* p, const uint8_t file_id, const uint32_t offset, const uint32_t size, bool resp)
 {
     uint8_t* t = p;
     
@@ -316,8 +323,38 @@
     return (uint32_t)(p - t);
 }
 
-void d7a_alp_construct_resp(d7a_msg_t** ret, uint8_t current_tag, uint32_t max_responses)
+static uint32_t d7a_alp_perm_request_action(uint8_t* p, uint8_t* req, uint32_t req_size, const uint8_t* root_key, bool resp)
 {
+    uint8_t* t = p;
+    uint8_t hash[32];
+    
+    *p++ = ALP_OPCODE_PERM_REQ + ((resp)? ALP_CTRL_RESP : 0);
+    *p++ = 1; // ROOT request
+    *p++ = 42; // Auth protocol ID
+    sha256_init();
+    sha256_update(req, req_size);
+    sha256_update((uint8_t*)root_key, D7A_ROOT_KEY_SIZE);
+    sha256_final(hash);
+    //PRINT_DATA("Token: ", "%02X", hash, D7A_AUTH_PROTOCOLE_TOKEN_SIZE, "\r\n");
+    p += d7a_alp_add(p, hash, D7A_AUTH_PROTOCOLE_TOKEN_SIZE);
+    
+    return (uint32_t)(p - t);
+}
+
+static uint32_t d7a_alp_flush_action(uint8_t* p, uint8_t fid, bool resp)
+{
+    uint8_t* t = p;
+    
+    *p++ = ALP_OPCODE_F_FLUSH + ((resp)? ALP_CTRL_RESP : 0);
+    *p++ = fid;
+    
+    return (uint32_t)(p - t);
+}
+
+static void d7a_alp_construct_resp(d7a_msg_t** ret, uint8_t current_tag, uint32_t max_responses)
+{
+    FPRINT("\r\n");
+    
     int i = 0;
     d7a_alp_rsp_t* pl = NULL;
     d7a_com_rx_msg_t* pkt = NULL;
@@ -335,7 +372,7 @@
         }
         
         pl = d7a_alp_parse_pl(pkt);
-        
+
         // Check TAG
         if (pl->tag == NO_TAG)
         {
@@ -392,8 +429,10 @@
     } while (1);
 }
 
-d7a_msg_t** d7a_alp_write_file(const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* const buf, d7a_addressee_t* addressee, uint8_t retry, bool resp)
+d7a_msg_t** d7a_alp_write_file(const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* const buf, const uint8_t* root_key, d7a_addressee_t* addressee, uint8_t retry, bool resp)
 {
+    FPRINT("\r\n");
+    
     // Get command buffer
     uint8_t* p = &g_alp_ctx.buffer[0];
     // Save initial position of the command buffer
@@ -455,13 +494,19 @@
         p += d7a_alp_forward_action(p, &itf, true);
     }
     
+    // Ask for root permissions
+    if (root_key)
+    {
+        uint8_t req[100];
+        uint8_t req_size = d7a_alp_write_action(req, file_id, offset, size, buf, resp);
+        p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
+    }
+    
     // Write action
     p += d7a_alp_write_action(p, file_id, offset, size, buf, resp);
     
     // Send command
     d7a_com_dump(&g_alp_ctx.buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
-
-    i = 0; // start with msg 0
     
     // Parse responses
     d7a_alp_construct_resp(ret, current_tag, max_responses);
@@ -469,8 +514,10 @@
     return ret;
 }
 
-d7a_msg_t** d7a_alp_read_file(const uint8_t file_id, const uint32_t offset, const uint32_t size, d7a_addressee_t* addressee, uint8_t retry)
+d7a_msg_t** d7a_alp_read_file(const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* root_key, d7a_addressee_t* addressee, uint8_t retry)
 {
+    FPRINT("\r\n");
+    
     // Get command buffer
     uint8_t* p = &g_alp_ctx.buffer[0];
     // Save initial position of the command buffer
@@ -533,13 +580,19 @@
         p += d7a_alp_forward_action(p, &itf, true);
     }
     
+    // Ask for root permissions
+    if (root_key)
+    {
+        uint8_t req[100];
+        uint8_t req_size = d7a_alp_read_action(req, file_id, offset, size, true);
+        p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
+    }
+    
     // Read action
     p += d7a_alp_read_action(p, file_id, offset, size, true);
     
     // Send command
     d7a_com_dump(&g_alp_ctx.buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
-
-    i = 0; // start with msg 0
     
     // Parse responses
     d7a_alp_construct_resp(ret, current_tag, max_responses);
@@ -547,6 +600,93 @@
     return ret;
 }
 
+
+d7a_msg_t** d7a_alp_flush_file(const uint8_t file_id, const uint8_t* root_key, d7a_addressee_t* addressee, uint8_t retry, bool resp)
+{
+    FPRINT("\r\n");
+    
+    // Get command buffer
+    uint8_t* p = &g_alp_ctx.buffer[0];
+    // Save initial position of the command buffer
+    uint8_t* t = p;
+    
+    bool broadcast = false;
+    uint8_t current_tag;
+    d7a_msg_t** ret = NULL;
+    uint32_t max_responses = 2;
+    uint8_t i;
+    
+    if (addressee)
+    {
+        if (addressee->ctrl.bf.idf == D7A_ID_NBID)
+        {
+            broadcast = true;
+            d7a_ctf_t ctf;
+            ctf.byte = addressee->id[0];
+            max_responses = ((1 << (2*ctf.bf.exp)) * ctf.bf.mant) + 1;
+        }
+        else if (addressee->ctrl.bf.idf == D7A_ID_NOID)
+        {
+            broadcast = true;
+            max_responses = 33;
+        }
+    }
+    
+    // malloc and init pointer array
+    ret = (d7a_msg_t**)MALLOC(sizeof(d7a_msg_t*) * (max_responses + 1));
+    for (i = 0; i < (max_responses + 1); i++)
+    {
+        ret[i] = NULL;
+    }
+    
+    // Construct command
+    
+    // Tag action
+    p += d7a_alp_tag(p, true);
+    
+    // get tag
+    current_tag = g_alp_ctx.tag;
+    
+    if (addressee)
+    {
+        // Construct interface
+        alp_d7a_itf_t itf = {
+            // Dash7 interface
+            .type = 0xD7,
+            // Switch response type if broadcast
+            .cfg.qos.bf.resp = (broadcast)? D7A_RESP_ALL : D7A_RESP_ANY,
+            .cfg.qos.bf.retry = retry,
+            .cfg.qos.bf.record = 0,
+            .cfg.qos.bf.stop_on_err = 0,
+            .cfg.dorm_to.byte = 0,
+        };
+        memcpy(&itf.cfg.addressee, addressee, sizeof(d7a_addressee_t));
+        
+        // Forward action
+        p += d7a_alp_forward_action(p, &itf, true);
+    }
+    
+    // Ask for root permissions
+    if (root_key)
+    {
+        uint8_t req[100];
+        uint8_t req_size = d7a_alp_flush_action(req, file_id, resp);
+        p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
+    }
+    
+    // Write action
+    p += d7a_alp_flush_action(p, file_id, resp);
+    
+    // Send command
+    d7a_com_dump(&g_alp_ctx.buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
+    
+    // Parse responses
+    d7a_alp_construct_resp(ret, current_tag, max_responses);
+    
+    return ret;
+}
+
+
 void d7a_alp_thread(const void *p)
 {
     FPRINT("(id:0x%08x)\r\n", osThreadGetId());