Exportable version of WizziLab's modem driver.

Dependents:   modem_ref_helper

Committer:
Jeej
Date:
Wed Jan 27 14:45:28 2021 +0000
Revision:
56:67e3d9608403
Parent:
51:92667569acc7
Child:
57:5444cfda9889
Sanity commit. Do not use.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 1:40ead20ecb14 1 #include "mbed.h"
Jeej 1:40ead20ecb14 2 #include "WizziDebug.h"
Jeej 1:40ead20ecb14 3
Jeej 0:027760f45e2c 4 #include "modem_ref.h"
Jeej 13:10589aaf8853 5 #include "kal_crypto.h"
Jeej 41:6f83174ffed4 6 #include "kal_codec.h"
Jeej 56:67e3d9608403 7 #include "d7a_1x_fs.h"
Jeej 0:027760f45e2c 8
Jeej 39:bc4fccf2d84b 9 #if 0
Jeej 4:8f031be3ff7d 10 #define REF_PRINT(...) PRINT(__VA_ARGS__)
Jeej 13:10589aaf8853 11 #define URC_PRINT(...) PRINT(__VA_ARGS__)
Jeej 4:8f031be3ff7d 12 #else
Jeej 4:8f031be3ff7d 13 #define REF_PRINT(...);
Jeej 13:10589aaf8853 14 #define URC_PRINT(...);
Jeej 4:8f031be3ff7d 15 #endif
Jeej 4:8f031be3ff7d 16
Jeej 0:027760f45e2c 17 typedef struct {
Jeej 0:027760f45e2c 18 action_callback_t* cb;
Jeej 56:67e3d9608403 19 uint8_t* data;
Jeej 56:67e3d9608403 20 uint8_t* istatus;
Jeej 56:67e3d9608403 21 } modem_ref_user_t;
Jeej 0:027760f45e2c 22
Jeej 0:027760f45e2c 23 typedef struct {
Jeej 56:67e3d9608403 24 uint8_t* data;
Jeej 56:67e3d9608403 25 uint8_t type;
Jeej 56:67e3d9608403 26 uint8_t length;
Jeej 56:67e3d9608403 27 } modem_ref_istatus_t;
Jeej 8:97875739f11a 28
Jeej 8:97875739f11a 29 typedef struct {
Jeej 0:027760f45e2c 30 fx_serial_send_t* send;
Jeej 56:67e3d9608403 31 modem_ref_callbacks_t* cb;
Jeej 56:67e3d9608403 32 modem_lwan_callbacks_t* lwan_cb;
Jeej 56:67e3d9608403 33 modem_ref_user_t user[MAX_USER_NB];
Jeej 56:67e3d9608403 34 modem_ref_istatus_t istatus;
Jeej 56:67e3d9608403 35 uint8_t state;
Jeej 56:67e3d9608403 36 uint8_t tx_sequ;
Jeej 41:6f83174ffed4 37 s32 action;
Jeej 56:67e3d9608403 38 } modem_ref_ctx_t;
Jeej 56:67e3d9608403 39 static modem_ref_ctx_t g_modem;
Jeej 0:027760f45e2c 40
Jeej 0:027760f45e2c 41 #define STATE_OPEN 0xab
Jeej 0:027760f45e2c 42 #define STATE_CLOSED 0
Jeej 0:027760f45e2c 43
Jeej 0:027760f45e2c 44 // Flows
Jeej 0:027760f45e2c 45 #define WC_FLOWID_CMD 0x10
Jeej 0:027760f45e2c 46 #define WC_FLOWID_ALP 0x20
Jeej 0:027760f45e2c 47 #define WC_FLOWID_SYS 0x30
Jeej 0:027760f45e2c 48
Jeej 0:027760f45e2c 49 // Sub-Flows
Jeej 0:027760f45e2c 50 #define WC_FLOW_ALP_CMD 0x20
Jeej 0:027760f45e2c 51 #define WC_FLOW_ALP_RESP 0x21
Jeej 0:027760f45e2c 52 #define WC_FLOW_ALP_UNS 0x22
Jeej 0:027760f45e2c 53 #define WC_FLOW_SYS_RST 0x30
Jeej 0:027760f45e2c 54 #define WC_FLOW_SYS_PING 0x34
Jeej 0:027760f45e2c 55 #define WC_FLOW_SYS_PONG 0x35
Jeej 0:027760f45e2c 56 #define WC_FLOW_SYS_CFG 0x36
Jeej 0:027760f45e2c 57 #define WC_FLOW_SYS_XON 0x39
Jeej 0:027760f45e2c 58 #define WC_FLOW_SYS_XOFF 0x3a
Jeej 0:027760f45e2c 59 #define WC_FLOW_SYS_XACK 0x3b
Jeej 0:027760f45e2c 60
Jeej 0:027760f45e2c 61 // Misc CMD...
Jeej 0:027760f45e2c 62 #define WM_BOOT 0x81
Jeej 0:027760f45e2c 63
Jeej 56:67e3d9608403 64 static void serial_send(uint8_t flowid, uint8_t* data, int size)
Jeej 46:9b83866cef2c 65 {
Jeej 56:67e3d9608403 66 uint8_t len = (uint8_t)size;
Jeej 56:67e3d9608403 67 uint8_t wch[WC_HEADER_SIZE] = {
Jeej 46:9b83866cef2c 68 WC_SYNC_BYTE_0,
Jeej 46:9b83866cef2c 69 WC_SYNC_BYTE_1,
Jeej 46:9b83866cef2c 70 len,
Jeej 46:9b83866cef2c 71 g_modem.tx_sequ++,
Jeej 46:9b83866cef2c 72 flowid
Jeej 46:9b83866cef2c 73 };
Jeej 46:9b83866cef2c 74
Jeej 46:9b83866cef2c 75 ASSERT(size < 256, "serial_send too big for serial protocol (%d/%dmax)", size, 255);
Jeej 56:67e3d9608403 76
Jeej 46:9b83866cef2c 77 g_modem.send(wch, WC_HEADER_SIZE, data, len);
Jeej 46:9b83866cef2c 78 }
Jeej 0:027760f45e2c 79
Jeej 56:67e3d9608403 80 void modem_ref_input(uint8_t flowid, uint8_t* payload, uint8_t size)
Jeej 0:027760f45e2c 81 {
Jeej 0:027760f45e2c 82 int rem =size;
Jeej 56:67e3d9608403 83 uint8_t* p = payload;
Jeej 0:027760f45e2c 84 alp_parsed_chunk_t r;
Jeej 0:027760f45e2c 85 int id = -1;
Jeej 56:67e3d9608403 86 int8_t err = ALP_ERR_NONE;
Jeej 56:67e3d9608403 87 uint8_t eop;
Jeej 34:137ae523ca43 88 uint32_t parsed;
Jeej 41:6f83174ffed4 89
Jeej 41:6f83174ffed4 90 g_modem.action = -1;
Jeej 41:6f83174ffed4 91
Jeej 56:67e3d9608403 92 //REF_PRINT("input 0x%x/%d Bytes\n", flowid, size);
Jeej 0:027760f45e2c 93 switch (flowid)
Jeej 0:027760f45e2c 94 {
Jeej 0:027760f45e2c 95 case WC_FLOW_ALP_UNS:
Jeej 0:027760f45e2c 96 case WC_FLOW_ALP_CMD:
Jeej 34:137ae523ca43 97 parsed = alp_parse_chunk(&p, &r);
Jeej 34:137ae523ca43 98 if (!parsed)
Jeej 34:137ae523ca43 99 {
Jeej 34:137ae523ca43 100 // Discard the payload in case of parsing error.
Jeej 41:6f83174ffed4 101 REF_PRINT("Parsing error line %d!\r\n", __LINE__);
Jeej 34:137ae523ca43 102 break;
Jeej 34:137ae523ca43 103 }
Jeej 34:137ae523ca43 104 rem -= parsed;
Jeej 41:6f83174ffed4 105 g_modem.action++;
Jeej 41:6f83174ffed4 106 //REF_PRINT("Rem %d Bytes\n", rem);
Jeej 0:027760f45e2c 107 // This should always be a TAG'ed request in case of FS access...
Jeej 0:027760f45e2c 108 if (r.type == ALP_OPCODE_TAG)
Jeej 0:027760f45e2c 109 {
Jeej 41:6f83174ffed4 110 REF_PRINT("ACT %d: TAG[%d]\n", g_modem.action, r.meta.tag.id);
Jeej 56:67e3d9608403 111
Jeej 0:027760f45e2c 112 id = r.meta.tag.id;
Jeej 56:67e3d9608403 113
Jeej 8:97875739f11a 114 while(rem>0)
Jeej 0:027760f45e2c 115 {
Jeej 8:97875739f11a 116 // Parse File Operation
Jeej 34:137ae523ca43 117 parsed = alp_parse_chunk(&p, &r);
Jeej 34:137ae523ca43 118 if (!parsed)
Jeej 34:137ae523ca43 119 {
Jeej 34:137ae523ca43 120 // Discard the payload in case of parsing error.
Jeej 41:6f83174ffed4 121 REF_PRINT("Parsing error line %d!\r\n", __LINE__);
Jeej 34:137ae523ca43 122 break;
Jeej 34:137ae523ca43 123 }
Jeej 34:137ae523ca43 124 rem -= parsed;
Jeej 41:6f83174ffed4 125 g_modem.action++;
Jeej 56:67e3d9608403 126 //REF_PRINT("ALP OP[%d]\n", r.type);
Jeej 8:97875739f11a 127 switch (r.type)
Jeej 8:97875739f11a 128 {
Jeej 8:97875739f11a 129 case ALP_OPCODE_F_RD_DATA:
Jeej 41:6f83174ffed4 130 REF_PRINT("ACT %d: F_RD_DATA[%d] @%d %d bytes\n", g_modem.action, r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length);
Jeej 31:517fc900afba 131 if (g_modem.cb->read)
Jeej 31:517fc900afba 132 {
Jeej 41:6f83174ffed4 133 g_modem.cb->read(r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length, id);
Jeej 31:517fc900afba 134 }
Jeej 8:97875739f11a 135 break;
Jeej 8:97875739f11a 136 case ALP_OPCODE_F_WR_DATA:
Jeej 41:6f83174ffed4 137 REF_PRINT("ACT %d: F_WR_DATA[%d] @%d %d bytes\n", g_modem.action, r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length);
Jeej 31:517fc900afba 138 if (g_modem.cb->write)
Jeej 31:517fc900afba 139 {
Jeej 41:6f83174ffed4 140 g_modem.cb->write(r.meta.f_data.fid, r.data, r.meta.f_data.offset, r.meta.f_data.length, id);
Jeej 31:517fc900afba 141 }
Jeej 8:97875739f11a 142 break;
Jeej 8:97875739f11a 143 case ALP_OPCODE_F_RD_PROP:
Jeej 41:6f83174ffed4 144 REF_PRINT("ACT %d: F_RD_PROP[%d]\n", g_modem.action, r.meta.f_data.fid);
Jeej 31:517fc900afba 145 if (g_modem.cb->read_fprop)
Jeej 31:517fc900afba 146 {
Jeej 41:6f83174ffed4 147 g_modem.cb->read_fprop(r.meta.f_data.fid, id);
Jeej 31:517fc900afba 148 }
Jeej 8:97875739f11a 149 break;
Jeej 8:97875739f11a 150 case ALP_OPCODE_F_DELETE:
Jeej 41:6f83174ffed4 151 REF_PRINT("ACT %d: F_DELETE[%d]\n", g_modem.action, r.meta.f_data.fid);
Jeej 31:517fc900afba 152 if (g_modem.cb->remove)
Jeej 31:517fc900afba 153 {
Jeej 41:6f83174ffed4 154 g_modem.cb->remove(r.meta.f_data.fid, id);
Jeej 31:517fc900afba 155 }
Jeej 8:97875739f11a 156 break;
Jeej 8:97875739f11a 157 case ALP_OPCODE_F_FLUSH:
Jeej 41:6f83174ffed4 158 REF_PRINT("ACT %d: F_FLUSH[%d]\n", g_modem.action, r.meta.f_data.fid);
Jeej 31:517fc900afba 159 if (g_modem.cb->flush)
Jeej 31:517fc900afba 160 {
Jeej 41:6f83174ffed4 161 g_modem.cb->flush(r.meta.f_data.fid, id);
Jeej 31:517fc900afba 162 }
Jeej 8:97875739f11a 163 break;
Jeej 8:97875739f11a 164 default:
Jeej 56:67e3d9608403 165 ASSERT(false, "ASSERT: Unsupported ALP File Operation: %d\n", r.type);
Jeej 8:97875739f11a 166 break;
Jeej 8:97875739f11a 167 }
Jeej 26:2c934a269914 168 //REF_PRINT("ALP Parsing done. rem %d\n", rem);
Jeej 0:027760f45e2c 169 }
Jeej 26:2c934a269914 170 //REF_PRINT("ALP Packet done.\n");
Jeej 0:027760f45e2c 171 }
Jeej 0:027760f45e2c 172 else
Jeej 0:027760f45e2c 173 {
Jeej 0:027760f45e2c 174 // ... or a 'real' URC (or ISTATUS if enabled on modem)
Jeej 56:67e3d9608403 175 g_modem.istatus = (modem_ref_istatus_t){0};
Jeej 9:2f921fe9c519 176 do
Jeej 0:027760f45e2c 177 {
Jeej 8:97875739f11a 178 switch (r.type)
Jeej 8:97875739f11a 179 {
Jeej 8:97875739f11a 180 case ALP_OPCODE_RSP_URC:
Jeej 25:14c01b9fc04d 181 if (ALP_URC_TYPE_LQUAL == r.meta.urc.type)
Jeej 41:6f83174ffed4 182 {
Jeej 41:6f83174ffed4 183 REF_PRINT("ACT %d: RSP_URC: LQUAL[%d] %d\n", g_modem.action, r.meta.urc.ifid, r.meta.urc.per);
Jeej 41:6f83174ffed4 184 if (g_modem.cb->lqual)
Jeej 41:6f83174ffed4 185 {
Jeej 41:6f83174ffed4 186 g_modem.cb->lqual(r.meta.urc.ifid, r.meta.urc.per);
Jeej 41:6f83174ffed4 187 }
Jeej 41:6f83174ffed4 188 }
Jeej 25:14c01b9fc04d 189 else if (ALP_URC_TYPE_LDOWN == r.meta.urc.type)
Jeej 41:6f83174ffed4 190 {
Jeej 41:6f83174ffed4 191 REF_PRINT("ACT %d: RSP_URC: LDOWN[%d]\n", g_modem.action, r.meta.urc.ifid);
Jeej 41:6f83174ffed4 192 if (g_modem.cb->ldown)
Jeej 41:6f83174ffed4 193 {
Jeej 41:6f83174ffed4 194 g_modem.cb->ldown(r.meta.urc.ifid);
Jeej 41:6f83174ffed4 195 }
Jeej 41:6f83174ffed4 196 }
Jeej 25:14c01b9fc04d 197 else if (ALP_URC_TYPE_BUSY == r.meta.urc.type)
Jeej 41:6f83174ffed4 198 {
Jeej 41:6f83174ffed4 199 REF_PRINT("ACT %d: RSP_URC: BUSY[%d]\n", g_modem.action, r.meta.urc.ifid);
Jeej 41:6f83174ffed4 200 if (g_modem.cb->busy)
Jeej 41:6f83174ffed4 201 {
Jeej 41:6f83174ffed4 202 g_modem.cb->busy(r.meta.urc.ifid);
Jeej 41:6f83174ffed4 203 }
Jeej 41:6f83174ffed4 204 }
Jeej 41:6f83174ffed4 205 else if (ALP_URC_TYPE_ITF_BUSY == r.meta.urc.type)
Jeej 41:6f83174ffed4 206 {
Jeej 41:6f83174ffed4 207 REF_PRINT("ACT %d: RSP_URC: ITF_BUSY[%d] for %d seconds\n", g_modem.action, r.meta.urc.ifid, r.meta.urc.per);
Jeej 56:67e3d9608403 208
Jeej 56:67e3d9608403 209 if (FID_LWAN_ITF == r.meta.urc.ifid)
Jeej 41:6f83174ffed4 210 {
Jeej 56:67e3d9608403 211 if (g_modem.lwan_cb)
Jeej 56:67e3d9608403 212 {
Jeej 56:67e3d9608403 213 if (MAX_U32 == r.meta.urc.per)
Jeej 56:67e3d9608403 214 {
Jeej 56:67e3d9608403 215 if (g_modem.lwan_cb->join_failed)
Jeej 56:67e3d9608403 216 {
Jeej 56:67e3d9608403 217 g_modem.lwan_cb->join_failed();
Jeej 56:67e3d9608403 218 }
Jeej 56:67e3d9608403 219 }
Jeej 56:67e3d9608403 220 else if (0 == r.meta.urc.per)
Jeej 56:67e3d9608403 221 {
Jeej 56:67e3d9608403 222 if (g_modem.lwan_cb->packet_sent)
Jeej 56:67e3d9608403 223 {
Jeej 56:67e3d9608403 224 g_modem.lwan_cb->packet_sent();
Jeej 56:67e3d9608403 225 }
Jeej 56:67e3d9608403 226 }
Jeej 56:67e3d9608403 227 else
Jeej 56:67e3d9608403 228 {
Jeej 56:67e3d9608403 229 if (g_modem.lwan_cb->itf_busy)
Jeej 56:67e3d9608403 230 {
Jeej 56:67e3d9608403 231 g_modem.lwan_cb->itf_busy(r.meta.urc.per);
Jeej 56:67e3d9608403 232 }
Jeej 56:67e3d9608403 233 }
Jeej 56:67e3d9608403 234 }
Jeej 56:67e3d9608403 235 }
Jeej 56:67e3d9608403 236 else
Jeej 56:67e3d9608403 237 {
Jeej 56:67e3d9608403 238 if (g_modem.cb->itf_busy)
Jeej 56:67e3d9608403 239 {
Jeej 56:67e3d9608403 240 g_modem.cb->itf_busy(r.meta.urc.ifid, r.meta.urc.per);
Jeej 56:67e3d9608403 241 }
Jeej 41:6f83174ffed4 242 }
Jeej 41:6f83174ffed4 243 }
Jeej 8:97875739f11a 244 else
Jeej 41:6f83174ffed4 245 {
Jeej 41:6f83174ffed4 246 ASSERT(false, "ASSERT: Unsupported ALP URC: %d\n", r.meta.urc.type);
Jeej 41:6f83174ffed4 247 }
Jeej 8:97875739f11a 248 break;
Jeej 8:97875739f11a 249 default:
Jeej 35:ac940cf8ebe6 250 // This could be anything
Jeej 35:ac940cf8ebe6 251 // Let user deal with the payload
Jeej 31:517fc900afba 252 if (g_modem.cb->udata)
Jeej 31:517fc900afba 253 {
Jeej 31:517fc900afba 254 g_modem.cb->udata(payload, size);
Jeej 31:517fc900afba 255 }
Jeej 31:517fc900afba 256 rem = 0;
Jeej 8:97875739f11a 257 break;
Jeej 8:97875739f11a 258 }
Jeej 13:10589aaf8853 259
Jeej 9:2f921fe9c519 260 int tem = alp_parse_chunk(&p, &r);
Jeej 9:2f921fe9c519 261 if (!tem)
Jeej 9:2f921fe9c519 262 {
Jeej 9:2f921fe9c519 263 break;
Jeej 9:2f921fe9c519 264 }
Jeej 9:2f921fe9c519 265 rem -= tem;
Jeej 9:2f921fe9c519 266 } while (rem>=0);
Jeej 0:027760f45e2c 267 }
Jeej 0:027760f45e2c 268 break;
Jeej 0:027760f45e2c 269 case WC_FLOW_ALP_RESP:
Jeej 0:027760f45e2c 270 // This should always be a TAG'ed response as we tag our requests
Jeej 34:137ae523ca43 271 parsed = alp_parse_chunk(&p, &r);
Jeej 34:137ae523ca43 272 if (!parsed)
Jeej 34:137ae523ca43 273 {
Jeej 34:137ae523ca43 274 // Discard the payload in case of parsing error.
Jeej 41:6f83174ffed4 275 REF_PRINT("Parsing error line %d!\r\n", __LINE__);
Jeej 34:137ae523ca43 276 break;
Jeej 34:137ae523ca43 277 }
Jeej 34:137ae523ca43 278 rem -= parsed;
Jeej 41:6f83174ffed4 279 g_modem.action++;
Jeej 41:6f83174ffed4 280 //REF_PRINT("Rem %d Bytes\n", rem);
Jeej 56:67e3d9608403 281
Jeej 56:67e3d9608403 282 ASSERT((r.type == ALP_OPCODE_RSP_TAG), "ASSERT: expecting RESP_TAG got %d\n", r.type);
Jeej 41:6f83174ffed4 283 REF_PRINT("ACT %d: TAG[%d]\n", g_modem.action, r.meta.tag.id);
Jeej 1:40ead20ecb14 284 id = r.meta.tag.id;
Jeej 1:40ead20ecb14 285 eop = r.meta.tag.eop;
Jeej 56:67e3d9608403 286 ASSERT(g_modem.user[id].cb != NULL, "ASSERT: NULL Callback for ID %d\n", id);
Jeej 0:027760f45e2c 287 // Empty response
Jeej 0:027760f45e2c 288 if (rem <= 0)
Jeej 0:027760f45e2c 289 {
Jeej 0:027760f45e2c 290 // TODO: still no info on error...
Jeej 0:027760f45e2c 291 err = r.meta.tag.err ? ALP_ERR_UNKNOWN : ALP_ERR_NONE;
Jeej 56:67e3d9608403 292
Jeej 41:6f83174ffed4 293 if (ALP_ERR_NONE != err)
Jeej 41:6f83174ffed4 294 {
Jeej 41:6f83174ffed4 295 REF_PRINT("NO INFO ON ERROR.\n");
Jeej 41:6f83174ffed4 296 }
Jeej 41:6f83174ffed4 297 else if (eop)
Jeej 41:6f83174ffed4 298 {
Jeej 41:6f83174ffed4 299 REF_PRINT("EOP.\n");
Jeej 41:6f83174ffed4 300 }
Jeej 56:67e3d9608403 301
Jeej 56:67e3d9608403 302 g_modem.user[id].cb(eop, err, id);
Jeej 0:027760f45e2c 303 return;
Jeej 0:027760f45e2c 304 }
Jeej 0:027760f45e2c 305
Jeej 1:40ead20ecb14 306 // Actual response(s)
Jeej 1:40ead20ecb14 307 while(rem>0)
Jeej 0:027760f45e2c 308 {
Jeej 34:137ae523ca43 309 parsed = alp_parse_chunk(&p, &r);
Jeej 34:137ae523ca43 310 if (!parsed)
Jeej 34:137ae523ca43 311 {
Jeej 34:137ae523ca43 312 // Discard the payload in case of parsing error.
Jeej 41:6f83174ffed4 313 REF_PRINT("Parsing error line %d!\r\n", __LINE__);
Jeej 34:137ae523ca43 314 break;
Jeej 34:137ae523ca43 315 }
Jeej 34:137ae523ca43 316 rem -= parsed;
Jeej 41:6f83174ffed4 317 g_modem.action++;
Jeej 41:6f83174ffed4 318 //REF_PRINT("Rem %d Bytes\n", rem);
Jeej 56:67e3d9608403 319
Jeej 1:40ead20ecb14 320 switch (r.type)
Jeej 1:40ead20ecb14 321 {
Jeej 14:a9c324663732 322 case ALP_OPCODE_RSP_TAG:
Jeej 41:6f83174ffed4 323 REF_PRINT("ACT %d: RSP_TAG[%d]\n", g_modem.action, r.meta.tag.id);
Jeej 14:a9c324663732 324 break;
Jeej 1:40ead20ecb14 325 case ALP_OPCODE_RSP_F_DATA:
Jeej 41:6f83174ffed4 326 REF_PRINT("ACT %d: RSP_F_DATA[%d]\n", g_modem.action, r.meta.f_data.length);
Jeej 56:67e3d9608403 327 ASSERT(g_modem.user[id].data != NULL, "ASSERT: NULL Data Buffer for RD on ID %d\n", id);
Jeej 41:6f83174ffed4 328 memcpy(g_modem.user[id].data, r.data, r.meta.f_data.length);
Jeej 20:17852941b19e 329 break;
Jeej 6:581caeee80e8 330 case ALP_OPCODE_RSP_F_PROP:
Jeej 41:6f83174ffed4 331 REF_PRINT("ACT %d: RSP_F_PROP[%d]\n", g_modem.action, r.meta.f_data.length);
Jeej 56:67e3d9608403 332 ASSERT(g_modem.user[id].data != NULL, "ASSERT: NULL Data Buffer for RD on ID %d\n", id);
Jeej 41:6f83174ffed4 333 memcpy(g_modem.user[id].data, r.data, r.meta.f_data.length);
Jeej 1:40ead20ecb14 334 break;
Jeej 1:40ead20ecb14 335 case ALP_OPCODE_RSP_STATUS:
Jeej 41:6f83174ffed4 336 REF_PRINT("ACT %d: RSP_STATUS[%d]\n", g_modem.action, r.meta.status.code);
Jeej 1:40ead20ecb14 337 err = r.meta.status.code;
Jeej 1:40ead20ecb14 338 break;
Jeej 1:40ead20ecb14 339 case ALP_OPCODE_RSP_ISTATUS:
Jeej 41:6f83174ffed4 340 REF_PRINT("ACT %d: RSP_ISTATUS[%d]\n", g_modem.action, r.meta.itf.length);
Jeej 56:67e3d9608403 341 ASSERT(g_modem.user[id].istatus != NULL, "ASSERT: NULL ISTAT Buffer for RD on ID %d\n", id);
Jeej 41:6f83174ffed4 342 memcpy(g_modem.user[id].istatus, r.data, r.meta.itf.length);
Jeej 1:40ead20ecb14 343 break;
Jeej 37:f5424d109c6d 344 case ALP_OPCODE_RSP_EOPISTATUS:
Jeej 41:6f83174ffed4 345 REF_PRINT("ACT %d: RSP_EOPISTATUS[%02X]\n", g_modem.action, r.meta.istatus.itf);
Jeej 37:f5424d109c6d 346 err = r.meta.istatus.err ? ALP_ERR_ITF_START + r.meta.istatus.err : ALP_ERR_NONE;
Jeej 37:f5424d109c6d 347 break;
Jeej 1:40ead20ecb14 348 default:
Jeej 56:67e3d9608403 349 ASSERT(false, "ASSERT: Unsupported ALP Response: %d\n", r.type);
Jeej 1:40ead20ecb14 350 break;
Jeej 1:40ead20ecb14 351 }
Jeej 0:027760f45e2c 352 }
Jeej 1:40ead20ecb14 353 if(eop)
Jeej 1:40ead20ecb14 354 { // This is mainly for debug, catch old pointers
Jeej 2:bcf269540633 355 //g_modem.user[id].data = NULL;
Jeej 2:bcf269540633 356 //g_modem.user[id].istatus= NULL;
Jeej 20:17852941b19e 357 REF_PRINT("EOP\n");
Jeej 1:40ead20ecb14 358 }
Jeej 6:581caeee80e8 359 // User Callback
Jeej 31:517fc900afba 360 if (g_modem.user[id].cb)
Jeej 31:517fc900afba 361 {
Jeej 56:67e3d9608403 362 g_modem.user[id].cb(eop, err, id);
Jeej 31:517fc900afba 363 }
Jeej 0:027760f45e2c 364 break;
Jeej 0:027760f45e2c 365 case WC_FLOW_SYS_RST:
Jeej 0:027760f45e2c 366 // 'Software' reset request
Jeej 31:517fc900afba 367 if (g_modem.cb->reset)
Jeej 31:517fc900afba 368 {
Jeej 31:517fc900afba 369 g_modem.cb->reset();
Jeej 31:517fc900afba 370 }
Jeej 0:027760f45e2c 371 break;
Jeej 0:027760f45e2c 372 case WC_FLOWID_CMD:
Jeej 0:027760f45e2c 373 if (*p == WM_BOOT)
Jeej 0:027760f45e2c 374 {
Jeej 56:67e3d9608403 375 uint16_t nb_boot;
Jeej 56:67e3d9608403 376 uint8_t cause;
Jeej 0:027760f45e2c 377 p++;
Jeej 0:027760f45e2c 378 cause = p[0];
Jeej 56:67e3d9608403 379 nb_boot = HAL_TO_U16(p[3], p[2]);
Jeej 31:517fc900afba 380 if (g_modem.cb->boot)
Jeej 31:517fc900afba 381 {
Jeej 56:67e3d9608403 382 g_modem.cb->boot(cause, nb_boot);
Jeej 31:517fc900afba 383 }
Jeej 0:027760f45e2c 384 }
Jeej 0:027760f45e2c 385 else
Jeej 0:027760f45e2c 386 {
Jeej 56:67e3d9608403 387 REF_PRINT("Unsupported CMD :0x%x\n", *p);
Jeej 0:027760f45e2c 388 }
Jeej 0:027760f45e2c 389 break;
Jeej 0:027760f45e2c 390 default:
Jeej 56:67e3d9608403 391 REF_PRINT("Unsupported WC Flowid:0x%x / %d Bytes\n", flowid, size);
Jeej 0:027760f45e2c 392 break;
Jeej 0:027760f45e2c 393 }
Jeej 0:027760f45e2c 394 }
Jeej 0:027760f45e2c 395
Jeej 56:67e3d9608403 396 static uint32_t modem_ref_add_root_permission(uint8_t* p, uint8_t* root_key, uint8_t* action, uint32_t action_size)
Jeej 13:10589aaf8853 397 {
Jeej 56:67e3d9608403 398 uint8_t hash[32];
Jeej 13:10589aaf8853 399
Jeej 13:10589aaf8853 400 // Calculate hash on action
Jeej 13:10589aaf8853 401 kal_sha256_init();
Jeej 13:10589aaf8853 402 kal_sha256_update(action, action_size);
Jeej 56:67e3d9608403 403 kal_sha256_update(root_key, D7A_FS_ROOT_KEY_SIZE);
Jeej 13:10589aaf8853 404 kal_sha256_final(hash);
Jeej 13:10589aaf8853 405 // Prepend Permission-request...
Jeej 56:67e3d9608403 406 ALP_ACTION_PERM_REQ(p, false, ALP_PERM_REQ_ROOT, ALP_WIZZILAB_AUTH_PROTOCOL_ID);
Jeej 13:10589aaf8853 407 // ... and hash
Jeej 56:67e3d9608403 408 memcpy(p, hash, ALP_ACTION_PERM_REQ_TOKEN_SIZE);
Jeej 13:10589aaf8853 409
Jeej 13:10589aaf8853 410 return ALP_ACTION_PERM_REQ_OFFSET;
Jeej 13:10589aaf8853 411 }
Jeej 13:10589aaf8853 412
Jeej 56:67e3d9608403 413 int modem_ref_get_id(action_callback_t* cb)
Jeej 0:027760f45e2c 414 {
Jeej 0:027760f45e2c 415 int i;
Jeej 56:67e3d9608403 416 // Use rolling ids
Jeej 56:67e3d9608403 417 static int rolling;
Jeej 56:67e3d9608403 418
Jeej 56:67e3d9608403 419 for(i = 0; i < MAX_USER_NB; i++)
Jeej 0:027760f45e2c 420 {
Jeej 56:67e3d9608403 421 int id = (i + rolling) % MAX_USER_NB;
Jeej 56:67e3d9608403 422
Jeej 56:67e3d9608403 423 if (g_modem.user[id].cb == NULL)
Jeej 0:027760f45e2c 424 {
Jeej 56:67e3d9608403 425 g_modem.user[id].cb = cb;
Jeej 56:67e3d9608403 426 rolling++;
Jeej 56:67e3d9608403 427 //REF_PRINT("Get ID:%d/0x%08x\n", i, cb);
Jeej 56:67e3d9608403 428 return id;
Jeej 0:027760f45e2c 429 }
Jeej 0:027760f45e2c 430 }
Jeej 56:67e3d9608403 431 ASSERT(i < MAX_USER_NB, "ASSERT: out of users\n");
Jeej 0:027760f45e2c 432 return -1;
Jeej 0:027760f45e2c 433 }
Jeej 0:027760f45e2c 434
Jeej 56:67e3d9608403 435 int modem_ref_free_id(int id)
Jeej 0:027760f45e2c 436 {
Jeej 0:027760f45e2c 437 if (id < MAX_USER_NB)
Jeej 0:027760f45e2c 438 {
Jeej 0:027760f45e2c 439 g_modem.user[id].cb = NULL;
Jeej 0:027760f45e2c 440 g_modem.user[id].data = NULL;
Jeej 1:40ead20ecb14 441 g_modem.user[id].istatus= NULL;
Jeej 56:67e3d9608403 442 //REF_PRINT("Free ID:%d\n", id);
Jeej 0:027760f45e2c 443 return id;
Jeej 0:027760f45e2c 444 }
Jeej 0:027760f45e2c 445 return -1;
Jeej 0:027760f45e2c 446 }
Jeej 0:027760f45e2c 447
Jeej 56:67e3d9608403 448 void modem_ref_open(fx_serial_send_t* send, modem_ref_callbacks_t* callbacks)
Jeej 0:027760f45e2c 449 {
Jeej 0:027760f45e2c 450 if (g_modem.state != STATE_OPEN)
Jeej 0:027760f45e2c 451 {
Jeej 0:027760f45e2c 452 g_modem.send= send;
Jeej 0:027760f45e2c 453 g_modem.cb = callbacks;
Jeej 56:67e3d9608403 454 memset(g_modem.user, 0, (MAX_USER_NB * sizeof(modem_ref_user_t)));
Jeej 0:027760f45e2c 455
Jeej 56:67e3d9608403 456 REF_PRINT("Open Modem - Max users:%d\n", MAX_USER_NB);
Jeej 0:027760f45e2c 457
Jeej 0:027760f45e2c 458 g_modem.state = STATE_OPEN;
Jeej 0:027760f45e2c 459 }
Jeej 0:027760f45e2c 460 }
Jeej 0:027760f45e2c 461
Jeej 56:67e3d9608403 462 void modem_ref_close(void)
Jeej 0:027760f45e2c 463 {
Jeej 0:027760f45e2c 464 if (g_modem.state == STATE_OPEN)
Jeej 0:027760f45e2c 465 {
Jeej 0:027760f45e2c 466 g_modem.state = STATE_CLOSED;
Jeej 0:027760f45e2c 467 }
Jeej 0:027760f45e2c 468 }
Jeej 0:027760f45e2c 469
Jeej 56:67e3d9608403 470 void modem_ref_reset(void)
Jeej 6:581caeee80e8 471 {
Jeej 56:67e3d9608403 472 serial_send(WC_FLOW_SYS_RST, NULL, 0);
Jeej 13:10589aaf8853 473 }
Jeej 13:10589aaf8853 474
Jeej 56:67e3d9608403 475 void modem_ref_set_lwan_cb(modem_lwan_callbacks_t* callbacks)
Jeej 13:10589aaf8853 476 {
Jeej 56:67e3d9608403 477 g_modem.lwan_cb = callbacks;
Jeej 13:10589aaf8853 478 }
Jeej 13:10589aaf8853 479
Jeej 56:67e3d9608403 480 static void _modem_ref_alp(void* itf, void* istatus, alp_pub_payload_t* alp_user, int id)
Jeej 13:10589aaf8853 481 {
Jeej 56:67e3d9608403 482 alp_pub_payload_t* alp = NULL;
Jeej 0:027760f45e2c 483
Jeej 56:67e3d9608403 484 REF_PRINT("ALP %d Bytes\n", alp_user->len);
Jeej 0:027760f45e2c 485
Jeej 56:67e3d9608403 486 // Always a tag
Jeej 56:67e3d9608403 487 alp = alp_payload_tag(alp, id);
Jeej 41:6f83174ffed4 488
Jeej 56:67e3d9608403 489 // Forward on itf if any
Jeej 56:67e3d9608403 490 if (itf)
Jeej 56:67e3d9608403 491 {
Jeej 56:67e3d9608403 492 alp = alp_payload_forward(alp, itf);
Jeej 56:67e3d9608403 493 }
Jeej 0:027760f45e2c 494
Jeej 56:67e3d9608403 495 // add nop to get istatus if any
Jeej 17:b4ea2a912fd3 496 if (istatus)
Jeej 17:b4ea2a912fd3 497 {
Jeej 17:b4ea2a912fd3 498 // NOP action to get istats on ACKs
Jeej 56:67e3d9608403 499 alp = alp_payload_nop(alp);
Jeej 17:b4ea2a912fd3 500 }
Jeej 56:67e3d9608403 501
Jeej 56:67e3d9608403 502 // Add user payload
Jeej 56:67e3d9608403 503 alp = alp_append(alp, alp_user);
Jeej 56:67e3d9608403 504
Jeej 56:67e3d9608403 505 // Send to modem
Jeej 56:67e3d9608403 506 serial_send(WC_FLOW_ALP_UNS, alp->d, alp->len);
Jeej 56:67e3d9608403 507
Jeej 56:67e3d9608403 508 FREE(alp);
Jeej 0:027760f45e2c 509 }
Jeej 0:027760f45e2c 510
Jeej 56:67e3d9608403 511 static void _modem_ref_rsp(alp_pub_payload_t* alp_user, u8 err, int id)
Jeej 1:40ead20ecb14 512 {
Jeej 56:67e3d9608403 513 alp_pub_payload_t* alp = NULL;
Jeej 56:67e3d9608403 514
Jeej 56:67e3d9608403 515 REF_PRINT("RSP %d Bytes\n", alp_user->len);
Jeej 1:40ead20ecb14 516
Jeej 56:67e3d9608403 517 // Always a tag
Jeej 56:67e3d9608403 518 alp = alp_payload_rsp_tag(alp, id, true, err);
Jeej 56:67e3d9608403 519
Jeej 56:67e3d9608403 520 // Add user payload
Jeej 56:67e3d9608403 521 alp = alp_append(alp, alp_user);
Jeej 56:67e3d9608403 522
Jeej 56:67e3d9608403 523 // Send to modem
Jeej 56:67e3d9608403 524 serial_send(WC_FLOW_ALP_UNS, alp->d, alp->len);
Jeej 56:67e3d9608403 525
Jeej 56:67e3d9608403 526 FREE(alp);
Jeej 1:40ead20ecb14 527 }
Jeej 1:40ead20ecb14 528
Jeej 56:67e3d9608403 529 static void _modem_ref_read(void* itf, void* istatus , uint8_t fid, void* data, uint32_t offset, uint32_t length, int id)
Jeej 48:37bf104b3a39 530 {
Jeej 56:67e3d9608403 531 alp_pub_payload_t* alp = NULL;
Jeej 48:37bf104b3a39 532
Jeej 56:67e3d9608403 533 // Expecting data and istatus
Jeej 56:67e3d9608403 534 g_modem.user[id].data = (uint8_t*)data;
Jeej 56:67e3d9608403 535 g_modem.user[id].istatus = (uint8_t*)istatus;
Jeej 56:67e3d9608403 536
Jeej 56:67e3d9608403 537 alp = alp_payload_f_rd_data(alp, fid, offset, length, false);
Jeej 56:67e3d9608403 538
Jeej 56:67e3d9608403 539 _modem_ref_alp(itf, istatus, alp, id);
Jeej 48:37bf104b3a39 540 }
Jeej 48:37bf104b3a39 541
Jeej 56:67e3d9608403 542 static void _modem_ref_write(void* itf, void* istatus, uint8_t fid, void* data, uint32_t offset, uint32_t length, int id)
Jeej 18:a11302a76e96 543 {
Jeej 56:67e3d9608403 544 alp_pub_payload_t* alp = NULL;
Jeej 56:67e3d9608403 545
Jeej 56:67e3d9608403 546 alp = alp_payload_f_wr_data(alp, fid, data, offset, length, false);
Jeej 56:67e3d9608403 547
Jeej 56:67e3d9608403 548 _modem_ref_alp(itf, istatus, alp, id);
Jeej 56:67e3d9608403 549 }
Jeej 56:67e3d9608403 550
Jeej 56:67e3d9608403 551 static void _modem_ref_flush(void* itf, void* istatus, uint8_t fid, int id)
Jeej 56:67e3d9608403 552 {
Jeej 56:67e3d9608403 553 alp_pub_payload_t* alp = NULL;
Jeej 18:a11302a76e96 554
Jeej 56:67e3d9608403 555 alp = alp_payload_f_flush(alp, fid, false);
Jeej 56:67e3d9608403 556
Jeej 56:67e3d9608403 557 _modem_ref_alp(itf, istatus, alp, id);
Jeej 56:67e3d9608403 558 }
Jeej 56:67e3d9608403 559
Jeej 56:67e3d9608403 560 void modem_ref_raw_alp(alp_pub_payload_t* alp_user, int id)
Jeej 56:67e3d9608403 561 {
Jeej 56:67e3d9608403 562 _modem_ref_alp(NULL, NULL, alp_user, id);
Jeej 56:67e3d9608403 563 }
Jeej 56:67e3d9608403 564
Jeej 56:67e3d9608403 565 void modem_ref_remote_raw_alp(void* itf, void* istatus, alp_pub_payload_t* alp_user, int id)
Jeej 56:67e3d9608403 566 {
Jeej 56:67e3d9608403 567 _modem_ref_alp(itf, istatus, alp_user, id);
Jeej 18:a11302a76e96 568 }
Jeej 18:a11302a76e96 569
Jeej 56:67e3d9608403 570 void modem_ref_read_file(uint8_t fid, void* data, uint32_t offset, uint32_t length, int id)
Jeej 56:67e3d9608403 571 {
Jeej 56:67e3d9608403 572 _modem_ref_read(NULL, NULL, fid, data, offset, length, id);
Jeej 56:67e3d9608403 573 }
Jeej 56:67e3d9608403 574
Jeej 56:67e3d9608403 575 void modem_ref_remote_read_file(void* itf, void* istatus , uint8_t fid, void* data, uint32_t offset, uint32_t length, int id)
Jeej 44:656cbcc7843b 576 {
Jeej 56:67e3d9608403 577 _modem_ref_read(itf, istatus, fid, data, offset, length, id);
Jeej 56:67e3d9608403 578 }
Jeej 56:67e3d9608403 579
Jeej 56:67e3d9608403 580 void modem_ref_write_file(uint8_t fid, void* data, uint32_t offset, uint32_t length, int id)
Jeej 56:67e3d9608403 581 {
Jeej 56:67e3d9608403 582 _modem_ref_write(NULL, NULL, fid, data, offset, length, id);
Jeej 56:67e3d9608403 583 }
Jeej 44:656cbcc7843b 584
Jeej 56:67e3d9608403 585 void modem_ref_remote_write_file(void* itf, void* istatus , uint8_t fid, void* data, uint32_t offset, uint32_t length, int id)
Jeej 56:67e3d9608403 586 {
Jeej 56:67e3d9608403 587 _modem_ref_write(itf, istatus, fid, data, offset, length, id);
Jeej 56:67e3d9608403 588 }
Jeej 56:67e3d9608403 589
Jeej 56:67e3d9608403 590 void modem_ref_flush_file(uint8_t fid, int id)
Jeej 56:67e3d9608403 591 {
Jeej 56:67e3d9608403 592 _modem_ref_flush(NULL, NULL, fid, id);
Jeej 56:67e3d9608403 593 }
Jeej 56:67e3d9608403 594
Jeej 56:67e3d9608403 595 void modem_ref_declare_file(u8 fid, alp_file_header_t* hdr, int id)
Jeej 56:67e3d9608403 596 {
Jeej 56:67e3d9608403 597 alp_pub_payload_t* alp = NULL;
Jeej 56:67e3d9608403 598
Jeej 56:67e3d9608403 599 alp = alp_payload_f_flush(alp, fid, false);
Jeej 56:67e3d9608403 600
Jeej 56:67e3d9608403 601 _modem_ref_alp(NULL, NULL, alp, id);
Jeej 18:a11302a76e96 602 }
Jeej 18:a11302a76e96 603
Jeej 56:67e3d9608403 604 void modem_ref_enable_urc(uint8_t type, uint8_t ifid, uint8_t val, int id)
Jeej 0:027760f45e2c 605 {
Jeej 56:67e3d9608403 606 alp_pub_payload_t* alp = NULL;
Jeej 0:027760f45e2c 607
Jeej 56:67e3d9608403 608 alp = alp_payload_urcc_en(alp, type, ifid, val);
Jeej 56:67e3d9608403 609
Jeej 56:67e3d9608403 610 _modem_ref_alp(NULL, NULL, alp, id);
Jeej 0:027760f45e2c 611 }
Jeej 0:027760f45e2c 612
Jeej 56:67e3d9608403 613 void modem_ref_activate_itf(uint8_t type, uint8_t nb_dev, uint8_t ifid, uint8_t flags, uint8_t enable, int id)
Jeej 1:40ead20ecb14 614 {
Jeej 56:67e3d9608403 615 alp_pub_payload_t* alp = NULL;
Jeej 1:40ead20ecb14 616
Jeej 56:67e3d9608403 617 alp = alp_payload_activate_itf(alp, type, nb_dev, ifid, flags, enable);
Jeej 56:67e3d9608403 618
Jeej 56:67e3d9608403 619 _modem_ref_alp(NULL, NULL, alp, id);
Jeej 1:40ead20ecb14 620 }
Jeej 1:40ead20ecb14 621
Jeej 56:67e3d9608403 622 void modem_ref_respond(uint8_t action, int8_t status, int id)
Jeej 0:027760f45e2c 623 {
Jeej 56:67e3d9608403 624 alp_pub_payload_t* alp = NULL;
Jeej 0:027760f45e2c 625
Jeej 56:67e3d9608403 626 alp = alp_payload_rsp_status(alp, action, status);
Jeej 56:67e3d9608403 627
Jeej 56:67e3d9608403 628 _modem_ref_rsp(alp, (status < ALP_ERR_NONE)? true: false, id);
Jeej 0:027760f45e2c 629 }
Jeej 0:027760f45e2c 630
Jeej 56:67e3d9608403 631 void modem_ref_respond_fprop(uint8_t fid, alp_file_header_t* hdr, int id)
Jeej 0:027760f45e2c 632 {
Jeej 56:67e3d9608403 633 alp_pub_payload_t* alp = NULL;
Jeej 0:027760f45e2c 634
Jeej 56:67e3d9608403 635 alp = alp_payload_rsp_fprop(alp, fid, hdr);
Jeej 56:67e3d9608403 636
Jeej 56:67e3d9608403 637 _modem_ref_rsp(alp, false, id);
Jeej 0:027760f45e2c 638 }
Jeej 0:027760f45e2c 639
Jeej 56:67e3d9608403 640 void modem_ref_respond_read(uint8_t fid, void* data, uint32_t offset, uint32_t length, int id)
Jeej 0:027760f45e2c 641 {
Jeej 56:67e3d9608403 642 alp_pub_payload_t* alp = NULL;
Jeej 56:67e3d9608403 643
Jeej 56:67e3d9608403 644 alp = alp_payload_rsp_f_data(alp, fid, data, offset, length);
Jeej 56:67e3d9608403 645
Jeej 56:67e3d9608403 646 _modem_ref_rsp(alp, false, id);
Jeej 13:10589aaf8853 647 }