Exportable version of WizziLab's modem driver.

Dependents:   modem_ref_helper

Committer:
Jeej
Date:
Fri Feb 19 10:59:42 2021 +0000
Revision:
60:08efaaca0e83
Parent:
59:3b38b5f499db
Fixed responses

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:027760f45e2c 1 /// @copyright
Jeej 0:027760f45e2c 2 /// ========================================================================={{{
Jeej 0:027760f45e2c 3 /// Copyright (c) 2012-2017 WizziLab /
Jeej 0:027760f45e2c 4 /// All rights reserved /
Jeej 0:027760f45e2c 5 /// /
Jeej 0:027760f45e2c 6 /// Should you have any questions regarding your right to use this Software, /
Jeej 0:027760f45e2c 7 /// contact WizziLab at www.wizzilab.com. /
Jeej 0:027760f45e2c 8 /// /
Jeej 0:027760f45e2c 9 /// =========================================================================}}}
Jeej 0:027760f45e2c 10 /// @endcopyright
Jeej 0:027760f45e2c 11
Jeej 0:027760f45e2c 12 // ====================================================================
Jeej 0:027760f45e2c 13 // @file alp_helpers.c
Jeej 56:67e3d9608403 14 // @brief ALP helpers functions.
Jeej 0:027760f45e2c 15 // This code should be disclosable in source.
Jeej 0:027760f45e2c 16 // ====================================================================
Jeej 0:027760f45e2c 17
Jeej 0:027760f45e2c 18
Jeej 0:027760f45e2c 19 #include "alp.h"
Jeej 56:67e3d9608403 20 #include "alp_dbg.h"
Jeej 41:6f83174ffed4 21 #include "kal_math.h"
Jeej 56:67e3d9608403 22 #include "kal_crypto.h"
Jeej 56:67e3d9608403 23 #include "d7a_1x_fs.h"
Jeej 0:027760f45e2c 24
Jeej 57:5444cfda9889 25 #include "WizziDebug.h"
Jeej 57:5444cfda9889 26
Jeej 0:027760f45e2c 27 //======================================================================
Jeej 0:027760f45e2c 28 // alp_size
Jeej 0:027760f45e2c 29 //----------------------------------------------------------------------
Jeej 0:027760f45e2c 30 /// @brief Return payload length of most ALP operations
Jeej 0:027760f45e2c 31 /// @param op : ALP Action amongst alp_opcodes_t
Jeej 0:027760f45e2c 32 /// @param offset : Associated Offset if relevant
Jeej 0:027760f45e2c 33 /// @param size : Associated Size if relevant
Jeej 0:027760f45e2c 34 /// @retval payload size in bytes
Jeej 0:027760f45e2c 35 //======================================================================
Jeej 56:67e3d9608403 36 uint alp_size(u8 op, u32 offset, u32 length)
Jeej 0:027760f45e2c 37 {
Jeej 0:027760f45e2c 38 uint len=2;// At least OP+FID / OP+TAG
Jeej 0:027760f45e2c 39 switch (op)
Jeej 0:027760f45e2c 40 {
Jeej 0:027760f45e2c 41 case ALP_OPCODE_NOP:
Jeej 0:027760f45e2c 42 case ALP_OPCODE_F_TOUCH:
Jeej 0:027760f45e2c 43 case ALP_OPCODE_F_EXIST:
Jeej 0:027760f45e2c 44 case ALP_OPCODE_F_DELETE:
Jeej 0:027760f45e2c 45 case ALP_OPCODE_F_FLUSH:
Jeej 0:027760f45e2c 46 case ALP_OPCODE_RSP_TAG:
Jeej 0:027760f45e2c 47 case ALP_OPCODE_F_RD_PROP:
Jeej 0:027760f45e2c 48 break;
Jeej 0:027760f45e2c 49 case ALP_OPCODE_RSP_STATUS:
Jeej 0:027760f45e2c 50 len += 1;
Jeej 0:027760f45e2c 51 break;
Jeej 0:027760f45e2c 52 case ALP_OPCODE_F_CREATE:
Jeej 0:027760f45e2c 53 case ALP_OPCODE_F_DECLARE:
Jeej 0:027760f45e2c 54 case ALP_OPCODE_RSP_F_PROP:
Jeej 0:027760f45e2c 55 len += ALP_FILE_HEADER_SIZE;
Jeej 0:027760f45e2c 56 break;
Jeej 0:027760f45e2c 57 case ALP_OPCODE_F_WR_PROP:
Jeej 0:027760f45e2c 58 case ALP_OPCODE_F_WR_DATA:
Jeej 0:027760f45e2c 59 case ALP_OPCODE_RSP_F_DATA:
Jeej 0:027760f45e2c 60 len = length;
Jeej 35:ac940cf8ebe6 61 // Fallthrough
Jeej 0:027760f45e2c 62 case ALP_OPCODE_F_RD_DATA:
Jeej 0:027760f45e2c 63 len += ALP_LFIELD_SIZE(offset) + ALP_LFIELD_SIZE(length);
Jeej 0:027760f45e2c 64 break;
Jeej 0:027760f45e2c 65 default:
Jeej 57:5444cfda9889 66 //ALP_ASSERT(false, "ASSERT: ALP: alp_size unsupported op %d\n", op);
Jeej 0:027760f45e2c 67 break;
Jeej 0:027760f45e2c 68 }
Jeej 0:027760f45e2c 69 return len;
Jeej 0:027760f45e2c 70 }
Jeej 0:027760f45e2c 71
Jeej 0:027760f45e2c 72 //======================================================================
Jeej 0:027760f45e2c 73 // alp_encode_length
Jeej 0:027760f45e2c 74 //----------------------------------------------------------------------
Jeej 0:027760f45e2c 75 /// @brief Encodes an ALP length/offset field
Jeej 0:027760f45e2c 76 /// @param p : pointer to the payload buffer
Jeej 0:027760f45e2c 77 /// @param len : value to be encoded
Jeej 0:027760f45e2c 78 /// @retval resulting payload size in bytes
Jeej 0:027760f45e2c 79 //======================================================================
Jeej 56:67e3d9608403 80 u8 alp_encode_length(u8* p, u32 len)
Jeej 0:027760f45e2c 81 {
Jeej 0:027760f45e2c 82 if (len <= 0x3F)
Jeej 0:027760f45e2c 83 {
Jeej 0:027760f45e2c 84 *p++ = len;
Jeej 0:027760f45e2c 85 return 1;
Jeej 0:027760f45e2c 86 }
Jeej 0:027760f45e2c 87 else if (len <= 0x3FFF)
Jeej 0:027760f45e2c 88 {
Jeej 0:027760f45e2c 89 *p++ = 0x40 + (u8)(len >> 8);
Jeej 0:027760f45e2c 90 *p++ = (u8)(len & 0xFF);
Jeej 0:027760f45e2c 91 return 2;
Jeej 0:027760f45e2c 92 }
Jeej 0:027760f45e2c 93 else if (len <= 0x3FFFFF)
Jeej 0:027760f45e2c 94 {
Jeej 0:027760f45e2c 95 *p++ = 0x80 + (u8) (len >> 16);
Jeej 0:027760f45e2c 96 *p++ = (u8)((len >> 8) & 0xFF);
Jeej 0:027760f45e2c 97 *p++ = (u8) (len & 0xFF);
Jeej 0:027760f45e2c 98 return 3;
Jeej 0:027760f45e2c 99 }
Jeej 0:027760f45e2c 100 else
Jeej 0:027760f45e2c 101 {
Jeej 0:027760f45e2c 102 *p++ = 0xC0 + (u8) (len >> 24);
Jeej 0:027760f45e2c 103 *p++ = (u8)((len >> 16) & 0xFF);
Jeej 0:027760f45e2c 104 *p++ = (u8)((len >> 8) & 0xFF);
Jeej 0:027760f45e2c 105 *p++ = (u8) (len & 0xFF);
Jeej 0:027760f45e2c 106 return 4;
Jeej 0:027760f45e2c 107 }
Jeej 0:027760f45e2c 108 }
Jeej 0:027760f45e2c 109
Jeej 0:027760f45e2c 110
Jeej 0:027760f45e2c 111 //======================================================================
Jeej 0:027760f45e2c 112 // alp_decode_length
Jeej 0:027760f45e2c 113 //----------------------------------------------------------------------
Jeej 0:027760f45e2c 114 /// @brief Decodes an ALP length/offset field
Jeej 0:027760f45e2c 115 /// @param p : pointer to the pointer to payload buffer
Jeej 0:027760f45e2c 116 /// @param actp : pointer to ALP's Action Protocol Substitution flag
Jeej 0:027760f45e2c 117 /// Result amongst alp_actp_substitution_mode_t
Jeej 0:027760f45e2c 118 /// @retval decoded value
Jeej 0:027760f45e2c 119 //======================================================================
Jeej 56:67e3d9608403 120 u32 alp_decode_length(u8** p, u8* actp)
Jeej 0:027760f45e2c 121 {
Jeej 0:027760f45e2c 122 u32 tmp = 0;
Jeej 0:027760f45e2c 123 switch ((**p) & 0xC0)
Jeej 0:027760f45e2c 124 {
Jeej 0:027760f45e2c 125 case 0xC0: // 0xCx xx xx xx
Jeej 0:027760f45e2c 126 tmp = ((*(*p)++) & 0x3F) << 24;
Jeej 0:027760f45e2c 127 tmp += (*(*p)++) << 16;
Jeej 0:027760f45e2c 128 tmp += (*(*p)++) << 8;
Jeej 0:027760f45e2c 129 tmp += (*(*p)++) << 0;
Jeej 0:027760f45e2c 130 break;
Jeej 0:027760f45e2c 131 case 0x80: // 0x8x xx xx : 16384 <= Len <4194303
Jeej 0:027760f45e2c 132 tmp = ((*(*p)++) & 0x3F) << 16;
Jeej 0:027760f45e2c 133 tmp += (*(*p)++) << 8;
Jeej 0:027760f45e2c 134 if (tmp == 0)
Jeej 0:027760f45e2c 135 {
Jeej 0:027760f45e2c 136 // 0x8000 ActP special ActP code
Jeej 0:027760f45e2c 137 // Do not fetch the extra byte
Jeej 0:027760f45e2c 138 *actp = 2;
Jeej 0:027760f45e2c 139 }
Jeej 0:027760f45e2c 140 else
Jeej 0:027760f45e2c 141 {
Jeej 0:027760f45e2c 142 tmp += (*(*p)++) << 0;
Jeej 0:027760f45e2c 143 }
Jeej 0:027760f45e2c 144 break;
Jeej 0:027760f45e2c 145 case 0x40: // 0x4x xx : 64 <= Len < 16383
Jeej 0:027760f45e2c 146 tmp = ((*(*p)++) & 0x3F) << 8;
Jeej 0:027760f45e2c 147 tmp += (*(*p)++) << 0;
Jeej 0:027760f45e2c 148 if (tmp == 0)
Jeej 0:027760f45e2c 149 {
Jeej 0:027760f45e2c 150 // 0x4000 ActP special ActP code
Jeej 0:027760f45e2c 151 *actp = 1;
Jeej 0:027760f45e2c 152 }
Jeej 0:027760f45e2c 153 break;
Jeej 0:027760f45e2c 154 case 0: // Len <63
Jeej 0:027760f45e2c 155 tmp = (*(*p)++ & 0x3F) << 0;
Jeej 0:027760f45e2c 156 break;
Jeej 0:027760f45e2c 157 }
Jeej 0:027760f45e2c 158 return tmp;
Jeej 0:027760f45e2c 159 }
Jeej 0:027760f45e2c 160
Jeej 56:67e3d9608403 161 //======================================================================
Jeej 56:67e3d9608403 162 // alp_itf_size
Jeej 56:67e3d9608403 163 //----------------------------------------------------------------------
Jeej 56:67e3d9608403 164 /// @brief Get size of the interface configuration
Jeej 56:67e3d9608403 165 /// @param itf pointer to the configuration
Jeej 56:67e3d9608403 166 /// @return int configuration size
Jeej 56:67e3d9608403 167 //======================================================================
Jeej 56:67e3d9608403 168 int alp_itf_size(void* itf)
Jeej 56:67e3d9608403 169 {
Jeej 56:67e3d9608403 170 alp_itf_cfg_t* p = (alp_itf_cfg_t*)itf;
Jeej 56:67e3d9608403 171
Jeej 56:67e3d9608403 172 switch (p->type)
Jeej 56:67e3d9608403 173 {
Jeej 56:67e3d9608403 174 case ALP_ITF_TYPE_D7A:
Jeej 57:5444cfda9889 175 {
Jeej 57:5444cfda9889 176 alp_itf_d7a_cfg_t* d7a_itf = (alp_itf_d7a_cfg_t*)itf;
Jeej 57:5444cfda9889 177 return (1 + alp_itf_d7a_cfg_size((u8*)&d7a_itf->cfg));
Jeej 57:5444cfda9889 178 }
Jeej 56:67e3d9608403 179 case ALP_ITF_TYPE_COM:
Jeej 56:67e3d9608403 180 return sizeof(alp_itf_com_cfg_t);
Jeej 56:67e3d9608403 181 case ALP_ITF_TYPE_LWAN:
Jeej 56:67e3d9608403 182 return sizeof(alp_itf_lwan_cfg_t);
Jeej 56:67e3d9608403 183 default:
Jeej 56:67e3d9608403 184 ALP_ASSERT(FALSE, "ASSERT: ALP: Unknown ITF 0x%02X for itf size\n", p->type);
Jeej 56:67e3d9608403 185 break;
Jeej 56:67e3d9608403 186 }
Jeej 56:67e3d9608403 187
Jeej 56:67e3d9608403 188 return 0;
Jeej 56:67e3d9608403 189 }
Jeej 0:027760f45e2c 190
Jeej 0:027760f45e2c 191 //======================================================================
Jeej 0:027760f45e2c 192 // alp_parse_chunk
Jeej 0:027760f45e2c 193 //----------------------------------------------------------------------
Jeej 0:027760f45e2c 194 /// @brief Parses an ALP payload and extract a single chunk (action or
Jeej 0:027760f45e2c 195 /// response) to a more generic alp_parsed_chunk_t structure.
Jeej 0:027760f45e2c 196 /// @param payload : pointer to the pointer to payload buffer
Jeej 0:027760f45e2c 197 /// @param resp : pointer to alp_parsed_chunk_t structure
Jeej 0:027760f45e2c 198 /// @retval number of parsed bytes
Jeej 0:027760f45e2c 199 //======================================================================
Jeej 56:67e3d9608403 200 int alp_parse_chunk(u8** payload, alp_parsed_chunk_t* resp) // {{{
Jeej 0:027760f45e2c 201 {
Jeej 0:027760f45e2c 202 u8* p = *payload;
Jeej 0:027760f45e2c 203 u8 op = *p++;
Jeej 0:027760f45e2c 204 u8 actp;
Jeej 0:027760f45e2c 205 u32 bytes;
Jeej 0:027760f45e2c 206 resp->type = op & 0x3F;
Jeej 0:027760f45e2c 207 resp->data = (u8*)NULL;
Jeej 0:027760f45e2c 208 switch(resp->type) // XXX preemption bits squashed
Jeej 0:027760f45e2c 209 {
Jeej 0:027760f45e2c 210 case ALP_OPCODE_RSP_TAG:
Jeej 0:027760f45e2c 211 case ALP_OPCODE_TAG:
Jeej 0:027760f45e2c 212 resp->meta.tag.id = *p++; // PID
Jeej 0:027760f45e2c 213 resp->meta.tag.eop = !!(op & ALP_OPCODE_EOP);
Jeej 0:027760f45e2c 214 resp->meta.tag.err = !!(op & ALP_OPCODE_ERR);
Jeej 0:027760f45e2c 215 break;
Jeej 0:027760f45e2c 216 case ALP_OPCODE_RSP_F_DATA:
Jeej 0:027760f45e2c 217 case ALP_OPCODE_F_WR_DATA:
Jeej 0:027760f45e2c 218 resp->meta.f_data.fid = *p++; // FID
Jeej 57:5444cfda9889 219 resp->meta.f_data.offset = alp_decode_length(&p, &actp); // Offset
Jeej 57:5444cfda9889 220 resp->meta.f_data.length = alp_decode_length(&p, &actp); // Length
Jeej 0:027760f45e2c 221 resp->data = p;
Jeej 0:027760f45e2c 222 p += resp->meta.f_data.length;
Jeej 0:027760f45e2c 223 break;
Jeej 0:027760f45e2c 224 case ALP_OPCODE_F_RD_DATA:
Jeej 0:027760f45e2c 225 resp->meta.f_data.fid = *p++; // FID
Jeej 57:5444cfda9889 226 resp->meta.f_data.offset = alp_decode_length(&p, &actp); // Offset
Jeej 57:5444cfda9889 227 resp->meta.f_data.length = alp_decode_length(&p, &actp); // Length
Jeej 0:027760f45e2c 228 break;
Jeej 0:027760f45e2c 229 case ALP_OPCODE_F_RD_PROP:
Jeej 0:027760f45e2c 230 resp->meta.f_prop.fid = *p++; // FID
Jeej 0:027760f45e2c 231 resp->meta.f_prop.offset = 0;
Jeej 0:027760f45e2c 232 resp->meta.f_prop.length = ALP_FILE_HEADER_SIZE; // Hardcoded Length
Jeej 0:027760f45e2c 233 break;
Jeej 0:027760f45e2c 234 case ALP_OPCODE_RSP_F_PROP:
Jeej 0:027760f45e2c 235 resp->meta.f_prop.fid = *p++; // FID
Jeej 0:027760f45e2c 236 resp->meta.f_prop.offset = 0;
Jeej 0:027760f45e2c 237 resp->meta.f_prop.length = ALP_FILE_HEADER_SIZE; // Hardcoded Length
Jeej 0:027760f45e2c 238 resp->data = p;
Jeej 0:027760f45e2c 239 p += resp->meta.f_prop.length;
Jeej 0:027760f45e2c 240 break;
Jeej 0:027760f45e2c 241 case ALP_OPCODE_RSP_STATUS:
Jeej 56:67e3d9608403 242 if (ALP_OPCODE_RSP_ISTATUS == op)
Jeej 0:027760f45e2c 243 {
Jeej 0:027760f45e2c 244 resp->type = ALP_OPCODE_RSP_ISTATUS;
Jeej 0:027760f45e2c 245 resp->meta.itf.type = *p++; // ITF Type
Jeej 57:5444cfda9889 246 resp->meta.itf.length = alp_decode_length(&p, &actp); // Length
Jeej 0:027760f45e2c 247 resp->data = p;
Jeej 0:027760f45e2c 248 p += resp->meta.itf.length;
Jeej 0:027760f45e2c 249 }
Jeej 56:67e3d9608403 250 else if (ALP_OPCODE_RSP_EOPISTATUS == op)
Jeej 37:f5424d109c6d 251 {
Jeej 37:f5424d109c6d 252 resp->type = ALP_OPCODE_RSP_EOPISTATUS;
Jeej 37:f5424d109c6d 253 resp->meta.istatus.itf = *p++; // ITF Type
Jeej 37:f5424d109c6d 254 p++; // Length (always 1)
Jeej 37:f5424d109c6d 255 resp->meta.istatus.err = *p++; // Interface error
Jeej 37:f5424d109c6d 256 }
Jeej 0:027760f45e2c 257 else
Jeej 0:027760f45e2c 258 {
Jeej 0:027760f45e2c 259 resp->meta.status.id = *p++; // Action ID
Jeej 0:027760f45e2c 260 resp->meta.status.code = *p++; // status
Jeej 0:027760f45e2c 261 }
Jeej 0:027760f45e2c 262 break;
Jeej 0:027760f45e2c 263 case ALP_OPCODE_RSP_URC:
Jeej 0:027760f45e2c 264 resp->meta.urc.type = *p++; // Type
Jeej 0:027760f45e2c 265 resp->meta.urc.ifid = *p++; // Ifid
Jeej 0:027760f45e2c 266 if (resp->meta.urc.type == ALP_URC_TYPE_LQUAL)
Jeej 41:6f83174ffed4 267 {
Jeej 0:027760f45e2c 268 resp->meta.urc.per = *p++; // Per
Jeej 41:6f83174ffed4 269 }
Jeej 41:6f83174ffed4 270 else if (resp->meta.urc.type == ALP_URC_TYPE_ITF_BUSY)
Jeej 41:6f83174ffed4 271 {
Jeej 41:6f83174ffed4 272 kal_ctf_t to;
Jeej 41:6f83174ffed4 273 to.byte = *p++; // timeout
Jeej 41:6f83174ffed4 274 resp->meta.urc.per = (to.byte == 0xff) ? MAX_U32 : kal_ctf_decode(to);
Jeej 41:6f83174ffed4 275 }
Jeej 0:027760f45e2c 276 break;
Jeej 0:027760f45e2c 277 case ALP_OPCODE_F_DELETE:
Jeej 0:027760f45e2c 278 case ALP_OPCODE_F_FLUSH:
Jeej 0:027760f45e2c 279 resp->meta.f_data.fid = *p++; // FID
Jeej 0:027760f45e2c 280 break;
Jeej 56:67e3d9608403 281 case ALP_OPCODE_RSP_SECURED:
Jeej 56:67e3d9608403 282 resp->type = ALP_OPCODE_RSP_SECURED;
Jeej 56:67e3d9608403 283 *payload = (u8*)NULL;
Jeej 56:67e3d9608403 284 return 0; // XXX payload length unknown
Jeej 0:027760f45e2c 285 default:
Jeej 0:027760f45e2c 286 resp->type = ALP_OPCODE_UNKNOWN;
Jeej 0:027760f45e2c 287 *payload = (u8*)NULL;
Jeej 0:027760f45e2c 288 return 0;
Jeej 0:027760f45e2c 289 }
Jeej 0:027760f45e2c 290 bytes = p - *payload;
Jeej 0:027760f45e2c 291 *payload = p;
Jeej 0:027760f45e2c 292 return bytes;
Jeej 0:027760f45e2c 293 } // }}}