Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Wed Dec 21 15:08:51 2016 +0000
Revision:
79:82b01c1a62f6
Parent:
78:f1c0affd99e7
Child:
80:30265d5dd20a
Unitary debug prints.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 43:28202405094d 1 #include "mbed.h"
Jeej 43:28202405094d 2 #include "rtos.h"
Jeej 43:28202405094d 3 #include "dbg.h"
Jeej 43:28202405094d 4 #include "d7a.h"
Jeej 43:28202405094d 5 #include "d7a_com.h"
Jeej 43:28202405094d 6 #include "d7a_common.h"
Jeej 43:28202405094d 7 #include "d7a_fs.h"
Jeej 43:28202405094d 8 #include "d7a_modem.h"
Jeej 43:28202405094d 9 #include "d7a_sys.h"
Jeej 43:28202405094d 10 #include "d7a_alp.h"
Jeej 67:9ac9d109b80a 11 #include "sha.h"
Jeej 43:28202405094d 12
Jeej 79:82b01c1a62f6 13 #if 0
Jeej 79:82b01c1a62f6 14 #define ALP_DPRINT(...) DPRINT(__VA_ARGS__)
Jeej 79:82b01c1a62f6 15 #define ALP_DPRINT_DATA(...) DPRINT_DATA(__VA_ARGS__)
Jeej 79:82b01c1a62f6 16 #else
Jeej 79:82b01c1a62f6 17 #define ALP_DPRINT(...);
Jeej 79:82b01c1a62f6 18 #define ALP_DPRINT_DATA(...);
Jeej 79:82b01c1a62f6 19 #endif
Jeej 79:82b01c1a62f6 20
Jeej 77:8c792719a1fc 21 #define ALP_CMD_MAX_LENGHT (256)
Jeej 43:28202405094d 22
Jeej 77:8c792719a1fc 23 static uint8_t g_alp_tag;
Jeej 77:8c792719a1fc 24 static uint8_t g_alp_buffer[ALP_CMD_MAX_LENGHT];
Jeej 77:8c792719a1fc 25 static Queue<d7a_com_rx_msg_t, 8> g_alp_pkt_queue;
Jeej 77:8c792719a1fc 26 static Queue<d7a_com_rx_msg_t, 8> g_alp_pl_queue;
Jeej 77:8c792719a1fc 27 static UnsolicitedMsgFunction g_alp_uns_msg;
Jeej 78:f1c0affd99e7 28 static Thread g_alp_thread(osPriorityHigh, 512, NULL);
Jeej 77:8c792719a1fc 29
Jeej 77:8c792719a1fc 30 static const uint32_t g_alp_stack_size = 1 + ALP_CMD_MAX_LENGHT + sizeof(g_alp_pkt_queue) + sizeof(g_alp_pl_queue) + 4 + 256;
Jeej 43:28202405094d 31
Jeej 76:fda2e34ff19d 32 void d7a_alp_thread();
Jeej 43:28202405094d 33
Jeej 59:b42eae56b51b 34 d7a_errors_t d7a_alp_open(UnsolicitedMsgFunction uns_msg)
Jeej 43:28202405094d 35 {
Jeej 43:28202405094d 36 FPRINT("\r\n");
Jeej 43:28202405094d 37
Jeej 77:8c792719a1fc 38 g_alp_uns_msg = uns_msg;
Jeej 76:fda2e34ff19d 39
Jeej 77:8c792719a1fc 40 osStatus err = g_alp_thread.start(d7a_alp_thread);
Jeej 76:fda2e34ff19d 41 ASSERT(err == osOK, "Failed to start d7a_alp_thread (err: %d)\r\n", err);
Jeej 49:81d5bddb02f0 42
Jeej 49:81d5bddb02f0 43 return D7A_ERR_NONE;
Jeej 43:28202405094d 44 }
Jeej 43:28202405094d 45
Jeej 56:da34fc11e760 46 d7a_errors_t d7a_alp_close(void)
Jeej 56:da34fc11e760 47 {
Jeej 56:da34fc11e760 48 FPRINT("\r\n");
Jeej 56:da34fc11e760 49
Jeej 77:8c792719a1fc 50 g_alp_thread.terminate();
Jeej 56:da34fc11e760 51
Jeej 56:da34fc11e760 52 return D7A_ERR_NONE;
Jeej 56:da34fc11e760 53 }
Jeej 56:da34fc11e760 54
Jeej 43:28202405094d 55 void d7a_alp_new_pkt(d7a_com_rx_msg_t* pkt)
Jeej 43:28202405094d 56 {
Jeej 43:28202405094d 57 FPRINT("\r\n");
Jeej 77:8c792719a1fc 58 ASSERT(g_alp_pkt_queue.put(pkt) == osOK, "ALP queue full!\r\n");
Jeej 43:28202405094d 59 }
Jeej 43:28202405094d 60
Jeej 67:9ac9d109b80a 61 static void d7a_alp_new_pl(d7a_com_rx_msg_t* pl)
Jeej 45:b85384e7d825 62 {
Jeej 45:b85384e7d825 63 FPRINT("\r\n");
Jeej 77:8c792719a1fc 64 ASSERT(g_alp_pl_queue.put(pl) == osOK, "ALP PL queue full!\r\n");
Jeej 45:b85384e7d825 65 }
Jeej 45:b85384e7d825 66
Jeej 67:9ac9d109b80a 67 static d7a_com_rx_msg_t* d7a_alp_wait_pkt(uint32_t millisec)
Jeej 43:28202405094d 68 {
Jeej 43:28202405094d 69 FPRINT("\r\n");
Jeej 77:8c792719a1fc 70 osEvent evt = g_alp_pkt_queue.get(millisec);
Jeej 43:28202405094d 71 return (evt.status == osEventMessage)? (d7a_com_rx_msg_t*)evt.value.p : NULL;
Jeej 43:28202405094d 72 }
Jeej 43:28202405094d 73
Jeej 67:9ac9d109b80a 74 static d7a_com_rx_msg_t* d7a_alp_wait_pl(uint32_t millisec)
Jeej 43:28202405094d 75 {
Jeej 43:28202405094d 76 FPRINT("\r\n");
Jeej 77:8c792719a1fc 77 osEvent evt = g_alp_pl_queue.get(millisec);
Jeej 45:b85384e7d825 78 return (evt.status == osEventMessage)? (d7a_com_rx_msg_t*)evt.value.p : NULL;
Jeej 43:28202405094d 79 }
Jeej 43:28202405094d 80
Jeej 58:38a366236bda 81 static uint32_t d7a_ctf_to_ti(d7a_ctf_t ctf)
Jeej 58:38a366236bda 82 {
Jeej 58:38a366236bda 83 return ((1 << (2*ctf.bf.exp)) * ctf.bf.mant);
Jeej 58:38a366236bda 84 }
Jeej 58:38a366236bda 85
Jeej 67:9ac9d109b80a 86 static uint32_t d7a_alp_encode_length(uint8_t* p, uint32_t len)
Jeej 43:28202405094d 87 {
Jeej 43:28202405094d 88 if (len <= 0x3F)
Jeej 43:28202405094d 89 {
Jeej 43:28202405094d 90 *p++ = len;
Jeej 43:28202405094d 91 return 1;
Jeej 43:28202405094d 92 }
Jeej 43:28202405094d 93 else if (len <= 0x3FFF)
Jeej 43:28202405094d 94 {
Jeej 43:28202405094d 95 *p++ = 0x40 + (uint8_t)(len >> 8);
Jeej 43:28202405094d 96 *p++ = (uint8_t)(len & 0xFF);
Jeej 43:28202405094d 97 return 2;
Jeej 43:28202405094d 98 }
Jeej 43:28202405094d 99 else if (len <= 0x3FFFFF)
Jeej 43:28202405094d 100 {
Jeej 43:28202405094d 101 *p++ = 0x80 + (uint8_t) (len >> 16);
Jeej 43:28202405094d 102 *p++ = (uint8_t)((len >> 8) & 0xFF);
Jeej 43:28202405094d 103 *p++ = (uint8_t) (len & 0xFF);
Jeej 43:28202405094d 104 return 3;
Jeej 43:28202405094d 105 }
Jeej 43:28202405094d 106 else
Jeej 43:28202405094d 107 {
Jeej 43:28202405094d 108 *p++ = 0xC0 + (uint8_t) (len >> 24);
Jeej 43:28202405094d 109 *p++ = (uint8_t)((len >> 16) & 0xFF);
Jeej 43:28202405094d 110 *p++ = (uint8_t)((len >> 8) & 0xFF);
Jeej 43:28202405094d 111 *p++ = (uint8_t) (len & 0xFF);
Jeej 43:28202405094d 112 return 4;
Jeej 43:28202405094d 113 }
Jeej 43:28202405094d 114 }
Jeej 43:28202405094d 115
Jeej 67:9ac9d109b80a 116 static uint32_t alp_decode_length(uint8_t* p, uint32_t* len)
Jeej 45:b85384e7d825 117 {
Jeej 45:b85384e7d825 118 uint32_t tmp = 0;
Jeej 45:b85384e7d825 119 switch ((*p) & 0xC0)
Jeej 45:b85384e7d825 120 {
Jeej 45:b85384e7d825 121 case 0xC0: // 0xCx xx xx xx
Jeej 45:b85384e7d825 122 tmp = (*p++ & 0x3F) << 24;
Jeej 45:b85384e7d825 123 tmp += *p++ << 16;
Jeej 45:b85384e7d825 124 tmp += *p++ << 8;
Jeej 45:b85384e7d825 125 tmp += *p++ << 0;
Jeej 45:b85384e7d825 126 *len = tmp;
Jeej 45:b85384e7d825 127 return 4;
Jeej 45:b85384e7d825 128 case 0x80: // 0x8x xx xx : 16384 <= Len <4194303
Jeej 45:b85384e7d825 129 tmp = (*p++ & 0x3F) << 16;
Jeej 45:b85384e7d825 130 tmp += *p++ << 8;
Jeej 45:b85384e7d825 131 if (tmp == 0) {
Jeej 45:b85384e7d825 132 // 0x8000 ActP special ActP code
Jeej 45:b85384e7d825 133 // Do not fetch the extra byte
Jeej 45:b85384e7d825 134 tmp = 2;
Jeej 45:b85384e7d825 135 }
Jeej 45:b85384e7d825 136 else
Jeej 45:b85384e7d825 137 {
Jeej 45:b85384e7d825 138 tmp += *p++ << 0;
Jeej 45:b85384e7d825 139 }
Jeej 45:b85384e7d825 140 *len = tmp;
Jeej 45:b85384e7d825 141 return 3;
Jeej 45:b85384e7d825 142 case 0x40: // 0x4x xx : 64 <= Len < 16383
Jeej 45:b85384e7d825 143 tmp = (*p++ & 0x3F) << 8;
Jeej 45:b85384e7d825 144 tmp += *p++ << 0;
Jeej 45:b85384e7d825 145 if (tmp == 0)
Jeej 45:b85384e7d825 146 {
Jeej 45:b85384e7d825 147 // 0x4000 ActP special ActP code
Jeej 45:b85384e7d825 148 tmp = 1;
Jeej 45:b85384e7d825 149 }
Jeej 45:b85384e7d825 150 *len = tmp;
Jeej 45:b85384e7d825 151 return 2;
Jeej 45:b85384e7d825 152 case 0: // Len <63
Jeej 45:b85384e7d825 153 tmp = (*p++ & 0x3F) << 0;
Jeej 45:b85384e7d825 154 *len = tmp;
Jeej 45:b85384e7d825 155 return 1;
Jeej 45:b85384e7d825 156 }
Jeej 45:b85384e7d825 157
Jeej 45:b85384e7d825 158 return 0;
Jeej 45:b85384e7d825 159 }
Jeej 43:28202405094d 160
Jeej 67:9ac9d109b80a 161 static uint32_t d7a_alp_add(uint8_t* p, const uint8_t* data, uint32_t len)
Jeej 43:28202405094d 162 {
Jeej 45:b85384e7d825 163 memcpy(p, data, len);
Jeej 43:28202405094d 164
Jeej 43:28202405094d 165 return len;
Jeej 43:28202405094d 166 }
Jeej 43:28202405094d 167
Jeej 59:b42eae56b51b 168 void d7a_alp_free_msg(d7a_msg_t* msg)
Jeej 59:b42eae56b51b 169 {
Jeej 67:9ac9d109b80a 170 FPRINT("\r\n");
Jeej 67:9ac9d109b80a 171
Jeej 59:b42eae56b51b 172 if (msg->data)
Jeej 59:b42eae56b51b 173 {
Jeej 59:b42eae56b51b 174 FREE(msg->data);
Jeej 59:b42eae56b51b 175 }
Jeej 59:b42eae56b51b 176 FREE(msg);
Jeej 59:b42eae56b51b 177 }
Jeej 59:b42eae56b51b 178
Jeej 67:9ac9d109b80a 179 static d7a_msg_t* d7a_alp_new_msg(void)
Jeej 59:b42eae56b51b 180 {
Jeej 67:9ac9d109b80a 181 FPRINT("\r\n");
Jeej 67:9ac9d109b80a 182
Jeej 59:b42eae56b51b 183 d7a_msg_t* msg = (d7a_msg_t*)MALLOC(sizeof(d7a_msg_t));
Jeej 59:b42eae56b51b 184 memset(msg, 0, sizeof(d7a_msg_t));
Jeej 59:b42eae56b51b 185 msg->err = D7A_ERR_NONE;
Jeej 59:b42eae56b51b 186
Jeej 59:b42eae56b51b 187 return msg;
Jeej 59:b42eae56b51b 188 }
Jeej 58:38a366236bda 189
Jeej 67:9ac9d109b80a 190 static d7a_alp_rsp_t* d7a_alp_parse_pl(d7a_com_rx_msg_t* pkt)
Jeej 67:9ac9d109b80a 191 {
Jeej 67:9ac9d109b80a 192 FPRINT("\r\n");
Jeej 67:9ac9d109b80a 193
Jeej 46:665391110051 194 if (pkt == NULL)
Jeej 46:665391110051 195 {
Jeej 46:665391110051 196 return NULL;
Jeej 46:665391110051 197 }
Jeej 46:665391110051 198
Jeej 45:b85384e7d825 199 uint8_t* p = pkt->buffer;
Jeej 45:b85384e7d825 200 uint8_t* t = p;
Jeej 45:b85384e7d825 201 uint8_t len = pkt->blen;
Jeej 45:b85384e7d825 202
Jeej 45:b85384e7d825 203 d7a_alp_rsp_t* rsp = (d7a_alp_rsp_t*)MALLOC(sizeof(d7a_alp_rsp_t));
Jeej 59:b42eae56b51b 204 rsp->tag = NO_TAG;
Jeej 59:b42eae56b51b 205 rsp->eop = false;
Jeej 59:b42eae56b51b 206 rsp->msg = d7a_alp_new_msg();
Jeej 45:b85384e7d825 207
Jeej 45:b85384e7d825 208 while ((p - t) < len)
Jeej 45:b85384e7d825 209 {
Jeej 45:b85384e7d825 210 uint8_t ctrl = *p++;
Jeej 45:b85384e7d825 211 switch (ctrl & 0x3F)
Jeej 45:b85384e7d825 212 {
Jeej 45:b85384e7d825 213 case ALP_OPCODE_RSP_STATUS:
Jeej 46:665391110051 214 if (ctrl & ALP_OPCODE_INDIRECT)
Jeej 46:665391110051 215 {
Jeej 58:38a366236bda 216 // ITF Type
Jeej 58:38a366236bda 217 uint8_t type = *p++;
Jeej 58:38a366236bda 218 // Length
Jeej 46:665391110051 219 uint32_t length;
Jeej 58:38a366236bda 220 p += alp_decode_length(p, &length);
Jeej 58:38a366236bda 221 // Data
Jeej 58:38a366236bda 222 d7a_sp_res_t* res = (d7a_sp_res_t*)p;
Jeej 58:38a366236bda 223 p += length;
Jeej 58:38a366236bda 224
Jeej 58:38a366236bda 225 // Fill corresponding fields
Jeej 59:b42eae56b51b 226 rsp->msg->lb = res->lb; // Get Link Budget
Jeej 61:87be16080640 227 rsp->msg->rxlev = res->rxlev; // Get RXLEV
Jeej 59:b42eae56b51b 228 memcpy(rsp->msg->id, res->addressee.id, D7A_UID_LEN); // Get UID
Jeej 58:38a366236bda 229
Jeej 79:82b01c1a62f6 230 ALP_DPRINT("ALP RSP ISTATUS type:%02X lb: %3d ", type, rsp->msg->lb);
Jeej 59:b42eae56b51b 231 DPRINT_DATA("UID:", "%02X", rsp->msg->id, D7A_UID_LEN, "\r\n");
Jeej 46:665391110051 232 }
Jeej 46:665391110051 233 else
Jeej 46:665391110051 234 {
Jeej 59:b42eae56b51b 235 uint8_t aid = *p++; // Action ID
Jeej 59:b42eae56b51b 236 rsp->msg->err = *p++; // Status
Jeej 79:82b01c1a62f6 237 ALP_DPRINT("ALP RSP STATUS aid:%d Status:%d\r\n", aid, rsp->msg->err);
Jeej 46:665391110051 238 }
Jeej 45:b85384e7d825 239 break;
Jeej 45:b85384e7d825 240 case ALP_OPCODE_RSP_TAG:
Jeej 59:b42eae56b51b 241 rsp->eop = !!(ctrl & ALP_CTRL_EOP);
Jeej 45:b85384e7d825 242 rsp->tag = *p++; // TAG
Jeej 79:82b01c1a62f6 243 ALP_DPRINT("ALP RSP TAG %d EOP %d\r\n", rsp->tag, rsp->eop);
Jeej 45:b85384e7d825 244 break;
Jeej 45:b85384e7d825 245 case ALP_OPCODE_RSP_F_DATA:
Jeej 59:b42eae56b51b 246 uint8_t fid;
Jeej 45:b85384e7d825 247 uint32_t offset;
Jeej 59:b42eae56b51b 248 uint32_t length;
Jeej 59:b42eae56b51b 249 fid = *p++; // File ID
Jeej 45:b85384e7d825 250 p += alp_decode_length(p, &offset); // offset
Jeej 59:b42eae56b51b 251 p += alp_decode_length(p, &length); // length
Jeej 59:b42eae56b51b 252 rsp->msg->data = (d7a_data_t*)MALLOC(sizeof(d7a_data_t) - 1 + length);
Jeej 59:b42eae56b51b 253 rsp->msg->data->fid = fid;
Jeej 59:b42eae56b51b 254 rsp->msg->data->offset = offset;
Jeej 59:b42eae56b51b 255 rsp->msg->data->length = length;
Jeej 59:b42eae56b51b 256 p += d7a_alp_add(rsp->msg->data->buf, p, length);
Jeej 79:82b01c1a62f6 257 ALP_DPRINT("ALP RSP F_DATA f:%d o:%d s:%d\r\n", fid, offset, length);
Jeej 59:b42eae56b51b 258 //DPRINT_DATA("DATA: ", "%02X ", (uint8_t*)rsp->data, rsp->data_len, "\r\n");
Jeej 45:b85384e7d825 259 break;
Jeej 45:b85384e7d825 260 default:
Jeej 45:b85384e7d825 261 WARNING(false, "ALP Untreated OP %d\r\n", ctrl);
Jeej 45:b85384e7d825 262 break;
Jeej 45:b85384e7d825 263 }
Jeej 45:b85384e7d825 264 }
Jeej 45:b85384e7d825 265
Jeej 45:b85384e7d825 266 ASSERT((p - t) == len, "Payload wrong size: %d expected %d\r\n", (p - t), len);
Jeej 67:9ac9d109b80a 267
Jeej 45:b85384e7d825 268 return rsp;
Jeej 45:b85384e7d825 269 }
Jeej 45:b85384e7d825 270
Jeej 45:b85384e7d825 271
Jeej 67:9ac9d109b80a 272 static uint32_t d7a_alp_tag(uint8_t* p, bool eop)
Jeej 43:28202405094d 273 {
Jeej 43:28202405094d 274 uint8_t* t = p;
Jeej 43:28202405094d 275
Jeej 45:b85384e7d825 276 *p++ = ALP_OPCODE_TAG + ((eop)? ALP_CTRL_EOP : 0);
Jeej 77:8c792719a1fc 277 *p++ = ++g_alp_tag;
Jeej 43:28202405094d 278
Jeej 43:28202405094d 279 return (uint32_t)(p - t);
Jeej 43:28202405094d 280 }
Jeej 43:28202405094d 281
Jeej 71:f03727ff0f99 282 static uint32_t d7a_alp_forward_action(uint8_t* p, d7a_itf_t* itf, bool resp)
Jeej 43:28202405094d 283 {
Jeej 43:28202405094d 284 uint8_t* t = p;
Jeej 43:28202405094d 285
Jeej 71:f03727ff0f99 286 uint32_t itf_size = sizeof(d7a_itf_t);
Jeej 58:38a366236bda 287 switch (itf->cfg.addressee.ctrl.bf.idf)
Jeej 58:38a366236bda 288 {
Jeej 58:38a366236bda 289 case D7A_ID_NBID:
Jeej 58:38a366236bda 290 itf_size -= 7;
Jeej 58:38a366236bda 291 break;
Jeej 58:38a366236bda 292 case D7A_ID_NOID:
Jeej 58:38a366236bda 293 itf_size -= 8;
Jeej 58:38a366236bda 294 break;
Jeej 58:38a366236bda 295 case D7A_ID_UID:
Jeej 58:38a366236bda 296 break;
Jeej 58:38a366236bda 297 case D7A_ID_VID:
Jeej 58:38a366236bda 298 itf_size -= 4;
Jeej 58:38a366236bda 299 break;
Jeej 58:38a366236bda 300 default:
Jeej 58:38a366236bda 301 break;
Jeej 58:38a366236bda 302 }
Jeej 58:38a366236bda 303
Jeej 45:b85384e7d825 304 *p++ = ALP_OPCODE_FORWARD + ((resp)? ALP_CTRL_RESP : 0);
Jeej 58:38a366236bda 305 p += d7a_alp_add(p, (uint8_t*)itf, itf_size);
Jeej 43:28202405094d 306
Jeej 43:28202405094d 307 return (uint32_t)(p - t);
Jeej 43:28202405094d 308 }
Jeej 43:28202405094d 309
Jeej 67:9ac9d109b80a 310 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)
Jeej 43:28202405094d 311 {
Jeej 43:28202405094d 312 uint8_t* t = p;
Jeej 43:28202405094d 313
Jeej 45:b85384e7d825 314 *p++ = ALP_OPCODE_F_WR_DATA + ((resp)? ALP_CTRL_RESP : 0);
Jeej 43:28202405094d 315 *p++ = file_id;
Jeej 43:28202405094d 316 p += d7a_alp_encode_length(p, offset);
Jeej 43:28202405094d 317 p += d7a_alp_encode_length(p, size);
Jeej 43:28202405094d 318 p += d7a_alp_add(p, buf, size);
Jeej 43:28202405094d 319
Jeej 43:28202405094d 320 return (uint32_t)(p - t);
Jeej 43:28202405094d 321 }
Jeej 43:28202405094d 322
Jeej 67:9ac9d109b80a 323 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)
Jeej 43:28202405094d 324 {
Jeej 43:28202405094d 325 uint8_t* t = p;
Jeej 43:28202405094d 326
Jeej 45:b85384e7d825 327 *p++ = ALP_OPCODE_F_RD_DATA + ((resp)? ALP_CTRL_RESP : 0);
Jeej 43:28202405094d 328 *p++ = file_id;
Jeej 43:28202405094d 329 p += d7a_alp_encode_length(p, offset);
Jeej 43:28202405094d 330 p += d7a_alp_encode_length(p, size);
Jeej 43:28202405094d 331
Jeej 43:28202405094d 332 return (uint32_t)(p - t);
Jeej 43:28202405094d 333 }
Jeej 43:28202405094d 334
Jeej 67:9ac9d109b80a 335 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)
Jeej 43:28202405094d 336 {
Jeej 67:9ac9d109b80a 337 uint8_t* t = p;
Jeej 67:9ac9d109b80a 338 uint8_t hash[32];
Jeej 67:9ac9d109b80a 339
Jeej 67:9ac9d109b80a 340 *p++ = ALP_OPCODE_PERM_REQ + ((resp)? ALP_CTRL_RESP : 0);
Jeej 67:9ac9d109b80a 341 *p++ = 1; // ROOT request
Jeej 67:9ac9d109b80a 342 *p++ = 42; // Auth protocol ID
Jeej 67:9ac9d109b80a 343 sha256_init();
Jeej 67:9ac9d109b80a 344 sha256_update(req, req_size);
Jeej 67:9ac9d109b80a 345 sha256_update((uint8_t*)root_key, D7A_ROOT_KEY_SIZE);
Jeej 67:9ac9d109b80a 346 sha256_final(hash);
Jeej 67:9ac9d109b80a 347 //PRINT_DATA("Token: ", "%02X", hash, D7A_AUTH_PROTOCOLE_TOKEN_SIZE, "\r\n");
Jeej 67:9ac9d109b80a 348 p += d7a_alp_add(p, hash, D7A_AUTH_PROTOCOLE_TOKEN_SIZE);
Jeej 67:9ac9d109b80a 349
Jeej 67:9ac9d109b80a 350 return (uint32_t)(p - t);
Jeej 67:9ac9d109b80a 351 }
Jeej 67:9ac9d109b80a 352
Jeej 67:9ac9d109b80a 353 static uint32_t d7a_alp_flush_action(uint8_t* p, uint8_t fid, bool resp)
Jeej 67:9ac9d109b80a 354 {
Jeej 67:9ac9d109b80a 355 uint8_t* t = p;
Jeej 67:9ac9d109b80a 356
Jeej 67:9ac9d109b80a 357 *p++ = ALP_OPCODE_F_FLUSH + ((resp)? ALP_CTRL_RESP : 0);
Jeej 67:9ac9d109b80a 358 *p++ = fid;
Jeej 67:9ac9d109b80a 359
Jeej 67:9ac9d109b80a 360 return (uint32_t)(p - t);
Jeej 67:9ac9d109b80a 361 }
Jeej 67:9ac9d109b80a 362
Jeej 67:9ac9d109b80a 363 static void d7a_alp_construct_resp(d7a_msg_t** ret, uint8_t current_tag, uint32_t max_responses)
Jeej 67:9ac9d109b80a 364 {
Jeej 67:9ac9d109b80a 365 FPRINT("\r\n");
Jeej 67:9ac9d109b80a 366
Jeej 59:b42eae56b51b 367 int i = 0;
Jeej 59:b42eae56b51b 368 d7a_alp_rsp_t* pl = NULL;
Jeej 59:b42eae56b51b 369 d7a_com_rx_msg_t* pkt = NULL;
Jeej 70:07b378285c95 370 int32_t time;
Jeej 70:07b378285c95 371 Timer timeout;
Jeej 70:07b378285c95 372
Jeej 70:07b378285c95 373 timeout.start();
Jeej 59:b42eae56b51b 374
Jeej 59:b42eae56b51b 375 // Parse responses
Jeej 59:b42eae56b51b 376 do
Jeej 43:28202405094d 377 {
Jeej 70:07b378285c95 378 time = D7A_ALP_RESP_TO - timeout.read_ms();
Jeej 70:07b378285c95 379 if (time < 0) time = 0;
Jeej 70:07b378285c95 380
Jeej 70:07b378285c95 381 pkt = d7a_alp_wait_pl(time);
Jeej 59:b42eae56b51b 382
Jeej 59:b42eae56b51b 383 if (pkt == NULL)
Jeej 59:b42eae56b51b 384 {
Jeej 59:b42eae56b51b 385 ret[i] = d7a_alp_new_msg();
Jeej 59:b42eae56b51b 386 ret[i]->err = D7A_ERR_CMD_TO;
Jeej 59:b42eae56b51b 387 break;
Jeej 59:b42eae56b51b 388 }
Jeej 59:b42eae56b51b 389
Jeej 59:b42eae56b51b 390 pl = d7a_alp_parse_pl(pkt);
Jeej 67:9ac9d109b80a 391
Jeej 59:b42eae56b51b 392 // Check TAG
Jeej 59:b42eae56b51b 393 if (pl->tag == NO_TAG)
Jeej 59:b42eae56b51b 394 {
Jeej 59:b42eae56b51b 395 WARNING(false, "No tag in payload expected %d\r\n", current_tag);
Jeej 59:b42eae56b51b 396 FREE(pkt);
Jeej 59:b42eae56b51b 397 d7a_alp_free_msg(pl->msg);
Jeej 59:b42eae56b51b 398 FREE(pl);
Jeej 59:b42eae56b51b 399 ret[i] = d7a_alp_new_msg();
Jeej 59:b42eae56b51b 400 ret[i]->err = D7A_ERR_UNKNOWN;
Jeej 59:b42eae56b51b 401 break;
Jeej 59:b42eae56b51b 402 }
Jeej 59:b42eae56b51b 403
Jeej 59:b42eae56b51b 404 if (pl->tag != current_tag)
Jeej 59:b42eae56b51b 405 {
Jeej 59:b42eae56b51b 406 WARNING(false, "Ingnoring tag %d expecting %d\r\n", pl->tag, current_tag);
Jeej 59:b42eae56b51b 407 d7a_alp_free_msg(pl->msg);
Jeej 59:b42eae56b51b 408 FREE(pl);
Jeej 59:b42eae56b51b 409 d7a_alp_new_pl(pkt);
Jeej 59:b42eae56b51b 410 continue;
Jeej 59:b42eae56b51b 411 }
Jeej 59:b42eae56b51b 412
Jeej 59:b42eae56b51b 413 FREE(pkt);
Jeej 59:b42eae56b51b 414
Jeej 59:b42eae56b51b 415 // Check for END OF PAYLOAD
Jeej 59:b42eae56b51b 416 if (pl->eop)
Jeej 59:b42eae56b51b 417 {
Jeej 79:82b01c1a62f6 418 ALP_DPRINT("EOP\r\n");
Jeej 59:b42eae56b51b 419
Jeej 59:b42eae56b51b 420 // If tag only
Jeej 62:f1e4da5162c2 421 if (!pl->msg->data && !pl->msg->lb && i != 0)
Jeej 59:b42eae56b51b 422 {
Jeej 59:b42eae56b51b 423 // Ignore response
Jeej 59:b42eae56b51b 424 d7a_alp_free_msg(pl->msg);
Jeej 59:b42eae56b51b 425 }
Jeej 59:b42eae56b51b 426 else
Jeej 59:b42eae56b51b 427 {
Jeej 79:82b01c1a62f6 428 ALP_DPRINT("last response (err %d)\r\n", pl->msg->err);
Jeej 59:b42eae56b51b 429 ret[i] = pl->msg;
Jeej 59:b42eae56b51b 430 }
Jeej 59:b42eae56b51b 431
Jeej 59:b42eae56b51b 432 FREE(pl);
Jeej 59:b42eae56b51b 433 break;
Jeej 59:b42eae56b51b 434 }
Jeej 59:b42eae56b51b 435 // Wait for new msg
Jeej 59:b42eae56b51b 436 else
Jeej 59:b42eae56b51b 437 {
Jeej 79:82b01c1a62f6 438 ALP_DPRINT("next response (err %d)\r\n", pl->msg->err);
Jeej 59:b42eae56b51b 439 ret[i] = pl->msg;
Jeej 59:b42eae56b51b 440 FREE(pl);
Jeej 59:b42eae56b51b 441 i++;
Jeej 59:b42eae56b51b 442 ASSERT(i <= max_responses, "Too much responses! max: %d\r\n", max_responses);
Jeej 59:b42eae56b51b 443 }
Jeej 59:b42eae56b51b 444
Jeej 59:b42eae56b51b 445 } while (1);
Jeej 58:38a366236bda 446 }
Jeej 45:b85384e7d825 447
Jeej 76:fda2e34ff19d 448 uint32_t d7a_alp_construct_itf(uint8_t* p, const uint8_t* root_key, d7a_addressee_t* addressee, uint8_t retry, bool resp)
Jeej 43:28202405094d 449 {
Jeej 58:38a366236bda 450 bool broadcast = false;
Jeej 60:8d4133fbc060 451 uint32_t max_responses = 2;
Jeej 58:38a366236bda 452
Jeej 58:38a366236bda 453 if (addressee)
Jeej 58:38a366236bda 454 {
Jeej 58:38a366236bda 455 if (addressee->ctrl.bf.idf == D7A_ID_NBID)
Jeej 58:38a366236bda 456 {
Jeej 58:38a366236bda 457 broadcast = true;
Jeej 58:38a366236bda 458 d7a_ctf_t ctf;
Jeej 58:38a366236bda 459 ctf.byte = addressee->id[0];
Jeej 60:8d4133fbc060 460 max_responses = ((1 << (2*ctf.bf.exp)) * ctf.bf.mant) + 1;
Jeej 58:38a366236bda 461 }
Jeej 58:38a366236bda 462 else if (addressee->ctrl.bf.idf == D7A_ID_NOID)
Jeej 58:38a366236bda 463 {
Jeej 58:38a366236bda 464 broadcast = true;
Jeej 60:8d4133fbc060 465 max_responses = 33;
Jeej 58:38a366236bda 466 }
Jeej 76:fda2e34ff19d 467
Jeej 46:665391110051 468 // Construct interface
Jeej 71:f03727ff0f99 469 d7a_itf_t itf = {
Jeej 58:38a366236bda 470 // Dash7 interface
Jeej 58:38a366236bda 471 .type = 0xD7,
Jeej 58:38a366236bda 472 // Switch response type if broadcast
Jeej 58:38a366236bda 473 .cfg.qos.bf.resp = (broadcast)? D7A_RESP_ALL : D7A_RESP_ANY,
Jeej 46:665391110051 474 .cfg.qos.bf.retry = retry,
Jeej 46:665391110051 475 .cfg.qos.bf.record = 0,
Jeej 46:665391110051 476 .cfg.qos.bf.stop_on_err = 0,
Jeej 76:fda2e34ff19d 477 .cfg.to.byte = 0,
Jeej 74:30180585b09e 478 .cfg.te.byte = 0,
Jeej 46:665391110051 479 };
Jeej 46:665391110051 480 memcpy(&itf.cfg.addressee, addressee, sizeof(d7a_addressee_t));
Jeej 58:38a366236bda 481
Jeej 58:38a366236bda 482 // Forward action
Jeej 46:665391110051 483 p += d7a_alp_forward_action(p, &itf, true);
Jeej 45:b85384e7d825 484 }
Jeej 45:b85384e7d825 485
Jeej 76:fda2e34ff19d 486 return max_responses;
Jeej 76:fda2e34ff19d 487 }
Jeej 76:fda2e34ff19d 488
Jeej 76:fda2e34ff19d 489 d7a_msg_t** d7a_alp_init_ret(uint32_t max_responses)
Jeej 76:fda2e34ff19d 490 {
Jeej 76:fda2e34ff19d 491 d7a_msg_t** ret = (d7a_msg_t**)MALLOC(sizeof(d7a_msg_t*) * (max_responses + 1));
Jeej 76:fda2e34ff19d 492 for (uint32_t i = 0; i < (max_responses + 1); i++)
Jeej 76:fda2e34ff19d 493 {
Jeej 76:fda2e34ff19d 494 ret[i] = NULL;
Jeej 76:fda2e34ff19d 495 }
Jeej 76:fda2e34ff19d 496
Jeej 76:fda2e34ff19d 497 return ret;
Jeej 76:fda2e34ff19d 498 }
Jeej 76:fda2e34ff19d 499
Jeej 76:fda2e34ff19d 500 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)
Jeej 76:fda2e34ff19d 501 {
Jeej 76:fda2e34ff19d 502 FPRINT("\r\n");
Jeej 76:fda2e34ff19d 503
Jeej 76:fda2e34ff19d 504 // Get command buffer
Jeej 77:8c792719a1fc 505 uint8_t* p = &g_alp_buffer[0];
Jeej 76:fda2e34ff19d 506 // Save initial position of the command buffer
Jeej 76:fda2e34ff19d 507 uint8_t* t = p;
Jeej 76:fda2e34ff19d 508
Jeej 76:fda2e34ff19d 509 uint8_t current_tag;
Jeej 76:fda2e34ff19d 510 d7a_msg_t** ret = NULL;
Jeej 76:fda2e34ff19d 511 uint32_t max_responses;
Jeej 76:fda2e34ff19d 512
Jeej 76:fda2e34ff19d 513 max_responses = d7a_alp_construct_itf(p, root_key, addressee, retry, resp);
Jeej 76:fda2e34ff19d 514
Jeej 76:fda2e34ff19d 515 // malloc and init pointer array
Jeej 76:fda2e34ff19d 516 ret = d7a_alp_init_ret(max_responses);
Jeej 76:fda2e34ff19d 517
Jeej 76:fda2e34ff19d 518
Jeej 76:fda2e34ff19d 519 // Tag action
Jeej 76:fda2e34ff19d 520 p += d7a_alp_tag(p, true);
Jeej 76:fda2e34ff19d 521
Jeej 76:fda2e34ff19d 522 // get tag
Jeej 77:8c792719a1fc 523 current_tag = g_alp_tag;
Jeej 76:fda2e34ff19d 524
Jeej 67:9ac9d109b80a 525 // Ask for root permissions
Jeej 67:9ac9d109b80a 526 if (root_key)
Jeej 67:9ac9d109b80a 527 {
Jeej 67:9ac9d109b80a 528 uint8_t req[100];
Jeej 67:9ac9d109b80a 529 uint8_t req_size = d7a_alp_write_action(req, file_id, offset, size, buf, resp);
Jeej 67:9ac9d109b80a 530 p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
Jeej 67:9ac9d109b80a 531 }
Jeej 76:fda2e34ff19d 532
Jeej 45:b85384e7d825 533 // Write action
Jeej 45:b85384e7d825 534 p += d7a_alp_write_action(p, file_id, offset, size, buf, resp);
Jeej 45:b85384e7d825 535
Jeej 58:38a366236bda 536 // Send command
Jeej 77:8c792719a1fc 537 d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
Jeej 59:b42eae56b51b 538
Jeej 58:38a366236bda 539 // Parse responses
Jeej 59:b42eae56b51b 540 d7a_alp_construct_resp(ret, current_tag, max_responses);
Jeej 45:b85384e7d825 541
Jeej 58:38a366236bda 542 return ret;
Jeej 45:b85384e7d825 543 }
Jeej 45:b85384e7d825 544
Jeej 67:9ac9d109b80a 545 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)
Jeej 45:b85384e7d825 546 {
Jeej 67:9ac9d109b80a 547 FPRINT("\r\n");
Jeej 67:9ac9d109b80a 548
Jeej 58:38a366236bda 549 // Get command buffer
Jeej 77:8c792719a1fc 550 uint8_t* p = &g_alp_buffer[0];
Jeej 58:38a366236bda 551 // Save initial position of the command buffer
Jeej 45:b85384e7d825 552 uint8_t* t = p;
Jeej 45:b85384e7d825 553
Jeej 58:38a366236bda 554 uint8_t current_tag;
Jeej 58:38a366236bda 555 d7a_msg_t** ret = NULL;
Jeej 76:fda2e34ff19d 556 uint32_t max_responses;
Jeej 58:38a366236bda 557
Jeej 76:fda2e34ff19d 558 max_responses = d7a_alp_construct_itf(p, root_key, addressee, retry, true);
Jeej 58:38a366236bda 559
Jeej 58:38a366236bda 560 // malloc and init pointer array
Jeej 76:fda2e34ff19d 561 ret = d7a_alp_init_ret(max_responses);
Jeej 76:fda2e34ff19d 562
Jeej 45:b85384e7d825 563 // Tag action
Jeej 45:b85384e7d825 564 p += d7a_alp_tag(p, true);
Jeej 43:28202405094d 565
Jeej 58:38a366236bda 566 // get tag
Jeej 77:8c792719a1fc 567 current_tag = g_alp_tag;
Jeej 76:fda2e34ff19d 568
Jeej 67:9ac9d109b80a 569 // Ask for root permissions
Jeej 67:9ac9d109b80a 570 if (root_key)
Jeej 67:9ac9d109b80a 571 {
Jeej 67:9ac9d109b80a 572 uint8_t req[100];
Jeej 76:fda2e34ff19d 573 uint8_t req_size = d7a_alp_read_action(p, file_id, offset, size, true);
Jeej 67:9ac9d109b80a 574 p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
Jeej 67:9ac9d109b80a 575 }
Jeej 67:9ac9d109b80a 576
Jeej 43:28202405094d 577 // Read action
Jeej 58:38a366236bda 578 p += d7a_alp_read_action(p, file_id, offset, size, true);
Jeej 45:b85384e7d825 579
Jeej 58:38a366236bda 580 // Send command
Jeej 77:8c792719a1fc 581 d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
Jeej 59:b42eae56b51b 582
Jeej 58:38a366236bda 583 // Parse responses
Jeej 59:b42eae56b51b 584 d7a_alp_construct_resp(ret, current_tag, max_responses);
Jeej 45:b85384e7d825 585
Jeej 58:38a366236bda 586 return ret;
Jeej 43:28202405094d 587 }
Jeej 43:28202405094d 588
Jeej 67:9ac9d109b80a 589
Jeej 67:9ac9d109b80a 590 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)
Jeej 67:9ac9d109b80a 591 {
Jeej 67:9ac9d109b80a 592 FPRINT("\r\n");
Jeej 67:9ac9d109b80a 593
Jeej 67:9ac9d109b80a 594 // Get command buffer
Jeej 77:8c792719a1fc 595 uint8_t* p = &g_alp_buffer[0];
Jeej 67:9ac9d109b80a 596 // Save initial position of the command buffer
Jeej 67:9ac9d109b80a 597 uint8_t* t = p;
Jeej 67:9ac9d109b80a 598
Jeej 67:9ac9d109b80a 599 uint8_t current_tag;
Jeej 67:9ac9d109b80a 600 d7a_msg_t** ret = NULL;
Jeej 76:fda2e34ff19d 601 uint32_t max_responses;
Jeej 67:9ac9d109b80a 602
Jeej 76:fda2e34ff19d 603 max_responses = d7a_alp_construct_itf(p, root_key, addressee, retry, resp);
Jeej 67:9ac9d109b80a 604
Jeej 67:9ac9d109b80a 605 // malloc and init pointer array
Jeej 76:fda2e34ff19d 606 ret = d7a_alp_init_ret(max_responses);
Jeej 67:9ac9d109b80a 607
Jeej 67:9ac9d109b80a 608 // Tag action
Jeej 67:9ac9d109b80a 609 p += d7a_alp_tag(p, true);
Jeej 67:9ac9d109b80a 610
Jeej 67:9ac9d109b80a 611 // get tag
Jeej 77:8c792719a1fc 612 current_tag = g_alp_tag;
Jeej 76:fda2e34ff19d 613
Jeej 67:9ac9d109b80a 614 // Ask for root permissions
Jeej 67:9ac9d109b80a 615 if (root_key)
Jeej 67:9ac9d109b80a 616 {
Jeej 67:9ac9d109b80a 617 uint8_t req[100];
Jeej 76:fda2e34ff19d 618 uint8_t req_size = d7a_alp_flush_action(p, file_id, resp);
Jeej 67:9ac9d109b80a 619 p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
Jeej 67:9ac9d109b80a 620 }
Jeej 67:9ac9d109b80a 621
Jeej 76:fda2e34ff19d 622 // Flush action
Jeej 67:9ac9d109b80a 623 p += d7a_alp_flush_action(p, file_id, resp);
Jeej 67:9ac9d109b80a 624
Jeej 67:9ac9d109b80a 625 // Send command
Jeej 77:8c792719a1fc 626 d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
Jeej 67:9ac9d109b80a 627
Jeej 67:9ac9d109b80a 628 // Parse responses
Jeej 67:9ac9d109b80a 629 d7a_alp_construct_resp(ret, current_tag, max_responses);
Jeej 67:9ac9d109b80a 630
Jeej 67:9ac9d109b80a 631 return ret;
Jeej 67:9ac9d109b80a 632 }
Jeej 67:9ac9d109b80a 633
Jeej 67:9ac9d109b80a 634
Jeej 76:fda2e34ff19d 635 void d7a_alp_thread()
Jeej 43:28202405094d 636 {
Jeej 58:38a366236bda 637 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 43:28202405094d 638 d7a_com_rx_msg_t* pkt;
Jeej 43:28202405094d 639
Jeej 43:28202405094d 640 while (true)
Jeej 43:28202405094d 641 {
Jeej 43:28202405094d 642 pkt = d7a_alp_wait_pkt();
Jeej 43:28202405094d 643 ASSERT(pkt != NULL, "ALP NULL pkt\r\n");
Jeej 43:28202405094d 644
Jeej 43:28202405094d 645 switch(pkt->id)
Jeej 43:28202405094d 646 {
Jeej 43:28202405094d 647 case KAL_COM_FLOW_AT_RESP:
Jeej 79:82b01c1a62f6 648 ALP_DPRINT("KAL_COM_FLOW_AT_RESP\r\n");
Jeej 45:b85384e7d825 649
Jeej 45:b85384e7d825 650 d7a_alp_new_pl(pkt);
Jeej 43:28202405094d 651
Jeej 43:28202405094d 652 break;
Jeej 59:b42eae56b51b 653 case KAL_COM_FLOW_AT_UNS:
Jeej 79:82b01c1a62f6 654 ALP_DPRINT("KAL_COM_FLOW_AT_UNS\r\n");
Jeej 77:8c792719a1fc 655 if (g_alp_uns_msg)
Jeej 65:ac3844adfe49 656 {
Jeej 65:ac3844adfe49 657 d7a_msg_t** uns = (d7a_msg_t**)MALLOC(sizeof(d7a_msg_t*) * 2);
Jeej 65:ac3844adfe49 658
Jeej 65:ac3844adfe49 659 d7a_alp_rsp_t* pl = d7a_alp_parse_pl(pkt);
Jeej 65:ac3844adfe49 660
Jeej 65:ac3844adfe49 661 uns[0] = pl->msg;
Jeej 65:ac3844adfe49 662 uns[1] = NULL;
Jeej 65:ac3844adfe49 663
Jeej 65:ac3844adfe49 664 FREE(pl);
Jeej 65:ac3844adfe49 665
Jeej 65:ac3844adfe49 666 // Callback
Jeej 77:8c792719a1fc 667 g_alp_uns_msg(uns);
Jeej 65:ac3844adfe49 668 }
Jeej 65:ac3844adfe49 669
Jeej 59:b42eae56b51b 670 FREE(pkt);
Jeej 59:b42eae56b51b 671 break;
Jeej 43:28202405094d 672 default:
Jeej 43:28202405094d 673 EPRINT("ALP Unknown Flow ID 0x%02X\r\n", pkt->id);
Jeej 45:b85384e7d825 674 FREE(pkt);
Jeej 43:28202405094d 675 break;
Jeej 43:28202405094d 676 }
Jeej 43:28202405094d 677 }
Jeej 43:28202405094d 678 }