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) encoding
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 * Returns octet count for length.
sam_grove 5:3f93dd1d4cb3 45 *
sam_grove 5:3f93dd1d4cb3 46 * @param length
sam_grove 5:3f93dd1d4cb3 47 * @param octets_needed points to the return value
sam_grove 5:3f93dd1d4cb3 48 */
sam_grove 5:3f93dd1d4cb3 49 void
sam_grove 5:3f93dd1d4cb3 50 snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed)
sam_grove 5:3f93dd1d4cb3 51 {
sam_grove 5:3f93dd1d4cb3 52 if (length < 0x80U)
sam_grove 5:3f93dd1d4cb3 53 {
sam_grove 5:3f93dd1d4cb3 54 *octets_needed = 1;
sam_grove 5:3f93dd1d4cb3 55 }
sam_grove 5:3f93dd1d4cb3 56 else if (length < 0x100U)
sam_grove 5:3f93dd1d4cb3 57 {
sam_grove 5:3f93dd1d4cb3 58 *octets_needed = 2;
sam_grove 5:3f93dd1d4cb3 59 }
sam_grove 5:3f93dd1d4cb3 60 else
sam_grove 5:3f93dd1d4cb3 61 {
sam_grove 5:3f93dd1d4cb3 62 *octets_needed = 3;
sam_grove 5:3f93dd1d4cb3 63 }
sam_grove 5:3f93dd1d4cb3 64 }
sam_grove 5:3f93dd1d4cb3 65
sam_grove 5:3f93dd1d4cb3 66 /**
sam_grove 5:3f93dd1d4cb3 67 * Returns octet count for an u32_t.
sam_grove 5:3f93dd1d4cb3 68 *
sam_grove 5:3f93dd1d4cb3 69 * @param value
sam_grove 5:3f93dd1d4cb3 70 * @param octets_needed points to the return value
sam_grove 5:3f93dd1d4cb3 71 *
sam_grove 5:3f93dd1d4cb3 72 * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded
sam_grove 5:3f93dd1d4cb3 73 * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value
sam_grove 5:3f93dd1d4cb3 74 * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!!
sam_grove 5:3f93dd1d4cb3 75 */
sam_grove 5:3f93dd1d4cb3 76 void
sam_grove 5:3f93dd1d4cb3 77 snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed)
sam_grove 5:3f93dd1d4cb3 78 {
sam_grove 5:3f93dd1d4cb3 79 if (value < 0x80UL)
sam_grove 5:3f93dd1d4cb3 80 {
sam_grove 5:3f93dd1d4cb3 81 *octets_needed = 1;
sam_grove 5:3f93dd1d4cb3 82 }
sam_grove 5:3f93dd1d4cb3 83 else if (value < 0x8000UL)
sam_grove 5:3f93dd1d4cb3 84 {
sam_grove 5:3f93dd1d4cb3 85 *octets_needed = 2;
sam_grove 5:3f93dd1d4cb3 86 }
sam_grove 5:3f93dd1d4cb3 87 else if (value < 0x800000UL)
sam_grove 5:3f93dd1d4cb3 88 {
sam_grove 5:3f93dd1d4cb3 89 *octets_needed = 3;
sam_grove 5:3f93dd1d4cb3 90 }
sam_grove 5:3f93dd1d4cb3 91 else if (value < 0x80000000UL)
sam_grove 5:3f93dd1d4cb3 92 {
sam_grove 5:3f93dd1d4cb3 93 *octets_needed = 4;
sam_grove 5:3f93dd1d4cb3 94 }
sam_grove 5:3f93dd1d4cb3 95 else
sam_grove 5:3f93dd1d4cb3 96 {
sam_grove 5:3f93dd1d4cb3 97 *octets_needed = 5;
sam_grove 5:3f93dd1d4cb3 98 }
sam_grove 5:3f93dd1d4cb3 99 }
sam_grove 5:3f93dd1d4cb3 100
sam_grove 5:3f93dd1d4cb3 101 /**
sam_grove 5:3f93dd1d4cb3 102 * Returns octet count for an s32_t.
sam_grove 5:3f93dd1d4cb3 103 *
sam_grove 5:3f93dd1d4cb3 104 * @param value
sam_grove 5:3f93dd1d4cb3 105 * @param octets_needed points to the return value
sam_grove 5:3f93dd1d4cb3 106 *
sam_grove 5:3f93dd1d4cb3 107 * @note ASN coded integers are _always_ signed.
sam_grove 5:3f93dd1d4cb3 108 */
sam_grove 5:3f93dd1d4cb3 109 void
sam_grove 5:3f93dd1d4cb3 110 snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed)
sam_grove 5:3f93dd1d4cb3 111 {
sam_grove 5:3f93dd1d4cb3 112 if (value < 0)
sam_grove 5:3f93dd1d4cb3 113 {
sam_grove 5:3f93dd1d4cb3 114 value = ~value;
sam_grove 5:3f93dd1d4cb3 115 }
sam_grove 5:3f93dd1d4cb3 116 if (value < 0x80L)
sam_grove 5:3f93dd1d4cb3 117 {
sam_grove 5:3f93dd1d4cb3 118 *octets_needed = 1;
sam_grove 5:3f93dd1d4cb3 119 }
sam_grove 5:3f93dd1d4cb3 120 else if (value < 0x8000L)
sam_grove 5:3f93dd1d4cb3 121 {
sam_grove 5:3f93dd1d4cb3 122 *octets_needed = 2;
sam_grove 5:3f93dd1d4cb3 123 }
sam_grove 5:3f93dd1d4cb3 124 else if (value < 0x800000L)
sam_grove 5:3f93dd1d4cb3 125 {
sam_grove 5:3f93dd1d4cb3 126 *octets_needed = 3;
sam_grove 5:3f93dd1d4cb3 127 }
sam_grove 5:3f93dd1d4cb3 128 else
sam_grove 5:3f93dd1d4cb3 129 {
sam_grove 5:3f93dd1d4cb3 130 *octets_needed = 4;
sam_grove 5:3f93dd1d4cb3 131 }
sam_grove 5:3f93dd1d4cb3 132 }
sam_grove 5:3f93dd1d4cb3 133
sam_grove 5:3f93dd1d4cb3 134 /**
sam_grove 5:3f93dd1d4cb3 135 * Returns octet count for an object identifier.
sam_grove 5:3f93dd1d4cb3 136 *
sam_grove 5:3f93dd1d4cb3 137 * @param ident_len object identifier array length
sam_grove 5:3f93dd1d4cb3 138 * @param ident points to object identifier array
sam_grove 5:3f93dd1d4cb3 139 * @param octets_needed points to the return value
sam_grove 5:3f93dd1d4cb3 140 */
sam_grove 5:3f93dd1d4cb3 141 void
sam_grove 5:3f93dd1d4cb3 142 snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed)
sam_grove 5:3f93dd1d4cb3 143 {
sam_grove 5:3f93dd1d4cb3 144 s32_t sub_id;
sam_grove 5:3f93dd1d4cb3 145 u8_t cnt;
sam_grove 5:3f93dd1d4cb3 146
sam_grove 5:3f93dd1d4cb3 147 cnt = 0;
sam_grove 5:3f93dd1d4cb3 148 if (ident_len > 1)
sam_grove 5:3f93dd1d4cb3 149 {
sam_grove 5:3f93dd1d4cb3 150 /* compressed prefix in one octet */
sam_grove 5:3f93dd1d4cb3 151 cnt++;
sam_grove 5:3f93dd1d4cb3 152 ident_len -= 2;
sam_grove 5:3f93dd1d4cb3 153 ident += 2;
sam_grove 5:3f93dd1d4cb3 154 }
sam_grove 5:3f93dd1d4cb3 155 while(ident_len > 0)
sam_grove 5:3f93dd1d4cb3 156 {
sam_grove 5:3f93dd1d4cb3 157 ident_len--;
sam_grove 5:3f93dd1d4cb3 158 sub_id = *ident;
sam_grove 5:3f93dd1d4cb3 159
sam_grove 5:3f93dd1d4cb3 160 sub_id >>= 7;
sam_grove 5:3f93dd1d4cb3 161 cnt++;
sam_grove 5:3f93dd1d4cb3 162 while(sub_id > 0)
sam_grove 5:3f93dd1d4cb3 163 {
sam_grove 5:3f93dd1d4cb3 164 sub_id >>= 7;
sam_grove 5:3f93dd1d4cb3 165 cnt++;
sam_grove 5:3f93dd1d4cb3 166 }
sam_grove 5:3f93dd1d4cb3 167 ident++;
sam_grove 5:3f93dd1d4cb3 168 }
sam_grove 5:3f93dd1d4cb3 169 *octets_needed = cnt;
sam_grove 5:3f93dd1d4cb3 170 }
sam_grove 5:3f93dd1d4cb3 171
sam_grove 5:3f93dd1d4cb3 172 /**
sam_grove 5:3f93dd1d4cb3 173 * Encodes ASN type field into a pbuf chained ASN1 msg.
sam_grove 5:3f93dd1d4cb3 174 *
sam_grove 5:3f93dd1d4cb3 175 * @param p points to output pbuf to encode value into
sam_grove 5:3f93dd1d4cb3 176 * @param ofs points to the offset within the pbuf chain
sam_grove 5:3f93dd1d4cb3 177 * @param type input ASN1 type
sam_grove 5:3f93dd1d4cb3 178 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
sam_grove 5:3f93dd1d4cb3 179 */
sam_grove 5:3f93dd1d4cb3 180 err_t
sam_grove 5:3f93dd1d4cb3 181 snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type)
sam_grove 5:3f93dd1d4cb3 182 {
sam_grove 5:3f93dd1d4cb3 183 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 184 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 185
sam_grove 5:3f93dd1d4cb3 186 plen = 0;
sam_grove 5:3f93dd1d4cb3 187 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 188 {
sam_grove 5:3f93dd1d4cb3 189 base = plen;
sam_grove 5:3f93dd1d4cb3 190 plen += p->len;
sam_grove 5:3f93dd1d4cb3 191 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 192 {
sam_grove 5:3f93dd1d4cb3 193 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 194 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 195 *msg_ptr = type;
sam_grove 5:3f93dd1d4cb3 196 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 197 }
sam_grove 5:3f93dd1d4cb3 198 p = p->next;
sam_grove 5:3f93dd1d4cb3 199 }
sam_grove 5:3f93dd1d4cb3 200 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 201 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 202 }
sam_grove 5:3f93dd1d4cb3 203
sam_grove 5:3f93dd1d4cb3 204 /**
sam_grove 5:3f93dd1d4cb3 205 * Encodes host order length field into a pbuf chained ASN1 msg.
sam_grove 5:3f93dd1d4cb3 206 *
sam_grove 5:3f93dd1d4cb3 207 * @param p points to output pbuf to encode length into
sam_grove 5:3f93dd1d4cb3 208 * @param ofs points to the offset within the pbuf chain
sam_grove 5:3f93dd1d4cb3 209 * @param length is the host order length to be encoded
sam_grove 5:3f93dd1d4cb3 210 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
sam_grove 5:3f93dd1d4cb3 211 */
sam_grove 5:3f93dd1d4cb3 212 err_t
sam_grove 5:3f93dd1d4cb3 213 snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length)
sam_grove 5:3f93dd1d4cb3 214 {
sam_grove 5:3f93dd1d4cb3 215 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 216 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 217
sam_grove 5:3f93dd1d4cb3 218 plen = 0;
sam_grove 5:3f93dd1d4cb3 219 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 220 {
sam_grove 5:3f93dd1d4cb3 221 base = plen;
sam_grove 5:3f93dd1d4cb3 222 plen += p->len;
sam_grove 5:3f93dd1d4cb3 223 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 224 {
sam_grove 5:3f93dd1d4cb3 225 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 226 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 227
sam_grove 5:3f93dd1d4cb3 228 if (length < 0x80)
sam_grove 5:3f93dd1d4cb3 229 {
sam_grove 5:3f93dd1d4cb3 230 *msg_ptr = (u8_t)length;
sam_grove 5:3f93dd1d4cb3 231 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 232 }
sam_grove 5:3f93dd1d4cb3 233 else if (length < 0x100)
sam_grove 5:3f93dd1d4cb3 234 {
sam_grove 5:3f93dd1d4cb3 235 *msg_ptr = 0x81;
sam_grove 5:3f93dd1d4cb3 236 ofs += 1;
sam_grove 5:3f93dd1d4cb3 237 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 238 {
sam_grove 5:3f93dd1d4cb3 239 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 240 p = p->next;
sam_grove 5:3f93dd1d4cb3 241 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 242 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 243 }
sam_grove 5:3f93dd1d4cb3 244 else
sam_grove 5:3f93dd1d4cb3 245 {
sam_grove 5:3f93dd1d4cb3 246 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 247 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 248 }
sam_grove 5:3f93dd1d4cb3 249 *msg_ptr = (u8_t)length;
sam_grove 5:3f93dd1d4cb3 250 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 251 }
sam_grove 5:3f93dd1d4cb3 252 else
sam_grove 5:3f93dd1d4cb3 253 {
sam_grove 5:3f93dd1d4cb3 254 u8_t i;
sam_grove 5:3f93dd1d4cb3 255
sam_grove 5:3f93dd1d4cb3 256 /* length >= 0x100 && length <= 0xFFFF */
sam_grove 5:3f93dd1d4cb3 257 *msg_ptr = 0x82;
sam_grove 5:3f93dd1d4cb3 258 i = 2;
sam_grove 5:3f93dd1d4cb3 259 while (i > 0)
sam_grove 5:3f93dd1d4cb3 260 {
sam_grove 5:3f93dd1d4cb3 261 i--;
sam_grove 5:3f93dd1d4cb3 262 ofs += 1;
sam_grove 5:3f93dd1d4cb3 263 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 264 {
sam_grove 5:3f93dd1d4cb3 265 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 266 p = p->next;
sam_grove 5:3f93dd1d4cb3 267 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 268 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 269 plen += p->len;
sam_grove 5:3f93dd1d4cb3 270 }
sam_grove 5:3f93dd1d4cb3 271 else
sam_grove 5:3f93dd1d4cb3 272 {
sam_grove 5:3f93dd1d4cb3 273 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 274 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 275 }
sam_grove 5:3f93dd1d4cb3 276 if (i == 0)
sam_grove 5:3f93dd1d4cb3 277 {
sam_grove 5:3f93dd1d4cb3 278 /* least significant length octet */
sam_grove 5:3f93dd1d4cb3 279 *msg_ptr = (u8_t)length;
sam_grove 5:3f93dd1d4cb3 280 }
sam_grove 5:3f93dd1d4cb3 281 else
sam_grove 5:3f93dd1d4cb3 282 {
sam_grove 5:3f93dd1d4cb3 283 /* most significant length octet */
sam_grove 5:3f93dd1d4cb3 284 *msg_ptr = (u8_t)(length >> 8);
sam_grove 5:3f93dd1d4cb3 285 }
sam_grove 5:3f93dd1d4cb3 286 }
sam_grove 5:3f93dd1d4cb3 287 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 288 }
sam_grove 5:3f93dd1d4cb3 289 }
sam_grove 5:3f93dd1d4cb3 290 p = p->next;
sam_grove 5:3f93dd1d4cb3 291 }
sam_grove 5:3f93dd1d4cb3 292 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 293 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 294 }
sam_grove 5:3f93dd1d4cb3 295
sam_grove 5:3f93dd1d4cb3 296 /**
sam_grove 5:3f93dd1d4cb3 297 * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg.
sam_grove 5:3f93dd1d4cb3 298 *
sam_grove 5:3f93dd1d4cb3 299 * @param p points to output pbuf to encode value into
sam_grove 5:3f93dd1d4cb3 300 * @param ofs points to the offset within the pbuf chain
sam_grove 5:3f93dd1d4cb3 301 * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt())
sam_grove 5:3f93dd1d4cb3 302 * @param value is the host order u32_t value to be encoded
sam_grove 5:3f93dd1d4cb3 303 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
sam_grove 5:3f93dd1d4cb3 304 *
sam_grove 5:3f93dd1d4cb3 305 * @see snmp_asn1_enc_u32t_cnt()
sam_grove 5:3f93dd1d4cb3 306 */
sam_grove 5:3f93dd1d4cb3 307 err_t
sam_grove 5:3f93dd1d4cb3 308 snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value)
sam_grove 5:3f93dd1d4cb3 309 {
sam_grove 5:3f93dd1d4cb3 310 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 311 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 312
sam_grove 5:3f93dd1d4cb3 313 plen = 0;
sam_grove 5:3f93dd1d4cb3 314 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 315 {
sam_grove 5:3f93dd1d4cb3 316 base = plen;
sam_grove 5:3f93dd1d4cb3 317 plen += p->len;
sam_grove 5:3f93dd1d4cb3 318 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 319 {
sam_grove 5:3f93dd1d4cb3 320 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 321 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 322
sam_grove 5:3f93dd1d4cb3 323 if (octets_needed == 5)
sam_grove 5:3f93dd1d4cb3 324 {
sam_grove 5:3f93dd1d4cb3 325 /* not enough bits in 'value' add leading 0x00 */
sam_grove 5:3f93dd1d4cb3 326 octets_needed--;
sam_grove 5:3f93dd1d4cb3 327 *msg_ptr = 0x00;
sam_grove 5:3f93dd1d4cb3 328 ofs += 1;
sam_grove 5:3f93dd1d4cb3 329 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 330 {
sam_grove 5:3f93dd1d4cb3 331 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 332 p = p->next;
sam_grove 5:3f93dd1d4cb3 333 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 334 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 335 plen += p->len;
sam_grove 5:3f93dd1d4cb3 336 }
sam_grove 5:3f93dd1d4cb3 337 else
sam_grove 5:3f93dd1d4cb3 338 {
sam_grove 5:3f93dd1d4cb3 339 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 340 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 341 }
sam_grove 5:3f93dd1d4cb3 342 }
sam_grove 5:3f93dd1d4cb3 343 while (octets_needed > 1)
sam_grove 5:3f93dd1d4cb3 344 {
sam_grove 5:3f93dd1d4cb3 345 octets_needed--;
sam_grove 5:3f93dd1d4cb3 346 *msg_ptr = (u8_t)(value >> (octets_needed << 3));
sam_grove 5:3f93dd1d4cb3 347 ofs += 1;
sam_grove 5:3f93dd1d4cb3 348 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 349 {
sam_grove 5:3f93dd1d4cb3 350 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 351 p = p->next;
sam_grove 5:3f93dd1d4cb3 352 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 353 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 354 plen += p->len;
sam_grove 5:3f93dd1d4cb3 355 }
sam_grove 5:3f93dd1d4cb3 356 else
sam_grove 5:3f93dd1d4cb3 357 {
sam_grove 5:3f93dd1d4cb3 358 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 359 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 360 }
sam_grove 5:3f93dd1d4cb3 361 }
sam_grove 5:3f93dd1d4cb3 362 /* (only) one least significant octet */
sam_grove 5:3f93dd1d4cb3 363 *msg_ptr = (u8_t)value;
sam_grove 5:3f93dd1d4cb3 364 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 365 }
sam_grove 5:3f93dd1d4cb3 366 p = p->next;
sam_grove 5:3f93dd1d4cb3 367 }
sam_grove 5:3f93dd1d4cb3 368 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 369 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 370 }
sam_grove 5:3f93dd1d4cb3 371
sam_grove 5:3f93dd1d4cb3 372 /**
sam_grove 5:3f93dd1d4cb3 373 * Encodes s32_t integer into a pbuf chained ASN1 msg.
sam_grove 5:3f93dd1d4cb3 374 *
sam_grove 5:3f93dd1d4cb3 375 * @param p points to output pbuf to encode value into
sam_grove 5:3f93dd1d4cb3 376 * @param ofs points to the offset within the pbuf chain
sam_grove 5:3f93dd1d4cb3 377 * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt())
sam_grove 5:3f93dd1d4cb3 378 * @param value is the host order s32_t value to be encoded
sam_grove 5:3f93dd1d4cb3 379 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
sam_grove 5:3f93dd1d4cb3 380 *
sam_grove 5:3f93dd1d4cb3 381 * @see snmp_asn1_enc_s32t_cnt()
sam_grove 5:3f93dd1d4cb3 382 */
sam_grove 5:3f93dd1d4cb3 383 err_t
sam_grove 5:3f93dd1d4cb3 384 snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value)
sam_grove 5:3f93dd1d4cb3 385 {
sam_grove 5:3f93dd1d4cb3 386 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 387 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 388
sam_grove 5:3f93dd1d4cb3 389 plen = 0;
sam_grove 5:3f93dd1d4cb3 390 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 391 {
sam_grove 5:3f93dd1d4cb3 392 base = plen;
sam_grove 5:3f93dd1d4cb3 393 plen += p->len;
sam_grove 5:3f93dd1d4cb3 394 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 395 {
sam_grove 5:3f93dd1d4cb3 396 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 397 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 398
sam_grove 5:3f93dd1d4cb3 399 while (octets_needed > 1)
sam_grove 5:3f93dd1d4cb3 400 {
sam_grove 5:3f93dd1d4cb3 401 octets_needed--;
sam_grove 5:3f93dd1d4cb3 402 *msg_ptr = (u8_t)(value >> (octets_needed << 3));
sam_grove 5:3f93dd1d4cb3 403 ofs += 1;
sam_grove 5:3f93dd1d4cb3 404 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 405 {
sam_grove 5:3f93dd1d4cb3 406 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 407 p = p->next;
sam_grove 5:3f93dd1d4cb3 408 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 409 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 410 plen += p->len;
sam_grove 5:3f93dd1d4cb3 411 }
sam_grove 5:3f93dd1d4cb3 412 else
sam_grove 5:3f93dd1d4cb3 413 {
sam_grove 5:3f93dd1d4cb3 414 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 415 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 416 }
sam_grove 5:3f93dd1d4cb3 417 }
sam_grove 5:3f93dd1d4cb3 418 /* (only) one least significant octet */
sam_grove 5:3f93dd1d4cb3 419 *msg_ptr = (u8_t)value;
sam_grove 5:3f93dd1d4cb3 420 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 421 }
sam_grove 5:3f93dd1d4cb3 422 p = p->next;
sam_grove 5:3f93dd1d4cb3 423 }
sam_grove 5:3f93dd1d4cb3 424 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 425 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 426 }
sam_grove 5:3f93dd1d4cb3 427
sam_grove 5:3f93dd1d4cb3 428 /**
sam_grove 5:3f93dd1d4cb3 429 * Encodes object identifier into a pbuf chained ASN1 msg.
sam_grove 5:3f93dd1d4cb3 430 *
sam_grove 5:3f93dd1d4cb3 431 * @param p points to output pbuf to encode oid into
sam_grove 5:3f93dd1d4cb3 432 * @param ofs points to the offset within the pbuf chain
sam_grove 5:3f93dd1d4cb3 433 * @param ident_len object identifier array length
sam_grove 5:3f93dd1d4cb3 434 * @param ident points to object identifier array
sam_grove 5:3f93dd1d4cb3 435 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
sam_grove 5:3f93dd1d4cb3 436 */
sam_grove 5:3f93dd1d4cb3 437 err_t
sam_grove 5:3f93dd1d4cb3 438 snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident)
sam_grove 5:3f93dd1d4cb3 439 {
sam_grove 5:3f93dd1d4cb3 440 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 441 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 442
sam_grove 5:3f93dd1d4cb3 443 plen = 0;
sam_grove 5:3f93dd1d4cb3 444 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 445 {
sam_grove 5:3f93dd1d4cb3 446 base = plen;
sam_grove 5:3f93dd1d4cb3 447 plen += p->len;
sam_grove 5:3f93dd1d4cb3 448 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 449 {
sam_grove 5:3f93dd1d4cb3 450 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 451 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 452
sam_grove 5:3f93dd1d4cb3 453 if (ident_len > 1)
sam_grove 5:3f93dd1d4cb3 454 {
sam_grove 5:3f93dd1d4cb3 455 if ((ident[0] == 1) && (ident[1] == 3))
sam_grove 5:3f93dd1d4cb3 456 {
sam_grove 5:3f93dd1d4cb3 457 /* compressed (most common) prefix .iso.org */
sam_grove 5:3f93dd1d4cb3 458 *msg_ptr = 0x2b;
sam_grove 5:3f93dd1d4cb3 459 }
sam_grove 5:3f93dd1d4cb3 460 else
sam_grove 5:3f93dd1d4cb3 461 {
sam_grove 5:3f93dd1d4cb3 462 /* calculate prefix */
sam_grove 5:3f93dd1d4cb3 463 *msg_ptr = (u8_t)((ident[0] * 40) + ident[1]);
sam_grove 5:3f93dd1d4cb3 464 }
sam_grove 5:3f93dd1d4cb3 465 ofs += 1;
sam_grove 5:3f93dd1d4cb3 466 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 467 {
sam_grove 5:3f93dd1d4cb3 468 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 469 p = p->next;
sam_grove 5:3f93dd1d4cb3 470 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 471 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 472 plen += p->len;
sam_grove 5:3f93dd1d4cb3 473 }
sam_grove 5:3f93dd1d4cb3 474 else
sam_grove 5:3f93dd1d4cb3 475 {
sam_grove 5:3f93dd1d4cb3 476 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 477 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 478 }
sam_grove 5:3f93dd1d4cb3 479 ident_len -= 2;
sam_grove 5:3f93dd1d4cb3 480 ident += 2;
sam_grove 5:3f93dd1d4cb3 481 }
sam_grove 5:3f93dd1d4cb3 482 else
sam_grove 5:3f93dd1d4cb3 483 {
sam_grove 5:3f93dd1d4cb3 484 /* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */
sam_grove 5:3f93dd1d4cb3 485 /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */
sam_grove 5:3f93dd1d4cb3 486 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 487 }
sam_grove 5:3f93dd1d4cb3 488 while (ident_len > 0)
sam_grove 5:3f93dd1d4cb3 489 {
sam_grove 5:3f93dd1d4cb3 490 s32_t sub_id;
sam_grove 5:3f93dd1d4cb3 491 u8_t shift, tail;
sam_grove 5:3f93dd1d4cb3 492
sam_grove 5:3f93dd1d4cb3 493 ident_len--;
sam_grove 5:3f93dd1d4cb3 494 sub_id = *ident;
sam_grove 5:3f93dd1d4cb3 495 tail = 0;
sam_grove 5:3f93dd1d4cb3 496 shift = 28;
sam_grove 5:3f93dd1d4cb3 497 while(shift > 0)
sam_grove 5:3f93dd1d4cb3 498 {
sam_grove 5:3f93dd1d4cb3 499 u8_t code;
sam_grove 5:3f93dd1d4cb3 500
sam_grove 5:3f93dd1d4cb3 501 code = (u8_t)(sub_id >> shift);
sam_grove 5:3f93dd1d4cb3 502 if ((code != 0) || (tail != 0))
sam_grove 5:3f93dd1d4cb3 503 {
sam_grove 5:3f93dd1d4cb3 504 tail = 1;
sam_grove 5:3f93dd1d4cb3 505 *msg_ptr = code | 0x80;
sam_grove 5:3f93dd1d4cb3 506 ofs += 1;
sam_grove 5:3f93dd1d4cb3 507 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 508 {
sam_grove 5:3f93dd1d4cb3 509 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 510 p = p->next;
sam_grove 5:3f93dd1d4cb3 511 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 512 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 513 plen += p->len;
sam_grove 5:3f93dd1d4cb3 514 }
sam_grove 5:3f93dd1d4cb3 515 else
sam_grove 5:3f93dd1d4cb3 516 {
sam_grove 5:3f93dd1d4cb3 517 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 518 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 519 }
sam_grove 5:3f93dd1d4cb3 520 }
sam_grove 5:3f93dd1d4cb3 521 shift -= 7;
sam_grove 5:3f93dd1d4cb3 522 }
sam_grove 5:3f93dd1d4cb3 523 *msg_ptr = (u8_t)sub_id & 0x7F;
sam_grove 5:3f93dd1d4cb3 524 if (ident_len > 0)
sam_grove 5:3f93dd1d4cb3 525 {
sam_grove 5:3f93dd1d4cb3 526 ofs += 1;
sam_grove 5:3f93dd1d4cb3 527 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 528 {
sam_grove 5:3f93dd1d4cb3 529 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 530 p = p->next;
sam_grove 5:3f93dd1d4cb3 531 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 532 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 533 plen += p->len;
sam_grove 5:3f93dd1d4cb3 534 }
sam_grove 5:3f93dd1d4cb3 535 else
sam_grove 5:3f93dd1d4cb3 536 {
sam_grove 5:3f93dd1d4cb3 537 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 538 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 539 }
sam_grove 5:3f93dd1d4cb3 540 }
sam_grove 5:3f93dd1d4cb3 541 /* proceed to next sub-identifier */
sam_grove 5:3f93dd1d4cb3 542 ident++;
sam_grove 5:3f93dd1d4cb3 543 }
sam_grove 5:3f93dd1d4cb3 544 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 545 }
sam_grove 5:3f93dd1d4cb3 546 p = p->next;
sam_grove 5:3f93dd1d4cb3 547 }
sam_grove 5:3f93dd1d4cb3 548 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 549 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 550 }
sam_grove 5:3f93dd1d4cb3 551
sam_grove 5:3f93dd1d4cb3 552 /**
sam_grove 5:3f93dd1d4cb3 553 * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg.
sam_grove 5:3f93dd1d4cb3 554 *
sam_grove 5:3f93dd1d4cb3 555 * @param p points to output pbuf to encode raw data into
sam_grove 5:3f93dd1d4cb3 556 * @param ofs points to the offset within the pbuf chain
sam_grove 5:3f93dd1d4cb3 557 * @param raw_len raw data length
sam_grove 5:3f93dd1d4cb3 558 * @param raw points raw data
sam_grove 5:3f93dd1d4cb3 559 * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode
sam_grove 5:3f93dd1d4cb3 560 */
sam_grove 5:3f93dd1d4cb3 561 err_t
sam_grove 5:3f93dd1d4cb3 562 snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw)
sam_grove 5:3f93dd1d4cb3 563 {
sam_grove 5:3f93dd1d4cb3 564 u16_t plen, base;
sam_grove 5:3f93dd1d4cb3 565 u8_t *msg_ptr;
sam_grove 5:3f93dd1d4cb3 566
sam_grove 5:3f93dd1d4cb3 567 plen = 0;
sam_grove 5:3f93dd1d4cb3 568 while (p != NULL)
sam_grove 5:3f93dd1d4cb3 569 {
sam_grove 5:3f93dd1d4cb3 570 base = plen;
sam_grove 5:3f93dd1d4cb3 571 plen += p->len;
sam_grove 5:3f93dd1d4cb3 572 if (ofs < plen)
sam_grove 5:3f93dd1d4cb3 573 {
sam_grove 5:3f93dd1d4cb3 574 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 575 msg_ptr += ofs - base;
sam_grove 5:3f93dd1d4cb3 576
sam_grove 5:3f93dd1d4cb3 577 while (raw_len > 1)
sam_grove 5:3f93dd1d4cb3 578 {
sam_grove 5:3f93dd1d4cb3 579 /* copy raw_len - 1 octets */
sam_grove 5:3f93dd1d4cb3 580 raw_len--;
sam_grove 5:3f93dd1d4cb3 581 *msg_ptr = *raw;
sam_grove 5:3f93dd1d4cb3 582 raw++;
sam_grove 5:3f93dd1d4cb3 583 ofs += 1;
sam_grove 5:3f93dd1d4cb3 584 if (ofs >= plen)
sam_grove 5:3f93dd1d4cb3 585 {
sam_grove 5:3f93dd1d4cb3 586 /* next octet in next pbuf */
sam_grove 5:3f93dd1d4cb3 587 p = p->next;
sam_grove 5:3f93dd1d4cb3 588 if (p == NULL) { return ERR_ARG; }
sam_grove 5:3f93dd1d4cb3 589 msg_ptr = (u8_t*)p->payload;
sam_grove 5:3f93dd1d4cb3 590 plen += p->len;
sam_grove 5:3f93dd1d4cb3 591 }
sam_grove 5:3f93dd1d4cb3 592 else
sam_grove 5:3f93dd1d4cb3 593 {
sam_grove 5:3f93dd1d4cb3 594 /* next octet in same pbuf */
sam_grove 5:3f93dd1d4cb3 595 msg_ptr++;
sam_grove 5:3f93dd1d4cb3 596 }
sam_grove 5:3f93dd1d4cb3 597 }
sam_grove 5:3f93dd1d4cb3 598 if (raw_len > 0)
sam_grove 5:3f93dd1d4cb3 599 {
sam_grove 5:3f93dd1d4cb3 600 /* copy last or single octet */
sam_grove 5:3f93dd1d4cb3 601 *msg_ptr = *raw;
sam_grove 5:3f93dd1d4cb3 602 }
sam_grove 5:3f93dd1d4cb3 603 return ERR_OK;
sam_grove 5:3f93dd1d4cb3 604 }
sam_grove 5:3f93dd1d4cb3 605 p = p->next;
sam_grove 5:3f93dd1d4cb3 606 }
sam_grove 5:3f93dd1d4cb3 607 /* p == NULL, ofs >= plen */
sam_grove 5:3f93dd1d4cb3 608 return ERR_ARG;
sam_grove 5:3f93dd1d4cb3 609 }
sam_grove 5:3f93dd1d4cb3 610
sam_grove 5:3f93dd1d4cb3 611 #endif /* LWIP_SNMP */