Integrating the ublox LISA C200 modem

Fork of SprintUSBModemHTTPClientTest by Donatien Garnier

Committer:
sam_grove
Date:
Thu Sep 26 00:44:20 2013 -0500
Revision:
5:3f93dd1d4cb3
Exported program and replaced contents of the repo with the source
to build and debug using keil mdk. Libs NOT upto date are lwip, lwip-sys
and socket. these have newer versions under mbed_official but were starting
from a know working point

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 5:3f93dd1d4cb3 1 /**
sam_grove 5:3f93dd1d4cb3 2 * @file
sam_grove 5:3f93dd1d4cb3 3 * Abstract Syntax Notation One (ISO 8824, 8825) decoding
sam_grove 5:3f93dd1d4cb3 4 *
sam_grove 5:3f93dd1d4cb3 5 * @todo not optimised (yet), favor correctness over speed, favor speed over size
sam_grove 5:3f93dd1d4cb3 6 */
sam_grove 5:3f93dd1d4cb3 7
sam_grove 5:3f93dd1d4cb3 8 /*
sam_grove 5:3f93dd1d4cb3 9 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
sam_grove 5:3f93dd1d4cb3 10 * All rights reserved.
sam_grove 5:3f93dd1d4cb3 11 *
sam_grove 5:3f93dd1d4cb3 12 * Redistribution and use in source and binary forms, with or without modification,
sam_grove 5:3f93dd1d4cb3 13 * are permitted provided that the following conditions are met:
sam_grove 5:3f93dd1d4cb3 14 *
sam_grove 5:3f93dd1d4cb3 15 * 1. Redistributions of source code must retain the above copyright notice,
sam_grove 5:3f93dd1d4cb3 16 * this list of conditions and the following disclaimer.
sam_grove 5:3f93dd1d4cb3 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
sam_grove 5:3f93dd1d4cb3 18 * this list of conditions and the following disclaimer in the documentation
sam_grove 5:3f93dd1d4cb3 19 * and/or other materials provided with the distribution.
sam_grove 5:3f93dd1d4cb3 20 * 3. The name of the author may not be used to endorse or promote products
sam_grove 5:3f93dd1d4cb3 21 * derived from this software without specific prior written permission.
sam_grove 5:3f93dd1d4cb3 22 *
sam_grove 5:3f93dd1d4cb3 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
sam_grove 5:3f93dd1d4cb3 24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
sam_grove 5:3f93dd1d4cb3 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
sam_grove 5:3f93dd1d4cb3 26 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
sam_grove 5:3f93dd1d4cb3 27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
sam_grove 5:3f93dd1d4cb3 28 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
sam_grove 5:3f93dd1d4cb3 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
sam_grove 5:3f93dd1d4cb3 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
sam_grove 5:3f93dd1d4cb3 31 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
sam_grove 5:3f93dd1d4cb3 32 * OF SUCH DAMAGE.
sam_grove 5:3f93dd1d4cb3 33 *
sam_grove 5:3f93dd1d4cb3 34 * Author: Christiaan Simons <christiaan.simons@axon.tv>
sam_grove 5:3f93dd1d4cb3 35 */
sam_grove 5:3f93dd1d4cb3 36
sam_grove 5:3f93dd1d4cb3 37 #include "lwip/opt.h"
sam_grove 5:3f93dd1d4cb3 38
sam_grove 5:3f93dd1d4cb3 39 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
sam_grove 5:3f93dd1d4cb3 40
sam_grove 5:3f93dd1d4cb3 41 #include "lwip/snmp_asn1.h"
sam_grove 5:3f93dd1d4cb3 42
sam_grove 5:3f93dd1d4cb3 43 /**
sam_grove 5:3f93dd1d4cb3 44 * Retrieves type field from incoming pbuf chain.
sam_grove 5:3f93dd1d4cb3 45 *
sam_grove 5:3f93dd1d4cb3 46 * @param p points to a pbuf holding an ASN1 coded type field
sam_grove 5:3f93dd1d4cb3 47 * @param ofs points to the offset within the pbuf chain of the ASN1 coded type field
sam_grove 5:3f93dd1d4cb3 48 * @param type return ASN1 type
sam_grove 5:3f93dd1d4cb3 49 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
sam_grove 5:3f93dd1d4cb3 50 */
sam_grove 5:3f93dd1d4cb3 51 err_t
sam_grove 5:3f93dd1d4cb3 52 snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type)
sam_grove 5:3f93dd1d4cb3 53 {
sam_grove 5:3f93dd1d4cb3 54 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 55 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 56
sam_grove 5:3f93dd1d4cb3 57 plen = 0;
sam_grove 5:3f93dd1d4cb3 58 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 59 {
sam_grove 5:3f93dd1d4cb3 60 base = plen;
sam_grove 5:3f93dd1d4cb3 61 plen += p->len;
sam_grove 5:3f93dd1d4cb3 62 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 63 {
sam_grove 5:3f93dd1d4cb3 64 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 65 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 66 *type = *msg_ptr;
sam_grove 5:3f93dd1d4cb3 67 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 68 }
sam_grove 5:3f93dd1d4cb3 69 p = p->next;
sam_grove 5:3f93dd1d4cb3 70 }
sam_grove 5:3f93dd1d4cb3 71 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 72 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 73 }
sam_grove 5:3f93dd1d4cb3 74
sam_grove 5:3f93dd1d4cb3 75 /**
sam_grove 5:3f93dd1d4cb3 76 * Decodes length field from incoming pbuf chain into host length.
sam_grove 5:3f93dd1d4cb3 77 *
sam_grove 5:3f93dd1d4cb3 78 * @param p points to a pbuf holding an ASN1 coded length
sam_grove 5:3f93dd1d4cb3 79 * @param ofs points to the offset within the pbuf chain of the ASN1 coded length
sam_grove 5:3f93dd1d4cb3 80 * @param octets_used returns number of octets used by the length code
sam_grove 5:3f93dd1d4cb3 81 * @param length return host order length, upto 64k
sam_grove 5:3f93dd1d4cb3 82 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
sam_grove 5:3f93dd1d4cb3 83 */
sam_grove 5:3f93dd1d4cb3 84 err_t
sam_grove 5:3f93dd1d4cb3 85 snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length)
sam_grove 5:3f93dd1d4cb3 86 {
sam_grove 5:3f93dd1d4cb3 87 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 88 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 89
sam_grove 5:3f93dd1d4cb3 90 plen = 0;
sam_grove 5:3f93dd1d4cb3 91 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 92 {
sam_grove 5:3f93dd1d4cb3 93 base = plen;
sam_grove 5:3f93dd1d4cb3 94 plen += p->len;
sam_grove 5:3f93dd1d4cb3 95 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 96 {
sam_grove 5:3f93dd1d4cb3 97 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 98 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 99
sam_grove 5:3f93dd1d4cb3 100 if (*msg_ptr < 0x80)
sam_grove 5:3f93dd1d4cb3 101 {
sam_grove 5:3f93dd1d4cb3 102 /* primitive definite length format */
sam_grove 5:3f93dd1d4cb3 103 *octets_used = 1;
sam_grove 5:3f93dd1d4cb3 104 *length = *msg_ptr;
sam_grove 5:3f93dd1d4cb3 105 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 106 }
sam_grove 5:3f93dd1d4cb3 107 else if (*msg_ptr == 0x80)
sam_grove 5:3f93dd1d4cb3 108 {
sam_grove 5:3f93dd1d4cb3 109 /* constructed indefinite length format, termination with two zero octets */
sam_grove 5:3f93dd1d4cb3 110 u8_t zeros;
sam_grove 5:3f93dd1d4cb3 111 u8_t i;
sam_grove 5:3f93dd1d4cb3 112
sam_grove 5:3f93dd1d4cb3 113 *length = 0;
sam_grove 5:3f93dd1d4cb3 114 zeros = 0;
sam_grove 5:3f93dd1d4cb3 115 while (zeros != 2)
sam_grove 5:3f93dd1d4cb3 116 {
sam_grove 5:3f93dd1d4cb3 117 i = 2;
sam_grove 5:3f93dd1d4cb3 118 while (i > 0)
sam_grove 5:3f93dd1d4cb3 119 {
sam_grove 5:3f93dd1d4cb3 120 i--;
sam_grove 5:3f93dd1d4cb3 121 (*length) += 1;
sam_grove 5:3f93dd1d4cb3 122 ofs += 1;
sam_grove 5:3f93dd1d4cb3 123 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 124 {
sam_grove 5:3f93dd1d4cb3 125 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 126 p = p->next;
sam_grove 5:3f93dd1d4cb3 127 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 128 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 129 plen += p->len;
sam_grove 5:3f93dd1d4cb3 130 }
sam_grove 5:3f93dd1d4cb3 131 else
sam_grove 5:3f93dd1d4cb3 132 {
sam_grove 5:3f93dd1d4cb3 133 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 134 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 135 }
sam_grove 5:3f93dd1d4cb3 136 if (*msg_ptr == 0)
sam_grove 5:3f93dd1d4cb3 137 {
sam_grove 5:3f93dd1d4cb3 138 zeros++;
sam_grove 5:3f93dd1d4cb3 139 if (zeros == 2)
sam_grove 5:3f93dd1d4cb3 140 {
sam_grove 5:3f93dd1d4cb3 141 /* stop while (i > 0) */
sam_grove 5:3f93dd1d4cb3 142 i = 0;
sam_grove 5:3f93dd1d4cb3 143 }
sam_grove 5:3f93dd1d4cb3 144 }
sam_grove 5:3f93dd1d4cb3 145 else
sam_grove 5:3f93dd1d4cb3 146 {
sam_grove 5:3f93dd1d4cb3 147 zeros = 0;
sam_grove 5:3f93dd1d4cb3 148 }
sam_grove 5:3f93dd1d4cb3 149 }
sam_grove 5:3f93dd1d4cb3 150 }
sam_grove 5:3f93dd1d4cb3 151 *octets_used = 1;
sam_grove 5:3f93dd1d4cb3 152 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 153 }
sam_grove 5:3f93dd1d4cb3 154 else if (*msg_ptr == 0x81)
sam_grove 5:3f93dd1d4cb3 155 {
sam_grove 5:3f93dd1d4cb3 156 /* constructed definite length format, one octet */
sam_grove 5:3f93dd1d4cb3 157 ofs += 1;
sam_grove 5:3f93dd1d4cb3 158 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 159 {
sam_grove 5:3f93dd1d4cb3 160 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 161 p = p->next;
sam_grove 5:3f93dd1d4cb3 162 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 163 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 164 }
sam_grove 5:3f93dd1d4cb3 165 else
sam_grove 5:3f93dd1d4cb3 166 {
sam_grove 5:3f93dd1d4cb3 167 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 168 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 169 }
sam_grove 5:3f93dd1d4cb3 170 *length = *msg_ptr;
sam_grove 5:3f93dd1d4cb3 171 *octets_used = 2;
sam_grove 5:3f93dd1d4cb3 172 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 173 }
sam_grove 5:3f93dd1d4cb3 174 else if (*msg_ptr == 0x82)
sam_grove 5:3f93dd1d4cb3 175 {
sam_grove 5:3f93dd1d4cb3 176 u8_t i;
sam_grove 5:3f93dd1d4cb3 177
sam_grove 5:3f93dd1d4cb3 178 /* constructed definite length format, two octets */
sam_grove 5:3f93dd1d4cb3 179 i = 2;
sam_grove 5:3f93dd1d4cb3 180 while (i > 0)
sam_grove 5:3f93dd1d4cb3 181 {
sam_grove 5:3f93dd1d4cb3 182 i--;
sam_grove 5:3f93dd1d4cb3 183 ofs += 1;
sam_grove 5:3f93dd1d4cb3 184 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 185 {
sam_grove 5:3f93dd1d4cb3 186 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 187 p = p->next;
sam_grove 5:3f93dd1d4cb3 188 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 189 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 190 plen += p->len;
sam_grove 5:3f93dd1d4cb3 191 }
sam_grove 5:3f93dd1d4cb3 192 else
sam_grove 5:3f93dd1d4cb3 193 {
sam_grove 5:3f93dd1d4cb3 194 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 195 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 196 }
sam_grove 5:3f93dd1d4cb3 197 if (i == 0)
sam_grove 5:3f93dd1d4cb3 198 {
sam_grove 5:3f93dd1d4cb3 199 /* least significant length octet */
sam_grove 5:3f93dd1d4cb3 200 *length |= *msg_ptr;
sam_grove 5:3f93dd1d4cb3 201 }
sam_grove 5:3f93dd1d4cb3 202 else
sam_grove 5:3f93dd1d4cb3 203 {
sam_grove 5:3f93dd1d4cb3 204 /* most significant length octet */
sam_grove 5:3f93dd1d4cb3 205 *length = (*msg_ptr) << 8;
sam_grove 5:3f93dd1d4cb3 206 }
sam_grove 5:3f93dd1d4cb3 207 }
sam_grove 5:3f93dd1d4cb3 208 *octets_used = 3;
sam_grove 5:3f93dd1d4cb3 209 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 210 }
sam_grove 5:3f93dd1d4cb3 211 else
sam_grove 5:3f93dd1d4cb3 212 {
sam_grove 5:3f93dd1d4cb3 213 /* constructed definite length format 3..127 octets, this is too big (>64k) */
sam_grove 5:3f93dd1d4cb3 214 /** @todo: do we need to accept inefficient codings with many leading zero's? */
sam_grove 5:3f93dd1d4cb3 215 *octets_used = 1 + ((*msg_ptr) & 0x7f);
sam_grove 5:3f93dd1d4cb3 216 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 217 }
sam_grove 5:3f93dd1d4cb3 218 }
sam_grove 5:3f93dd1d4cb3 219 p = p->next;
sam_grove 5:3f93dd1d4cb3 220 }
sam_grove 5:3f93dd1d4cb3 221
sam_grove 5:3f93dd1d4cb3 222 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 223 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 224 }
sam_grove 5:3f93dd1d4cb3 225
sam_grove 5:3f93dd1d4cb3 226 /**
sam_grove 5:3f93dd1d4cb3 227 * Decodes positive integer (counter, gauge, timeticks) into u32_t.
sam_grove 5:3f93dd1d4cb3 228 *
sam_grove 5:3f93dd1d4cb3 229 * @param p points to a pbuf holding an ASN1 coded integer
sam_grove 5:3f93dd1d4cb3 230 * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer
sam_grove 5:3f93dd1d4cb3 231 * @param len length of the coded integer field
sam_grove 5:3f93dd1d4cb3 232 * @param value return host order integer
sam_grove 5:3f93dd1d4cb3 233 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
sam_grove 5:3f93dd1d4cb3 234 *
sam_grove 5:3f93dd1d4cb3 235 * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
sam_grove 5:3f93dd1d4cb3 236 * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
sam_grove 5:3f93dd1d4cb3 237 * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
sam_grove 5:3f93dd1d4cb3 238 */
sam_grove 5:3f93dd1d4cb3 239 err_t
sam_grove 5:3f93dd1d4cb3 240 snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value)
sam_grove 5:3f93dd1d4cb3 241 {
sam_grove 5:3f93dd1d4cb3 242 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 243 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 244
sam_grove 5:3f93dd1d4cb3 245 plen = 0;
sam_grove 5:3f93dd1d4cb3 246 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 247 {
sam_grove 5:3f93dd1d4cb3 248 base = plen;
sam_grove 5:3f93dd1d4cb3 249 plen += p->len;
sam_grove 5:3f93dd1d4cb3 250 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 251 {
sam_grove 5:3f93dd1d4cb3 252 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 253 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 254 if ((len > 0) && (len < 6))
sam_grove 5:3f93dd1d4cb3 255 {
sam_grove 5:3f93dd1d4cb3 256 /* start from zero */
sam_grove 5:3f93dd1d4cb3 257 *value = 0;
sam_grove 5:3f93dd1d4cb3 258 if (*msg_ptr & 0x80)
sam_grove 5:3f93dd1d4cb3 259 {
sam_grove 5:3f93dd1d4cb3 260 /* negative, expecting zero sign bit! */
sam_grove 5:3f93dd1d4cb3 261 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 262 }
sam_grove 5:3f93dd1d4cb3 263 else
sam_grove 5:3f93dd1d4cb3 264 {
sam_grove 5:3f93dd1d4cb3 265 /* positive */
sam_grove 5:3f93dd1d4cb3 266 if ((len > 1) && (*msg_ptr == 0))
sam_grove 5:3f93dd1d4cb3 267 {
sam_grove 5:3f93dd1d4cb3 268 /* skip leading "sign byte" octet 0x00 */
sam_grove 5:3f93dd1d4cb3 269 len--;
sam_grove 5:3f93dd1d4cb3 270 ofs += 1;
sam_grove 5:3f93dd1d4cb3 271 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 272 {
sam_grove 5:3f93dd1d4cb3 273 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 274 p = p->next;
sam_grove 5:3f93dd1d4cb3 275 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 276 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 277 plen += p->len;
sam_grove 5:3f93dd1d4cb3 278 }
sam_grove 5:3f93dd1d4cb3 279 else
sam_grove 5:3f93dd1d4cb3 280 {
sam_grove 5:3f93dd1d4cb3 281 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 282 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 283 }
sam_grove 5:3f93dd1d4cb3 284 }
sam_grove 5:3f93dd1d4cb3 285 }
sam_grove 5:3f93dd1d4cb3 286 /* OR octets with value */
sam_grove 5:3f93dd1d4cb3 287 while (len > 1)
sam_grove 5:3f93dd1d4cb3 288 {
sam_grove 5:3f93dd1d4cb3 289 len--;
sam_grove 5:3f93dd1d4cb3 290 *value |= *msg_ptr;
sam_grove 5:3f93dd1d4cb3 291 *value <<= 8;
sam_grove 5:3f93dd1d4cb3 292 ofs += 1;
sam_grove 5:3f93dd1d4cb3 293 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 294 {
sam_grove 5:3f93dd1d4cb3 295 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 296 p = p->next;
sam_grove 5:3f93dd1d4cb3 297 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 298 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 299 plen += p->len;
sam_grove 5:3f93dd1d4cb3 300 }
sam_grove 5:3f93dd1d4cb3 301 else
sam_grove 5:3f93dd1d4cb3 302 {
sam_grove 5:3f93dd1d4cb3 303 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 304 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 305 }
sam_grove 5:3f93dd1d4cb3 306 }
sam_grove 5:3f93dd1d4cb3 307 *value |= *msg_ptr;
sam_grove 5:3f93dd1d4cb3 308 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 309 }
sam_grove 5:3f93dd1d4cb3 310 else
sam_grove 5:3f93dd1d4cb3 311 {
sam_grove 5:3f93dd1d4cb3 312 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 313 }
sam_grove 5:3f93dd1d4cb3 314 }
sam_grove 5:3f93dd1d4cb3 315 p = p->next;
sam_grove 5:3f93dd1d4cb3 316 }
sam_grove 5:3f93dd1d4cb3 317 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 318 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 319 }
sam_grove 5:3f93dd1d4cb3 320
sam_grove 5:3f93dd1d4cb3 321 /**
sam_grove 5:3f93dd1d4cb3 322 * Decodes integer into s32_t.
sam_grove 5:3f93dd1d4cb3 323 *
sam_grove 5:3f93dd1d4cb3 324 * @param p points to a pbuf holding an ASN1 coded integer
sam_grove 5:3f93dd1d4cb3 325 * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer
sam_grove 5:3f93dd1d4cb3 326 * @param len length of the coded integer field
sam_grove 5:3f93dd1d4cb3 327 * @param value return host order integer
sam_grove 5:3f93dd1d4cb3 328 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
sam_grove 5:3f93dd1d4cb3 329 *
sam_grove 5:3f93dd1d4cb3 330 * @note ASN coded integers are _always_ signed!
sam_grove 5:3f93dd1d4cb3 331 */
sam_grove 5:3f93dd1d4cb3 332 err_t
sam_grove 5:3f93dd1d4cb3 333 snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value)
sam_grove 5:3f93dd1d4cb3 334 {
sam_grove 5:3f93dd1d4cb3 335 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 336 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 337 #if BYTE_ORDER == LITTLE_ENDIAN
sam_grove 5:3f93dd1d4cb3 338 u8_t *lsb_ptr = (u8_t*)value;
sam_grove 5:3f93dd1d4cb3 339 #endif
sam_grove 5:3f93dd1d4cb3 340 #if BYTE_ORDER == BIG_ENDIAN
sam_grove 5:3f93dd1d4cb3 341 u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1;
sam_grove 5:3f93dd1d4cb3 342 #endif
sam_grove 5:3f93dd1d4cb3 343 u8_t sign;
sam_grove 5:3f93dd1d4cb3 344
sam_grove 5:3f93dd1d4cb3 345 plen = 0;
sam_grove 5:3f93dd1d4cb3 346 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 347 {
sam_grove 5:3f93dd1d4cb3 348 base = plen;
sam_grove 5:3f93dd1d4cb3 349 plen += p->len;
sam_grove 5:3f93dd1d4cb3 350 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 351 {
sam_grove 5:3f93dd1d4cb3 352 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 353 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 354 if ((len > 0) && (len < 5))
sam_grove 5:3f93dd1d4cb3 355 {
sam_grove 5:3f93dd1d4cb3 356 if (*msg_ptr & 0x80)
sam_grove 5:3f93dd1d4cb3 357 {
sam_grove 5:3f93dd1d4cb3 358 /* negative, start from -1 */
sam_grove 5:3f93dd1d4cb3 359 *value = -1;
sam_grove 5:3f93dd1d4cb3 360 sign = 1;
sam_grove 5:3f93dd1d4cb3 361 }
sam_grove 5:3f93dd1d4cb3 362 else
sam_grove 5:3f93dd1d4cb3 363 {
sam_grove 5:3f93dd1d4cb3 364 /* positive, start from 0 */
sam_grove 5:3f93dd1d4cb3 365 *value = 0;
sam_grove 5:3f93dd1d4cb3 366 sign = 0;
sam_grove 5:3f93dd1d4cb3 367 }
sam_grove 5:3f93dd1d4cb3 368 /* OR/AND octets with value */
sam_grove 5:3f93dd1d4cb3 369 while (len > 1)
sam_grove 5:3f93dd1d4cb3 370 {
sam_grove 5:3f93dd1d4cb3 371 len--;
sam_grove 5:3f93dd1d4cb3 372 if (sign)
sam_grove 5:3f93dd1d4cb3 373 {
sam_grove 5:3f93dd1d4cb3 374 *lsb_ptr &= *msg_ptr;
sam_grove 5:3f93dd1d4cb3 375 *value <<= 8;
sam_grove 5:3f93dd1d4cb3 376 *lsb_ptr |= 255;
sam_grove 5:3f93dd1d4cb3 377 }
sam_grove 5:3f93dd1d4cb3 378 else
sam_grove 5:3f93dd1d4cb3 379 {
sam_grove 5:3f93dd1d4cb3 380 *lsb_ptr |= *msg_ptr;
sam_grove 5:3f93dd1d4cb3 381 *value <<= 8;
sam_grove 5:3f93dd1d4cb3 382 }
sam_grove 5:3f93dd1d4cb3 383 ofs += 1;
sam_grove 5:3f93dd1d4cb3 384 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 385 {
sam_grove 5:3f93dd1d4cb3 386 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 387 p = p->next;
sam_grove 5:3f93dd1d4cb3 388 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 389 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 390 plen += p->len;
sam_grove 5:3f93dd1d4cb3 391 }
sam_grove 5:3f93dd1d4cb3 392 else
sam_grove 5:3f93dd1d4cb3 393 {
sam_grove 5:3f93dd1d4cb3 394 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 395 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 396 }
sam_grove 5:3f93dd1d4cb3 397 }
sam_grove 5:3f93dd1d4cb3 398 if (sign)
sam_grove 5:3f93dd1d4cb3 399 {
sam_grove 5:3f93dd1d4cb3 400 *lsb_ptr &= *msg_ptr;
sam_grove 5:3f93dd1d4cb3 401 }
sam_grove 5:3f93dd1d4cb3 402 else
sam_grove 5:3f93dd1d4cb3 403 {
sam_grove 5:3f93dd1d4cb3 404 *lsb_ptr |= *msg_ptr;
sam_grove 5:3f93dd1d4cb3 405 }
sam_grove 5:3f93dd1d4cb3 406 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 407 }
sam_grove 5:3f93dd1d4cb3 408 else
sam_grove 5:3f93dd1d4cb3 409 {
sam_grove 5:3f93dd1d4cb3 410 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 411 }
sam_grove 5:3f93dd1d4cb3 412 }
sam_grove 5:3f93dd1d4cb3 413 p = p->next;
sam_grove 5:3f93dd1d4cb3 414 }
sam_grove 5:3f93dd1d4cb3 415 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 416 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 417 }
sam_grove 5:3f93dd1d4cb3 418
sam_grove 5:3f93dd1d4cb3 419 /**
sam_grove 5:3f93dd1d4cb3 420 * Decodes object identifier from incoming message into array of s32_t.
sam_grove 5:3f93dd1d4cb3 421 *
sam_grove 5:3f93dd1d4cb3 422 * @param p points to a pbuf holding an ASN1 coded object identifier
sam_grove 5:3f93dd1d4cb3 423 * @param ofs points to the offset within the pbuf chain of the ASN1 coded object identifier
sam_grove 5:3f93dd1d4cb3 424 * @param len length of the coded object identifier
sam_grove 5:3f93dd1d4cb3 425 * @param oid return object identifier struct
sam_grove 5:3f93dd1d4cb3 426 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
sam_grove 5:3f93dd1d4cb3 427 */
sam_grove 5:3f93dd1d4cb3 428 err_t
sam_grove 5:3f93dd1d4cb3 429 snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid)
sam_grove 5:3f93dd1d4cb3 430 {
sam_grove 5:3f93dd1d4cb3 431 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 432 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 433 s32_t *oid_ptr;
sam_grove 5:3f93dd1d4cb3 434
sam_grove 5:3f93dd1d4cb3 435 plen = 0;
sam_grove 5:3f93dd1d4cb3 436 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 437 {
sam_grove 5:3f93dd1d4cb3 438 base = plen;
sam_grove 5:3f93dd1d4cb3 439 plen += p->len;
sam_grove 5:3f93dd1d4cb3 440 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 441 {
sam_grove 5:3f93dd1d4cb3 442 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 443 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 444
sam_grove 5:3f93dd1d4cb3 445 oid->len = 0;
sam_grove 5:3f93dd1d4cb3 446 oid_ptr = &oid->id[0];
sam_grove 5:3f93dd1d4cb3 447 if (len > 0)
sam_grove 5:3f93dd1d4cb3 448 {
sam_grove 5:3f93dd1d4cb3 449 /* first compressed octet */
sam_grove 5:3f93dd1d4cb3 450 if (*msg_ptr == 0x2B)
sam_grove 5:3f93dd1d4cb3 451 {
sam_grove 5:3f93dd1d4cb3 452 /* (most) common case 1.3 (iso.org) */
sam_grove 5:3f93dd1d4cb3 453 *oid_ptr = 1;
sam_grove 5:3f93dd1d4cb3 454 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 455 *oid_ptr = 3;
sam_grove 5:3f93dd1d4cb3 456 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 457 }
sam_grove 5:3f93dd1d4cb3 458 else if (*msg_ptr < 40)
sam_grove 5:3f93dd1d4cb3 459 {
sam_grove 5:3f93dd1d4cb3 460 *oid_ptr = 0;
sam_grove 5:3f93dd1d4cb3 461 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 462 *oid_ptr = *msg_ptr;
sam_grove 5:3f93dd1d4cb3 463 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 464 }
sam_grove 5:3f93dd1d4cb3 465 else if (*msg_ptr < 80)
sam_grove 5:3f93dd1d4cb3 466 {
sam_grove 5:3f93dd1d4cb3 467 *oid_ptr = 1;
sam_grove 5:3f93dd1d4cb3 468 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 469 *oid_ptr = (*msg_ptr) - 40;
sam_grove 5:3f93dd1d4cb3 470 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 471 }
sam_grove 5:3f93dd1d4cb3 472 else
sam_grove 5:3f93dd1d4cb3 473 {
sam_grove 5:3f93dd1d4cb3 474 *oid_ptr = 2;
sam_grove 5:3f93dd1d4cb3 475 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 476 *oid_ptr = (*msg_ptr) - 80;
sam_grove 5:3f93dd1d4cb3 477 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 478 }
sam_grove 5:3f93dd1d4cb3 479 oid->len = 2;
sam_grove 5:3f93dd1d4cb3 480 }
sam_grove 5:3f93dd1d4cb3 481 else
sam_grove 5:3f93dd1d4cb3 482 {
sam_grove 5:3f93dd1d4cb3 483 /* accepting zero length identifiers e.g. for
sam_grove 5:3f93dd1d4cb3 484 getnext operation. uncommon but valid */
sam_grove 5:3f93dd1d4cb3 485 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 486 }
sam_grove 5:3f93dd1d4cb3 487 len--;
sam_grove 5:3f93dd1d4cb3 488 if (len > 0)
sam_grove 5:3f93dd1d4cb3 489 {
sam_grove 5:3f93dd1d4cb3 490 ofs += 1;
sam_grove 5:3f93dd1d4cb3 491 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 492 {
sam_grove 5:3f93dd1d4cb3 493 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 494 p = p->next;
sam_grove 5:3f93dd1d4cb3 495 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 496 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 497 plen += p->len;
sam_grove 5:3f93dd1d4cb3 498 }
sam_grove 5:3f93dd1d4cb3 499 else
sam_grove 5:3f93dd1d4cb3 500 {
sam_grove 5:3f93dd1d4cb3 501 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 502 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 503 }
sam_grove 5:3f93dd1d4cb3 504 }
sam_grove 5:3f93dd1d4cb3 505 while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN))
sam_grove 5:3f93dd1d4cb3 506 {
sam_grove 5:3f93dd1d4cb3 507 /* sub-identifier uses multiple octets */
sam_grove 5:3f93dd1d4cb3 508 if (*msg_ptr & 0x80)
sam_grove 5:3f93dd1d4cb3 509 {
sam_grove 5:3f93dd1d4cb3 510 s32_t sub_id = 0;
sam_grove 5:3f93dd1d4cb3 511
sam_grove 5:3f93dd1d4cb3 512 while ((*msg_ptr & 0x80) && (len > 1))
sam_grove 5:3f93dd1d4cb3 513 {
sam_grove 5:3f93dd1d4cb3 514 len--;
sam_grove 5:3f93dd1d4cb3 515 sub_id = (sub_id << 7) + (*msg_ptr & ~0x80);
sam_grove 5:3f93dd1d4cb3 516 ofs += 1;
sam_grove 5:3f93dd1d4cb3 517 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 518 {
sam_grove 5:3f93dd1d4cb3 519 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 520 p = p->next;
sam_grove 5:3f93dd1d4cb3 521 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 522 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 523 plen += p->len;
sam_grove 5:3f93dd1d4cb3 524 }
sam_grove 5:3f93dd1d4cb3 525 else
sam_grove 5:3f93dd1d4cb3 526 {
sam_grove 5:3f93dd1d4cb3 527 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 528 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 529 }
sam_grove 5:3f93dd1d4cb3 530 }
sam_grove 5:3f93dd1d4cb3 531 if (!(*msg_ptr & 0x80) && (len > 0))
sam_grove 5:3f93dd1d4cb3 532 {
sam_grove 5:3f93dd1d4cb3 533 /* last octet sub-identifier */
sam_grove 5:3f93dd1d4cb3 534 len--;
sam_grove 5:3f93dd1d4cb3 535 sub_id = (sub_id << 7) + *msg_ptr;
sam_grove 5:3f93dd1d4cb3 536 *oid_ptr = sub_id;
sam_grove 5:3f93dd1d4cb3 537 }
sam_grove 5:3f93dd1d4cb3 538 }
sam_grove 5:3f93dd1d4cb3 539 else
sam_grove 5:3f93dd1d4cb3 540 {
sam_grove 5:3f93dd1d4cb3 541 /* !(*msg_ptr & 0x80) sub-identifier uses single octet */
sam_grove 5:3f93dd1d4cb3 542 len--;
sam_grove 5:3f93dd1d4cb3 543 *oid_ptr = *msg_ptr;
sam_grove 5:3f93dd1d4cb3 544 }
sam_grove 5:3f93dd1d4cb3 545 if (len > 0)
sam_grove 5:3f93dd1d4cb3 546 {
sam_grove 5:3f93dd1d4cb3 547 /* remaining oid bytes available ... */
sam_grove 5:3f93dd1d4cb3 548 ofs += 1;
sam_grove 5:3f93dd1d4cb3 549 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 550 {
sam_grove 5:3f93dd1d4cb3 551 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 552 p = p->next;
sam_grove 5:3f93dd1d4cb3 553 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 554 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 555 plen += p->len;
sam_grove 5:3f93dd1d4cb3 556 }
sam_grove 5:3f93dd1d4cb3 557 else
sam_grove 5:3f93dd1d4cb3 558 {
sam_grove 5:3f93dd1d4cb3 559 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 560 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 561 }
sam_grove 5:3f93dd1d4cb3 562 }
sam_grove 5:3f93dd1d4cb3 563 oid_ptr++;
sam_grove 5:3f93dd1d4cb3 564 oid->len++;
sam_grove 5:3f93dd1d4cb3 565 }
sam_grove 5:3f93dd1d4cb3 566 if (len == 0)
sam_grove 5:3f93dd1d4cb3 567 {
sam_grove 5:3f93dd1d4cb3 568 /* len == 0, end of oid */
sam_grove 5:3f93dd1d4cb3 569 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 570 }
sam_grove 5:3f93dd1d4cb3 571 else
sam_grove 5:3f93dd1d4cb3 572 {
sam_grove 5:3f93dd1d4cb3 573 /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */
sam_grove 5:3f93dd1d4cb3 574 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 575 }
sam_grove 5:3f93dd1d4cb3 576
sam_grove 5:3f93dd1d4cb3 577 }
sam_grove 5:3f93dd1d4cb3 578 p = p->next;
sam_grove 5:3f93dd1d4cb3 579 }
sam_grove 5:3f93dd1d4cb3 580 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 581 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 582 }
sam_grove 5:3f93dd1d4cb3 583
sam_grove 5:3f93dd1d4cb3 584 /**
sam_grove 5:3f93dd1d4cb3 585 * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding)
sam_grove 5:3f93dd1d4cb3 586 * from incoming message into array.
sam_grove 5:3f93dd1d4cb3 587 *
sam_grove 5:3f93dd1d4cb3 588 * @param p points to a pbuf holding an ASN1 coded raw data
sam_grove 5:3f93dd1d4cb3 589 * @param ofs points to the offset within the pbuf chain of the ASN1 coded raw data
sam_grove 5:3f93dd1d4cb3 590 * @param len length of the coded raw data (zero is valid, e.g. empty string!)
sam_grove 5:3f93dd1d4cb3 591 * @param raw_len length of the raw return value
sam_grove 5:3f93dd1d4cb3 592 * @param raw return raw bytes
sam_grove 5:3f93dd1d4cb3 593 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode
sam_grove 5:3f93dd1d4cb3 594 */
sam_grove 5:3f93dd1d4cb3 595 err_t
sam_grove 5:3f93dd1d4cb3 596 snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw)
sam_grove 5:3f93dd1d4cb3 597 {
sam_grove 5:3f93dd1d4cb3 598 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 599 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 600
sam_grove 5:3f93dd1d4cb3 601 if (len > 0)
sam_grove 5:3f93dd1d4cb3 602 {
sam_grove 5:3f93dd1d4cb3 603 plen = 0;
sam_grove 5:3f93dd1d4cb3 604 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 605 {
sam_grove 5:3f93dd1d4cb3 606 base = plen;
sam_grove 5:3f93dd1d4cb3 607 plen += p->len;
sam_grove 5:3f93dd1d4cb3 608 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 609 {
sam_grove 5:3f93dd1d4cb3 610 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 611 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 612 if (raw_len >= len)
sam_grove 5:3f93dd1d4cb3 613 {
sam_grove 5:3f93dd1d4cb3 614 while (len > 1)
sam_grove 5:3f93dd1d4cb3 615 {
sam_grove 5:3f93dd1d4cb3 616 /* copy len - 1 octets */
sam_grove 5:3f93dd1d4cb3 617 len--;
sam_grove 5:3f93dd1d4cb3 618 *raw = *msg_ptr;
sam_grove 5:3f93dd1d4cb3 619 raw++;
sam_grove 5:3f93dd1d4cb3 620 ofs += 1;
sam_grove 5:3f93dd1d4cb3 621 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 622 {
sam_grove 5:3f93dd1d4cb3 623 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 624 p = p->next;
sam_grove 5:3f93dd1d4cb3 625 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 626 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 627 plen += p->len;
sam_grove 5:3f93dd1d4cb3 628 }
sam_grove 5:3f93dd1d4cb3 629 else
sam_grove 5:3f93dd1d4cb3 630 {
sam_grove 5:3f93dd1d4cb3 631 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 632 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 633 }
sam_grove 5:3f93dd1d4cb3 634 }
sam_grove 5:3f93dd1d4cb3 635 /* copy last octet */
sam_grove 5:3f93dd1d4cb3 636 *raw = *msg_ptr;
sam_grove 5:3f93dd1d4cb3 637 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 638 }
sam_grove 5:3f93dd1d4cb3 639 else
sam_grove 5:3f93dd1d4cb3 640 {
sam_grove 5:3f93dd1d4cb3 641 /* raw_len < len, not enough dst space */
sam_grove 5:3f93dd1d4cb3 642 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 643 }
sam_grove 5:3f93dd1d4cb3 644 }
sam_grove 5:3f93dd1d4cb3 645 p = p->next;
sam_grove 5:3f93dd1d4cb3 646 }
sam_grove 5:3f93dd1d4cb3 647 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 648 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 649 }
sam_grove 5:3f93dd1d4cb3 650 else
sam_grove 5:3f93dd1d4cb3 651 {
sam_grove 5:3f93dd1d4cb3 652 /* len == 0, empty string */
sam_grove 5:3f93dd1d4cb3 653 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 654 }
sam_grove 5:3f93dd1d4cb3 655 }
sam_grove 5:3f93dd1d4cb3 656
sam_grove 5:3f93dd1d4cb3 657 #endif /* LWIP_SNMP */