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
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 public helpers functions. 00015 // This code should be disclosable in source. 00016 // ==================================================================== 00017 00018 00019 #include "alp.h" 00020 #include "kal_math.h" 00021 00022 //====================================================================== 00023 // alp_size 00024 //---------------------------------------------------------------------- 00025 /// @brief Return payload length of most ALP operations 00026 /// @param op : ALP Action amongst alp_opcodes_t 00027 /// @param offset : Associated Offset if relevant 00028 /// @param size : Associated Size if relevant 00029 /// @retval payload size in bytes 00030 //====================================================================== 00031 public uint alp_size(u8 op, u32 offset, u32 length) 00032 { 00033 uint len=2;// At least OP+FID / OP+TAG 00034 switch (op) 00035 { 00036 case ALP_OPCODE_NOP: 00037 case ALP_OPCODE_F_TOUCH: 00038 case ALP_OPCODE_F_EXIST: 00039 case ALP_OPCODE_F_DELETE: 00040 case ALP_OPCODE_F_FLUSH: 00041 case ALP_OPCODE_RSP_TAG: 00042 case ALP_OPCODE_F_RD_PROP: 00043 break; 00044 case ALP_OPCODE_RSP_STATUS: 00045 len += 1; 00046 break; 00047 case ALP_OPCODE_F_CREATE: 00048 case ALP_OPCODE_F_DECLARE: 00049 case ALP_OPCODE_RSP_F_PROP: 00050 len += ALP_FILE_HEADER_SIZE; 00051 break; 00052 case ALP_OPCODE_F_WR_PROP: 00053 case ALP_OPCODE_F_WR_DATA: 00054 case ALP_OPCODE_RSP_F_DATA: 00055 len = length; 00056 // Fallthrough 00057 case ALP_OPCODE_F_RD_DATA: 00058 len += ALP_LFIELD_SIZE(offset) + ALP_LFIELD_SIZE(length); 00059 break; 00060 default: 00061 //ALP_ASSERT(false,"ASSERT: ALP: alp_size unsupported op %d\n",op); 00062 break; 00063 } 00064 return len; 00065 } 00066 00067 //====================================================================== 00068 // alp_encode_length 00069 //---------------------------------------------------------------------- 00070 /// @brief Encodes an ALP length/offset field 00071 /// @param p : pointer to the payload buffer 00072 /// @param len : value to be encoded 00073 /// @retval resulting payload size in bytes 00074 //====================================================================== 00075 public u8 alp_encode_length(u8* p, u32 len) 00076 { 00077 if (len <= 0x3F) 00078 { 00079 *p++ = len; 00080 return 1; 00081 } 00082 else if (len <= 0x3FFF) 00083 { 00084 *p++ = 0x40 + (u8)(len >> 8); 00085 *p++ = (u8)(len & 0xFF); 00086 return 2; 00087 } 00088 else if (len <= 0x3FFFFF) 00089 { 00090 *p++ = 0x80 + (u8) (len >> 16); 00091 *p++ = (u8)((len >> 8) & 0xFF); 00092 *p++ = (u8) (len & 0xFF); 00093 return 3; 00094 } 00095 else 00096 { 00097 *p++ = 0xC0 + (u8) (len >> 24); 00098 *p++ = (u8)((len >> 16) & 0xFF); 00099 *p++ = (u8)((len >> 8) & 0xFF); 00100 *p++ = (u8) (len & 0xFF); 00101 return 4; 00102 } 00103 } 00104 00105 00106 //====================================================================== 00107 // alp_decode_length 00108 //---------------------------------------------------------------------- 00109 /// @brief Decodes an ALP length/offset field 00110 /// @param p : pointer to the pointer to payload buffer 00111 /// @param actp : pointer to ALP's Action Protocol Substitution flag 00112 /// Result amongst alp_actp_substitution_mode_t 00113 /// @retval decoded value 00114 //====================================================================== 00115 public u32 alp_decode_length(u8** p, u8* actp) 00116 { 00117 u32 tmp = 0; 00118 switch ((**p) & 0xC0) 00119 { 00120 case 0xC0: // 0xCx xx xx xx 00121 tmp = ((*(*p)++) & 0x3F) << 24; 00122 tmp += (*(*p)++) << 16; 00123 tmp += (*(*p)++) << 8; 00124 tmp += (*(*p)++) << 0; 00125 break; 00126 case 0x80: // 0x8x xx xx : 16384 <= Len <4194303 00127 tmp = ((*(*p)++) & 0x3F) << 16; 00128 tmp += (*(*p)++) << 8; 00129 if (tmp == 0) 00130 { 00131 // 0x8000 ActP special ActP code 00132 // Do not fetch the extra byte 00133 *actp = 2; 00134 } 00135 else 00136 { 00137 tmp += (*(*p)++) << 0; 00138 } 00139 break; 00140 case 0x40: // 0x4x xx : 64 <= Len < 16383 00141 tmp = ((*(*p)++) & 0x3F) << 8; 00142 tmp += (*(*p)++) << 0; 00143 if (tmp == 0) 00144 { 00145 // 0x4000 ActP special ActP code 00146 *actp = 1; 00147 } 00148 break; 00149 case 0: // Len <63 00150 tmp = (*(*p)++ & 0x3F) << 0; 00151 break; 00152 } 00153 return tmp; 00154 } 00155 00156 00157 //====================================================================== 00158 // alp_parse_chunk 00159 //---------------------------------------------------------------------- 00160 /// @brief Parses an ALP payload and extract a single chunk (action or 00161 /// response) to a more generic alp_parsed_chunk_t structure. 00162 /// @param payload : pointer to the pointer to payload buffer 00163 /// @param resp : pointer to alp_parsed_chunk_t structure 00164 /// @retval number of parsed bytes 00165 //====================================================================== 00166 public int alp_parse_chunk(u8** payload, alp_parsed_chunk_t* resp) // {{{ 00167 { 00168 u8* p = *payload; 00169 u8 op = *p++; 00170 u8 actp; 00171 u32 bytes; 00172 resp->type = op & 0x3F; 00173 resp->data = (u8*)NULL; 00174 switch(resp->type) // XXX preemption bits squashed 00175 { 00176 case ALP_OPCODE_RSP_TAG: 00177 case ALP_OPCODE_TAG: 00178 resp->meta.tag.id = *p++; // PID 00179 resp->meta.tag.eop = !!(op & ALP_OPCODE_EOP); 00180 resp->meta.tag.err = !!(op & ALP_OPCODE_ERR); 00181 break; 00182 case ALP_OPCODE_RSP_F_DATA: 00183 case ALP_OPCODE_F_WR_DATA: 00184 resp->meta.f_data.fid = *p++; // FID 00185 resp->meta.f_data.offset = alp_decode_length(&p,&actp); // Offset 00186 resp->meta.f_data.length = alp_decode_length(&p,&actp); // Length 00187 resp->data = p; 00188 p += resp->meta.f_data.length; 00189 break; 00190 case ALP_OPCODE_F_RD_DATA: 00191 resp->meta.f_data.fid = *p++; // FID 00192 resp->meta.f_data.offset = alp_decode_length(&p,&actp); // Offset 00193 resp->meta.f_data.length = alp_decode_length(&p,&actp); // Length 00194 break; 00195 case ALP_OPCODE_F_RD_PROP: 00196 resp->meta.f_prop.fid = *p++; // FID 00197 resp->meta.f_prop.offset = 0; 00198 resp->meta.f_prop.length = ALP_FILE_HEADER_SIZE; // Hardcoded Length 00199 break; 00200 case ALP_OPCODE_RSP_F_PROP: 00201 resp->meta.f_prop.fid = *p++; // FID 00202 resp->meta.f_prop.offset = 0; 00203 resp->meta.f_prop.length = ALP_FILE_HEADER_SIZE; // Hardcoded Length 00204 resp->data = p; 00205 p += resp->meta.f_prop.length; 00206 break; 00207 case ALP_OPCODE_RSP_STATUS: 00208 if (op == ALP_OPCODE_RSP_ISTATUS) 00209 { 00210 resp->type = ALP_OPCODE_RSP_ISTATUS; 00211 resp->meta.itf.type = *p++; // ITF Type 00212 resp->meta.itf.length = alp_decode_length(&p,&actp); // Length 00213 resp->data = p; 00214 p += resp->meta.itf.length; 00215 } 00216 else if (op == ALP_OPCODE_RSP_EOPISTATUS) 00217 { 00218 resp->type = ALP_OPCODE_RSP_EOPISTATUS; 00219 resp->meta.istatus.itf = *p++; // ITF Type 00220 p++; // Length (always 1) 00221 resp->meta.istatus.err = *p++; // Interface error 00222 } 00223 else 00224 { 00225 resp->meta.status.id = *p++; // Action ID 00226 resp->meta.status.code = *p++; // status 00227 } 00228 break; 00229 case ALP_OPCODE_RSP_URC: 00230 resp->meta.urc.type = *p++; // Type 00231 resp->meta.urc.ifid = *p++; // Ifid 00232 if (resp->meta.urc.type == ALP_URC_TYPE_LQUAL) 00233 { 00234 resp->meta.urc.per = *p++; // Per 00235 } 00236 else if (resp->meta.urc.type == ALP_URC_TYPE_ITF_BUSY) 00237 { 00238 kal_ctf_t to; 00239 to.byte = *p++; // timeout 00240 resp->meta.urc.per = (to.byte == 0xff) ? MAX_U32 : kal_ctf_decode(to); 00241 } 00242 break; 00243 case ALP_OPCODE_F_DELETE: 00244 case ALP_OPCODE_F_FLUSH: 00245 resp->meta.f_data.fid = *p++; // FID 00246 break; 00247 default: 00248 resp->type = ALP_OPCODE_UNKNOWN; 00249 *payload = (u8*)NULL; 00250 return 0; 00251 } 00252 bytes = p - *payload; 00253 *payload = p; 00254 return bytes; 00255 } // }}}
Generated on Wed Jul 20 2022 12:33:07 by
