Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Wed Dec 21 14:11:09 2016 +0000
Revision:
78:f1c0affd99e7
Parent:
77:8c792719a1fc
Child:
79:82b01c1a62f6
Reduced stack size to fit in target NUCLEO-L432KC.

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