Exportable version of WizziLab's modem driver.
src/alp_helpers.cpp@67:e458db8402dc, 2021-10-29 (annotated)
- Committer:
- marin_wizzi
- Date:
- Fri Oct 29 13:54:43 2021 +0000
- Revision:
- 67:e458db8402dc
- Parent:
- 59:3b38b5f499db
had to be commited for Scanner test
Who changed what in which revision?
User | Revision | Line number | New 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 | } // }}} |