Web server based weather station using Sparkfun Weather Meters.

Dependencies:   FatFileSystem mbed WeatherMeters SDFileSystem

Committer:
AdamGreen
Date:
Thu Feb 23 21:38:39 2012 +0000
Revision:
0:616601bde9fb

        

Who changed what in which revision?

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