Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Thu Jan 05 12:59:13 2017 +0000
Revision:
83:f4054d0b29ba
Parent:
82:5d1b101b6d11
Child:
84:e5388f1b8ed9
Selective FPRINT

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 80:30265d5dd20a 15 #define ALP_DPRINT_DATA(...) ALP_DPRINT_DATA(__VA_ARGS__)
Jeej 83:f4054d0b29ba 16 #define ALP_FPRINT(...) FPRINT(__VA_ARGS__)
Jeej 79:82b01c1a62f6 17 #else
Jeej 79:82b01c1a62f6 18 #define ALP_DPRINT(...);
Jeej 79:82b01c1a62f6 19 #define ALP_DPRINT_DATA(...);
Jeej 83:f4054d0b29ba 20 #define ALP_FPRINT(...);
Jeej 79:82b01c1a62f6 21 #endif
Jeej 79:82b01c1a62f6 22
Jeej 77:8c792719a1fc 23 #define ALP_CMD_MAX_LENGHT (256)
Jeej 43:28202405094d 24
Jeej 77:8c792719a1fc 25 static uint8_t g_alp_tag;
Jeej 77:8c792719a1fc 26 static uint8_t g_alp_buffer[ALP_CMD_MAX_LENGHT];
Jeej 77:8c792719a1fc 27 static Queue<d7a_com_rx_msg_t, 8> g_alp_pkt_queue;
Jeej 77:8c792719a1fc 28 static Queue<d7a_com_rx_msg_t, 8> g_alp_pl_queue;
Jeej 77:8c792719a1fc 29 static UnsolicitedMsgFunction g_alp_uns_msg;
Jeej 78:f1c0affd99e7 30 static Thread g_alp_thread(osPriorityHigh, 512, NULL);
Jeej 77:8c792719a1fc 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 83:f4054d0b29ba 36 ALP_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 83:f4054d0b29ba 48 ALP_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 83:f4054d0b29ba 57 ALP_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 83:f4054d0b29ba 63 ALP_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 83:f4054d0b29ba 69 ALP_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 83:f4054d0b29ba 76 ALP_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 83:f4054d0b29ba 170 ALP_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 83:f4054d0b29ba 181 ALP_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 83:f4054d0b29ba 192 ALP_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 80:30265d5dd20a 231 ALP_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 80:30265d5dd20a 258 //ALP_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 82:5d1b101b6d11 347 //PRINT_DATA("Req : ", "%02X ", (uint8_t*)req, req_size, "\r\n");
Jeej 82:5d1b101b6d11 348 //PRINT_DATA("Key : ", "%d ", (uint8_t*)root_key, D7A_ROOT_KEY_SIZE, "\r\n");
Jeej 67:9ac9d109b80a 349 //PRINT_DATA("Token: ", "%02X", hash, D7A_AUTH_PROTOCOLE_TOKEN_SIZE, "\r\n");
Jeej 67:9ac9d109b80a 350 p += d7a_alp_add(p, hash, D7A_AUTH_PROTOCOLE_TOKEN_SIZE);
Jeej 67:9ac9d109b80a 351
Jeej 67:9ac9d109b80a 352 return (uint32_t)(p - t);
Jeej 67:9ac9d109b80a 353 }
Jeej 67:9ac9d109b80a 354
Jeej 67:9ac9d109b80a 355 static uint32_t d7a_alp_flush_action(uint8_t* p, uint8_t fid, bool resp)
Jeej 67:9ac9d109b80a 356 {
Jeej 67:9ac9d109b80a 357 uint8_t* t = p;
Jeej 67:9ac9d109b80a 358
Jeej 67:9ac9d109b80a 359 *p++ = ALP_OPCODE_F_FLUSH + ((resp)? ALP_CTRL_RESP : 0);
Jeej 67:9ac9d109b80a 360 *p++ = fid;
Jeej 67:9ac9d109b80a 361
Jeej 67:9ac9d109b80a 362 return (uint32_t)(p - t);
Jeej 67:9ac9d109b80a 363 }
Jeej 67:9ac9d109b80a 364
Jeej 67:9ac9d109b80a 365 static void d7a_alp_construct_resp(d7a_msg_t** ret, uint8_t current_tag, uint32_t max_responses)
Jeej 67:9ac9d109b80a 366 {
Jeej 83:f4054d0b29ba 367 ALP_FPRINT("\r\n");
Jeej 67:9ac9d109b80a 368
Jeej 59:b42eae56b51b 369 int i = 0;
Jeej 59:b42eae56b51b 370 d7a_alp_rsp_t* pl = NULL;
Jeej 59:b42eae56b51b 371 d7a_com_rx_msg_t* pkt = NULL;
Jeej 70:07b378285c95 372 int32_t time;
Jeej 70:07b378285c95 373 Timer timeout;
Jeej 70:07b378285c95 374
Jeej 70:07b378285c95 375 timeout.start();
Jeej 59:b42eae56b51b 376
Jeej 59:b42eae56b51b 377 // Parse responses
Jeej 59:b42eae56b51b 378 do
Jeej 43:28202405094d 379 {
Jeej 70:07b378285c95 380 time = D7A_ALP_RESP_TO - timeout.read_ms();
Jeej 70:07b378285c95 381 if (time < 0) time = 0;
Jeej 70:07b378285c95 382
Jeej 70:07b378285c95 383 pkt = d7a_alp_wait_pl(time);
Jeej 59:b42eae56b51b 384
Jeej 59:b42eae56b51b 385 if (pkt == NULL)
Jeej 59:b42eae56b51b 386 {
Jeej 59:b42eae56b51b 387 ret[i] = d7a_alp_new_msg();
Jeej 59:b42eae56b51b 388 ret[i]->err = D7A_ERR_CMD_TO;
Jeej 59:b42eae56b51b 389 break;
Jeej 59:b42eae56b51b 390 }
Jeej 59:b42eae56b51b 391
Jeej 59:b42eae56b51b 392 pl = d7a_alp_parse_pl(pkt);
Jeej 67:9ac9d109b80a 393
Jeej 59:b42eae56b51b 394 // Check TAG
Jeej 59:b42eae56b51b 395 if (pl->tag == NO_TAG)
Jeej 59:b42eae56b51b 396 {
Jeej 59:b42eae56b51b 397 WARNING(false, "No tag in payload expected %d\r\n", current_tag);
Jeej 59:b42eae56b51b 398 FREE(pkt);
Jeej 59:b42eae56b51b 399 d7a_alp_free_msg(pl->msg);
Jeej 59:b42eae56b51b 400 FREE(pl);
Jeej 59:b42eae56b51b 401 ret[i] = d7a_alp_new_msg();
Jeej 59:b42eae56b51b 402 ret[i]->err = D7A_ERR_UNKNOWN;
Jeej 59:b42eae56b51b 403 break;
Jeej 59:b42eae56b51b 404 }
Jeej 59:b42eae56b51b 405
Jeej 59:b42eae56b51b 406 if (pl->tag != current_tag)
Jeej 59:b42eae56b51b 407 {
Jeej 59:b42eae56b51b 408 WARNING(false, "Ingnoring tag %d expecting %d\r\n", pl->tag, current_tag);
Jeej 59:b42eae56b51b 409 d7a_alp_free_msg(pl->msg);
Jeej 59:b42eae56b51b 410 FREE(pl);
Jeej 59:b42eae56b51b 411 d7a_alp_new_pl(pkt);
Jeej 59:b42eae56b51b 412 continue;
Jeej 59:b42eae56b51b 413 }
Jeej 59:b42eae56b51b 414
Jeej 59:b42eae56b51b 415 FREE(pkt);
Jeej 59:b42eae56b51b 416
Jeej 59:b42eae56b51b 417 // Check for END OF PAYLOAD
Jeej 59:b42eae56b51b 418 if (pl->eop)
Jeej 59:b42eae56b51b 419 {
Jeej 79:82b01c1a62f6 420 ALP_DPRINT("EOP\r\n");
Jeej 59:b42eae56b51b 421
Jeej 59:b42eae56b51b 422 // If tag only
Jeej 62:f1e4da5162c2 423 if (!pl->msg->data && !pl->msg->lb && i != 0)
Jeej 59:b42eae56b51b 424 {
Jeej 59:b42eae56b51b 425 // Ignore response
Jeej 59:b42eae56b51b 426 d7a_alp_free_msg(pl->msg);
Jeej 59:b42eae56b51b 427 }
Jeej 59:b42eae56b51b 428 else
Jeej 59:b42eae56b51b 429 {
Jeej 79:82b01c1a62f6 430 ALP_DPRINT("last response (err %d)\r\n", pl->msg->err);
Jeej 59:b42eae56b51b 431 ret[i] = pl->msg;
Jeej 59:b42eae56b51b 432 }
Jeej 59:b42eae56b51b 433
Jeej 59:b42eae56b51b 434 FREE(pl);
Jeej 59:b42eae56b51b 435 break;
Jeej 59:b42eae56b51b 436 }
Jeej 59:b42eae56b51b 437 // Wait for new msg
Jeej 59:b42eae56b51b 438 else
Jeej 59:b42eae56b51b 439 {
Jeej 79:82b01c1a62f6 440 ALP_DPRINT("next response (err %d)\r\n", pl->msg->err);
Jeej 59:b42eae56b51b 441 ret[i] = pl->msg;
Jeej 59:b42eae56b51b 442 FREE(pl);
Jeej 59:b42eae56b51b 443 i++;
Jeej 59:b42eae56b51b 444 ASSERT(i <= max_responses, "Too much responses! max: %d\r\n", max_responses);
Jeej 59:b42eae56b51b 445 }
Jeej 59:b42eae56b51b 446
Jeej 59:b42eae56b51b 447 } while (1);
Jeej 58:38a366236bda 448 }
Jeej 45:b85384e7d825 449
Jeej 82:5d1b101b6d11 450 uint32_t d7a_alp_construct_itf(uint8_t* p, d7a_addressee_t* addressee, uint8_t retry, bool resp)
Jeej 43:28202405094d 451 {
Jeej 58:38a366236bda 452 bool broadcast = false;
Jeej 60:8d4133fbc060 453 uint32_t max_responses = 2;
Jeej 58:38a366236bda 454
Jeej 58:38a366236bda 455 if (addressee)
Jeej 58:38a366236bda 456 {
Jeej 58:38a366236bda 457 if (addressee->ctrl.bf.idf == D7A_ID_NBID)
Jeej 58:38a366236bda 458 {
Jeej 58:38a366236bda 459 broadcast = true;
Jeej 58:38a366236bda 460 d7a_ctf_t ctf;
Jeej 58:38a366236bda 461 ctf.byte = addressee->id[0];
Jeej 60:8d4133fbc060 462 max_responses = ((1 << (2*ctf.bf.exp)) * ctf.bf.mant) + 1;
Jeej 58:38a366236bda 463 }
Jeej 58:38a366236bda 464 else if (addressee->ctrl.bf.idf == D7A_ID_NOID)
Jeej 58:38a366236bda 465 {
Jeej 58:38a366236bda 466 broadcast = true;
Jeej 60:8d4133fbc060 467 max_responses = 33;
Jeej 58:38a366236bda 468 }
Jeej 76:fda2e34ff19d 469
Jeej 46:665391110051 470 // Construct interface
Jeej 71:f03727ff0f99 471 d7a_itf_t itf = {
Jeej 58:38a366236bda 472 // Dash7 interface
Jeej 58:38a366236bda 473 .type = 0xD7,
Jeej 58:38a366236bda 474 // Switch response type if broadcast
Jeej 58:38a366236bda 475 .cfg.qos.bf.resp = (broadcast)? D7A_RESP_ALL : D7A_RESP_ANY,
Jeej 46:665391110051 476 .cfg.qos.bf.retry = retry,
Jeej 46:665391110051 477 .cfg.qos.bf.record = 0,
Jeej 46:665391110051 478 .cfg.qos.bf.stop_on_err = 0,
Jeej 76:fda2e34ff19d 479 .cfg.to.byte = 0,
Jeej 74:30180585b09e 480 .cfg.te.byte = 0,
Jeej 46:665391110051 481 };
Jeej 46:665391110051 482 memcpy(&itf.cfg.addressee, addressee, sizeof(d7a_addressee_t));
Jeej 58:38a366236bda 483
Jeej 58:38a366236bda 484 // Forward action
Jeej 46:665391110051 485 p += d7a_alp_forward_action(p, &itf, true);
Jeej 45:b85384e7d825 486 }
Jeej 45:b85384e7d825 487
Jeej 76:fda2e34ff19d 488 return max_responses;
Jeej 76:fda2e34ff19d 489 }
Jeej 76:fda2e34ff19d 490
Jeej 76:fda2e34ff19d 491 d7a_msg_t** d7a_alp_init_ret(uint32_t max_responses)
Jeej 76:fda2e34ff19d 492 {
Jeej 76:fda2e34ff19d 493 d7a_msg_t** ret = (d7a_msg_t**)MALLOC(sizeof(d7a_msg_t*) * (max_responses + 1));
Jeej 76:fda2e34ff19d 494 for (uint32_t i = 0; i < (max_responses + 1); i++)
Jeej 76:fda2e34ff19d 495 {
Jeej 76:fda2e34ff19d 496 ret[i] = NULL;
Jeej 76:fda2e34ff19d 497 }
Jeej 76:fda2e34ff19d 498
Jeej 76:fda2e34ff19d 499 return ret;
Jeej 76:fda2e34ff19d 500 }
Jeej 76:fda2e34ff19d 501
Jeej 76:fda2e34ff19d 502 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 503 {
Jeej 83:f4054d0b29ba 504 ALP_FPRINT("\r\n");
Jeej 76:fda2e34ff19d 505
Jeej 76:fda2e34ff19d 506 // Get command buffer
Jeej 77:8c792719a1fc 507 uint8_t* p = &g_alp_buffer[0];
Jeej 76:fda2e34ff19d 508 // Save initial position of the command buffer
Jeej 76:fda2e34ff19d 509 uint8_t* t = p;
Jeej 76:fda2e34ff19d 510
Jeej 76:fda2e34ff19d 511 uint8_t current_tag;
Jeej 76:fda2e34ff19d 512 d7a_msg_t** ret = NULL;
Jeej 76:fda2e34ff19d 513 uint32_t max_responses;
Jeej 76:fda2e34ff19d 514
Jeej 82:5d1b101b6d11 515 max_responses = d7a_alp_construct_itf(p, addressee, retry, resp);
Jeej 76:fda2e34ff19d 516
Jeej 76:fda2e34ff19d 517 // malloc and init pointer array
Jeej 76:fda2e34ff19d 518 ret = d7a_alp_init_ret(max_responses);
Jeej 76:fda2e34ff19d 519
Jeej 76:fda2e34ff19d 520
Jeej 76:fda2e34ff19d 521 // Tag action
Jeej 76:fda2e34ff19d 522 p += d7a_alp_tag(p, true);
Jeej 76:fda2e34ff19d 523
Jeej 76:fda2e34ff19d 524 // get tag
Jeej 77:8c792719a1fc 525 current_tag = g_alp_tag;
Jeej 76:fda2e34ff19d 526
Jeej 67:9ac9d109b80a 527 // Ask for root permissions
Jeej 67:9ac9d109b80a 528 if (root_key)
Jeej 67:9ac9d109b80a 529 {
Jeej 67:9ac9d109b80a 530 uint8_t req[100];
Jeej 67:9ac9d109b80a 531 uint8_t req_size = d7a_alp_write_action(req, file_id, offset, size, buf, resp);
Jeej 67:9ac9d109b80a 532 p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
Jeej 67:9ac9d109b80a 533 }
Jeej 76:fda2e34ff19d 534
Jeej 45:b85384e7d825 535 // Write action
Jeej 45:b85384e7d825 536 p += d7a_alp_write_action(p, file_id, offset, size, buf, resp);
Jeej 45:b85384e7d825 537
Jeej 58:38a366236bda 538 // Send command
Jeej 77:8c792719a1fc 539 d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
Jeej 59:b42eae56b51b 540
Jeej 58:38a366236bda 541 // Parse responses
Jeej 59:b42eae56b51b 542 d7a_alp_construct_resp(ret, current_tag, max_responses);
Jeej 45:b85384e7d825 543
Jeej 58:38a366236bda 544 return ret;
Jeej 45:b85384e7d825 545 }
Jeej 45:b85384e7d825 546
Jeej 67:9ac9d109b80a 547 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 548 {
Jeej 83:f4054d0b29ba 549 ALP_FPRINT("\r\n");
Jeej 67:9ac9d109b80a 550
Jeej 58:38a366236bda 551 // Get command buffer
Jeej 77:8c792719a1fc 552 uint8_t* p = &g_alp_buffer[0];
Jeej 58:38a366236bda 553 // Save initial position of the command buffer
Jeej 45:b85384e7d825 554 uint8_t* t = p;
Jeej 45:b85384e7d825 555
Jeej 58:38a366236bda 556 uint8_t current_tag;
Jeej 58:38a366236bda 557 d7a_msg_t** ret = NULL;
Jeej 76:fda2e34ff19d 558 uint32_t max_responses;
Jeej 58:38a366236bda 559
Jeej 82:5d1b101b6d11 560 max_responses = d7a_alp_construct_itf(p, addressee, retry, true);
Jeej 58:38a366236bda 561
Jeej 58:38a366236bda 562 // malloc and init pointer array
Jeej 76:fda2e34ff19d 563 ret = d7a_alp_init_ret(max_responses);
Jeej 76:fda2e34ff19d 564
Jeej 45:b85384e7d825 565 // Tag action
Jeej 45:b85384e7d825 566 p += d7a_alp_tag(p, true);
Jeej 43:28202405094d 567
Jeej 58:38a366236bda 568 // get tag
Jeej 77:8c792719a1fc 569 current_tag = g_alp_tag;
Jeej 76:fda2e34ff19d 570
Jeej 67:9ac9d109b80a 571 // Ask for root permissions
Jeej 67:9ac9d109b80a 572 if (root_key)
Jeej 67:9ac9d109b80a 573 {
Jeej 67:9ac9d109b80a 574 uint8_t req[100];
Jeej 82:5d1b101b6d11 575 uint8_t req_size = d7a_alp_read_action(req, file_id, offset, size, true);
Jeej 67:9ac9d109b80a 576 p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
Jeej 67:9ac9d109b80a 577 }
Jeej 67:9ac9d109b80a 578
Jeej 43:28202405094d 579 // Read action
Jeej 58:38a366236bda 580 p += d7a_alp_read_action(p, file_id, offset, size, true);
Jeej 45:b85384e7d825 581
Jeej 58:38a366236bda 582 // Send command
Jeej 77:8c792719a1fc 583 d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
Jeej 59:b42eae56b51b 584
Jeej 58:38a366236bda 585 // Parse responses
Jeej 59:b42eae56b51b 586 d7a_alp_construct_resp(ret, current_tag, max_responses);
Jeej 45:b85384e7d825 587
Jeej 58:38a366236bda 588 return ret;
Jeej 43:28202405094d 589 }
Jeej 43:28202405094d 590
Jeej 67:9ac9d109b80a 591
Jeej 67:9ac9d109b80a 592 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 593 {
Jeej 83:f4054d0b29ba 594 ALP_FPRINT("\r\n");
Jeej 67:9ac9d109b80a 595
Jeej 67:9ac9d109b80a 596 // Get command buffer
Jeej 77:8c792719a1fc 597 uint8_t* p = &g_alp_buffer[0];
Jeej 67:9ac9d109b80a 598 // Save initial position of the command buffer
Jeej 67:9ac9d109b80a 599 uint8_t* t = p;
Jeej 67:9ac9d109b80a 600
Jeej 67:9ac9d109b80a 601 uint8_t current_tag;
Jeej 67:9ac9d109b80a 602 d7a_msg_t** ret = NULL;
Jeej 76:fda2e34ff19d 603 uint32_t max_responses;
Jeej 67:9ac9d109b80a 604
Jeej 82:5d1b101b6d11 605 max_responses = d7a_alp_construct_itf(p, addressee, retry, resp);
Jeej 67:9ac9d109b80a 606
Jeej 67:9ac9d109b80a 607 // malloc and init pointer array
Jeej 76:fda2e34ff19d 608 ret = d7a_alp_init_ret(max_responses);
Jeej 67:9ac9d109b80a 609
Jeej 67:9ac9d109b80a 610 // Tag action
Jeej 67:9ac9d109b80a 611 p += d7a_alp_tag(p, true);
Jeej 67:9ac9d109b80a 612
Jeej 67:9ac9d109b80a 613 // get tag
Jeej 77:8c792719a1fc 614 current_tag = g_alp_tag;
Jeej 76:fda2e34ff19d 615
Jeej 67:9ac9d109b80a 616 // Ask for root permissions
Jeej 67:9ac9d109b80a 617 if (root_key)
Jeej 67:9ac9d109b80a 618 {
Jeej 67:9ac9d109b80a 619 uint8_t req[100];
Jeej 82:5d1b101b6d11 620 uint8_t req_size = d7a_alp_flush_action(req, file_id, resp);
Jeej 67:9ac9d109b80a 621 p += d7a_alp_perm_request_action(p, req, req_size, root_key, false);
Jeej 67:9ac9d109b80a 622 }
Jeej 67:9ac9d109b80a 623
Jeej 76:fda2e34ff19d 624 // Flush action
Jeej 67:9ac9d109b80a 625 p += d7a_alp_flush_action(p, file_id, resp);
Jeej 67:9ac9d109b80a 626
Jeej 67:9ac9d109b80a 627 // Send command
Jeej 77:8c792719a1fc 628 d7a_com_dump(&g_alp_buffer[0], (uint8_t)(p - t), KAL_COM_FLOW_AT_CMD);
Jeej 67:9ac9d109b80a 629
Jeej 67:9ac9d109b80a 630 // Parse responses
Jeej 67:9ac9d109b80a 631 d7a_alp_construct_resp(ret, current_tag, max_responses);
Jeej 67:9ac9d109b80a 632
Jeej 67:9ac9d109b80a 633 return ret;
Jeej 67:9ac9d109b80a 634 }
Jeej 67:9ac9d109b80a 635
Jeej 67:9ac9d109b80a 636
Jeej 76:fda2e34ff19d 637 void d7a_alp_thread()
Jeej 43:28202405094d 638 {
Jeej 83:f4054d0b29ba 639 ALP_FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 43:28202405094d 640 d7a_com_rx_msg_t* pkt;
Jeej 43:28202405094d 641
Jeej 43:28202405094d 642 while (true)
Jeej 43:28202405094d 643 {
Jeej 43:28202405094d 644 pkt = d7a_alp_wait_pkt();
Jeej 43:28202405094d 645 ASSERT(pkt != NULL, "ALP NULL pkt\r\n");
Jeej 43:28202405094d 646
Jeej 43:28202405094d 647 switch(pkt->id)
Jeej 43:28202405094d 648 {
Jeej 43:28202405094d 649 case KAL_COM_FLOW_AT_RESP:
Jeej 79:82b01c1a62f6 650 ALP_DPRINT("KAL_COM_FLOW_AT_RESP\r\n");
Jeej 45:b85384e7d825 651
Jeej 45:b85384e7d825 652 d7a_alp_new_pl(pkt);
Jeej 43:28202405094d 653
Jeej 43:28202405094d 654 break;
Jeej 59:b42eae56b51b 655 case KAL_COM_FLOW_AT_UNS:
Jeej 79:82b01c1a62f6 656 ALP_DPRINT("KAL_COM_FLOW_AT_UNS\r\n");
Jeej 77:8c792719a1fc 657 if (g_alp_uns_msg)
Jeej 65:ac3844adfe49 658 {
Jeej 65:ac3844adfe49 659 d7a_msg_t** uns = (d7a_msg_t**)MALLOC(sizeof(d7a_msg_t*) * 2);
Jeej 65:ac3844adfe49 660
Jeej 65:ac3844adfe49 661 d7a_alp_rsp_t* pl = d7a_alp_parse_pl(pkt);
Jeej 65:ac3844adfe49 662
Jeej 65:ac3844adfe49 663 uns[0] = pl->msg;
Jeej 65:ac3844adfe49 664 uns[1] = NULL;
Jeej 65:ac3844adfe49 665
Jeej 65:ac3844adfe49 666 FREE(pl);
Jeej 65:ac3844adfe49 667
Jeej 65:ac3844adfe49 668 // Callback
Jeej 77:8c792719a1fc 669 g_alp_uns_msg(uns);
Jeej 65:ac3844adfe49 670 }
Jeej 65:ac3844adfe49 671
Jeej 59:b42eae56b51b 672 FREE(pkt);
Jeej 59:b42eae56b51b 673 break;
Jeej 43:28202405094d 674 default:
Jeej 43:28202405094d 675 EPRINT("ALP Unknown Flow ID 0x%02X\r\n", pkt->id);
Jeej 45:b85384e7d825 676 FREE(pkt);
Jeej 43:28202405094d 677 break;
Jeej 43:28202405094d 678 }
Jeej 43:28202405094d 679 }
Jeej 43:28202405094d 680 }