Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Fri Sep 23 15:00:41 2016 +0000
Revision:
59:b42eae56b51b
Parent:
58:38a366236bda
Child:
60:8d4133fbc060
Optimized ALP parsing

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