Exportable version of WizziLab's modem driver.

Dependents:   modem_ref_helper

Committer:
Jeej
Date:
Fri Jan 29 16:36:32 2021 +0000
Revision:
57:5444cfda9889
Parent:
56:67e3d9608403
Child:
58:8d58e5cb4037
Sanity commit. Reworked driver version. Partially functional. To be tested with all demo applications.

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 57:5444cfda9889 10 #define REF_PRINT(...) PRINT(__VA_ARGS__)
Jeej 57:5444cfda9889 11 #define URC_PRINT(...) PRINT(__VA_ARGS__)
Jeej 4:8f031be3ff7d 12 #else
Jeej 57:5444cfda9889 13 #define REF_PRINT(...);
Jeej 57:5444cfda9889 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 57:5444cfda9889 19 alp_payload_t** alp_rsp;
Jeej 56:67e3d9608403 20 } modem_ref_user_t;
Jeej 0:027760f45e2c 21
Jeej 0:027760f45e2c 22 typedef struct {
Jeej 57:5444cfda9889 23 fx_serial_send_t* send;
Jeej 56:67e3d9608403 24 modem_ref_callbacks_t* cb;
Jeej 56:67e3d9608403 25 modem_lwan_callbacks_t* lwan_cb;
Jeej 56:67e3d9608403 26 modem_ref_user_t user[MAX_USER_NB];
Jeej 57:5444cfda9889 27 u8 state;
Jeej 56:67e3d9608403 28 } modem_ref_ctx_t;
Jeej 57:5444cfda9889 29
Jeej 56:67e3d9608403 30 static modem_ref_ctx_t g_modem;
Jeej 0:027760f45e2c 31
Jeej 0:027760f45e2c 32 #define STATE_OPEN 0xab
Jeej 0:027760f45e2c 33 #define STATE_CLOSED 0
Jeej 0:027760f45e2c 34
Jeej 0:027760f45e2c 35 // Flows
Jeej 0:027760f45e2c 36 #define WC_FLOWID_CMD 0x10
Jeej 0:027760f45e2c 37 #define WC_FLOWID_ALP 0x20
Jeej 0:027760f45e2c 38 #define WC_FLOWID_SYS 0x30
Jeej 0:027760f45e2c 39
Jeej 0:027760f45e2c 40 // Sub-Flows
Jeej 0:027760f45e2c 41 #define WC_FLOW_ALP_CMD 0x20
Jeej 0:027760f45e2c 42 #define WC_FLOW_ALP_RESP 0x21
Jeej 0:027760f45e2c 43 #define WC_FLOW_ALP_UNS 0x22
Jeej 0:027760f45e2c 44 #define WC_FLOW_SYS_RST 0x30
Jeej 0:027760f45e2c 45 #define WC_FLOW_SYS_PING 0x34
Jeej 0:027760f45e2c 46 #define WC_FLOW_SYS_PONG 0x35
Jeej 0:027760f45e2c 47 #define WC_FLOW_SYS_CFG 0x36
Jeej 0:027760f45e2c 48 #define WC_FLOW_SYS_XON 0x39
Jeej 0:027760f45e2c 49 #define WC_FLOW_SYS_XOFF 0x3a
Jeej 0:027760f45e2c 50 #define WC_FLOW_SYS_XACK 0x3b
Jeej 0:027760f45e2c 51
Jeej 0:027760f45e2c 52 // Misc CMD...
Jeej 0:027760f45e2c 53 #define WM_BOOT 0x81
Jeej 0:027760f45e2c 54
Jeej 57:5444cfda9889 55 #define PKT_MAX_SIZE 255
Jeej 57:5444cfda9889 56 static void serial_send(WizziComPacketType type, alp_payload_t* alp)
Jeej 57:5444cfda9889 57 {
Jeej 57:5444cfda9889 58 u8 buf[PKT_MAX_SIZE];
Jeej 57:5444cfda9889 59 u32 len = alp_payload_to_buf(alp, buf, 0, PKT_MAX_SIZE);
Jeej 57:5444cfda9889 60
Jeej 57:5444cfda9889 61 g_modem.send(type, buf, len);
Jeej 57:5444cfda9889 62 }
Jeej 57:5444cfda9889 63
Jeej 57:5444cfda9889 64 static void _call_fs_user_cb(alp_payload_t* alp, int id, u32 action)
Jeej 46:9b83866cef2c 65 {
Jeej 57:5444cfda9889 66 alp_parsed_chunk_t r;
Jeej 57:5444cfda9889 67 u8* p = alp->d;
Jeej 57:5444cfda9889 68
Jeej 57:5444cfda9889 69 if (NULL == alp)
Jeej 57:5444cfda9889 70 {
Jeej 57:5444cfda9889 71 return;
Jeej 57:5444cfda9889 72 }
Jeej 57:5444cfda9889 73
Jeej 57:5444cfda9889 74 alp_parse_chunk(&p, &r);
Jeej 57:5444cfda9889 75
Jeej 57:5444cfda9889 76 switch (r.type)
Jeej 57:5444cfda9889 77 {
Jeej 57:5444cfda9889 78 case ALP_OPCODE_TAG:
Jeej 57:5444cfda9889 79 id = r.meta.tag.id;
Jeej 57:5444cfda9889 80 REF_PRINT("ACT %d: TAG[%d] ID:%d ERR:%d EOP:%d\n", action, id, r.meta.tag.err, r.meta.tag.eop);
Jeej 57:5444cfda9889 81 break;
Jeej 57:5444cfda9889 82 case ALP_OPCODE_F_RD_DATA:
Jeej 57:5444cfda9889 83 REF_PRINT("ACT %d: F_RD_DATA[%d] @%d %d bytes\n", action, r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length);
Jeej 57:5444cfda9889 84 if (g_modem.cb->read)
Jeej 57:5444cfda9889 85 {
Jeej 57:5444cfda9889 86 g_modem.cb->read(action, r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length, id);
Jeej 57:5444cfda9889 87 }
Jeej 57:5444cfda9889 88 break;
Jeej 57:5444cfda9889 89 case ALP_OPCODE_F_WR_DATA:
Jeej 57:5444cfda9889 90 REF_PRINT("ACT %d: F_WR_DATA[%d] @%d %d bytes\n", action, r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length);
Jeej 57:5444cfda9889 91 if (g_modem.cb->write)
Jeej 57:5444cfda9889 92 {
Jeej 57:5444cfda9889 93 g_modem.cb->write(action, r.meta.f_data.fid, r.data, r.meta.f_data.offset, r.meta.f_data.length, id);
Jeej 57:5444cfda9889 94 }
Jeej 57:5444cfda9889 95 break;
Jeej 57:5444cfda9889 96 case ALP_OPCODE_F_RD_PROP:
Jeej 57:5444cfda9889 97 REF_PRINT("ACT %d: F_RD_PROP[%d]\n", action, r.meta.f_data.fid);
Jeej 57:5444cfda9889 98 if (g_modem.cb->read_fprop)
Jeej 57:5444cfda9889 99 {
Jeej 57:5444cfda9889 100 g_modem.cb->read_fprop(action, r.meta.f_data.fid, id);
Jeej 57:5444cfda9889 101 }
Jeej 57:5444cfda9889 102 break;
Jeej 57:5444cfda9889 103 case ALP_OPCODE_F_DELETE:
Jeej 57:5444cfda9889 104 REF_PRINT("ACT %d: F_DELETE[%d]\n", action, r.meta.f_data.fid);
Jeej 57:5444cfda9889 105 if (g_modem.cb->remove)
Jeej 57:5444cfda9889 106 {
Jeej 57:5444cfda9889 107 g_modem.cb->remove(action, r.meta.f_data.fid, id);
Jeej 57:5444cfda9889 108 }
Jeej 57:5444cfda9889 109 break;
Jeej 57:5444cfda9889 110 case ALP_OPCODE_F_FLUSH:
Jeej 57:5444cfda9889 111 REF_PRINT("ACT %d: F_FLUSH[%d]\n", action, r.meta.f_data.fid);
Jeej 57:5444cfda9889 112 if (g_modem.cb->flush)
Jeej 57:5444cfda9889 113 {
Jeej 57:5444cfda9889 114 g_modem.cb->flush(action, r.meta.f_data.fid, id);
Jeej 57:5444cfda9889 115 }
Jeej 57:5444cfda9889 116 break;
Jeej 57:5444cfda9889 117 default:
Jeej 57:5444cfda9889 118 ASSERT(false, "ASSERT: Unsupported ALP File Operation: %d\n", r.type);
Jeej 57:5444cfda9889 119 break;
Jeej 57:5444cfda9889 120 }
Jeej 57:5444cfda9889 121
Jeej 57:5444cfda9889 122 ASSERT(id >= 0, "ASSERT: Wrong id %d\n", id);
Jeej 57:5444cfda9889 123
Jeej 57:5444cfda9889 124 _call_fs_user_cb(alp->next, id, ++action);
Jeej 57:5444cfda9889 125 }
Jeej 46:9b83866cef2c 126
Jeej 57:5444cfda9889 127 static void call_fs_user_cb(alp_payload_t* alp)
Jeej 57:5444cfda9889 128 {
Jeej 57:5444cfda9889 129 _call_fs_user_cb(alp, -1, 0);
Jeej 46:9b83866cef2c 130 }
Jeej 0:027760f45e2c 131
Jeej 57:5444cfda9889 132 static void _call_urc_user_cb(alp_payload_t* alp, u32 action)
Jeej 57:5444cfda9889 133 {
Jeej 57:5444cfda9889 134 alp_parsed_chunk_t r;
Jeej 57:5444cfda9889 135 u8* p = alp->d;
Jeej 57:5444cfda9889 136
Jeej 57:5444cfda9889 137 if (NULL == alp)
Jeej 57:5444cfda9889 138 {
Jeej 57:5444cfda9889 139 return;
Jeej 57:5444cfda9889 140 }
Jeej 57:5444cfda9889 141
Jeej 57:5444cfda9889 142 alp_parse_chunk(&p, &r);
Jeej 57:5444cfda9889 143
Jeej 57:5444cfda9889 144 switch (r.type)
Jeej 57:5444cfda9889 145 {
Jeej 57:5444cfda9889 146 case ALP_OPCODE_RSP_URC:
Jeej 57:5444cfda9889 147 if (ALP_URC_TYPE_LQUAL == r.meta.urc.type)
Jeej 57:5444cfda9889 148 {
Jeej 57:5444cfda9889 149 REF_PRINT("ACT %d: RSP_URC: LQUAL[%d] %d\n", action, r.meta.urc.ifid, r.meta.urc.per);
Jeej 57:5444cfda9889 150 if (g_modem.cb->lqual)
Jeej 57:5444cfda9889 151 {
Jeej 57:5444cfda9889 152 g_modem.cb->lqual(r.meta.urc.ifid, r.meta.urc.per);
Jeej 57:5444cfda9889 153 }
Jeej 57:5444cfda9889 154 }
Jeej 57:5444cfda9889 155 else if (ALP_URC_TYPE_LDOWN == r.meta.urc.type)
Jeej 57:5444cfda9889 156 {
Jeej 57:5444cfda9889 157 REF_PRINT("ACT %d: RSP_URC: LDOWN[%d]\n", action, r.meta.urc.ifid);
Jeej 57:5444cfda9889 158 if (g_modem.cb->ldown)
Jeej 57:5444cfda9889 159 {
Jeej 57:5444cfda9889 160 g_modem.cb->ldown(r.meta.urc.ifid);
Jeej 57:5444cfda9889 161 }
Jeej 57:5444cfda9889 162 }
Jeej 57:5444cfda9889 163 else if (ALP_URC_TYPE_BUSY == r.meta.urc.type)
Jeej 57:5444cfda9889 164 {
Jeej 57:5444cfda9889 165 REF_PRINT("ACT %d: RSP_URC: BUSY[%d]\n", action, r.meta.urc.ifid);
Jeej 57:5444cfda9889 166 if (g_modem.cb->busy)
Jeej 57:5444cfda9889 167 {
Jeej 57:5444cfda9889 168 g_modem.cb->busy(r.meta.urc.ifid);
Jeej 57:5444cfda9889 169 }
Jeej 57:5444cfda9889 170 }
Jeej 57:5444cfda9889 171 else if (ALP_URC_TYPE_ITF_BUSY == r.meta.urc.type)
Jeej 57:5444cfda9889 172 {
Jeej 57:5444cfda9889 173 REF_PRINT("ACT %d: RSP_URC: ITF_BUSY[%d] for %d seconds\n", action, r.meta.urc.ifid, r.meta.urc.per);
Jeej 57:5444cfda9889 174
Jeej 57:5444cfda9889 175 if (FID_LWAN_ITF == r.meta.urc.ifid)
Jeej 57:5444cfda9889 176 {
Jeej 57:5444cfda9889 177 if (g_modem.lwan_cb)
Jeej 57:5444cfda9889 178 {
Jeej 57:5444cfda9889 179 if (MAX_U32 == r.meta.urc.per)
Jeej 57:5444cfda9889 180 {
Jeej 57:5444cfda9889 181 if (g_modem.lwan_cb->join_failed)
Jeej 57:5444cfda9889 182 {
Jeej 57:5444cfda9889 183 g_modem.lwan_cb->join_failed();
Jeej 57:5444cfda9889 184 }
Jeej 57:5444cfda9889 185 }
Jeej 57:5444cfda9889 186 else if (0 == r.meta.urc.per)
Jeej 57:5444cfda9889 187 {
Jeej 57:5444cfda9889 188 if (g_modem.lwan_cb->packet_sent)
Jeej 57:5444cfda9889 189 {
Jeej 57:5444cfda9889 190 g_modem.lwan_cb->packet_sent();
Jeej 57:5444cfda9889 191 }
Jeej 57:5444cfda9889 192 }
Jeej 57:5444cfda9889 193 else
Jeej 57:5444cfda9889 194 {
Jeej 57:5444cfda9889 195 if (g_modem.lwan_cb->itf_busy)
Jeej 57:5444cfda9889 196 {
Jeej 57:5444cfda9889 197 g_modem.lwan_cb->itf_busy(r.meta.urc.per);
Jeej 57:5444cfda9889 198 }
Jeej 57:5444cfda9889 199 }
Jeej 57:5444cfda9889 200 }
Jeej 57:5444cfda9889 201 }
Jeej 57:5444cfda9889 202 else
Jeej 57:5444cfda9889 203 {
Jeej 57:5444cfda9889 204 if (g_modem.cb->itf_busy)
Jeej 57:5444cfda9889 205 {
Jeej 57:5444cfda9889 206 g_modem.cb->itf_busy(r.meta.urc.ifid, r.meta.urc.per);
Jeej 57:5444cfda9889 207 }
Jeej 57:5444cfda9889 208 }
Jeej 57:5444cfda9889 209 }
Jeej 57:5444cfda9889 210 else
Jeej 57:5444cfda9889 211 {
Jeej 57:5444cfda9889 212 ASSERT(false, "ASSERT: Unsupported ALP URC: %d\n", r.meta.urc.type);
Jeej 57:5444cfda9889 213 }
Jeej 57:5444cfda9889 214 break;
Jeej 57:5444cfda9889 215 default:
Jeej 57:5444cfda9889 216 // This could be anything
Jeej 57:5444cfda9889 217 // Let user deal with the payload
Jeej 57:5444cfda9889 218 if (g_modem.cb->udata)
Jeej 57:5444cfda9889 219 {
Jeej 57:5444cfda9889 220 g_modem.cb->udata(alp);
Jeej 57:5444cfda9889 221 }
Jeej 57:5444cfda9889 222 break;
Jeej 57:5444cfda9889 223 }
Jeej 57:5444cfda9889 224
Jeej 57:5444cfda9889 225 _call_urc_user_cb(alp->next, ++action);
Jeej 57:5444cfda9889 226 }
Jeej 57:5444cfda9889 227
Jeej 57:5444cfda9889 228 static void call_urc_user_cb(alp_payload_t* alp)
Jeej 57:5444cfda9889 229 {
Jeej 57:5444cfda9889 230 _call_urc_user_cb(alp, 0);
Jeej 57:5444cfda9889 231 }
Jeej 57:5444cfda9889 232
Jeej 57:5444cfda9889 233 void modem_ref_input(u8 flowid, u8* payload, u8 size)
Jeej 0:027760f45e2c 234 {
Jeej 0:027760f45e2c 235 int rem =size;
Jeej 57:5444cfda9889 236 u8* p = payload;
Jeej 0:027760f45e2c 237 alp_parsed_chunk_t r;
Jeej 0:027760f45e2c 238 int id = -1;
Jeej 57:5444cfda9889 239 s8 err = ALP_ERR_NONE;
Jeej 57:5444cfda9889 240 u8 eop;
Jeej 57:5444cfda9889 241 u32 parsed;
Jeej 57:5444cfda9889 242 alp_payload_t* alp;
Jeej 41:6f83174ffed4 243
Jeej 57:5444cfda9889 244 REF_PRINT("input 0x%x/%d Bytes\n", flowid, size);
Jeej 0:027760f45e2c 245 switch (flowid)
Jeej 0:027760f45e2c 246 {
Jeej 0:027760f45e2c 247 case WC_FLOW_ALP_UNS:
Jeej 0:027760f45e2c 248 case WC_FLOW_ALP_CMD:
Jeej 57:5444cfda9889 249
Jeej 57:5444cfda9889 250 // pre-parse payload
Jeej 57:5444cfda9889 251 alp = alp_payload_parse(p, size);
Jeej 57:5444cfda9889 252 //alp_payload_print(alp);
Jeej 57:5444cfda9889 253
Jeej 57:5444cfda9889 254 if (ALP_OPCODE_TAG == (alp->d[0] & 0x3F))
Jeej 0:027760f45e2c 255 {
Jeej 57:5444cfda9889 256 // Payload starts with a tag, this must be a FS command
Jeej 57:5444cfda9889 257 call_fs_user_cb(alp);
Jeej 0:027760f45e2c 258 }
Jeej 0:027760f45e2c 259 else
Jeej 0:027760f45e2c 260 {
Jeej 57:5444cfda9889 261 // else this is a 'real' URC (or ISTATUS if enabled on modem)
Jeej 57:5444cfda9889 262 call_urc_user_cb(alp);
Jeej 57:5444cfda9889 263 }
Jeej 57:5444cfda9889 264
Jeej 57:5444cfda9889 265 alp_payload_free(alp);
Jeej 56:67e3d9608403 266
Jeej 0:027760f45e2c 267 break;
Jeej 0:027760f45e2c 268 case WC_FLOW_ALP_RESP:
Jeej 57:5444cfda9889 269
Jeej 57:5444cfda9889 270 // pre-parse payload
Jeej 57:5444cfda9889 271 alp = alp_payload_parse(p, size);
Jeej 57:5444cfda9889 272 //alp_payload_print(alp);
Jeej 57:5444cfda9889 273
Jeej 57:5444cfda9889 274 p = alp->d;
Jeej 57:5444cfda9889 275 alp_parse_chunk(&p, &r);
Jeej 57:5444cfda9889 276
Jeej 0:027760f45e2c 277 // This should always be a TAG'ed response as we tag our requests
Jeej 57:5444cfda9889 278 ASSERT((r.type == ALP_OPCODE_RSP_TAG), "ASSERT: expecting RESP_TAG got 0x%02X\n", r.type);
Jeej 57:5444cfda9889 279
Jeej 1:40ead20ecb14 280 id = r.meta.tag.id;
Jeej 1:40ead20ecb14 281 eop = r.meta.tag.eop;
Jeej 56:67e3d9608403 282 ASSERT(g_modem.user[id].cb != NULL, "ASSERT: NULL Callback for ID %d\n", id);
Jeej 56:67e3d9608403 283
Jeej 57:5444cfda9889 284 // Give the remaining of the payload to the user to deal with
Jeej 57:5444cfda9889 285 *(g_modem.user[id].alp_rsp) = alp_payload_append(*(g_modem.user[id].alp_rsp), alp);
Jeej 57:5444cfda9889 286
Jeej 1:40ead20ecb14 287 if(eop)
Jeej 1:40ead20ecb14 288 { // This is mainly for debug, catch old pointers
Jeej 2:bcf269540633 289 //g_modem.user[id].data = NULL;
Jeej 2:bcf269540633 290 //g_modem.user[id].istatus= NULL;
Jeej 20:17852941b19e 291 REF_PRINT("EOP\n");
Jeej 1:40ead20ecb14 292 }
Jeej 57:5444cfda9889 293
Jeej 6:581caeee80e8 294 // User Callback
Jeej 57:5444cfda9889 295 g_modem.user[id].cb(eop, err, id);
Jeej 57:5444cfda9889 296
Jeej 0:027760f45e2c 297 break;
Jeej 0:027760f45e2c 298 case WC_FLOW_SYS_RST:
Jeej 0:027760f45e2c 299 // 'Software' reset request
Jeej 31:517fc900afba 300 if (g_modem.cb->reset)
Jeej 31:517fc900afba 301 {
Jeej 31:517fc900afba 302 g_modem.cb->reset();
Jeej 31:517fc900afba 303 }
Jeej 0:027760f45e2c 304 break;
Jeej 0:027760f45e2c 305 case WC_FLOWID_CMD:
Jeej 0:027760f45e2c 306 if (*p == WM_BOOT)
Jeej 0:027760f45e2c 307 {
Jeej 56:67e3d9608403 308 uint16_t nb_boot;
Jeej 57:5444cfda9889 309 u8 cause;
Jeej 0:027760f45e2c 310 p++;
Jeej 0:027760f45e2c 311 cause = p[0];
Jeej 56:67e3d9608403 312 nb_boot = HAL_TO_U16(p[3], p[2]);
Jeej 31:517fc900afba 313 if (g_modem.cb->boot)
Jeej 31:517fc900afba 314 {
Jeej 56:67e3d9608403 315 g_modem.cb->boot(cause, nb_boot);
Jeej 31:517fc900afba 316 }
Jeej 0:027760f45e2c 317 }
Jeej 0:027760f45e2c 318 else
Jeej 0:027760f45e2c 319 {
Jeej 56:67e3d9608403 320 REF_PRINT("Unsupported CMD :0x%x\n", *p);
Jeej 0:027760f45e2c 321 }
Jeej 0:027760f45e2c 322 break;
Jeej 57:5444cfda9889 323 default:
Jeej 56:67e3d9608403 324 REF_PRINT("Unsupported WC Flowid:0x%x / %d Bytes\n", flowid, size);
Jeej 0:027760f45e2c 325 break;
Jeej 0:027760f45e2c 326 }
Jeej 0:027760f45e2c 327 }
Jeej 0:027760f45e2c 328
Jeej 57:5444cfda9889 329 static u32 modem_ref_add_root_permission(u8* p, u8* root_key, u8* action, u32 action_size)
Jeej 13:10589aaf8853 330 {
Jeej 57:5444cfda9889 331 u8 hash[32];
Jeej 13:10589aaf8853 332
Jeej 13:10589aaf8853 333 // Calculate hash on action
Jeej 13:10589aaf8853 334 kal_sha256_init();
Jeej 13:10589aaf8853 335 kal_sha256_update(action, action_size);
Jeej 56:67e3d9608403 336 kal_sha256_update(root_key, D7A_FS_ROOT_KEY_SIZE);
Jeej 13:10589aaf8853 337 kal_sha256_final(hash);
Jeej 13:10589aaf8853 338 // Prepend Permission-request...
Jeej 56:67e3d9608403 339 ALP_ACTION_PERM_REQ(p, false, ALP_PERM_REQ_ROOT, ALP_WIZZILAB_AUTH_PROTOCOL_ID);
Jeej 13:10589aaf8853 340 // ... and hash
Jeej 56:67e3d9608403 341 memcpy(p, hash, ALP_ACTION_PERM_REQ_TOKEN_SIZE);
Jeej 13:10589aaf8853 342
Jeej 13:10589aaf8853 343 return ALP_ACTION_PERM_REQ_OFFSET;
Jeej 13:10589aaf8853 344 }
Jeej 13:10589aaf8853 345
Jeej 56:67e3d9608403 346 int modem_ref_get_id(action_callback_t* cb)
Jeej 0:027760f45e2c 347 {
Jeej 0:027760f45e2c 348 int i;
Jeej 56:67e3d9608403 349 // Use rolling ids
Jeej 57:5444cfda9889 350 static u8 rolling;
Jeej 56:67e3d9608403 351
Jeej 56:67e3d9608403 352 for(i = 0; i < MAX_USER_NB; i++)
Jeej 0:027760f45e2c 353 {
Jeej 56:67e3d9608403 354 int id = (i + rolling) % MAX_USER_NB;
Jeej 56:67e3d9608403 355
Jeej 56:67e3d9608403 356 if (g_modem.user[id].cb == NULL)
Jeej 0:027760f45e2c 357 {
Jeej 56:67e3d9608403 358 g_modem.user[id].cb = cb;
Jeej 56:67e3d9608403 359 rolling++;
Jeej 56:67e3d9608403 360 //REF_PRINT("Get ID:%d/0x%08x\n", i, cb);
Jeej 56:67e3d9608403 361 return id;
Jeej 0:027760f45e2c 362 }
Jeej 0:027760f45e2c 363 }
Jeej 56:67e3d9608403 364 ASSERT(i < MAX_USER_NB, "ASSERT: out of users\n");
Jeej 0:027760f45e2c 365 return -1;
Jeej 0:027760f45e2c 366 }
Jeej 0:027760f45e2c 367
Jeej 57:5444cfda9889 368 int modem_ref_free_id(u8 id)
Jeej 0:027760f45e2c 369 {
Jeej 0:027760f45e2c 370 if (id < MAX_USER_NB)
Jeej 0:027760f45e2c 371 {
Jeej 0:027760f45e2c 372 g_modem.user[id].cb = NULL;
Jeej 56:67e3d9608403 373 //REF_PRINT("Free ID:%d\n", id);
Jeej 0:027760f45e2c 374 return id;
Jeej 0:027760f45e2c 375 }
Jeej 0:027760f45e2c 376 return -1;
Jeej 0:027760f45e2c 377 }
Jeej 0:027760f45e2c 378
Jeej 56:67e3d9608403 379 void modem_ref_open(fx_serial_send_t* send, modem_ref_callbacks_t* callbacks)
Jeej 0:027760f45e2c 380 {
Jeej 0:027760f45e2c 381 if (g_modem.state != STATE_OPEN)
Jeej 0:027760f45e2c 382 {
Jeej 57:5444cfda9889 383 g_modem.send = send;
Jeej 0:027760f45e2c 384 g_modem.cb = callbacks;
Jeej 56:67e3d9608403 385 memset(g_modem.user, 0, (MAX_USER_NB * sizeof(modem_ref_user_t)));
Jeej 0:027760f45e2c 386
Jeej 56:67e3d9608403 387 REF_PRINT("Open Modem - Max users:%d\n", MAX_USER_NB);
Jeej 0:027760f45e2c 388
Jeej 0:027760f45e2c 389 g_modem.state = STATE_OPEN;
Jeej 0:027760f45e2c 390 }
Jeej 0:027760f45e2c 391 }
Jeej 0:027760f45e2c 392
Jeej 56:67e3d9608403 393 void modem_ref_close(void)
Jeej 0:027760f45e2c 394 {
Jeej 0:027760f45e2c 395 if (g_modem.state == STATE_OPEN)
Jeej 0:027760f45e2c 396 {
Jeej 0:027760f45e2c 397 g_modem.state = STATE_CLOSED;
Jeej 0:027760f45e2c 398 }
Jeej 0:027760f45e2c 399 }
Jeej 0:027760f45e2c 400
Jeej 56:67e3d9608403 401 void modem_ref_reset(void)
Jeej 6:581caeee80e8 402 {
Jeej 57:5444cfda9889 403 serial_send(WizziComPacketSysReset, NULL);
Jeej 13:10589aaf8853 404 }
Jeej 13:10589aaf8853 405
Jeej 56:67e3d9608403 406 void modem_ref_set_lwan_cb(modem_lwan_callbacks_t* callbacks)
Jeej 13:10589aaf8853 407 {
Jeej 56:67e3d9608403 408 g_modem.lwan_cb = callbacks;
Jeej 13:10589aaf8853 409 }
Jeej 13:10589aaf8853 410
Jeej 57:5444cfda9889 411 void modem_ref_alp(void* itf, alp_payload_t* alp_user, alp_payload_t** alp_rsp, int id)
Jeej 13:10589aaf8853 412 {
Jeej 57:5444cfda9889 413 alp_payload_t* alp = NULL;
Jeej 57:5444cfda9889 414
Jeej 57:5444cfda9889 415 if (alp_rsp)
Jeej 57:5444cfda9889 416 {
Jeej 57:5444cfda9889 417 // Expecting a response
Jeej 0:027760f45e2c 418
Jeej 57:5444cfda9889 419 // Make sure pointer value is NULL
Jeej 57:5444cfda9889 420 *alp_rsp = NULL;
Jeej 57:5444cfda9889 421 }
Jeej 57:5444cfda9889 422
Jeej 57:5444cfda9889 423 // response pointer
Jeej 57:5444cfda9889 424 g_modem.user[id].alp_rsp = alp_rsp;
Jeej 0:027760f45e2c 425
Jeej 56:67e3d9608403 426 // Always a tag
Jeej 56:67e3d9608403 427 alp = alp_payload_tag(alp, id);
Jeej 41:6f83174ffed4 428
Jeej 56:67e3d9608403 429 // Forward on itf if any
Jeej 56:67e3d9608403 430 if (itf)
Jeej 56:67e3d9608403 431 {
Jeej 56:67e3d9608403 432 alp = alp_payload_forward(alp, itf);
Jeej 17:b4ea2a912fd3 433 // NOP action to get istats on ACKs
Jeej 56:67e3d9608403 434 alp = alp_payload_nop(alp);
Jeej 17:b4ea2a912fd3 435 }
Jeej 56:67e3d9608403 436
Jeej 56:67e3d9608403 437 // Add user payload
Jeej 57:5444cfda9889 438 alp = alp_payload_append(alp, alp_user);
Jeej 56:67e3d9608403 439
Jeej 56:67e3d9608403 440 // Send to modem
Jeej 57:5444cfda9889 441 serial_send(WizziComPacketAlpUns, alp);
Jeej 0:027760f45e2c 442 }
Jeej 0:027760f45e2c 443
Jeej 57:5444cfda9889 444 static void _modem_ref_rsp(alp_payload_t* alp_user, u8 err, int id)
Jeej 1:40ead20ecb14 445 {
Jeej 57:5444cfda9889 446 alp_payload_t* alp = NULL;
Jeej 56:67e3d9608403 447
Jeej 57:5444cfda9889 448 // response pointer
Jeej 57:5444cfda9889 449 g_modem.user[id].alp_rsp = NULL;
Jeej 1:40ead20ecb14 450
Jeej 56:67e3d9608403 451 // Always a tag
Jeej 56:67e3d9608403 452 alp = alp_payload_rsp_tag(alp, id, true, err);
Jeej 56:67e3d9608403 453
Jeej 56:67e3d9608403 454 // Add user payload
Jeej 57:5444cfda9889 455 alp = alp_payload_append(alp, alp_user);
Jeej 56:67e3d9608403 456
Jeej 56:67e3d9608403 457 // Send to modem
Jeej 57:5444cfda9889 458 serial_send(WizziComPacketAlpUns, alp);
Jeej 18:a11302a76e96 459 }
Jeej 18:a11302a76e96 460
Jeej 57:5444cfda9889 461 void modem_ref_respond(u8 action, s8 status, int id)
Jeej 56:67e3d9608403 462 {
Jeej 57:5444cfda9889 463 alp_payload_t* alp = NULL;
Jeej 0:027760f45e2c 464
Jeej 56:67e3d9608403 465 alp = alp_payload_rsp_status(alp, action, status);
Jeej 56:67e3d9608403 466
Jeej 56:67e3d9608403 467 _modem_ref_rsp(alp, (status < ALP_ERR_NONE)? true: false, id);
Jeej 0:027760f45e2c 468 }
Jeej 0:027760f45e2c 469
Jeej 57:5444cfda9889 470 void modem_ref_respond_fprop(u8 fid, alp_file_header_t* hdr, int id)
Jeej 0:027760f45e2c 471 {
Jeej 57:5444cfda9889 472 alp_payload_t* alp = NULL;
Jeej 0:027760f45e2c 473
Jeej 56:67e3d9608403 474 alp = alp_payload_rsp_fprop(alp, fid, hdr);
Jeej 56:67e3d9608403 475
Jeej 56:67e3d9608403 476 _modem_ref_rsp(alp, false, id);
Jeej 0:027760f45e2c 477 }
Jeej 0:027760f45e2c 478
Jeej 57:5444cfda9889 479 void modem_ref_respond_read(u8 fid, void* data, u32 offset, u32 length, int id)
Jeej 0:027760f45e2c 480 {
Jeej 57:5444cfda9889 481 alp_payload_t* alp = NULL;
Jeej 56:67e3d9608403 482
Jeej 56:67e3d9608403 483 alp = alp_payload_rsp_f_data(alp, fid, data, offset, length);
Jeej 56:67e3d9608403 484
Jeej 56:67e3d9608403 485 _modem_ref_rsp(alp, false, id);
Jeej 13:10589aaf8853 486 }