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.
alp_helpers.cpp
00001 /// @copyright 00002 /// ========================================================================={{{ 00003 /// Copyright (c) 2012-2017 WizziLab / 00004 /// All rights reserved / 00005 /// / 00006 /// Should you have any questions regarding your right to use this Software, / 00007 /// contact WizziLab at www.wizzilab.com. / 00008 /// / 00009 /// =========================================================================}}} 00010 /// @endcopyright 00011 00012 // ==================================================================== 00013 // @file alp_helpers.c 00014 // @brief ALP helpers functions. 00015 // This code should be disclosable in source. 00016 // ==================================================================== 00017 00018 00019 #include "alp.h" 00020 #include "alp_dbg.h" 00021 #include "kal_math.h" 00022 #include "kal_crypto.h" 00023 #include "d7a_1x_fs.h" 00024 00025 #include "WizziDebug.h" 00026 00027 //====================================================================== 00028 // alp_size 00029 //---------------------------------------------------------------------- 00030 /// @brief Return payload length of most ALP operations 00031 /// @param op : ALP Action amongst alp_opcodes_t 00032 /// @param offset : Associated Offset if relevant 00033 /// @param size : Associated Size if relevant 00034 /// @retval payload size in bytes 00035 //====================================================================== 00036 uint alp_size(u8 op, u32 offset, u32 length) 00037 { 00038 uint len=2;// At least OP+FID / OP+TAG 00039 switch (op) 00040 { 00041 case ALP_OPCODE_NOP: 00042 case ALP_OPCODE_F_TOUCH: 00043 case ALP_OPCODE_F_EXIST: 00044 case ALP_OPCODE_F_DELETE: 00045 case ALP_OPCODE_F_FLUSH: 00046 case ALP_OPCODE_RSP_TAG: 00047 case ALP_OPCODE_F_RD_PROP: 00048 break; 00049 case ALP_OPCODE_RSP_STATUS: 00050 len += 1; 00051 break; 00052 case ALP_OPCODE_F_CREATE: 00053 case ALP_OPCODE_F_DECLARE: 00054 case ALP_OPCODE_RSP_F_PROP: 00055 len += ALP_FILE_HEADER_SIZE; 00056 break; 00057 case ALP_OPCODE_F_WR_PROP: 00058 case ALP_OPCODE_F_WR_DATA: 00059 case ALP_OPCODE_RSP_F_DATA: 00060 len = length; 00061 // Fallthrough 00062 case ALP_OPCODE_F_RD_DATA: 00063 len += ALP_LFIELD_SIZE(offset) + ALP_LFIELD_SIZE(length); 00064 break; 00065 default: 00066 //ALP_ASSERT(false, "ASSERT: ALP: alp_size unsupported op %d\n", op); 00067 break; 00068 } 00069 return len; 00070 } 00071 00072 //====================================================================== 00073 // alp_encode_length 00074 //---------------------------------------------------------------------- 00075 /// @brief Encodes an ALP length/offset field 00076 /// @param p : pointer to the payload buffer 00077 /// @param len : value to be encoded 00078 /// @retval resulting payload size in bytes 00079 //====================================================================== 00080 u8 alp_encode_length(u8* p, u32 len) 00081 { 00082 if (len <= 0x3F) 00083 { 00084 *p++ = len; 00085 return 1; 00086 } 00087 else if (len <= 0x3FFF) 00088 { 00089 *p++ = 0x40 + (u8)(len >> 8); 00090 *p++ = (u8)(len & 0xFF); 00091 return 2; 00092 } 00093 else if (len <= 0x3FFFFF) 00094 { 00095 *p++ = 0x80 + (u8) (len >> 16); 00096 *p++ = (u8)((len >> 8) & 0xFF); 00097 *p++ = (u8) (len & 0xFF); 00098 return 3; 00099 } 00100 else 00101 { 00102 *p++ = 0xC0 + (u8) (len >> 24); 00103 *p++ = (u8)((len >> 16) & 0xFF); 00104 *p++ = (u8)((len >> 8) & 0xFF); 00105 *p++ = (u8) (len & 0xFF); 00106 return 4; 00107 } 00108 } 00109 00110 00111 //====================================================================== 00112 // alp_decode_length 00113 //---------------------------------------------------------------------- 00114 /// @brief Decodes an ALP length/offset field 00115 /// @param p : pointer to the pointer to payload buffer 00116 /// @param actp : pointer to ALP's Action Protocol Substitution flag 00117 /// Result amongst alp_actp_substitution_mode_t 00118 /// @retval decoded value 00119 //====================================================================== 00120 u32 alp_decode_length(u8** p, u8* actp) 00121 { 00122 u32 tmp = 0; 00123 switch ((**p) & 0xC0) 00124 { 00125 case 0xC0: // 0xCx xx xx xx 00126 tmp = ((*(*p)++) & 0x3F) << 24; 00127 tmp += (*(*p)++) << 16; 00128 tmp += (*(*p)++) << 8; 00129 tmp += (*(*p)++) << 0; 00130 break; 00131 case 0x80: // 0x8x xx xx : 16384 <= Len <4194303 00132 tmp = ((*(*p)++) & 0x3F) << 16; 00133 tmp += (*(*p)++) << 8; 00134 if (tmp == 0) 00135 { 00136 // 0x8000 ActP special ActP code 00137 // Do not fetch the extra byte 00138 *actp = 2; 00139 } 00140 else 00141 { 00142 tmp += (*(*p)++) << 0; 00143 } 00144 break; 00145 case 0x40: // 0x4x xx : 64 <= Len < 16383 00146 tmp = ((*(*p)++) & 0x3F) << 8; 00147 tmp += (*(*p)++) << 0; 00148 if (tmp == 0) 00149 { 00150 // 0x4000 ActP special ActP code 00151 *actp = 1; 00152 } 00153 break; 00154 case 0: // Len <63 00155 tmp = (*(*p)++ & 0x3F) << 0; 00156 break; 00157 } 00158 return tmp; 00159 } 00160 00161 //====================================================================== 00162 // alp_itf_size 00163 //---------------------------------------------------------------------- 00164 /// @brief Get size of the interface configuration 00165 /// @param itf pointer to the configuration 00166 /// @return int configuration size 00167 //====================================================================== 00168 int alp_itf_size(void* itf) 00169 { 00170 alp_itf_cfg_t* p = (alp_itf_cfg_t*)itf; 00171 00172 switch (p->type) 00173 { 00174 case ALP_ITF_TYPE_D7A: 00175 { 00176 alp_itf_d7a_cfg_t* d7a_itf = (alp_itf_d7a_cfg_t*)itf; 00177 return (1 + alp_itf_d7a_cfg_size((u8*)&d7a_itf->cfg)); 00178 } 00179 case ALP_ITF_TYPE_COM: 00180 return sizeof(alp_itf_com_cfg_t); 00181 case ALP_ITF_TYPE_LWAN: 00182 return sizeof(alp_itf_lwan_cfg_t); 00183 default: 00184 ALP_ASSERT(FALSE, "ASSERT: ALP: Unknown ITF 0x%02X for itf size\n", p->type); 00185 break; 00186 } 00187 00188 return 0; 00189 } 00190 00191 //====================================================================== 00192 // alp_parse_chunk 00193 //---------------------------------------------------------------------- 00194 /// @brief Parses an ALP payload and extract a single chunk (action or 00195 /// response) to a more generic alp_parsed_chunk_t structure. 00196 /// @param payload : pointer to the pointer to payload buffer 00197 /// @param resp : pointer to alp_parsed_chunk_t structure 00198 /// @retval number of parsed bytes 00199 //====================================================================== 00200 int alp_parse_chunk(u8** payload, alp_parsed_chunk_t* resp) // {{{ 00201 { 00202 u8* p = *payload; 00203 u8 op = *p++; 00204 u8 actp; 00205 u32 bytes; 00206 resp->type = op & 0x3F; 00207 resp->data = (u8*)NULL; 00208 switch(resp->type) // XXX preemption bits squashed 00209 { 00210 case ALP_OPCODE_RSP_TAG: 00211 case ALP_OPCODE_TAG: 00212 resp->meta.tag.id = *p++; // PID 00213 resp->meta.tag.eop = !!(op & ALP_OPCODE_EOP); 00214 resp->meta.tag.err = !!(op & ALP_OPCODE_ERR); 00215 break; 00216 case ALP_OPCODE_RSP_F_DATA: 00217 case ALP_OPCODE_F_WR_DATA: 00218 resp->meta.f_data.fid = *p++; // FID 00219 resp->meta.f_data.offset = alp_decode_length(&p, &actp); // Offset 00220 resp->meta.f_data.length = alp_decode_length(&p, &actp); // Length 00221 resp->data = p; 00222 p += resp->meta.f_data.length; 00223 break; 00224 case ALP_OPCODE_F_RD_DATA: 00225 resp->meta.f_data.fid = *p++; // FID 00226 resp->meta.f_data.offset = alp_decode_length(&p, &actp); // Offset 00227 resp->meta.f_data.length = alp_decode_length(&p, &actp); // Length 00228 break; 00229 case ALP_OPCODE_F_RD_PROP: 00230 resp->meta.f_prop.fid = *p++; // FID 00231 resp->meta.f_prop.offset = 0; 00232 resp->meta.f_prop.length = ALP_FILE_HEADER_SIZE; // Hardcoded Length 00233 break; 00234 case ALP_OPCODE_RSP_F_PROP: 00235 resp->meta.f_prop.fid = *p++; // FID 00236 resp->meta.f_prop.offset = 0; 00237 resp->meta.f_prop.length = ALP_FILE_HEADER_SIZE; // Hardcoded Length 00238 resp->data = p; 00239 p += resp->meta.f_prop.length; 00240 break; 00241 case ALP_OPCODE_RSP_STATUS: 00242 if (ALP_OPCODE_RSP_ISTATUS == op) 00243 { 00244 resp->type = ALP_OPCODE_RSP_ISTATUS; 00245 resp->meta.itf.type = *p++; // ITF Type 00246 resp->meta.itf.length = alp_decode_length(&p, &actp); // Length 00247 resp->data = p; 00248 p += resp->meta.itf.length; 00249 } 00250 else if (ALP_OPCODE_RSP_EOPISTATUS == op) 00251 { 00252 resp->type = ALP_OPCODE_RSP_EOPISTATUS; 00253 resp->meta.istatus.itf = *p++; // ITF Type 00254 p++; // Length (always 1) 00255 resp->meta.istatus.err = *p++; // Interface error 00256 } 00257 else 00258 { 00259 resp->meta.status.id = *p++; // Action ID 00260 resp->meta.status.code = *p++; // status 00261 } 00262 break; 00263 case ALP_OPCODE_RSP_URC: 00264 resp->meta.urc.type = *p++; // Type 00265 resp->meta.urc.ifid = *p++; // Ifid 00266 if (resp->meta.urc.type == ALP_URC_TYPE_LQUAL) 00267 { 00268 resp->meta.urc.per = *p++; // Per 00269 } 00270 else if (resp->meta.urc.type == ALP_URC_TYPE_ITF_BUSY) 00271 { 00272 kal_ctf_t to; 00273 to.byte = *p++; // timeout 00274 resp->meta.urc.per = (to.byte == 0xff) ? MAX_U32 : kal_ctf_decode(to); 00275 } 00276 break; 00277 case ALP_OPCODE_F_DELETE: 00278 case ALP_OPCODE_F_FLUSH: 00279 resp->meta.f_data.fid = *p++; // FID 00280 break; 00281 case ALP_OPCODE_RSP_SECURED: 00282 resp->type = ALP_OPCODE_RSP_SECURED; 00283 *payload = (u8*)NULL; 00284 return 0; // XXX payload length unknown 00285 default: 00286 resp->type = ALP_OPCODE_UNKNOWN; 00287 *payload = (u8*)NULL; 00288 return 0; 00289 } 00290 bytes = p - *payload; 00291 *payload = p; 00292 return bytes; 00293 } // }}}
Generated on Tue Jul 12 2022 13:52:23 by
1.7.2