Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: modem_ref_helper_for_v5_3_217
modem_ref.cpp
00001 #include "mbed.h" 00002 #include "WizziDebug.h" 00003 00004 #include "modem_ref.h" 00005 #include "kal_crypto.h" 00006 #include "kal_codec.h" 00007 00008 #if 0 00009 #define REF_PRINT(...) PRINT(__VA_ARGS__) 00010 #define URC_PRINT(...) PRINT(__VA_ARGS__) 00011 #else 00012 #define REF_PRINT(...); 00013 #define URC_PRINT(...); 00014 #endif 00015 00016 typedef struct { 00017 action_callback_t* cb; 00018 u8* data; 00019 u8* istatus; 00020 } modem_user_t; 00021 00022 typedef struct { 00023 u8* data; 00024 u8 type; 00025 u8 length; 00026 } modem_istatus_t; 00027 00028 typedef struct { 00029 fx_serial_send_t* send; 00030 modem_callbacks_t* cb; 00031 modem_user_t user[MAX_USER_NB]; 00032 modem_istatus_t istatus; 00033 u8 state; 00034 u8 tx_sequ; 00035 s32 action; 00036 } modem_ctx_t; 00037 static modem_ctx_t g_modem; 00038 00039 #define STATE_OPEN 0xab 00040 #define STATE_CLOSED 0 00041 00042 #define ROOT_KEY_SIZE 16 00043 00044 // Flows 00045 #define WC_FLOWID_CMD 0x10 00046 #define WC_FLOWID_ALP 0x20 00047 #define WC_FLOWID_SYS 0x30 00048 00049 // Sub-Flows 00050 #define WC_FLOW_ALP_CMD 0x20 00051 #define WC_FLOW_ALP_RESP 0x21 00052 #define WC_FLOW_ALP_UNS 0x22 00053 #define WC_FLOW_SYS_RST 0x30 00054 #define WC_FLOW_SYS_PING 0x34 00055 #define WC_FLOW_SYS_PONG 0x35 00056 #define WC_FLOW_SYS_CFG 0x36 00057 #define WC_FLOW_SYS_XON 0x39 00058 #define WC_FLOW_SYS_XOFF 0x3a 00059 #define WC_FLOW_SYS_XACK 0x3b 00060 00061 // Misc CMD... 00062 #define WM_BOOT 0x81 00063 00064 static void serial_send(u8 flowid, u8* data, int size) 00065 { 00066 u8 len = (u8)size; 00067 u8 wch[WC_HEADER_SIZE] = { 00068 WC_SYNC_BYTE_0, 00069 WC_SYNC_BYTE_1, 00070 len, 00071 g_modem.tx_sequ++, 00072 flowid 00073 }; 00074 00075 ASSERT(size < 256, "serial_send too big for serial protocol (%d/%dmax)", size, 255); 00076 00077 g_modem.send(wch, WC_HEADER_SIZE, data, len); 00078 } 00079 00080 protected void modem_input(u8 flowid,u8* payload,u8 size) 00081 { 00082 int rem =size; 00083 u8* p = payload; 00084 alp_parsed_chunk_t r; 00085 int id = -1; 00086 s8 err = ALP_ERR_NONE; 00087 u8 eop; 00088 uint32_t parsed; 00089 00090 g_modem.action = -1; 00091 00092 //REF_PRINT("input 0x%x/%d Bytes\n",flowid,size); 00093 switch (flowid) 00094 { 00095 case WC_FLOW_ALP_UNS: 00096 case WC_FLOW_ALP_CMD: 00097 parsed = alp_parse_chunk(&p, &r); 00098 if (!parsed) 00099 { 00100 // Discard the payload in case of parsing error. 00101 REF_PRINT("Parsing error line %d!\r\n", __LINE__); 00102 break; 00103 } 00104 rem -= parsed; 00105 g_modem.action++; 00106 //REF_PRINT("Rem %d Bytes\n", rem); 00107 // This should always be a TAG'ed request in case of FS access... 00108 if (r.type == ALP_OPCODE_TAG) 00109 { 00110 REF_PRINT("ACT %d: TAG[%d]\n", g_modem.action, r.meta.tag.id); 00111 00112 id = r.meta.tag.id; 00113 00114 while(rem>0) 00115 { 00116 // Parse File Operation 00117 parsed = alp_parse_chunk(&p, &r); 00118 if (!parsed) 00119 { 00120 // Discard the payload in case of parsing error. 00121 REF_PRINT("Parsing error line %d!\r\n", __LINE__); 00122 break; 00123 } 00124 rem -= parsed; 00125 g_modem.action++; 00126 //REF_PRINT("ALP OP[%d]\n",r.type); 00127 switch (r.type) 00128 { 00129 case ALP_OPCODE_F_RD_DATA: 00130 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); 00131 if (g_modem.cb->read) 00132 { 00133 g_modem.cb->read(r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length, id); 00134 } 00135 break; 00136 case ALP_OPCODE_F_WR_DATA: 00137 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); 00138 if (g_modem.cb->write) 00139 { 00140 g_modem.cb->write(r.meta.f_data.fid, r.data, r.meta.f_data.offset, r.meta.f_data.length, id); 00141 } 00142 break; 00143 case ALP_OPCODE_F_RD_PROP: 00144 REF_PRINT("ACT %d: F_RD_PROP[%d]\n", g_modem.action, r.meta.f_data.fid); 00145 if (g_modem.cb->read_fprop) 00146 { 00147 g_modem.cb->read_fprop(r.meta.f_data.fid, id); 00148 } 00149 break; 00150 case ALP_OPCODE_F_DELETE: 00151 REF_PRINT("ACT %d: F_DELETE[%d]\n", g_modem.action, r.meta.f_data.fid); 00152 if (g_modem.cb->remove) 00153 { 00154 g_modem.cb->remove(r.meta.f_data.fid, id); 00155 } 00156 break; 00157 case ALP_OPCODE_F_FLUSH: 00158 REF_PRINT("ACT %d: F_FLUSH[%d]\n", g_modem.action, r.meta.f_data.fid); 00159 if (g_modem.cb->flush) 00160 { 00161 g_modem.cb->flush(r.meta.f_data.fid, id); 00162 } 00163 break; 00164 default: 00165 ASSERT(false,"ASSERT: Unsupported ALP File Operation: %d\n", r.type); 00166 break; 00167 } 00168 //REF_PRINT("ALP Parsing done. rem %d\n", rem); 00169 } 00170 //REF_PRINT("ALP Packet done.\n"); 00171 } 00172 else 00173 { 00174 // ... or a 'real' URC (or ISTATUS if enabled on modem) 00175 g_modem.istatus = (modem_istatus_t){0}; 00176 do 00177 { 00178 switch (r.type) 00179 { 00180 case ALP_OPCODE_RSP_URC: 00181 if (ALP_URC_TYPE_LQUAL == r.meta.urc.type) 00182 { 00183 REF_PRINT("ACT %d: RSP_URC: LQUAL[%d] %d\n", g_modem.action, r.meta.urc.ifid, r.meta.urc.per); 00184 if (g_modem.cb->lqual) 00185 { 00186 g_modem.cb->lqual(r.meta.urc.ifid, r.meta.urc.per); 00187 } 00188 } 00189 else if (ALP_URC_TYPE_LDOWN == r.meta.urc.type) 00190 { 00191 REF_PRINT("ACT %d: RSP_URC: LDOWN[%d]\n", g_modem.action, r.meta.urc.ifid); 00192 if (g_modem.cb->ldown) 00193 { 00194 g_modem.cb->ldown(r.meta.urc.ifid); 00195 } 00196 } 00197 else if (ALP_URC_TYPE_BUSY == r.meta.urc.type) 00198 { 00199 REF_PRINT("ACT %d: RSP_URC: BUSY[%d]\n", g_modem.action, r.meta.urc.ifid); 00200 if (g_modem.cb->busy) 00201 { 00202 g_modem.cb->busy(r.meta.urc.ifid); 00203 } 00204 } 00205 else if (ALP_URC_TYPE_ITF_BUSY == r.meta.urc.type) 00206 { 00207 REF_PRINT("ACT %d: RSP_URC: ITF_BUSY[%d] for %d seconds\n", g_modem.action, r.meta.urc.ifid, r.meta.urc.per); 00208 if (g_modem.cb->itf_busy) 00209 { 00210 g_modem.cb->itf_busy(r.meta.urc.ifid, r.meta.urc.per); 00211 } 00212 } 00213 else 00214 { 00215 ASSERT(false, "ASSERT: Unsupported ALP URC: %d\n", r.meta.urc.type); 00216 } 00217 break; 00218 default: 00219 // This could be anything 00220 // Let user deal with the payload 00221 if (g_modem.cb->udata) 00222 { 00223 g_modem.cb->udata(payload, size); 00224 } 00225 rem = 0; 00226 break; 00227 } 00228 00229 int tem = alp_parse_chunk(&p, &r); 00230 if (!tem) 00231 { 00232 break; 00233 } 00234 rem -= tem; 00235 } while (rem>=0); 00236 } 00237 break; 00238 case WC_FLOW_ALP_RESP: 00239 // This should always be a TAG'ed response as we tag our requests 00240 parsed = alp_parse_chunk(&p, &r); 00241 if (!parsed) 00242 { 00243 // Discard the payload in case of parsing error. 00244 REF_PRINT("Parsing error line %d!\r\n", __LINE__); 00245 break; 00246 } 00247 rem -= parsed; 00248 g_modem.action++; 00249 //REF_PRINT("Rem %d Bytes\n", rem); 00250 00251 ASSERT((r.type == ALP_OPCODE_RSP_TAG),"ASSERT: expecting RESP_TAG got %d\n",r.type); 00252 REF_PRINT("ACT %d: TAG[%d]\n", g_modem.action, r.meta.tag.id); 00253 id = r.meta.tag.id; 00254 eop = r.meta.tag.eop; 00255 ASSERT(g_modem.user[id].cb != NULL,"ASSERT: NULL Callback for ID %d\n",id); 00256 // Empty response 00257 if (rem <= 0) 00258 { 00259 // TODO: still no info on error... 00260 err = r.meta.tag.err ? ALP_ERR_UNKNOWN : ALP_ERR_NONE; 00261 00262 if (ALP_ERR_NONE != err) 00263 { 00264 REF_PRINT("NO INFO ON ERROR.\n"); 00265 } 00266 else if (eop) 00267 { 00268 REF_PRINT("EOP.\n"); 00269 } 00270 00271 g_modem.user[id].cb(eop,err,id); 00272 return; 00273 } 00274 00275 // Actual response(s) 00276 while(rem>0) 00277 { 00278 parsed = alp_parse_chunk(&p, &r); 00279 if (!parsed) 00280 { 00281 // Discard the payload in case of parsing error. 00282 REF_PRINT("Parsing error line %d!\r\n", __LINE__); 00283 break; 00284 } 00285 rem -= parsed; 00286 g_modem.action++; 00287 //REF_PRINT("Rem %d Bytes\n", rem); 00288 00289 switch (r.type) 00290 { 00291 case ALP_OPCODE_RSP_TAG: 00292 REF_PRINT("ACT %d: RSP_TAG[%d]\n", g_modem.action, r.meta.tag.id); 00293 break; 00294 case ALP_OPCODE_RSP_F_DATA: 00295 REF_PRINT("ACT %d: RSP_F_DATA[%d]\n", g_modem.action, r.meta.f_data.length); 00296 ASSERT(g_modem.user[id].data != NULL,"ASSERT: NULL Data Buffer for RD on ID %d\n",id); 00297 memcpy(g_modem.user[id].data, r.data, r.meta.f_data.length); 00298 break; 00299 case ALP_OPCODE_RSP_F_PROP: 00300 REF_PRINT("ACT %d: RSP_F_PROP[%d]\n", g_modem.action, r.meta.f_data.length); 00301 ASSERT(g_modem.user[id].data != NULL,"ASSERT: NULL Data Buffer for RD on ID %d\n",id); 00302 memcpy(g_modem.user[id].data, r.data, r.meta.f_data.length); 00303 break; 00304 case ALP_OPCODE_RSP_STATUS: 00305 REF_PRINT("ACT %d: RSP_STATUS[%d]\n", g_modem.action, r.meta.status.code); 00306 err = r.meta.status.code; 00307 break; 00308 case ALP_OPCODE_RSP_ISTATUS: 00309 REF_PRINT("ACT %d: RSP_ISTATUS[%d]\n", g_modem.action, r.meta.itf.length); 00310 ASSERT(g_modem.user[id].istatus != NULL,"ASSERT: NULL ISTAT Buffer for RD on ID %d\n",id); 00311 memcpy(g_modem.user[id].istatus, r.data, r.meta.itf.length); 00312 break; 00313 case ALP_OPCODE_RSP_EOPISTATUS: 00314 REF_PRINT("ACT %d: RSP_EOPISTATUS[%02X]\n", g_modem.action, r.meta.istatus.itf); 00315 err = r.meta.istatus.err ? ALP_ERR_ITF_START + r.meta.istatus.err : ALP_ERR_NONE; 00316 break; 00317 default: 00318 ASSERT(false,"ASSERT: Unsupported ALP Response: %d\n",r.type); 00319 break; 00320 } 00321 } 00322 if(eop) 00323 { // This is mainly for debug, catch old pointers 00324 //g_modem.user[id].data = NULL; 00325 //g_modem.user[id].istatus= NULL; 00326 REF_PRINT("EOP\n"); 00327 } 00328 // User Callback 00329 if (g_modem.user[id].cb) 00330 { 00331 g_modem.user[id].cb(eop,err,id); 00332 } 00333 break; 00334 case WC_FLOW_SYS_RST: 00335 // 'Software' reset request 00336 if (g_modem.cb->reset) 00337 { 00338 g_modem.cb->reset(); 00339 } 00340 break; 00341 case WC_FLOWID_CMD: 00342 if (*p == WM_BOOT) 00343 { 00344 u16 nb_boot; 00345 u8 cause; 00346 p++; 00347 cause = p[0]; 00348 nb_boot = HAL_TO_U16(p[3],p[2]); 00349 if (g_modem.cb->boot) 00350 { 00351 g_modem.cb->boot(cause,nb_boot); 00352 } 00353 } 00354 else 00355 { 00356 REF_PRINT("Unsupported CMD :0x%x\n",*p); 00357 } 00358 break; 00359 default: 00360 REF_PRINT("Unsupported WC Flowid:0x%x / %d Bytes\n",flowid,size); 00361 break; 00362 } 00363 } 00364 00365 private u32 modem_add_root_permission(u8* p, u8* root_key, u8* action, u32 action_size) 00366 { 00367 u8 hash[32]; 00368 00369 // Calculate hash on action 00370 kal_sha256_init(); 00371 kal_sha256_update(action, action_size); 00372 kal_sha256_update(root_key, ROOT_KEY_SIZE); 00373 kal_sha256_final(hash); 00374 // Prepend Permission-request... 00375 ALP_ACTION_PERM_REQ(p, false, ALP_PERM_REQ_ROOT); 00376 // ... and hash 00377 memcpy(p, hash, ALP_WIZZILAB_AUTH_PROTOCOL_TOKEN_SIZE); 00378 00379 return ALP_ACTION_PERM_REQ_OFFSET; 00380 } 00381 00382 public int modem_get_id(action_callback_t* cb) 00383 { 00384 int i; 00385 for(i=0;i<MAX_USER_NB;i++) 00386 { 00387 if (g_modem.user[i].cb == NULL) 00388 { 00389 g_modem.user[i].cb = cb; 00390 //REF_PRINT("Get ID:%d/0x%08x\n",i,cb); 00391 return i; 00392 } 00393 } 00394 ASSERT(i < MAX_USER_NB,"ASSERT: out of users\n"); 00395 return -1; 00396 } 00397 00398 public int modem_free_id(u8 id) 00399 { 00400 if (id < MAX_USER_NB) 00401 { 00402 g_modem.user[id].cb = NULL; 00403 g_modem.user[id].data = NULL; 00404 g_modem.user[id].istatus= NULL; 00405 //REF_PRINT("Free ID:%d\n",id); 00406 return id; 00407 } 00408 return -1; 00409 } 00410 00411 public void modem_open(fx_serial_send_t* send,modem_callbacks_t* callbacks) 00412 { 00413 if (g_modem.state != STATE_OPEN) 00414 { 00415 g_modem.send= send; 00416 g_modem.cb = callbacks; 00417 memset(g_modem.user,0,(MAX_USER_NB * sizeof(modem_user_t))); 00418 00419 REF_PRINT("Open Modem - Max users:%d\n",MAX_USER_NB); 00420 00421 g_modem.state = STATE_OPEN; 00422 } 00423 } 00424 00425 public void modem_close(void) 00426 { 00427 if (g_modem.state == STATE_OPEN) 00428 { 00429 g_modem.state = STATE_CLOSED; 00430 } 00431 } 00432 00433 public void modem_reset(void) 00434 { 00435 serial_send(WC_FLOW_SYS_RST,NULL,0); 00436 } 00437 00438 public void modem_read_file(u8 fid, void *data, u32 offset, u32 length, u8 id) 00439 { 00440 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_RD_DATA_SIZE_MAX]; 00441 u8* p = tmp; 00442 REF_PRINT("RD[%d]@%d %d Bytes\n",fid,offset,length); 00443 g_modem.user[id].data = (u8*)data; 00444 ALP_ACTION_TAG(p,id,true); 00445 ALP_ACTION_F_RD_DATA(p,true,fid,offset,length); 00446 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00447 } 00448 00449 public void modem_read_fprop(u8 fid, alp_file_header_t* data, u8 id) 00450 { 00451 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_RD_PROP_SIZE]; 00452 u8* p = tmp; 00453 REF_PRINT("RD PROPS[%d]\n",fid); 00454 g_modem.user[id].data = (u8*)data; 00455 ALP_ACTION_TAG(p,id,true); 00456 ALP_ACTION_F_RD_PROP(p,true,fid); 00457 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00458 } 00459 00460 public void modem_read_fprop_root(u8 fid, alp_file_header_t* data, u8* root_key, u8 id) 00461 { 00462 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_RD_PROP_SIZE)]; 00463 u8* p = tmp; 00464 u8* lastp; 00465 REF_PRINT("RD PROPS (ROOT)[%d]\n",fid); 00466 ASSERT(root_key != NULL, "Missing ROOT KEY\n"); 00467 g_modem.user[id].data = (u8*)data; 00468 ALP_ACTION_TAG(p, id, true); 00469 // Actual Operation will take place after PERM_REQ 00470 p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET]; 00471 ALP_ACTION_F_RD_PROP(p,true,fid); 00472 lastp = p; 00473 modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key, 00474 &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET], 00475 ALP_ACTION_F_RD_PROP_SIZE); 00476 serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp)); 00477 } 00478 00479 public void modem_write_fprop(u8 fid, alp_file_header_t* data, u8 id) 00480 { 00481 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_WR_PROP_SIZE_MAX]; 00482 u8* p = tmp; 00483 DPRINT(L_API, "WR PROPS[%d]\n",fid); 00484 ALP_ACTION_TAG(p,id,true); 00485 ALP_ACTION_F_WR_PROP(p,true,fid,0,sizeof(alp_file_header_t),data); 00486 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00487 } 00488 00489 public void modem_write_fprop_root(u8 fid, alp_file_header_t* data, u8* root_key, u8 id) 00490 { 00491 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_WR_PROP_SIZE_MAX)]; 00492 u8* p = tmp; 00493 u8* lastp; 00494 DPRINT(L_API, "WR PROPS (ROOT)[%d]\n",fid); 00495 ASSERT(root_key != NULL, "Missing ROOT KEY\n"); 00496 ALP_ACTION_TAG(p, id, true); 00497 // Actual Operation will take place after PERM_REQ 00498 p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET]; 00499 ALP_ACTION_F_WR_PROP(p,true,fid,0,sizeof(alp_file_header_t),data); 00500 lastp = p; 00501 modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key, 00502 &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET], 00503 ALP_ACTION_F_WR_PROP_SIZE_MAX); 00504 serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp)); 00505 } 00506 00507 public void modem_write_file(u8 fid, void *data, u32 offset, u32 length, u8 id) 00508 { 00509 ALLOC_BUFFER(u8, tmp,(ALP_ACTION_TAG_SIZE + ALP_ACTION_F_WR_DATA_SIZE_MAX(length))); 00510 00511 u8* p = tmp; 00512 REF_PRINT("WR[%d]@%d %d Bytes\n",fid,offset,length); 00513 ALP_ACTION_TAG(p,id,true); 00514 ALP_ACTION_F_WR_DATA(p,true,fid,offset,length,data); 00515 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00516 DEALLOC_BUFFER(tmp); 00517 } 00518 00519 public void modem_write_file_root(u8 fid, void *data, u32 offset, u32 length, u8* root_key, u8 id) 00520 { 00521 ALLOC_BUFFER(u8, tmp,(ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_WR_DATA_SIZE_MAX(length)))); 00522 00523 u8* p = tmp; 00524 u8* lastp; 00525 REF_PRINT("WR (ROOT)[%d]@%d %d Bytes\n",fid,offset,length); 00526 ASSERT(root_key != NULL, "Missing ROOT KEY\n"); 00527 ALP_ACTION_TAG(p, id, true); 00528 // Actual Operation will take place after PERM_REQ 00529 p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET]; 00530 ALP_ACTION_F_WR_DATA(p,true,fid,offset,length,data); 00531 lastp = p; 00532 modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key, 00533 &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET], 00534 ALP_ACTION_F_WR_DATA_SIZE(offset,length)); 00535 serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp)); 00536 DEALLOC_BUFFER(tmp); 00537 } 00538 00539 public void modem_flush_file(u8 fid, u8 id) 00540 { 00541 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_FLUSH_SIZE]; 00542 u8* p = tmp; 00543 REF_PRINT("FLUSH[%d]\n",fid); 00544 ALP_ACTION_TAG(p,id,true); 00545 ALP_ACTION_F_FLUSH(p,true,fid); 00546 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00547 } 00548 00549 public void modem_flush_file_root(u8 fid, u8* root_key, u8 id) 00550 { 00551 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_FLUSH_SIZE)]; 00552 u8* p = tmp; 00553 u8* lastp; 00554 REF_PRINT("FLUSH (ROOT)[%d]\n",fid); 00555 ASSERT(root_key != NULL, "Missing ROOT KEY\n"); 00556 ALP_ACTION_TAG(p, id, true); 00557 // Actual Operation will take place after PERM_REQ 00558 p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET]; 00559 ALP_ACTION_F_FLUSH(p,true,fid); 00560 lastp = p; 00561 modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key, 00562 &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET], 00563 ALP_ACTION_F_FLUSH_SIZE); 00564 serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp)); 00565 } 00566 00567 public void modem_declare_file(u8 fid, alp_file_header_t* hdr, u8 local, u8 id) 00568 { 00569 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_DECLARE_SIZE]; 00570 u8* p = tmp; 00571 00572 REF_PRINT("DECLARE[%d]\n",fid); 00573 ALP_ACTION_TAG(p,id,true); 00574 ALP_ACTION_F_DECLARE(p,true,fid,hdr,local); 00575 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00576 } 00577 00578 public void modem_create_file(u8 fid, alp_file_header_t* hdr, u8 id) 00579 { 00580 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_CREATE_SIZE]; 00581 u8* p = tmp; 00582 00583 REF_PRINT("CREATE[%d]\n",fid); 00584 ALP_ACTION_TAG(p,id,true); 00585 ALP_ACTION_F_CREATE(p,true,fid,hdr); 00586 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00587 } 00588 00589 public void modem_notify_file(u8 fid, u32 offset, u32 length, u8 id) 00590 { 00591 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_TOUCH_SIZE_MAX]; 00592 u8* p = tmp; 00593 00594 REF_PRINT("NOTIFY[%d]@%d %d Bytes\n",fid,offset,length); 00595 ALP_ACTION_TAG(p,id,true); 00596 ALP_ACTION_F_TOUCH(p,true,fid,offset,length); 00597 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00598 } 00599 00600 public void modem_delete_file(u8 fid, u8 id) 00601 { 00602 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_DELETE_SIZE]; 00603 u8* p = tmp; 00604 00605 REF_PRINT("DELETE[%d]\n",fid); 00606 ALP_ACTION_TAG(p,id,true); 00607 ALP_ACTION_F_DELETE(p,true,fid); 00608 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00609 } 00610 00611 public void modem_delete_file_root(u8 fid, u8* root_key, u8 id) 00612 { 00613 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_DELETE_SIZE)]; 00614 u8* p = tmp; 00615 u8* lastp; 00616 00617 REF_PRINT("DELETE ROOT[%d]\n",fid); 00618 ALP_ACTION_TAG(p,id,true); 00619 // Actual Operation will take place after PERM_REQ 00620 p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET]; 00621 ALP_ACTION_F_DELETE(p,true,fid); 00622 lastp = p; 00623 modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key, 00624 &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET], 00625 ALP_ACTION_F_DELETE_SIZE); 00626 serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp)); 00627 } 00628 00629 public void modem_send_raw_alp(u8* payload, u32 length, u8 id) 00630 { 00631 ALLOC_BUFFER(u8, tmp,ALP_ACTION_TAG_SIZE + length); 00632 u8* p = tmp; 00633 00634 REF_PRINT("ALP RAW %d Bytes\n",length); 00635 ALP_ACTION_TAG(p,id,true); 00636 // User Payload 00637 memcpy(p,payload,length);p+=length; 00638 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00639 DEALLOC_BUFFER(tmp); 00640 } 00641 00642 public void modem_send_file_content(u8* itf, u8 itf_length, void *istatus, u8 fid, void *data, u32 offset, u32 length, u8 id) 00643 { 00644 ALLOC_BUFFER(u8, tmp,ALP_ACTION_TAG_SIZE + ALP_ACTION_FORWARD_SIZE(itf_length) + ALP_ACTION_RSP_F_DATA_SIZE_MAX(length)); 00645 u8* p = tmp; 00646 g_modem.user[id].istatus= (u8*)istatus; 00647 00648 REF_PRINT("SEND FILE[%d] CONTENTS @%d %d Bytes (itf %d Bytes)\n",fid,offset,length,itf_length); 00649 ALP_ACTION_TAG(p,id,true); 00650 ALP_ACTION_FORWARD(p,itf,itf_length); 00651 if (istatus) 00652 { 00653 // NOP action to get istats on ACKs 00654 ALP_ACTION_NOP(p,true); 00655 } 00656 ALP_ACTION_RSP_F_DATA(p,fid,offset,length,data); 00657 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00658 DEALLOC_BUFFER(tmp); 00659 } 00660 00661 public void modem_remote_read_file(u8* itf, u8 itf_length, void *istatus , u8 fid, void *data, u32 offset, u32 length, u8 id) 00662 { 00663 ALLOC_BUFFER(u8, tmp,ALP_ACTION_TAG_SIZE + ALP_ACTION_FORWARD_SIZE(itf_length) + ALP_ACTION_F_RD_DATA_SIZE_MAX); 00664 u8* p = tmp; 00665 g_modem.user[id].data = (u8*)data; 00666 g_modem.user[id].istatus = (u8*)istatus; 00667 00668 REF_PRINT("RMT RD FILE[%d]@%d %d Bytes (itf %d Bytes)\n",fid,offset,length,itf_length); 00669 ALP_ACTION_TAG(p,id,true); 00670 ALP_ACTION_FORWARD(p,itf,itf_length); 00671 ALP_ACTION_F_RD_DATA(p,true,fid,offset,length); 00672 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00673 DEALLOC_BUFFER(tmp); 00674 } 00675 00676 public void modem_remote_read_file_root(u8* itf, u8 itf_length, void *istatus , u8 fid, void *data, u32 offset, u32 length, u8* root_key, u8 id) 00677 { 00678 ALLOC_BUFFER(u8, tmp, ALP_ACTION_TAG_SIZE + ALP_ACTION_FORWARD_SIZE(itf_length) + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_RD_DATA_SIZE_MAX)); 00679 u8* p = tmp; 00680 u32 perm_offset; 00681 00682 ASSERT(root_key != NULL, "Missing ROOT KEY\n"); 00683 00684 g_modem.user[id].data = (u8*)data; 00685 g_modem.user[id].istatus = (u8*)istatus; 00686 00687 REF_PRINT("RMT RD FILE (ROOT)[%d]@%d %d Bytes (itf %d Bytes)\n", fid, offset, length, itf_length); 00688 ALP_ACTION_TAG(p, id, true); 00689 ALP_ACTION_FORWARD(p, itf, itf_length); 00690 00691 // Mark start of permission request 00692 perm_offset = (u32)(p-tmp); 00693 00694 // Actual Operation will take place after PERM_REQ 00695 p = &tmp[perm_offset + ALP_ACTION_PERM_REQ_OFFSET]; 00696 ALP_ACTION_F_RD_DATA(p, true, fid, offset, length); 00697 00698 modem_add_root_permission(&tmp[perm_offset], root_key, 00699 &tmp[perm_offset + ALP_ACTION_PERM_REQ_OFFSET], 00700 ALP_ACTION_F_RD_DATA_SIZE(offset, length)); 00701 00702 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00703 DEALLOC_BUFFER(tmp); 00704 } 00705 00706 public void modem_remote_write_file(u8* itf, u8 itf_length, void *istatus , u8 fid, void *data, u32 offset, u32 length, u8 id) 00707 { 00708 ALLOC_BUFFER(u8, tmp,ALP_ACTION_TAG_SIZE + ALP_ACTION_FORWARD_SIZE(itf_length) + ALP_ACTION_F_WR_DATA_SIZE_MAX(length)); 00709 u8* p = tmp; 00710 g_modem.user[id].istatus = (u8*)istatus; 00711 00712 REF_PRINT("RMT WR FILE[%d]@%d %d Bytes (itf %d Bytes)\n",fid,offset,length,itf_length); 00713 ALP_ACTION_TAG(p,id,true); 00714 ALP_ACTION_FORWARD(p,itf,itf_length); 00715 ALP_ACTION_F_WR_DATA(p,true,fid,offset,length,data); 00716 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00717 DEALLOC_BUFFER(tmp); 00718 } 00719 00720 public void modem_remote_write_file_root(u8* itf, u8 itf_length, void *istatus, u8 fid, void *data, u32 offset, u32 length, u8* root_key, u8 id) 00721 { 00722 ALLOC_BUFFER(u8, tmp, (ALP_ACTION_TAG_SIZE + ALP_ACTION_FORWARD_SIZE(itf_length) + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_WR_DATA_SIZE_MAX(length)))); 00723 00724 u8* p = tmp; 00725 u8* actp; 00726 u8* reqp; 00727 00728 g_modem.user[id].istatus = (u8*)istatus; 00729 00730 REF_PRINT("WR (ROOT)[%d]@%d %d Bytes\n",fid,offset,length); 00731 ASSERT(root_key != NULL, "Missing ROOT KEY\n"); 00732 00733 // TAG and FORWARD 00734 ALP_ACTION_TAG(p, id, true); 00735 ALP_ACTION_FORWARD(p,itf,itf_length); 00736 00737 // Save offset of permission request 00738 reqp = p; 00739 00740 // Actual Operation will take place after PERM_REQ, skip it 00741 p += ALP_ACTION_PERM_REQ_OFFSET; 00742 00743 // Save action offset 00744 actp = p; 00745 00746 // Actual action 00747 ALP_ACTION_F_WR_DATA(p,true,fid,offset,length,data); 00748 00749 // Add permission request at request offset 00750 modem_add_root_permission( 00751 reqp, 00752 root_key, 00753 actp, 00754 ALP_ACTION_F_WR_DATA_SIZE(offset,length) 00755 ); 00756 00757 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00758 DEALLOC_BUFFER(tmp); 00759 } 00760 00761 public void modem_enable_urc(u8 type, u8 ifid, u8 val, u8 enable, u8 id) 00762 { 00763 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_URCC_SIZE(ALP_URC_TYPE_LQUAL)]; 00764 u8* p = tmp; 00765 REF_PRINT("URC[%d] Type %d ifid %d\n",enable,type,ifid); 00766 00767 ALP_ACTION_TAG(p,id,true); 00768 // Actual Operation 00769 if (enable) 00770 { 00771 ALP_ACTION_URCC_EN(p,true,type,ifid,val); 00772 } 00773 else 00774 { 00775 ALP_ACTION_URCC_DIS(p,true,type,ifid,val); 00776 } 00777 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00778 } 00779 00780 public void modem_activate_itf(u8 type, u8 nb_dev, u8 ifid, u8 flags, u8 enable, u8 id) 00781 { 00782 u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_ACTIVATE_ITF_SIZE]; 00783 u8* p = tmp; 00784 00785 REF_PRINT("ACTIVATE ITFTYPE[%x]:%d\n",type,enable); 00786 ALP_ACTION_TAG(p,id,true); 00787 ALP_ACTION_ACTIVATE_ITF(p,true,enable,type,nb_dev,ifid,flags); 00788 serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp)); 00789 } 00790 00791 public void modem_respond(s8 status, int id) 00792 { 00793 u8 tmp[ALP_ACTION_RSP_TAG_SIZE + ALP_ACTION_RSP_STATUS_SIZE]; 00794 u8* p = tmp; 00795 REF_PRINT("RESP[%d]:%d\n",g_modem.action,status); 00796 00797 if (id>=0) { ALP_ACTION_RSP_TAG(p,id,true,(status<0)?true:false); } 00798 ALP_ACTION_RSP_STATUS(p, g_modem.action, status); 00799 serial_send(WC_FLOW_ALP_RESP, tmp, (p-tmp)); 00800 } 00801 00802 public void modem_respond_fprop(u8 fid, u8* hdr, int id) 00803 { 00804 u8 tmp[ALP_ACTION_RSP_TAG_SIZE + ALP_ACTION_RSP_F_PROP_SIZE]; 00805 u8* p = tmp; 00806 REF_PRINT("RESP FPROP[%d]\n",fid); 00807 00808 if (id>=0) { ALP_ACTION_RSP_TAG(p,id,true,false); } 00809 ALP_ACTION_RSP_F_PROP(p,fid,hdr); 00810 serial_send(WC_FLOW_ALP_RESP, tmp, (p-tmp)); 00811 } 00812 00813 public void modem_respond_read(u8 fid,void *data, u32 offset, u32 length, int id) 00814 { 00815 ALLOC_BUFFER(u8, tmp,ALP_ACTION_RSP_TAG_SIZE + ALP_ACTION_RSP_F_DATA_SIZE_MAX(length)); 00816 u8* p = tmp; 00817 REF_PRINT("F_DATA[%d]@%d %d Bytes\n",fid,offset,length); 00818 if (id>=0) { ALP_ACTION_RSP_TAG(p,id,true,false); } 00819 ALP_ACTION_RSP_F_DATA(p,fid,offset,length,data); 00820 serial_send(WC_FLOW_ALP_RESP, tmp, (p-tmp)); 00821 DEALLOC_BUFFER(tmp); 00822 }
Generated on Wed Jul 20 2022 12:33:07 by
