Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Mon Sep 12 16:36:09 2016 +0000
Revision:
58:38a366236bda
Parent:
57:fd9c8b67ffdc
Child:
59:b42eae56b51b
Broadcast.

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