Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Tue Dec 20 09:30:14 2016 +0000
Revision:
76:fda2e34ff19d
Parent:
74:30180585b09e
Child:
77:8c792719a1fc
Updated for mbed OS 5

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