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.
src/modem_ref.cpp
- Committer:
- Jeej
- Date:
- 2020-05-26
- Revision:
- 50:9eb5eed8b014
- Parent:
- 46:9b83866cef2c
- Parent:
- 49:7a2f4992ff90
- Child:
- 51:92667569acc7
File content as of revision 50:9eb5eed8b014:
#include "mbed.h"
#include "WizziDebug.h"
#include "modem_ref.h"
#include "kal_crypto.h"
#include "kal_codec.h"
#if 0
#define REF_PRINT(...) PRINT(__VA_ARGS__)
#define URC_PRINT(...) PRINT(__VA_ARGS__)
#else
#define REF_PRINT(...);
#define URC_PRINT(...);
#endif
typedef struct {
action_callback_t* cb;
u8* data;
u8* istatus;
} modem_user_t;
typedef struct {
u8* data;
u8 type;
u8 length;
} modem_istatus_t;
typedef struct {
fx_serial_send_t* send;
modem_callbacks_t* cb;
modem_user_t user[MAX_USER_NB];
modem_istatus_t istatus;
u8 state;
u8 tx_sequ;
s32 action;
} modem_ctx_t;
static modem_ctx_t g_modem;
#define STATE_OPEN 0xab
#define STATE_CLOSED 0
#define ROOT_KEY_SIZE 16
// Flows
#define WC_FLOWID_CMD 0x10
#define WC_FLOWID_ALP 0x20
#define WC_FLOWID_SYS 0x30
// Sub-Flows
#define WC_FLOW_ALP_CMD 0x20
#define WC_FLOW_ALP_RESP 0x21
#define WC_FLOW_ALP_UNS 0x22
#define WC_FLOW_SYS_RST 0x30
#define WC_FLOW_SYS_PING 0x34
#define WC_FLOW_SYS_PONG 0x35
#define WC_FLOW_SYS_CFG 0x36
#define WC_FLOW_SYS_XON 0x39
#define WC_FLOW_SYS_XOFF 0x3a
#define WC_FLOW_SYS_XACK 0x3b
// Misc CMD...
#define WM_BOOT 0x81
static void serial_send(u8 flowid, u8* data, int size)
{
u8 len = (u8)size;
u8 wch[WC_HEADER_SIZE] = {
WC_SYNC_BYTE_0,
WC_SYNC_BYTE_1,
len,
g_modem.tx_sequ++,
flowid
};
ASSERT(size < 256, "serial_send too big for serial protocol (%d/%dmax)", size, 255);
g_modem.send(wch, WC_HEADER_SIZE, data, len);
}
protected void modem_input(u8 flowid,u8* payload,u8 size)
{
int rem =size;
u8* p = payload;
alp_parsed_chunk_t r;
int id = -1;
s8 err = ALP_ERR_NONE;
u8 eop;
uint32_t parsed;
g_modem.action = -1;
//REF_PRINT("input 0x%x/%d Bytes\n",flowid,size);
switch (flowid)
{
case WC_FLOW_ALP_UNS:
case WC_FLOW_ALP_CMD:
parsed = alp_parse_chunk(&p, &r);
if (!parsed)
{
// Discard the payload in case of parsing error.
REF_PRINT("Parsing error line %d!\r\n", __LINE__);
break;
}
rem -= parsed;
g_modem.action++;
//REF_PRINT("Rem %d Bytes\n", rem);
// This should always be a TAG'ed request in case of FS access...
if (r.type == ALP_OPCODE_TAG)
{
REF_PRINT("ACT %d: TAG[%d]\n", g_modem.action, r.meta.tag.id);
id = r.meta.tag.id;
while(rem>0)
{
// Parse File Operation
parsed = alp_parse_chunk(&p, &r);
if (!parsed)
{
// Discard the payload in case of parsing error.
REF_PRINT("Parsing error line %d!\r\n", __LINE__);
break;
}
rem -= parsed;
g_modem.action++;
//REF_PRINT("ALP OP[%d]\n",r.type);
switch (r.type)
{
case ALP_OPCODE_F_RD_DATA:
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);
if (g_modem.cb->read)
{
g_modem.cb->read(r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length, id);
}
break;
case ALP_OPCODE_F_WR_DATA:
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);
if (g_modem.cb->write)
{
g_modem.cb->write(r.meta.f_data.fid, r.data, r.meta.f_data.offset, r.meta.f_data.length, id);
}
break;
case ALP_OPCODE_F_RD_PROP:
REF_PRINT("ACT %d: F_RD_PROP[%d]\n", g_modem.action, r.meta.f_data.fid);
if (g_modem.cb->read_fprop)
{
g_modem.cb->read_fprop(r.meta.f_data.fid, id);
}
break;
case ALP_OPCODE_F_DELETE:
REF_PRINT("ACT %d: F_DELETE[%d]\n", g_modem.action, r.meta.f_data.fid);
if (g_modem.cb->remove)
{
g_modem.cb->remove(r.meta.f_data.fid, id);
}
break;
case ALP_OPCODE_F_FLUSH:
REF_PRINT("ACT %d: F_FLUSH[%d]\n", g_modem.action, r.meta.f_data.fid);
if (g_modem.cb->flush)
{
g_modem.cb->flush(r.meta.f_data.fid, id);
}
break;
default:
ASSERT(false,"ASSERT: Unsupported ALP File Operation: %d\n", r.type);
break;
}
//REF_PRINT("ALP Parsing done. rem %d\n", rem);
}
//REF_PRINT("ALP Packet done.\n");
}
else
{
// ... or a 'real' URC (or ISTATUS if enabled on modem)
g_modem.istatus = (modem_istatus_t){0};
do
{
switch (r.type)
{
case ALP_OPCODE_RSP_URC:
if (ALP_URC_TYPE_LQUAL == r.meta.urc.type)
{
REF_PRINT("ACT %d: RSP_URC: LQUAL[%d] %d\n", g_modem.action, r.meta.urc.ifid, r.meta.urc.per);
if (g_modem.cb->lqual)
{
g_modem.cb->lqual(r.meta.urc.ifid, r.meta.urc.per);
}
}
else if (ALP_URC_TYPE_LDOWN == r.meta.urc.type)
{
REF_PRINT("ACT %d: RSP_URC: LDOWN[%d]\n", g_modem.action, r.meta.urc.ifid);
if (g_modem.cb->ldown)
{
g_modem.cb->ldown(r.meta.urc.ifid);
}
}
else if (ALP_URC_TYPE_BUSY == r.meta.urc.type)
{
REF_PRINT("ACT %d: RSP_URC: BUSY[%d]\n", g_modem.action, r.meta.urc.ifid);
if (g_modem.cb->busy)
{
g_modem.cb->busy(r.meta.urc.ifid);
}
}
else if (ALP_URC_TYPE_ITF_BUSY == r.meta.urc.type)
{
REF_PRINT("ACT %d: RSP_URC: ITF_BUSY[%d] for %d seconds\n", g_modem.action, r.meta.urc.ifid, r.meta.urc.per);
if (g_modem.cb->itf_busy)
{
g_modem.cb->itf_busy(r.meta.urc.ifid, r.meta.urc.per);
}
}
else
{
ASSERT(false, "ASSERT: Unsupported ALP URC: %d\n", r.meta.urc.type);
}
break;
default:
// This could be anything
// Let user deal with the payload
if (g_modem.cb->udata)
{
g_modem.cb->udata(payload, size);
}
rem = 0;
break;
}
int tem = alp_parse_chunk(&p, &r);
if (!tem)
{
break;
}
rem -= tem;
} while (rem>=0);
}
break;
case WC_FLOW_ALP_RESP:
// This should always be a TAG'ed response as we tag our requests
parsed = alp_parse_chunk(&p, &r);
if (!parsed)
{
// Discard the payload in case of parsing error.
REF_PRINT("Parsing error line %d!\r\n", __LINE__);
break;
}
rem -= parsed;
g_modem.action++;
//REF_PRINT("Rem %d Bytes\n", rem);
ASSERT((r.type == ALP_OPCODE_RSP_TAG),"ASSERT: expecting RESP_TAG got %d\n",r.type);
REF_PRINT("ACT %d: TAG[%d]\n", g_modem.action, r.meta.tag.id);
id = r.meta.tag.id;
eop = r.meta.tag.eop;
ASSERT(g_modem.user[id].cb != NULL,"ASSERT: NULL Callback for ID %d\n",id);
// Empty response
if (rem <= 0)
{
// TODO: still no info on error...
err = r.meta.tag.err ? ALP_ERR_UNKNOWN : ALP_ERR_NONE;
if (ALP_ERR_NONE != err)
{
REF_PRINT("NO INFO ON ERROR.\n");
}
else if (eop)
{
REF_PRINT("EOP.\n");
}
g_modem.user[id].cb(eop,err,id);
return;
}
// Actual response(s)
while(rem>0)
{
parsed = alp_parse_chunk(&p, &r);
if (!parsed)
{
// Discard the payload in case of parsing error.
REF_PRINT("Parsing error line %d!\r\n", __LINE__);
break;
}
rem -= parsed;
g_modem.action++;
//REF_PRINT("Rem %d Bytes\n", rem);
switch (r.type)
{
case ALP_OPCODE_RSP_TAG:
REF_PRINT("ACT %d: RSP_TAG[%d]\n", g_modem.action, r.meta.tag.id);
break;
case ALP_OPCODE_RSP_F_DATA:
REF_PRINT("ACT %d: RSP_F_DATA[%d]\n", g_modem.action, r.meta.f_data.length);
ASSERT(g_modem.user[id].data != NULL,"ASSERT: NULL Data Buffer for RD on ID %d\n",id);
memcpy(g_modem.user[id].data, r.data, r.meta.f_data.length);
break;
case ALP_OPCODE_RSP_F_PROP:
REF_PRINT("ACT %d: RSP_F_PROP[%d]\n", g_modem.action, r.meta.f_data.length);
ASSERT(g_modem.user[id].data != NULL,"ASSERT: NULL Data Buffer for RD on ID %d\n",id);
memcpy(g_modem.user[id].data, r.data, r.meta.f_data.length);
break;
case ALP_OPCODE_RSP_STATUS:
REF_PRINT("ACT %d: RSP_STATUS[%d]\n", g_modem.action, r.meta.status.code);
err = r.meta.status.code;
break;
case ALP_OPCODE_RSP_ISTATUS:
REF_PRINT("ACT %d: RSP_ISTATUS[%d]\n", g_modem.action, r.meta.itf.length);
ASSERT(g_modem.user[id].istatus != NULL,"ASSERT: NULL ISTAT Buffer for RD on ID %d\n",id);
memcpy(g_modem.user[id].istatus, r.data, r.meta.itf.length);
break;
case ALP_OPCODE_RSP_EOPISTATUS:
REF_PRINT("ACT %d: RSP_EOPISTATUS[%02X]\n", g_modem.action, r.meta.istatus.itf);
err = r.meta.istatus.err ? ALP_ERR_ITF_START + r.meta.istatus.err : ALP_ERR_NONE;
break;
default:
ASSERT(false,"ASSERT: Unsupported ALP Response: %d\n",r.type);
break;
}
}
if(eop)
{ // This is mainly for debug, catch old pointers
//g_modem.user[id].data = NULL;
//g_modem.user[id].istatus= NULL;
REF_PRINT("EOP\n");
}
// User Callback
if (g_modem.user[id].cb)
{
g_modem.user[id].cb(eop,err,id);
}
break;
case WC_FLOW_SYS_RST:
// 'Software' reset request
if (g_modem.cb->reset)
{
g_modem.cb->reset();
}
break;
case WC_FLOWID_CMD:
if (*p == WM_BOOT)
{
u16 nb_boot;
u8 cause;
p++;
cause = p[0];
nb_boot = HAL_TO_U16(p[3],p[2]);
if (g_modem.cb->boot)
{
g_modem.cb->boot(cause,nb_boot);
}
}
else
{
REF_PRINT("Unsupported CMD :0x%x\n",*p);
}
break;
default:
REF_PRINT("Unsupported WC Flowid:0x%x / %d Bytes\n",flowid,size);
break;
}
}
private u32 modem_add_root_permission(u8* p, u8* root_key, u8* action, u32 action_size)
{
u8 hash[32];
// Calculate hash on action
kal_sha256_init();
kal_sha256_update(action, action_size);
kal_sha256_update(root_key, ROOT_KEY_SIZE);
kal_sha256_final(hash);
// Prepend Permission-request...
ALP_ACTION_PERM_REQ(p, false, ALP_PERM_REQ_ROOT);
// ... and hash
memcpy(p, hash, ALP_WIZZILAB_AUTH_PROTOCOL_TOKEN_SIZE);
return ALP_ACTION_PERM_REQ_OFFSET;
}
public int modem_get_id(action_callback_t* cb)
{
int i;
for(i=0;i<MAX_USER_NB;i++)
{
if (g_modem.user[i].cb == NULL)
{
g_modem.user[i].cb = cb;
//REF_PRINT("Get ID:%d/0x%08x\n",i,cb);
return i;
}
}
ASSERT(i < MAX_USER_NB,"ASSERT: out of users\n");
return -1;
}
public int modem_free_id(u8 id)
{
if (id < MAX_USER_NB)
{
g_modem.user[id].cb = NULL;
g_modem.user[id].data = NULL;
g_modem.user[id].istatus= NULL;
//REF_PRINT("Free ID:%d\n",id);
return id;
}
return -1;
}
public void modem_open(fx_serial_send_t* send,modem_callbacks_t* callbacks)
{
if (g_modem.state != STATE_OPEN)
{
g_modem.send= send;
g_modem.cb = callbacks;
memset(g_modem.user,0,(MAX_USER_NB * sizeof(modem_user_t)));
REF_PRINT("Open Modem - Max users:%d\n",MAX_USER_NB);
g_modem.state = STATE_OPEN;
}
}
public void modem_close(void)
{
if (g_modem.state == STATE_OPEN)
{
g_modem.state = STATE_CLOSED;
}
}
public void modem_reset(void)
{
serial_send(WC_FLOW_SYS_RST,NULL,0);
}
public void modem_read_file(u8 fid, void *data, u32 offset, u32 length, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_RD_DATA_SIZE_MAX];
u8* p = tmp;
REF_PRINT("RD[%d]@%d %d Bytes\n",fid,offset,length);
g_modem.user[id].data = (u8*)data;
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_RD_DATA(p,true,fid,offset,length);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_read_fprop(u8 fid, alp_file_header_t* data, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_RD_PROP_SIZE];
u8* p = tmp;
REF_PRINT("RD PROPS[%d]\n",fid);
g_modem.user[id].data = (u8*)data;
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_RD_PROP(p,true,fid);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_read_fprop_root(u8 fid, alp_file_header_t* data, u8* root_key, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_RD_PROP_SIZE)];
u8* p = tmp;
u8* lastp;
REF_PRINT("RD PROPS (ROOT)[%d]\n",fid);
ASSERT(root_key != NULL, "Missing ROOT KEY\n");
g_modem.user[id].data = (u8*)data;
ALP_ACTION_TAG(p, id, true);
// Actual Operation will take place after PERM_REQ
p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET];
ALP_ACTION_F_RD_PROP(p,true,fid);
lastp = p;
modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key,
&tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET],
ALP_ACTION_F_RD_PROP_SIZE);
serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp));
}
public void modem_write_fprop(u8 fid, alp_file_header_t* data, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_WR_PROP_SIZE_MAX];
u8* p = tmp;
DPRINT(L_API, "WR PROPS[%d]\n",fid);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_WR_PROP(p,true,fid,0,sizeof(alp_file_header_t),data);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_write_fprop_root(u8 fid, alp_file_header_t* data, u8* root_key, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_WR_PROP_SIZE_MAX)];
u8* p = tmp;
u8* lastp;
DPRINT(L_API, "WR PROPS (ROOT)[%d]\n",fid);
ASSERT(root_key != NULL, "Missing ROOT KEY\n");
ALP_ACTION_TAG(p, id, true);
// Actual Operation will take place after PERM_REQ
p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET];
ALP_ACTION_F_WR_PROP(p,true,fid,0,sizeof(alp_file_header_t),data);
lastp = p;
modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key,
&tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET],
ALP_ACTION_F_WR_PROP_SIZE_MAX);
serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp));
}
public void modem_write_file(u8 fid, void *data, u32 offset, u32 length, u8 id)
{
ALLOC_BUFFER(u8, tmp,(ALP_ACTION_TAG_SIZE + ALP_ACTION_F_WR_DATA_SIZE_MAX(length)));
u8* p = tmp;
REF_PRINT("WR[%d]@%d %d Bytes\n",fid,offset,length);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_WR_DATA(p,true,fid,offset,length,data);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
DEALLOC_BUFFER(tmp);
}
public void modem_write_file_root(u8 fid, void *data, u32 offset, u32 length, u8* root_key, u8 id)
{
ALLOC_BUFFER(u8, tmp,(ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_WR_DATA_SIZE_MAX(length))));
u8* p = tmp;
u8* lastp;
REF_PRINT("WR (ROOT)[%d]@%d %d Bytes\n",fid,offset,length);
ASSERT(root_key != NULL, "Missing ROOT KEY\n");
ALP_ACTION_TAG(p, id, true);
// Actual Operation will take place after PERM_REQ
p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET];
ALP_ACTION_F_WR_DATA(p,true,fid,offset,length,data);
lastp = p;
modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key,
&tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET],
ALP_ACTION_F_WR_DATA_SIZE(offset,length));
serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp));
DEALLOC_BUFFER(tmp);
}
public void modem_flush_file(u8 fid, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_FLUSH_SIZE];
u8* p = tmp;
REF_PRINT("FLUSH[%d]\n",fid);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_FLUSH(p,true,fid);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_flush_file_root(u8 fid, u8* root_key, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_FLUSH_SIZE)];
u8* p = tmp;
u8* lastp;
REF_PRINT("FLUSH (ROOT)[%d]\n",fid);
ASSERT(root_key != NULL, "Missing ROOT KEY\n");
ALP_ACTION_TAG(p, id, true);
// Actual Operation will take place after PERM_REQ
p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET];
ALP_ACTION_F_FLUSH(p,true,fid);
lastp = p;
modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key,
&tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET],
ALP_ACTION_F_FLUSH_SIZE);
serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp));
}
public void modem_declare_file(u8 fid, alp_file_header_t* hdr, u8 local, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_DECLARE_SIZE];
u8* p = tmp;
REF_PRINT("DECLARE[%d]\n",fid);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_DECLARE(p,true,fid,hdr,local);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_create_file(u8 fid, alp_file_header_t* hdr, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_CREATE_SIZE];
u8* p = tmp;
REF_PRINT("CREATE[%d]\n",fid);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_CREATE(p,true,fid,hdr);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_notify_file(u8 fid, u32 offset, u32 length, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_TOUCH_SIZE_MAX];
u8* p = tmp;
REF_PRINT("NOTIFY[%d]@%d %d Bytes\n",fid,offset,length);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_TOUCH(p,true,fid,offset,length);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_delete_file(u8 fid, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_F_DELETE_SIZE];
u8* p = tmp;
REF_PRINT("DELETE[%d]\n",fid);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_F_DELETE(p,true,fid);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_delete_file_root(u8 fid, u8* root_key, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_SIZE(ALP_ACTION_F_DELETE_SIZE)];
u8* p = tmp;
u8* lastp;
REF_PRINT("DELETE ROOT[%d]\n",fid);
ALP_ACTION_TAG(p,id,true);
// Actual Operation will take place after PERM_REQ
p = &tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET];
ALP_ACTION_F_DELETE(p,true,fid);
lastp = p;
modem_add_root_permission(&tmp[ALP_ACTION_TAG_SIZE], root_key,
&tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_PERM_REQ_OFFSET],
ALP_ACTION_F_DELETE_SIZE);
serial_send(WC_FLOW_ALP_UNS, tmp, (lastp-tmp));
}
public void modem_send_raw_alp(u8* payload, u32 length, u8 id)
{
ALLOC_BUFFER(u8, tmp,ALP_ACTION_TAG_SIZE + length);
u8* p = tmp;
REF_PRINT("ALP RAW %d Bytes\n",length);
ALP_ACTION_TAG(p,id,true);
// User Payload
memcpy(p,payload,length);p+=length;
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
DEALLOC_BUFFER(tmp);
}
public void modem_send_file_content(u8* itf, u8 itf_length, void *istatus, u8 fid, void *data, u32 offset, u32 length, u8 id)
{
ALLOC_BUFFER(u8, tmp,ALP_ACTION_TAG_SIZE + ALP_ACTION_FORWARD_SIZE(itf_length) + ALP_ACTION_RSP_F_DATA_SIZE_MAX(length));
u8* p = tmp;
g_modem.user[id].istatus= (u8*)istatus;
REF_PRINT("SEND FILE[%d] CONTENTS @%d %d Bytes (itf %d Bytes)\n",fid,offset,length,itf_length);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_FORWARD(p,itf,itf_length);
if (istatus)
{
// NOP action to get istats on ACKs
ALP_ACTION_NOP(p,true);
}
ALP_ACTION_RSP_F_DATA(p,fid,offset,length,data);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
DEALLOC_BUFFER(tmp);
}
public void modem_remote_read_file(u8* itf, u8 itf_length, void *istatus , u8 fid, void *data, u32 offset, u32 length, u8 id)
{
ALLOC_BUFFER(u8, tmp,ALP_ACTION_TAG_SIZE + ALP_ACTION_FORWARD_SIZE(itf_length) + ALP_ACTION_F_RD_DATA_SIZE_MAX);
u8* p = tmp;
g_modem.user[id].data = (u8*)data;
g_modem.user[id].istatus = (u8*)istatus;
REF_PRINT("RMT RD FILE[%d]@%d %d Bytes (itf %d Bytes)\n",fid,offset,length,itf_length);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_FORWARD(p,itf,itf_length);
ALP_ACTION_F_RD_DATA(p,true,fid,offset,length);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
DEALLOC_BUFFER(tmp);
}
<<<<<<< working copy
public void modem_remote_write_file(u8* itf, u8 itf_length, void *istatus, u8 fid, void *data, u32 offset, u32 length, u8 id)
=======
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)
{
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));
u8* p = tmp;
u32 perm_offset;
ASSERT(root_key != NULL, "Missing ROOT KEY\n");
g_modem.user[id].data = (u8*)data;
g_modem.user[id].istatus = (u8*)istatus;
REF_PRINT("RMT RD FILE (ROOT)[%d]@%d %d Bytes (itf %d Bytes)\n", fid, offset, length, itf_length);
ALP_ACTION_TAG(p, id, true);
ALP_ACTION_FORWARD(p, itf, itf_length);
// Mark start of permission request
perm_offset = (u32)(p-tmp);
// Actual Operation will take place after PERM_REQ
p = &tmp[perm_offset + ALP_ACTION_PERM_REQ_OFFSET];
ALP_ACTION_F_RD_DATA(p, true, fid, offset, length);
modem_add_root_permission(&tmp[perm_offset], root_key,
&tmp[perm_offset + ALP_ACTION_PERM_REQ_OFFSET],
ALP_ACTION_F_RD_DATA_SIZE(offset, length));
SERIAL_SEND(WC_FLOW_ALP_UNS, tmp, (u8)(p-tmp));
DEALLOC_BUFFER(tmp);
}
public void modem_remote_write_file(u8* itf, u8 itf_length, void *istatus , u8 fid, void *data, u32 offset, u32 length, u8 id)
>>>>>>> merge rev
{
ALLOC_BUFFER(u8, tmp,ALP_ACTION_TAG_SIZE + ALP_ACTION_FORWARD_SIZE(itf_length) + ALP_ACTION_F_WR_DATA_SIZE_MAX(length));
u8* p = tmp;
g_modem.user[id].istatus = (u8*)istatus;
REF_PRINT("RMT WR FILE[%d]@%d %d Bytes (itf %d Bytes)\n",fid,offset,length,itf_length);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_FORWARD(p,itf,itf_length);
ALP_ACTION_F_WR_DATA(p,true,fid,offset,length,data);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
DEALLOC_BUFFER(tmp);
}
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)
{
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))));
u8* p = tmp;
u8* actp;
u8* reqp;
g_modem.user[id].istatus = (u8*)istatus;
REF_PRINT("WR (ROOT)[%d]@%d %d Bytes\n",fid,offset,length);
ASSERT(root_key != NULL, "Missing ROOT KEY\n");
// TAG and FORWARD
ALP_ACTION_TAG(p, id, true);
ALP_ACTION_FORWARD(p,itf,itf_length);
// Save offset of permission request
reqp = p;
// Actual Operation will take place after PERM_REQ, skip it
p += ALP_ACTION_PERM_REQ_OFFSET;
// Save action offset
actp = p;
// Actual action
ALP_ACTION_F_WR_DATA(p,true,fid,offset,length,data);
// Add permission request at request offset
modem_add_root_permission(
reqp,
root_key,
actp,
ALP_ACTION_F_WR_DATA_SIZE(offset,length)
);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
DEALLOC_BUFFER(tmp);
}
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)
{
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)));
u8* p = tmp;
u32 perm_offset;
ASSERT(root_key != NULL, "Missing ROOT KEY\n");
g_modem.user[id].istatus = (u8*)istatus;
REF_PRINT("RMT WR FILE (ROOT)[%d]@%d %d Bytes (itf %d Bytes)\n", fid, offset, length, itf_length);
ALP_ACTION_TAG(p, id, true);
ALP_ACTION_FORWARD(p, itf, itf_length);
// Mark start of permission request
perm_offset = (u32)(p-tmp);
// Actual Operation will take place after PERM_REQ
p = &tmp[perm_offset + ALP_ACTION_PERM_REQ_OFFSET];
ALP_ACTION_F_WR_DATA(p, true, fid, offset, length, data);
modem_add_root_permission(&tmp[perm_offset], root_key,
&tmp[perm_offset + ALP_ACTION_PERM_REQ_OFFSET],
ALP_ACTION_F_WR_DATA_SIZE(offset, length));
SERIAL_SEND(WC_FLOW_ALP_UNS,tmp, (u8)(p-tmp));
DEALLOC_BUFFER(tmp);
}
public void modem_enable_urc(u8 type, u8 ifid, u8 val, u8 enable, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_URCC_SIZE(ALP_URC_TYPE_LQUAL)];
u8* p = tmp;
REF_PRINT("URC[%d] Type %d ifid %d\n",enable,type,ifid);
ALP_ACTION_TAG(p,id,true);
// Actual Operation
if (enable)
{
ALP_ACTION_URCC_EN(p,true,type,ifid,val);
}
else
{
ALP_ACTION_URCC_DIS(p,true,type,ifid,val);
}
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_activate_itf(u8 type, u8 nb_dev, u8 ifid, u8 flags, u8 enable, u8 id)
{
u8 tmp[ALP_ACTION_TAG_SIZE + ALP_ACTION_ACTIVATE_ITF_SIZE];
u8* p = tmp;
REF_PRINT("ACTIVATE ITFTYPE[%x]:%d\n",type,enable);
ALP_ACTION_TAG(p,id,true);
ALP_ACTION_ACTIVATE_ITF(p,true,enable,type,nb_dev,ifid,flags);
serial_send(WC_FLOW_ALP_UNS, tmp, (p-tmp));
}
public void modem_respond(s8 status, int id)
{
u8 tmp[ALP_ACTION_RSP_TAG_SIZE + ALP_ACTION_RSP_STATUS_SIZE];
u8* p = tmp;
REF_PRINT("RESP[%d]:%d\n",g_modem.action,status);
if (id>=0) { ALP_ACTION_RSP_TAG(p,id,true,(status<0)?true:false); }
ALP_ACTION_RSP_STATUS(p, g_modem.action, status);
serial_send(WC_FLOW_ALP_RESP, tmp, (p-tmp));
}
public void modem_respond_fprop(u8 fid, u8* hdr, int id)
{
u8 tmp[ALP_ACTION_RSP_TAG_SIZE + ALP_ACTION_RSP_F_PROP_SIZE];
u8* p = tmp;
REF_PRINT("RESP FPROP[%d]\n",fid);
if (id>=0) { ALP_ACTION_RSP_TAG(p,id,true,false); }
ALP_ACTION_RSP_F_PROP(p,fid,hdr);
serial_send(WC_FLOW_ALP_RESP, tmp, (p-tmp));
}
public void modem_respond_read(u8 fid,void *data, u32 offset, u32 length, int id)
{
ALLOC_BUFFER(u8, tmp,ALP_ACTION_RSP_TAG_SIZE + ALP_ACTION_RSP_F_DATA_SIZE_MAX(length));
u8* p = tmp;
REF_PRINT("F_DATA[%d]@%d %d Bytes\n",fid,offset,length);
if (id>=0) { ALP_ACTION_RSP_TAG(p,id,true,false); }
ALP_ACTION_RSP_F_DATA(p,fid,offset,length,data);
serial_send(WC_FLOW_ALP_RESP, tmp, (p-tmp));
DEALLOC_BUFFER(tmp);
}