Exportable version of WizziLab's modem driver.

Dependents:   modem_ref_helper

Committer:
Jeej
Date:
Thu Oct 04 09:58:18 2018 +0000
Revision:
38:73ad040ae741
Parent:
37:f5424d109c6d
Child:
41:6f83174ffed4
Revert uncommented line.

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 0:027760f45e2c 14 // @brief ALP public 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 0:027760f45e2c 20
Jeej 0:027760f45e2c 21 //======================================================================
Jeej 0:027760f45e2c 22 // alp_size
Jeej 0:027760f45e2c 23 //----------------------------------------------------------------------
Jeej 0:027760f45e2c 24 /// @brief Return payload length of most ALP operations
Jeej 0:027760f45e2c 25 /// @param op : ALP Action amongst alp_opcodes_t
Jeej 0:027760f45e2c 26 /// @param offset : Associated Offset if relevant
Jeej 0:027760f45e2c 27 /// @param size : Associated Size if relevant
Jeej 0:027760f45e2c 28 /// @retval payload size in bytes
Jeej 0:027760f45e2c 29 //======================================================================
Jeej 0:027760f45e2c 30 public uint alp_size(u8 op, u32 offset, u32 length)
Jeej 0:027760f45e2c 31 {
Jeej 0:027760f45e2c 32 uint len=2;// At least OP+FID / OP+TAG
Jeej 0:027760f45e2c 33 switch (op)
Jeej 0:027760f45e2c 34 {
Jeej 0:027760f45e2c 35 case ALP_OPCODE_NOP:
Jeej 0:027760f45e2c 36 case ALP_OPCODE_F_TOUCH:
Jeej 0:027760f45e2c 37 case ALP_OPCODE_F_EXIST:
Jeej 0:027760f45e2c 38 case ALP_OPCODE_F_DELETE:
Jeej 0:027760f45e2c 39 case ALP_OPCODE_F_FLUSH:
Jeej 0:027760f45e2c 40 case ALP_OPCODE_RSP_TAG:
Jeej 0:027760f45e2c 41 case ALP_OPCODE_F_RD_PROP:
Jeej 0:027760f45e2c 42 break;
Jeej 0:027760f45e2c 43 case ALP_OPCODE_RSP_STATUS:
Jeej 0:027760f45e2c 44 len += 1;
Jeej 0:027760f45e2c 45 break;
Jeej 0:027760f45e2c 46 case ALP_OPCODE_F_CREATE:
Jeej 0:027760f45e2c 47 case ALP_OPCODE_F_DECLARE:
Jeej 0:027760f45e2c 48 case ALP_OPCODE_RSP_F_PROP:
Jeej 0:027760f45e2c 49 len += ALP_FILE_HEADER_SIZE;
Jeej 0:027760f45e2c 50 break;
Jeej 0:027760f45e2c 51 case ALP_OPCODE_F_WR_PROP:
Jeej 0:027760f45e2c 52 case ALP_OPCODE_F_WR_DATA:
Jeej 0:027760f45e2c 53 case ALP_OPCODE_RSP_F_DATA:
Jeej 0:027760f45e2c 54 len = length;
Jeej 35:ac940cf8ebe6 55 // Fallthrough
Jeej 0:027760f45e2c 56 case ALP_OPCODE_F_RD_DATA:
Jeej 0:027760f45e2c 57 len += ALP_LFIELD_SIZE(offset) + ALP_LFIELD_SIZE(length);
Jeej 0:027760f45e2c 58 break;
Jeej 0:027760f45e2c 59 default:
Jeej 38:73ad040ae741 60 //ALP_ASSERT(false,"ASSERT: ALP: alp_size unsupported op %d\n",op);
Jeej 0:027760f45e2c 61 break;
Jeej 0:027760f45e2c 62 }
Jeej 0:027760f45e2c 63 return len;
Jeej 0:027760f45e2c 64 }
Jeej 0:027760f45e2c 65
Jeej 0:027760f45e2c 66 //======================================================================
Jeej 0:027760f45e2c 67 // alp_encode_length
Jeej 0:027760f45e2c 68 //----------------------------------------------------------------------
Jeej 0:027760f45e2c 69 /// @brief Encodes an ALP length/offset field
Jeej 0:027760f45e2c 70 /// @param p : pointer to the payload buffer
Jeej 0:027760f45e2c 71 /// @param len : value to be encoded
Jeej 0:027760f45e2c 72 /// @retval resulting payload size in bytes
Jeej 0:027760f45e2c 73 //======================================================================
Jeej 0:027760f45e2c 74 public u8 alp_encode_length(u8* p, u32 len)
Jeej 0:027760f45e2c 75 {
Jeej 0:027760f45e2c 76 if (len <= 0x3F)
Jeej 0:027760f45e2c 77 {
Jeej 0:027760f45e2c 78 *p++ = len;
Jeej 0:027760f45e2c 79 return 1;
Jeej 0:027760f45e2c 80 }
Jeej 0:027760f45e2c 81 else if (len <= 0x3FFF)
Jeej 0:027760f45e2c 82 {
Jeej 0:027760f45e2c 83 *p++ = 0x40 + (u8)(len >> 8);
Jeej 0:027760f45e2c 84 *p++ = (u8)(len & 0xFF);
Jeej 0:027760f45e2c 85 return 2;
Jeej 0:027760f45e2c 86 }
Jeej 0:027760f45e2c 87 else if (len <= 0x3FFFFF)
Jeej 0:027760f45e2c 88 {
Jeej 0:027760f45e2c 89 *p++ = 0x80 + (u8) (len >> 16);
Jeej 0:027760f45e2c 90 *p++ = (u8)((len >> 8) & 0xFF);
Jeej 0:027760f45e2c 91 *p++ = (u8) (len & 0xFF);
Jeej 0:027760f45e2c 92 return 3;
Jeej 0:027760f45e2c 93 }
Jeej 0:027760f45e2c 94 else
Jeej 0:027760f45e2c 95 {
Jeej 0:027760f45e2c 96 *p++ = 0xC0 + (u8) (len >> 24);
Jeej 0:027760f45e2c 97 *p++ = (u8)((len >> 16) & 0xFF);
Jeej 0:027760f45e2c 98 *p++ = (u8)((len >> 8) & 0xFF);
Jeej 0:027760f45e2c 99 *p++ = (u8) (len & 0xFF);
Jeej 0:027760f45e2c 100 return 4;
Jeej 0:027760f45e2c 101 }
Jeej 0:027760f45e2c 102 }
Jeej 0:027760f45e2c 103
Jeej 0:027760f45e2c 104
Jeej 0:027760f45e2c 105 //======================================================================
Jeej 0:027760f45e2c 106 // alp_decode_length
Jeej 0:027760f45e2c 107 //----------------------------------------------------------------------
Jeej 0:027760f45e2c 108 /// @brief Decodes an ALP length/offset field
Jeej 0:027760f45e2c 109 /// @param p : pointer to the pointer to payload buffer
Jeej 0:027760f45e2c 110 /// @param actp : pointer to ALP's Action Protocol Substitution flag
Jeej 0:027760f45e2c 111 /// Result amongst alp_actp_substitution_mode_t
Jeej 0:027760f45e2c 112 /// @retval decoded value
Jeej 0:027760f45e2c 113 //======================================================================
Jeej 0:027760f45e2c 114 public u32 alp_decode_length(u8** p, u8* actp)
Jeej 0:027760f45e2c 115 {
Jeej 0:027760f45e2c 116 u32 tmp = 0;
Jeej 0:027760f45e2c 117 switch ((**p) & 0xC0)
Jeej 0:027760f45e2c 118 {
Jeej 0:027760f45e2c 119 case 0xC0: // 0xCx xx xx xx
Jeej 0:027760f45e2c 120 tmp = ((*(*p)++) & 0x3F) << 24;
Jeej 0:027760f45e2c 121 tmp += (*(*p)++) << 16;
Jeej 0:027760f45e2c 122 tmp += (*(*p)++) << 8;
Jeej 0:027760f45e2c 123 tmp += (*(*p)++) << 0;
Jeej 0:027760f45e2c 124 break;
Jeej 0:027760f45e2c 125 case 0x80: // 0x8x xx xx : 16384 <= Len <4194303
Jeej 0:027760f45e2c 126 tmp = ((*(*p)++) & 0x3F) << 16;
Jeej 0:027760f45e2c 127 tmp += (*(*p)++) << 8;
Jeej 0:027760f45e2c 128 if (tmp == 0)
Jeej 0:027760f45e2c 129 {
Jeej 0:027760f45e2c 130 // 0x8000 ActP special ActP code
Jeej 0:027760f45e2c 131 // Do not fetch the extra byte
Jeej 0:027760f45e2c 132 *actp = 2;
Jeej 0:027760f45e2c 133 }
Jeej 0:027760f45e2c 134 else
Jeej 0:027760f45e2c 135 {
Jeej 0:027760f45e2c 136 tmp += (*(*p)++) << 0;
Jeej 0:027760f45e2c 137 }
Jeej 0:027760f45e2c 138 break;
Jeej 0:027760f45e2c 139 case 0x40: // 0x4x xx : 64 <= Len < 16383
Jeej 0:027760f45e2c 140 tmp = ((*(*p)++) & 0x3F) << 8;
Jeej 0:027760f45e2c 141 tmp += (*(*p)++) << 0;
Jeej 0:027760f45e2c 142 if (tmp == 0)
Jeej 0:027760f45e2c 143 {
Jeej 0:027760f45e2c 144 // 0x4000 ActP special ActP code
Jeej 0:027760f45e2c 145 *actp = 1;
Jeej 0:027760f45e2c 146 }
Jeej 0:027760f45e2c 147 break;
Jeej 0:027760f45e2c 148 case 0: // Len <63
Jeej 0:027760f45e2c 149 tmp = (*(*p)++ & 0x3F) << 0;
Jeej 0:027760f45e2c 150 break;
Jeej 0:027760f45e2c 151 }
Jeej 0:027760f45e2c 152 return tmp;
Jeej 0:027760f45e2c 153 }
Jeej 0:027760f45e2c 154
Jeej 0:027760f45e2c 155
Jeej 0:027760f45e2c 156 //======================================================================
Jeej 0:027760f45e2c 157 // alp_parse_chunk
Jeej 0:027760f45e2c 158 //----------------------------------------------------------------------
Jeej 0:027760f45e2c 159 /// @brief Parses an ALP payload and extract a single chunk (action or
Jeej 0:027760f45e2c 160 /// response) to a more generic alp_parsed_chunk_t structure.
Jeej 0:027760f45e2c 161 /// @param payload : pointer to the pointer to payload buffer
Jeej 0:027760f45e2c 162 /// @param resp : pointer to alp_parsed_chunk_t structure
Jeej 0:027760f45e2c 163 /// @retval number of parsed bytes
Jeej 0:027760f45e2c 164 //======================================================================
Jeej 0:027760f45e2c 165 public int alp_parse_chunk(u8** payload, alp_parsed_chunk_t* resp) // {{{
Jeej 0:027760f45e2c 166 {
Jeej 0:027760f45e2c 167 u8* p = *payload;
Jeej 0:027760f45e2c 168 u8 op = *p++;
Jeej 0:027760f45e2c 169 u8 actp;
Jeej 0:027760f45e2c 170 u32 bytes;
Jeej 0:027760f45e2c 171 resp->type = op & 0x3F;
Jeej 0:027760f45e2c 172 resp->data = (u8*)NULL;
Jeej 0:027760f45e2c 173 switch(resp->type) // XXX preemption bits squashed
Jeej 0:027760f45e2c 174 {
Jeej 0:027760f45e2c 175 case ALP_OPCODE_RSP_TAG:
Jeej 0:027760f45e2c 176 case ALP_OPCODE_TAG:
Jeej 0:027760f45e2c 177 resp->meta.tag.id = *p++; // PID
Jeej 0:027760f45e2c 178 resp->meta.tag.eop = !!(op & ALP_OPCODE_EOP);
Jeej 0:027760f45e2c 179 resp->meta.tag.err = !!(op & ALP_OPCODE_ERR);
Jeej 0:027760f45e2c 180 break;
Jeej 0:027760f45e2c 181 case ALP_OPCODE_RSP_F_DATA:
Jeej 0:027760f45e2c 182 case ALP_OPCODE_F_WR_DATA:
Jeej 0:027760f45e2c 183 resp->meta.f_data.fid = *p++; // FID
Jeej 0:027760f45e2c 184 resp->meta.f_data.offset = alp_decode_length(&p,&actp); // Offset
Jeej 0:027760f45e2c 185 resp->meta.f_data.length = alp_decode_length(&p,&actp); // Length
Jeej 0:027760f45e2c 186 resp->data = p;
Jeej 0:027760f45e2c 187 p += resp->meta.f_data.length;
Jeej 0:027760f45e2c 188 break;
Jeej 0:027760f45e2c 189 case ALP_OPCODE_F_RD_DATA:
Jeej 0:027760f45e2c 190 resp->meta.f_data.fid = *p++; // FID
Jeej 0:027760f45e2c 191 resp->meta.f_data.offset = alp_decode_length(&p,&actp); // Offset
Jeej 0:027760f45e2c 192 resp->meta.f_data.length = alp_decode_length(&p,&actp); // Length
Jeej 0:027760f45e2c 193 break;
Jeej 0:027760f45e2c 194 case ALP_OPCODE_F_RD_PROP:
Jeej 0:027760f45e2c 195 resp->meta.f_prop.fid = *p++; // FID
Jeej 0:027760f45e2c 196 resp->meta.f_prop.offset = 0;
Jeej 0:027760f45e2c 197 resp->meta.f_prop.length = ALP_FILE_HEADER_SIZE; // Hardcoded Length
Jeej 0:027760f45e2c 198 break;
Jeej 0:027760f45e2c 199 case ALP_OPCODE_RSP_F_PROP:
Jeej 0:027760f45e2c 200 resp->meta.f_prop.fid = *p++; // FID
Jeej 0:027760f45e2c 201 resp->meta.f_prop.offset = 0;
Jeej 0:027760f45e2c 202 resp->meta.f_prop.length = ALP_FILE_HEADER_SIZE; // Hardcoded Length
Jeej 0:027760f45e2c 203 resp->data = p;
Jeej 0:027760f45e2c 204 p += resp->meta.f_prop.length;
Jeej 0:027760f45e2c 205 break;
Jeej 0:027760f45e2c 206 case ALP_OPCODE_RSP_STATUS:
Jeej 0:027760f45e2c 207 if (op == ALP_OPCODE_RSP_ISTATUS)
Jeej 0:027760f45e2c 208 {
Jeej 0:027760f45e2c 209 resp->type = ALP_OPCODE_RSP_ISTATUS;
Jeej 0:027760f45e2c 210 resp->meta.itf.type = *p++; // ITF Type
Jeej 0:027760f45e2c 211 resp->meta.itf.length = alp_decode_length(&p,&actp); // Length
Jeej 0:027760f45e2c 212 resp->data = p;
Jeej 0:027760f45e2c 213 p += resp->meta.itf.length;
Jeej 0:027760f45e2c 214 }
Jeej 37:f5424d109c6d 215 else if (op == ALP_OPCODE_RSP_EOPISTATUS)
Jeej 37:f5424d109c6d 216 {
Jeej 37:f5424d109c6d 217 resp->type = ALP_OPCODE_RSP_EOPISTATUS;
Jeej 37:f5424d109c6d 218 resp->meta.istatus.itf = *p++; // ITF Type
Jeej 37:f5424d109c6d 219 p++; // Length (always 1)
Jeej 37:f5424d109c6d 220 resp->meta.istatus.err = *p++; // Interface error
Jeej 37:f5424d109c6d 221 }
Jeej 0:027760f45e2c 222 else
Jeej 0:027760f45e2c 223 {
Jeej 0:027760f45e2c 224 resp->meta.status.id = *p++; // Action ID
Jeej 0:027760f45e2c 225 resp->meta.status.code = *p++; // status
Jeej 0:027760f45e2c 226 }
Jeej 0:027760f45e2c 227 break;
Jeej 0:027760f45e2c 228 case ALP_OPCODE_RSP_URC:
Jeej 0:027760f45e2c 229 resp->meta.urc.type = *p++; // Type
Jeej 0:027760f45e2c 230 resp->meta.urc.ifid = *p++; // Ifid
Jeej 0:027760f45e2c 231 if (resp->meta.urc.type == ALP_URC_TYPE_LQUAL)
Jeej 0:027760f45e2c 232 resp->meta.urc.per = *p++; // Per
Jeej 0:027760f45e2c 233 break;
Jeej 0:027760f45e2c 234 case ALP_OPCODE_F_DELETE:
Jeej 0:027760f45e2c 235 case ALP_OPCODE_F_FLUSH:
Jeej 0:027760f45e2c 236 resp->meta.f_data.fid = *p++; // FID
Jeej 0:027760f45e2c 237 break;
Jeej 0:027760f45e2c 238 default:
Jeej 0:027760f45e2c 239 resp->type = ALP_OPCODE_UNKNOWN;
Jeej 0:027760f45e2c 240 *payload = (u8*)NULL;
Jeej 0:027760f45e2c 241 return 0;
Jeej 0:027760f45e2c 242 }
Jeej 0:027760f45e2c 243 bytes = p - *payload;
Jeej 0:027760f45e2c 244 *payload = p;
Jeej 0:027760f45e2c 245 return bytes;
Jeej 0:027760f45e2c 246 } // }}}