Example

Dependencies:   FXAS21002 FXOS8700Q

Committer:
maygup01
Date:
Tue Nov 19 09:49:38 2019 +0000
Revision:
0:11cc2b7889af
Example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
maygup01 0:11cc2b7889af 1 /*
maygup01 0:11cc2b7889af 2 * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
maygup01 0:11cc2b7889af 3 * SPDX-License-Identifier: Apache-2.0
maygup01 0:11cc2b7889af 4 * Licensed under the Apache License, Version 2.0 (the License); you may
maygup01 0:11cc2b7889af 5 * not use this file except in compliance with the License.
maygup01 0:11cc2b7889af 6 * You may obtain a copy of the License at
maygup01 0:11cc2b7889af 7 *
maygup01 0:11cc2b7889af 8 * http://www.apache.org/licenses/LICENSE-2.0
maygup01 0:11cc2b7889af 9 *
maygup01 0:11cc2b7889af 10 * Unless required by applicable law or agreed to in writing, software
maygup01 0:11cc2b7889af 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
maygup01 0:11cc2b7889af 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
maygup01 0:11cc2b7889af 13 * See the License for the specific language governing permissions and
maygup01 0:11cc2b7889af 14 * limitations under the License.
maygup01 0:11cc2b7889af 15 */
maygup01 0:11cc2b7889af 16 #include <stdio.h>
maygup01 0:11cc2b7889af 17 #include <string.h>
maygup01 0:11cc2b7889af 18 #include "common_functions.h"
maygup01 0:11cc2b7889af 19 #include "ip6string.h"
maygup01 0:11cc2b7889af 20
maygup01 0:11cc2b7889af 21 /**
maygup01 0:11cc2b7889af 22 * Print binary IPv6 address to a string.
maygup01 0:11cc2b7889af 23 * String must contain enough room for full address, 40 bytes exact.
maygup01 0:11cc2b7889af 24 * IPv4 tunneling addresses are not covered.
maygup01 0:11cc2b7889af 25 * \param addr IPv6 address.
maygup01 0:11cc2b7889af 26 * \p buffer to write string to.
maygup01 0:11cc2b7889af 27 */
maygup01 0:11cc2b7889af 28 uint_fast8_t ip6tos(const void *ip6addr, char *p)
maygup01 0:11cc2b7889af 29 {
maygup01 0:11cc2b7889af 30 char *p_orig = p;
maygup01 0:11cc2b7889af 31 uint_fast8_t zero_start = 255, zero_len = 1;
maygup01 0:11cc2b7889af 32 const uint8_t *addr = ip6addr;
maygup01 0:11cc2b7889af 33 uint_fast16_t part;
maygup01 0:11cc2b7889af 34
maygup01 0:11cc2b7889af 35 /* Follow RFC 5952 - pre-scan for longest run of zeros */
maygup01 0:11cc2b7889af 36 for (uint_fast8_t n = 0; n < 8; n++) {
maygup01 0:11cc2b7889af 37 part = *addr++;
maygup01 0:11cc2b7889af 38 part = (part << 8) | *addr++;
maygup01 0:11cc2b7889af 39 if (part != 0) {
maygup01 0:11cc2b7889af 40 continue;
maygup01 0:11cc2b7889af 41 }
maygup01 0:11cc2b7889af 42
maygup01 0:11cc2b7889af 43 /* We're at the start of a run of zeros - scan to non-zero (or end) */
maygup01 0:11cc2b7889af 44 uint_fast8_t n0 = n;
maygup01 0:11cc2b7889af 45 for (n = n0 + 1; n < 8; n++) {
maygup01 0:11cc2b7889af 46 part = *addr++;
maygup01 0:11cc2b7889af 47 part = (part << 8) | *addr++;
maygup01 0:11cc2b7889af 48 if (part != 0) {
maygup01 0:11cc2b7889af 49 break;
maygup01 0:11cc2b7889af 50 }
maygup01 0:11cc2b7889af 51 }
maygup01 0:11cc2b7889af 52
maygup01 0:11cc2b7889af 53 /* Now n0->initial zero of run, n->after final zero in run. Is this the
maygup01 0:11cc2b7889af 54 * longest run yet? If equal, we stick with the previous one - RFC 5952
maygup01 0:11cc2b7889af 55 * S4.2.3. Note that zero_len being initialised to 1 stops us
maygup01 0:11cc2b7889af 56 * shortening a 1-part run (S4.2.2.)
maygup01 0:11cc2b7889af 57 */
maygup01 0:11cc2b7889af 58 if (n - n0 > zero_len) {
maygup01 0:11cc2b7889af 59 zero_start = n0;
maygup01 0:11cc2b7889af 60 zero_len = n - n0;
maygup01 0:11cc2b7889af 61 }
maygup01 0:11cc2b7889af 62
maygup01 0:11cc2b7889af 63 /* Continue scan for initial zeros from part n+1 - we've already
maygup01 0:11cc2b7889af 64 * consumed part n, and know it's non-zero. */
maygup01 0:11cc2b7889af 65 }
maygup01 0:11cc2b7889af 66
maygup01 0:11cc2b7889af 67 /* Now go back and print, jumping over any zero run */
maygup01 0:11cc2b7889af 68 addr = ip6addr;
maygup01 0:11cc2b7889af 69 for (uint_fast8_t n = 0; n < 8;) {
maygup01 0:11cc2b7889af 70 if (n == zero_start) {
maygup01 0:11cc2b7889af 71 if (n == 0) {
maygup01 0:11cc2b7889af 72 *p++ = ':';
maygup01 0:11cc2b7889af 73 }
maygup01 0:11cc2b7889af 74 *p++ = ':';
maygup01 0:11cc2b7889af 75 addr += 2 * zero_len;
maygup01 0:11cc2b7889af 76 n += zero_len;
maygup01 0:11cc2b7889af 77 continue;
maygup01 0:11cc2b7889af 78 }
maygup01 0:11cc2b7889af 79
maygup01 0:11cc2b7889af 80 part = *addr++;
maygup01 0:11cc2b7889af 81 part = (part << 8) | *addr++;
maygup01 0:11cc2b7889af 82 n++;
maygup01 0:11cc2b7889af 83
maygup01 0:11cc2b7889af 84 p += sprintf(p, "%"PRIxFAST16, part);
maygup01 0:11cc2b7889af 85
maygup01 0:11cc2b7889af 86 /* One iteration writes "part:" rather than ":part", and has the
maygup01 0:11cc2b7889af 87 * explicit check for n == 8 below, to allow easy extension for
maygup01 0:11cc2b7889af 88 * IPv4-in-IPv6-type addresses ("xxxx::xxxx:a.b.c.d"): we'd just
maygup01 0:11cc2b7889af 89 * run the same loop for 6 parts, and output would then finish with the
maygup01 0:11cc2b7889af 90 * required : or ::, ready for "a.b.c.d" to be tacked on.
maygup01 0:11cc2b7889af 91 */
maygup01 0:11cc2b7889af 92 if (n != 8) {
maygup01 0:11cc2b7889af 93 *p++ = ':';
maygup01 0:11cc2b7889af 94 }
maygup01 0:11cc2b7889af 95 }
maygup01 0:11cc2b7889af 96 *p = '\0';
maygup01 0:11cc2b7889af 97
maygup01 0:11cc2b7889af 98 // Return length of generated string, excluding the terminating null character
maygup01 0:11cc2b7889af 99 return p - p_orig;
maygup01 0:11cc2b7889af 100 }
maygup01 0:11cc2b7889af 101
maygup01 0:11cc2b7889af 102 uint_fast8_t ip6_prefix_tos(const void *prefix, uint_fast8_t prefix_len, char *p)
maygup01 0:11cc2b7889af 103 {
maygup01 0:11cc2b7889af 104 char *wptr = p;
maygup01 0:11cc2b7889af 105 uint8_t addr[16] = {0};
maygup01 0:11cc2b7889af 106
maygup01 0:11cc2b7889af 107 if (prefix_len > 128) {
maygup01 0:11cc2b7889af 108 return 0;
maygup01 0:11cc2b7889af 109 }
maygup01 0:11cc2b7889af 110
maygup01 0:11cc2b7889af 111 // Generate prefix part of the string
maygup01 0:11cc2b7889af 112 bitcopy(addr, prefix, prefix_len);
maygup01 0:11cc2b7889af 113 wptr += ip6tos(addr, wptr);
maygup01 0:11cc2b7889af 114 // Add the prefix length part of the string
maygup01 0:11cc2b7889af 115 wptr += sprintf(wptr, "/%"PRIuFAST8, prefix_len);
maygup01 0:11cc2b7889af 116
maygup01 0:11cc2b7889af 117 // Return total length of generated string
maygup01 0:11cc2b7889af 118 return wptr - p;
maygup01 0:11cc2b7889af 119 }