mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers common_functions.h Source File

common_functions.h

00001 /*
00002  * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #ifndef COMMON_FUNCTIONS_H_
00017 #define COMMON_FUNCTIONS_H_
00018 
00019 #include "ns_types.h"
00020 
00021 #ifdef __cplusplus
00022 extern "C" {
00023 #endif
00024 
00025 /*
00026  * Common write 64-bit variable to 8-bit pointer.
00027  *
00028  * Write 64 bits in big-endian (network) byte order.
00029  *
00030  * \param value 64-bit variable
00031  * \param ptr pointer where data to be written
00032  *
00033  * \return updated pointer
00034  */
00035 NS_INLINE uint8_t *common_write_64_bit(uint64_t value, uint8_t ptr[__static 8]);
00036 
00037 /*
00038  * Common read 64-bit variable from 8-bit pointer.
00039  *
00040  * Read 64 bits in big-endian (network) byte order.
00041  *
00042  * \param data_buf pointer where data to be read
00043  *
00044  * \return 64-bit variable
00045  */
00046 NS_INLINE uint64_t common_read_64_bit(const uint8_t data_buf[__static 8]);
00047 
00048 /*
00049  * Common write 32-bit variable to 8-bit pointer.
00050  *
00051  * Write 32 bits in big-endian (network) byte order.
00052  *
00053  * \param value 32-bit variable
00054  * \param ptr pointer where data to be written
00055  *
00056  * \return updated pointer
00057  */
00058 NS_INLINE uint8_t *common_write_32_bit(uint32_t value, uint8_t ptr[__static 4]);
00059 
00060 /*
00061  * Common read 32-bit variable from 8-bit pointer.
00062  *
00063  * Read 32 bits in big-endian (network) byte order.
00064  *
00065  * \param data_buf pointer where data to be read
00066  *
00067  * \return 32-bit variable
00068  */
00069 NS_INLINE uint32_t common_read_32_bit(const uint8_t data_buf[__static 4]);
00070 
00071 /*
00072  * Common write 32-bit variable to 8-bit pointer.
00073  *
00074  * Write 32 bits in little-endian byte order.
00075  *
00076  * \param value 32-bit variable
00077  * \param ptr pointer where data to be written
00078  *
00079  * \return updated pointer
00080  */
00081 NS_INLINE uint8_t *common_write_32_bit_inverse(uint32_t value, uint8_t ptr[__static 4]);
00082 
00083 /*
00084  * Common read 32-bit variable from 8-bit pointer.
00085  *
00086  * Read 32 bits in little-endian byte order.
00087  *
00088  * \param data_buf pointer where data to be read
00089  *
00090  * \return 32-bit variable
00091  */
00092 NS_INLINE uint32_t common_read_32_bit_inverse(const uint8_t data_buf[__static 4]);
00093 
00094 /*
00095  * Common write 24-bit variable to 8-bit pointer.
00096  *
00097  * Write 24 bits in big-endian (network) byte order.
00098  *
00099  * \param value 24-bit variable
00100  * \param ptr pointer where data to be written
00101  *
00102  * \return updated pointer
00103  */
00104 NS_INLINE uint8_t *common_write_24_bit(uint_fast24_t value, uint8_t ptr[__static 3]);
00105 
00106 /*
00107  * Common read 24-bit variable from 8-bit pointer.
00108  *
00109  * Read 24 bits in big-endian (network) byte order.
00110  *
00111  * \param data_buf pointer where data to be read
00112  *
00113  * \return 24-bit variable
00114  */
00115 NS_INLINE uint_fast24_t common_read_24_bit(const uint8_t data_buf[__static 3]);
00116 
00117 /*
00118  * Common write 16-bit variable to 8-bit pointer.
00119  *
00120  * Write 16 bits in big-endian (network) byte order.
00121  *
00122  * \param value 16-bit variable
00123  * \param ptr pointer where data to be written
00124  *
00125  * \return updated pointer
00126  */
00127 NS_INLINE uint8_t *common_write_16_bit(uint16_t value, uint8_t ptr[__static 2]);
00128 
00129 /*
00130  * Common read 16-bit variable from 8-bit pointer.
00131  *
00132  * Read 16 bits in big-endian (network) byte order.
00133  *
00134  * \param data_buf pointer where data to be read
00135  *
00136  * \return 16-bit variable
00137  */
00138 NS_INLINE uint16_t common_read_16_bit(const uint8_t data_buf[__static 2]);
00139 
00140 /*
00141  * Common write 16-bit variable to 8-bit pointer.
00142  *
00143  * Write 16 bits in little-endian byte order.
00144  *
00145  * \param value 16-bit variable
00146  * \param ptr pointer where data to be written
00147  *
00148  * \return updated pointer
00149  */
00150 NS_INLINE uint8_t *common_write_16_bit_inverse(uint16_t value, uint8_t ptr[__static 2]);
00151 
00152 /*
00153  * Count bits in a byte
00154  *
00155  * \param byte byte to inspect
00156  *
00157  * \return number of 1-bits in byte
00158  */
00159 NS_INLINE uint_fast8_t common_count_bits(uint8_t byte);
00160 
00161 /*
00162  * Count leading zeros in a byte
00163  *
00164  * \param byte byte to inspect
00165  *
00166  * \return number of leading zeros in byte (0-8)
00167  */
00168 NS_INLINE uint_fast8_t common_count_leading_zeros(uint8_t byte);
00169 
00170 /*
00171  * Compare 8-bit serial numbers
00172  *
00173  * Compare two 8-bit serial numbers, according to RFC 1982 Serial Number
00174  * Arithmetic.
00175  *
00176  * \param s1 first serial number
00177  * \param s2 second serial number
00178  *
00179  * \return true if s1 > s2
00180  * \return false if s1 <= s2, or the comparison is undefined
00181  */
00182 NS_INLINE bool common_serial_number_greater_8(uint8_t s1, uint8_t s2);
00183 
00184 /*
00185  * Compare 16-bit serial numbers
00186  *
00187  * Compare two 16-bit serial numbers, according to RFC 1982 Serial Number
00188  * Arithmetic.
00189  *
00190  * \param s1 first serial number
00191  * \param s2 second serial number
00192  *
00193  * \return true if s1 > s2
00194  * \return false if s1 <= s2, or the comparison is undefined
00195  */
00196 NS_INLINE bool common_serial_number_greater_16(uint16_t s1, uint16_t s2);
00197 
00198 /*
00199  * Compare 32-bit serial numbers
00200  *
00201  * Compare two 32-bit serial numbers, according to RFC 1982 Serial Number
00202  * Arithmetic.
00203  *
00204  * \param s1 first serial number
00205  * \param s2 second serial number
00206  *
00207  * \return true if s1 > s2
00208  * \return false if s1 <= s2, or the comparison is undefined
00209  */
00210 NS_INLINE bool common_serial_number_greater_32(uint32_t s1, uint32_t s2);
00211 
00212 /*
00213  * Test a bit in an bit array.
00214  *
00215  * Check whether a particular bit is set in a bit string. The bit array
00216  * is in big-endian (network) bit order.
00217  *
00218  * \param bitset pointer to bit array
00219  * \param bit index of bit - 0 is the most significant bit of the first byte
00220  *
00221  * \return true if the bit is set
00222  */
00223 NS_INLINE bool bit_test(const uint8_t *bitset, uint_fast8_t bit);
00224 
00225 /*
00226  * Set a bit in an bit array.
00227  *
00228  * Set a bit in a bit array. The array is in big-endian (network) bit order.
00229  *
00230  * \param bitset pointer to bit array
00231  * \param bit index of bit - 0 is the most significant bit of the first byte
00232  */
00233 NS_INLINE void bit_set(uint8_t *bitset, uint_fast8_t bit);
00234 
00235 /*
00236  * Clear a bit in an bit array.
00237  *
00238  * Clear a bit in a bit array. The bit array is in big-endian (network) bit order.
00239  *
00240  * \param bitset pointer to bit array
00241  * \param bit index of bit - 0 is the most significant bit of the first byte
00242  */
00243 NS_INLINE void bit_clear(uint8_t *bitset, uint_fast8_t bit);
00244 
00245 /*
00246  * Compare two bitstrings.
00247  *
00248  * Compare two bitstrings of specified length. The bit strings are in
00249  * big-endian (network) bit order.
00250  *
00251  * \param a pointer to first string
00252  * \param b pointer to second string
00253  * \param bits number of bits to compare
00254  *
00255  * \return true if the strings compare equal
00256  */
00257 bool bitsequal(const uint8_t *a, const uint8_t *b, uint_fast8_t bits);
00258 
00259 /*
00260  * Copy a bitstring
00261  *
00262  * Copy a bitstring of specified length. The bit string is in big-endian
00263  * (network) bit order. Bits beyond the bitlength at the destination are not
00264  * modified.
00265  *
00266  * For example, copying 4 bits sets the first 4 bits of dst[0] from src[0],
00267  * the lower 4 bits of dst[0] are unmodified.
00268  *
00269  * \param dst destination pointer
00270  * \param src source pointer
00271  * \param bits number of bits to copy
00272  *
00273  * \return the value of dst
00274  */
00275 uint8_t *bitcopy(uint8_t *restrict dst, const uint8_t *restrict src, uint_fast8_t bits);
00276 
00277 /*
00278  * Copy a bitstring and pad last byte with zeros
00279  *
00280  * Copy a bitstring of specified length. The bit string is in big-endian
00281  * (network) bit order. Bits beyond the bitlength in the last destination byte are
00282  * zeroed.
00283  *
00284  * For example, copying 4 bits sets the first 4 bits of dst[0] from src[0], and
00285  * the lower 4 bits of dst[0] are set to 0.
00286  *
00287  * \param dst destination pointer
00288  * \param src source pointer
00289  * \param bits number of bits to copy
00290  *
00291  * \return the value of dst
00292  */
00293 uint8_t *bitcopy0(uint8_t *restrict dst, const uint8_t *restrict src, uint_fast8_t bits);
00294 
00295 /* Provide definitions, either for inlining, or for common_functions.c */
00296 #if defined NS_ALLOW_INLINING || defined COMMON_FUNCTIONS_FN
00297 #ifndef COMMON_FUNCTIONS_FN
00298 #define COMMON_FUNCTIONS_FN NS_INLINE
00299 #endif
00300 
00301 COMMON_FUNCTIONS_FN uint8_t *common_write_64_bit(uint64_t value, uint8_t ptr[__static 8])
00302 {
00303     *ptr++ = value >> 56;
00304     *ptr++ = value >> 48;
00305     *ptr++ = value >> 40;
00306     *ptr++ = value >> 32;
00307     *ptr++ = value >> 24;
00308     *ptr++ = value >> 16;
00309     *ptr++ = value >> 8;
00310     *ptr++ = value;
00311     return ptr;
00312 }
00313 
00314 COMMON_FUNCTIONS_FN uint64_t common_read_64_bit(const uint8_t data_buf[__static 8])
00315 {
00316     uint64_t temp_64;
00317     temp_64 = (uint64_t)(*data_buf++) << 56;
00318     temp_64 += (uint64_t)(*data_buf++) << 48;
00319     temp_64 += (uint64_t)(*data_buf++) << 40;
00320     temp_64 += (uint64_t)(*data_buf++) << 32;
00321     temp_64 += (uint64_t)(*data_buf++) << 24;
00322     temp_64 += (uint64_t)(*data_buf++) << 16;
00323     temp_64 += (uint64_t)(*data_buf++) << 8;
00324     temp_64 += *data_buf++;
00325     return temp_64;
00326 }
00327 
00328 COMMON_FUNCTIONS_FN uint8_t *common_write_32_bit(uint32_t value, uint8_t ptr[__static 4])
00329 {
00330     *ptr++ = value >> 24;
00331     *ptr++ = value >> 16;
00332     *ptr++ = value >> 8;
00333     *ptr++ = value;
00334     return ptr;
00335 }
00336 
00337 COMMON_FUNCTIONS_FN uint32_t common_read_32_bit(const uint8_t data_buf[__static 4])
00338 {
00339     uint32_t temp_32;
00340     temp_32 = (uint32_t)(*data_buf++) << 24;
00341     temp_32 += (uint32_t)(*data_buf++) << 16;
00342     temp_32 += (uint32_t)(*data_buf++) << 8;
00343     temp_32 += *data_buf++;
00344     return temp_32;
00345 }
00346 
00347 COMMON_FUNCTIONS_FN uint8_t *common_write_32_bit_inverse(uint32_t value, uint8_t ptr[__static 4])
00348 {
00349     *ptr++ = value;
00350     *ptr++ = value >> 8;
00351     *ptr++ = value >> 16;
00352     *ptr++ = value >> 24;
00353     return ptr;
00354 }
00355 
00356 COMMON_FUNCTIONS_FN uint32_t common_read_32_bit_inverse(const uint8_t data_buf[__static 4])
00357 {
00358     uint32_t temp_32;
00359     temp_32 =  *data_buf++;
00360     temp_32 += (uint32_t)(*data_buf++) << 8;
00361     temp_32 += (uint32_t)(*data_buf++) << 16;
00362     temp_32 += (uint32_t)(*data_buf++) << 24;
00363     return temp_32;
00364 }
00365 
00366 COMMON_FUNCTIONS_FN uint8_t *common_write_24_bit(uint_fast24_t value, uint8_t ptr[__static 3])
00367 {
00368     *ptr++ = value >> 16;
00369     *ptr++ = value >> 8;
00370     *ptr++ = value;
00371     return ptr;
00372 }
00373 
00374 COMMON_FUNCTIONS_FN uint_fast24_t common_read_24_bit(const uint8_t data_buf[__static 3])
00375 {
00376     uint_fast24_t temp_24;
00377     temp_24 = (uint_fast24_t)(*data_buf++) << 16;
00378     temp_24 += (uint_fast24_t)(*data_buf++) << 8;
00379     temp_24 += *data_buf++;
00380     return temp_24;
00381 }
00382 
00383 COMMON_FUNCTIONS_FN uint8_t *common_write_16_bit(uint16_t value, uint8_t ptr[__static 2])
00384 {
00385     *ptr++ = value >> 8;
00386     *ptr++ = value;
00387     return ptr;
00388 }
00389 
00390 COMMON_FUNCTIONS_FN uint16_t common_read_16_bit(const uint8_t data_buf[__static 2])
00391 {
00392     uint16_t temp_16;
00393     temp_16 = (uint16_t)(*data_buf++) << 8;
00394     temp_16 += *data_buf++;
00395     return temp_16;
00396 }
00397 
00398 COMMON_FUNCTIONS_FN uint8_t *common_write_16_bit_inverse(uint16_t value, uint8_t ptr[__static 2])
00399 {
00400     *ptr++ = value;
00401     *ptr++ = value >> 8;
00402     return ptr;
00403 }
00404 
00405 COMMON_FUNCTIONS_FN uint_fast8_t common_count_bits(uint8_t byte)
00406 {
00407     /* First step sets each bit pair to be count of bits (00,01,10) */
00408     /* [00-00 = 00, 01-00 = 01, 10-01 = 01, 11-01 = 10] */
00409     uint_fast8_t count = byte - ((byte >> 1) & 0x55);
00410     /* Add bit pairs to make each nibble contain count of bits (0-4) */
00411     count = (count & 0x33) + ((count >> 2) & 0x33);
00412     /* Final result is sum of nibbles (0-8) */
00413     count = (count >> 4) + (count & 0x0F);
00414     return count;
00415 }
00416 
00417 COMMON_FUNCTIONS_FN uint_fast8_t common_count_leading_zeros(uint8_t byte)
00418 {
00419 #ifdef  __CC_ARM
00420     return byte ? __clz((unsigned int) byte << 24) : 8;
00421 #elif defined __GNUC__
00422     return byte ? __builtin_clz((unsigned int) byte << 24) : 8;
00423 #else
00424     uint_fast8_t cnt = 0;
00425     if (byte == 0) {
00426         return 8;
00427     }
00428     if ((byte & 0xF0) == 0) {
00429         byte <<= 4;
00430         cnt += 4;
00431     }
00432     if ((byte & 0xC0) == 0) {
00433         byte <<= 2;
00434         cnt += 2;
00435     }
00436     if ((byte & 0x80) == 0) {
00437         cnt += 1;
00438     }
00439 
00440     return cnt;
00441 #endif
00442 }
00443 
00444 COMMON_FUNCTIONS_FN bool common_serial_number_greater_8(uint8_t s1, uint8_t s2)
00445 {
00446     return (s1 > s2 && s1 - s2 < UINT8_C(0x80)) || (s1 < s2 && s2 - s1 > UINT8_C(0x80));
00447 }
00448 
00449 COMMON_FUNCTIONS_FN bool common_serial_number_greater_16(uint16_t s1, uint16_t s2)
00450 {
00451     return (s1 > s2 && s1 - s2 < UINT16_C(0x8000)) || (s1 < s2 && s2 - s1 > UINT16_C(0x8000));
00452 }
00453 
00454 COMMON_FUNCTIONS_FN bool common_serial_number_greater_32(uint32_t s1, uint32_t s2)
00455 {
00456     return (s1 > s2 && s1 - s2 < UINT32_C(0x80000000)) || (s1 < s2 && s2 - s1 > UINT32_C(0x80000000));
00457 }
00458 
00459 COMMON_FUNCTIONS_FN bool bit_test(const uint8_t *bitset, uint_fast8_t bit)
00460 {
00461     return bitset[bit >> 3] & (0x80 >> (bit & 7));
00462 }
00463 
00464 COMMON_FUNCTIONS_FN void bit_set(uint8_t *bitset, uint_fast8_t bit)
00465 {
00466     bitset[bit >> 3] |= (0x80 >> (bit & 7));
00467 }
00468 
00469 COMMON_FUNCTIONS_FN void bit_clear(uint8_t *bitset, uint_fast8_t bit)
00470 {
00471     bitset[bit >> 3] &= ~(0x80 >> (bit & 7));
00472 }
00473 
00474 #endif /* defined NS_ALLOW_INLINING || defined COMMON_FUNCTIONS_FN */
00475 
00476 #ifdef __cplusplus
00477 }
00478 #endif
00479 #endif /*__COMMON_FUNCTIONS_H_*/