Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ns_buffer.h Source File

ns_buffer.h

00001 /*
00002  * Copyright (c) 2008-2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 /**
00018  *
00019  * \file buffer.h
00020  * \brief buffer type definitions.
00021  *
00022  *  nanoStack: buffer carrier structure.
00023  *
00024  */
00025 
00026 
00027 #ifndef _NS_BUFFER_H
00028 #define _NS_BUFFER_H
00029 
00030 #ifndef _NANOSTACK_SOURCE_CONFIG_H
00031 #error "Why haven't you included config.h before all other headers?"
00032 #endif
00033 
00034 #include "ns_types.h"
00035 #include "Core/include/address.h"
00036 #include "NWK_INTERFACE/Include/protocol_abstract.h"
00037 #include "ns_list.h"
00038 #include "ipv6_stack/ipv6_routing_table.h"
00039 
00040 #ifndef BUFFERS_MAX
00041 #define BUFFERS_MAX 10
00042 #endif
00043 
00044 #ifndef BUFFER_SIZE
00045 #define BUFFER_SIZE 128
00046 #endif
00047 
00048 #ifndef ACK_BUFFER_SIZE
00049 #define ACK_BUFFER_SIZE 5
00050 #endif
00051 
00052 /*
00053  * headroom given to buffers by default.
00054  * if buffer value is below 107 bytes then remaining value is allocated as headroom.
00055  */
00056 #define BUFFER_DEFAULT_HEADROOM     40
00057 
00058 /*
00059  * default minimum size for buffers.
00060  * if size is below this then extra space is allocated as headroom.
00061  */
00062 #define BUFFER_DEFAULT_MIN_SIZE     127
00063 
00064 /* The new, really-configurable default hop limit (RFC 4861 CurHopLimit);
00065  * this can be overridden at compile-time, or changed on a per-socket basis
00066  * with socket_setsockopt. It can also be overridden by Router Advertisements.
00067  */
00068 #ifndef UNICAST_HOP_LIMIT_DEFAULT
00069 #define UNICAST_HOP_LIMIT_DEFAULT 64
00070 #endif
00071 
00072 typedef enum {
00073     B_SECURITY_KEY_ID_MODE_DEFAULT = 0,
00074     B_SECURITY_KEY_ID_2,
00075     B_SECURITY_KEY_ID_IMPLICIT,
00076 } buffer_security_key_id_mode;
00077 
00078 /** link-specific buffer data */
00079 typedef struct buffer_link_ieee802_15_4 {
00080     bool fc_security: 1;            // Security Enabled flag from frame control
00081     bool ack_fc_frame_pending: 1;   // Frame Pending flag that was transmitted in Ack for this frame (used in Data Request)
00082     bool useDefaultPanId: 1;       // Transmit to broadcast PAN ID (0xffff)
00083     bool indirectTxProcess: 1;
00084     bool requestAck: 1;
00085     bool rf_channel_switch: 1;
00086     buffer_security_key_id_mode key_id_mode;
00087     uint8_t selected_channel;
00088     uint32_t indirectTTL;
00089     uint16_t srcPanId;
00090     uint16_t dstPanId;
00091 } buffer_link_ieee802_15_4_t;
00092 
00093 typedef union buffer_link_info {
00094     buffer_link_ieee802_15_4_t ieee802_15_4;
00095 } buffer_link_info_t;
00096 
00097 /* Flags to indicate presence of extension headers in _current_ IP layer */
00098 /* (As opposed to, eg, rpl_option, which is any-layer metadata) */
00099 /* Placed as a non-bitfield in ip_extflags so that IP core can bulk clear */
00100 #define IPEXT_HBH_RPL           0x01    /*!< RPL hop-by-hop option */
00101 #define IPEXT_SRH_RPL           0x02    /*!< RPL Routing Header */
00102 #define IPEXT_HBH_ROUTER_ALERT  0x04    /*!< Router alert */
00103 #define IPEXT_HBH_MPL           0x08    /*!< MPL hop-by-hop option */
00104 #define IPEXT_HBH_MPL_UNFILLED  0x10    /*!< MPL option is unfilled */
00105 #define IPEXT_FRAGMENT          0x20    /*!< Fragment header present - if set on entry to IP parsing this was reassembled packet */
00106 
00107 /** buffer option fields */
00108 typedef struct buffer_options {
00109     uint8_t lqi ;                        /*!< LQI from RF */
00110     int8_t  dbm ;                        /*!< Signal level */
00111     uint8_t hop_limit ;                  /*!< IPv6 hop limit */
00112     uint8_t type ;                       /*!< ICMP type, IP next header, MAC frame type... */
00113     uint8_t code ;                       /*!< ICMP code, TCP flags, MAC ack request... */
00114     uint8_t ip_extflags ;                /*!< IPv6 extension header flags */
00115     bool    ll_security_bypass_tx : 1;   /*!< Tx without link-layer security */
00116     bool    ll_sec_bypass_frag_deny : 1; /*!< Deny ll_security_bypass_tx usage in fragmented packets */
00117     bool    ll_security_bypass_rx : 1;   /*!< Was received without link-layer security, when security was enabled */
00118     bool    ll_broadcast_tx : 1;         /*!< Tx as link-layer broadcast (set to override multicast-as-unicast) */
00119     bool    ll_broadcast_rx : 1;         /*!< Was received as link-layer broadcast */
00120     bool    ll_multicast_rx : 1;         /*!< Was received as link-layer multicast */
00121     bool    ll_not_ours_rx : 1;          /*!< Not addressed to us at link layer - snooped */
00122     bool    lowpan_mesh_rx : 1;          /*!< Had a 6LoWPAN mesh header */
00123     bool    tunnelled :1;                /*!< We tunnelled it as part of (RPL?) routing */
00124     bool    need_predecessor :1;         /*!< Used as an indicator that predecessor address needed */
00125     bool    multicast_loop :1;           /*!< We want loopback if we're a group member (TX), or this IS the loopback if RX */
00126     bool    mpl_permitted :1;            /*!< MPL will be used if enabled on interface and scope >=3 */
00127 #ifndef NO_IP_FRAGMENT_TX
00128     bool    ipv6_dontfrag :1;            /*!< Don't IPv6 fragment (RFC 3542) */
00129 #endif
00130 #ifndef NO_IPV6_PMTUD
00131     signed  ipv6_use_min_mtu :2;         /*!< Use minimum 1280-byte MTU (RFC 3542) - three settings +1, 0, -1 */
00132 #endif
00133     uint8_t traffic_class ;              /*!< Traffic class */
00134     int_least24_t flow_label ;           /*!< IPv6 flow label; -1 means unspecified (may auto-generate); -2 means auto-generate required */
00135 } buffer_options_t;
00136 
00137 #define IPV6_FLOW_UNSPECIFIED (-1)
00138 #define IPV6_FLOW_AUTOGENERATE (-2)
00139 
00140 typedef enum {
00141     B_TO_NONE           = 0x0000,
00142     B_TO_MAC            = 0x0001,
00143     B_TO_IPV6           = 0x0002,
00144     B_TO_UDP            = 0x0003,
00145     B_TO_ICMP           = 0x0004,
00146     B_TO_NAP            = 0x0005,
00147     B_TO_FRAGMENTATION  = 0x0006,
00148     B_TO_TCP            = 0x0007,
00149     B_TO_MLME           = 0x0008,
00150     B_TO_IPV6_TXRX      = 0x0009,
00151     B_TO_DNSSD          = 0x000A,
00152     B_TO_IPV6_FWD       = 0x000B,
00153     B_TO_TLS            = 0x000C,
00154     B_TO_MESH_ROUTING   = 0x000D,
00155     B_TO_PHY            = 0x000E,
00156     B_TO_APP            = 0x000F,
00157     B_TO_MASK           = 0x000F,
00158     B_FROM_NONE         = 0x0000,
00159     B_FROM_MAC          = 0x0010,
00160     B_FROM_IPV6         = 0x0020,
00161     B_FROM_UDP          = 0x0030,
00162     B_FROM_ICMP         = 0x0040,
00163     B_FROM_NAP          = 0x0050,
00164     B_FROM_FRAGMENTATION = 0x0060,
00165     B_FROM_TCP          = 0x0070,
00166     B_FROM_MLME         = 0x0080,
00167     B_FROM_IPV6_TXRX    = 0x0090,
00168     B_FROM_DNSSD        = 0x00A0,
00169     B_FROM_IPV6_FWD     = 0x00B0,
00170     B_FROM_LOCAL        = 0x00C0,
00171     B_FROM_MESH_ROUTING = 0x00D0,
00172     B_FROM_APP          = 0x00F0,
00173     B_FROM_MASK         = 0x00F0,
00174     B_DIR_DOWN          = 0x0000,
00175     B_DIR_UP            = 0x0800,
00176     B_DIR_MASK          = 0x0800,
00177 } buffer_info_t;
00178 
00179 typedef enum {
00180     QOS_NORMAL = 0,
00181     QOS_HIGH = 1,
00182     QOS_MAC_BEACON = 2
00183 } buffer_priority_t;
00184 
00185 #define B_TO_MAC_MLME_MASK (B_DIR_MASK + B_FROM_MASK + B_TO_MASK )
00186 #define B_TO_MAC_FROM_MAC (B_DIR_UP + B_FROM_MAC + B_TO_MAC )
00187 
00188 struct socket;
00189 
00190 typedef struct buffer_routing_info {
00191     ipv6_route_info_t   route_info;
00192     const uint8_t       *ip_dest;
00193     uint8_t             ref_count;
00194 } buffer_routing_info_t;
00195 
00196 /** buffer structure */
00197 /* If adding pointers to this, ensure buffer_free and buffer_copy_metadata are informed */
00198 typedef struct buffer {
00199     ns_list_link_t      link;
00200     sockaddr_t          dst_sa ;                 /*!< Destination sockaddr */
00201     sockaddr_t          src_sa ;                 /*!< Source sockaddr */
00202     sockaddr_t          *predecessor ;           /*!< Predecessor - used by RPL */
00203     protocol_interface_info_entry_t *interface ; /*!< Pointer to interface */
00204     struct socket       *socket ;                /*!< Indicate is data came trough socket */
00205     buffer_info_t       info ;                   /*!< Protocol information */
00206     uint8_t             seq ;                    /*!< Packet MAC header sequence number */
00207     uint16_t            buf_ptr ;                /*!< Current pointer in the buffer */
00208     uint16_t            buf_end ;                /*!< End pointer in the buffer */
00209     uint16_t            size ;                   /*!< Buffer size */
00210     uint16_t            offset ;                 /*!< Offset indicator (used in some upward paths) */
00211     //uint16_t            queue_timer;
00212     uint16_t            payload_length ;         /*!< Socket payload length */
00213     uint8_t             IPHC_NH;
00214     uint8_t             rpl_instance;
00215     bool                rpl_instance_known:1;
00216     bool                ip_routed_up:1;
00217     uint8_t             rpl_flag_error;
00218     //uint8_t             bc_sending_superframe;  /*FHSS uses this randomly chosen superframe to send this packet (if broadcast)*/
00219     //uint8_t             fhss_channel_retries_left;
00220     //uint8_t             ip_transmission_prev_seq;  /*!< XXX: this stores the data packet seq. number, which is needed for re-transmission. */
00221     //uint16_t            bad_channel;
00222     void                *session_ptr;
00223     uint8_t             *rpl_option;
00224     buffer_priority_t   priority;
00225     buffer_link_info_t  link_specific;
00226     uint16_t            mpl_option_data_offset;
00227     uint8_t             trickle_data_len;
00228     uint8_t             trickle_data_field[4];
00229     buffer_options_t    options ;                /*!< Additional signal info etc */
00230     buffer_routing_info_t *route;               /* A pointer last to try to get neat alignment for data */
00231     uint8_t             buf [];                  /*!< Trailing buffer data */
00232  } buffer_t;
00233 
00234 typedef NS_LIST_HEAD (buffer_t, link ) buffer_list_t;
00235 NS_STATIC_ASSERT(offsetof(buffer_t, link ) == 0, "Some use NS_LIST_HEAD_INCOMPLETE")
00236 
00237 #define SYST_WDCLEAR    0xff
00238 #define SYST_TX_TO      0xfe
00239 
00240 /** Macro to check buffer corruptions with debug flagging. */
00241 #ifdef EXTRA_CONSISTENCY_CHECKS
00242 #define buffer_data_pointer_after_adjustment(x) buffer_corrupt_check(x)
00243 #define _buffer_corruption_check(x) buffer_corrupt_check(x)
00244 #else
00245 #define buffer_data_pointer_after_adjustment(x) buffer_data_pointer(x)
00246 #define _buffer_corruption_check(x)
00247 #endif
00248 
00249 
00250 
00251 /** Allocate memory for a buffer_t from the heap */
00252 extern buffer_t *buffer_get(uint16_t size);
00253 
00254 /** Allocate memory for a buffer_t from the heap, with more detailed sizing */
00255 extern buffer_t *buffer_get_specific(uint16_t headroom, uint16_t size, uint16_t minspace);
00256 
00257 /** Allocate memory for a minimal buffer (no headroom or extra space) */
00258 extern buffer_t *buffer_get_minimal(uint16_t size);
00259 
00260 /** Free a buffer from the heap, and return NULL */
00261 extern buffer_t *buffer_free(buffer_t *buf);
00262 
00263 /** Free a linked buffer list from the heap */
00264 void buffer_free_list(buffer_list_t *list);
00265 
00266 /** Free any routing info in the buffer, returning the buffer pointer */
00267 extern buffer_t *buffer_free_route(buffer_t *buf);
00268 
00269 /** Compute IPv6 checksum for buffer data + IPv6 pseudo-header */
00270 uint16_t buffer_ipv6_fcf(const buffer_t *buf, uint8_t next_header);
00271 
00272 /** Check for corrupt buffers should only be used when testing.*/
00273 #ifdef EXTRA_CONSISTENCY_CHECKS
00274 uint8_t *buffer_corrupt_check(buffer_t *buf);
00275 #else
00276 #define buffer_corrupt_check(b) ((void)0)
00277 #endif
00278 /** Allocate header space in buffer */
00279 extern buffer_t *buffer_headroom(buffer_t *buf, uint16_t size);
00280 
00281 /** Add buffer at the end of current buffer.
00282  * Modifies all pointer and indexes correctly.
00283  *
00284  */
00285 void buffer_data_add(buffer_t *buf, const uint8_t *data_ptr, uint16_t data_len);
00286 
00287 /** create new buffer and copy all fields and data
00288  *
00289  *  Notice that data can have different headroom reserved. so the actual data might
00290  *  be located in different part of buffer than in original.*/
00291 buffer_t *buffer_clone(buffer_t *buf);
00292 
00293 /** prepare an input buffer to become a response - clear unwanted metadata */
00294 buffer_t *buffer_turnaround(buffer_t *buf);
00295 
00296 /** copy metadata from src to dst - see definition for more info */
00297 void buffer_copy_metadata(buffer_t *dst, buffer_t *src, bool non_clonable_to_dst);
00298 
00299 /** remember the predecessor address, if needed */
00300 void buffer_note_predecessor(buffer_t *buf, const sockaddr_t *addr);
00301 
00302 /** set the socket pointer in the buffer (dealing with reference counting) */
00303 struct socket *buffer_socket_set(buffer_t *buf, struct socket *socket);
00304 
00305 /** set buffer_priority */
00306 #define buffer_priority_set(x,z)  ((x)->priority = (z))
00307 
00308 /** get pointer to data*/
00309 #define buffer_data_pointer(x)  (&(x)->buf[(x)->buf_ptr])
00310 
00311 /** get pointer to end of data*/
00312 #define buffer_data_end(x)  (&(x)->buf[(x)->buf_end])
00313 
00314 /** get pointer to data*/
00315 #define buffer_data_pointer_set(x,new_start_ptr)  ((x)->buf_ptr = (new_start_ptr) - (x)->buf)
00316 
00317 /** get pointer to end of data*/
00318 #define buffer_data_end_set(x,new_end_ptr)     do {\
00319         ((x)->buf_end = (new_end_ptr) - (x)->buf);\
00320         _buffer_corruption_check(x);\
00321         } while(0)
00322 
00323 /** get data length*/
00324 #define buffer_data_length(x)  (int16_t)(x->buf_end - x->buf_ptr)
00325 
00326 /** get data length Set*/
00327 #define buffer_data_length_set(x,z)  ((x)->buf_end = (x)->buf_ptr + (z))
00328 
00329 /** free data bytes in buffer */
00330 #define buffer_data_free_length(x)  ((x)->size - (x)->buf_end)
00331 
00332 /** Clears buffer to initial value
00333  * uint8_t *buffer_data_clear(buffer_t *x)
00334  * */
00335 #define buffer_data_clear(x) ((x)->buf_ptr = (x)->buf_end = BUFFER_DEFAULT_HEADROOM, buffer_data_pointer_after_adjustment(x))
00336 
00337 /** Clears buffer and sets the headroom */
00338 #define buffer_data_clear_with_headroom(x,z)  ((x)->buf_ptr = (x)->buf_end = (z))
00339 
00340 /** Removes z amount of bytes from the begining of buffer
00341  * uint8_t *buffer_data_strip_header(buffer_t *x, uint16_t z)
00342  * */
00343 static inline uint8_t *buffer_data_strip_header(buffer_t *x, uint16_t z)
00344 {
00345     x->buf_ptr  += z;
00346     return buffer_data_pointer_after_adjustment(x);
00347 }
00348 
00349 /** Adds z amount of bytes to the begining of buffer check if this is allowed using buffer_headroom method.
00350  * uint8_t *buffer_data_reserve_header(buffer_t *x, uint16_t z)
00351  * */
00352 static inline uint8_t *buffer_data_reserve_header(buffer_t *x, uint16_t z)
00353 {
00354     x->buf_ptr  -= z;
00355     return buffer_data_pointer_after_adjustment(x);
00356 }
00357 
00358 /** append 1 byte to data*/
00359 #define buffer_push_uint8(x, z)   do {\
00360                                     (x)->buf[x->buf_end++] = (z);\
00361                                     _buffer_corruption_check(x);\
00362                                     } while(0)
00363 
00364 /** append 2 byte to data*/
00365 #define buffer_push_uint16(x, z)  do {\
00366                                     (x)->buf[x->buf_end++] = (uint8_t)( (z) >> 8);\
00367                                     (x)->buf[x->buf_end++] = (uint8_t)  (z);\
00368                                     _buffer_corruption_check(x);\
00369                                     } while(0)
00370 
00371 
00372 /** append 4 byte to data*/
00373 #define buffer_push_uint32(x, z)    do {\
00374                                     (x)->buf[(x)->buf_end++] = (uint8_t) ((z) >> 24);\
00375                                     (x)->buf[(x)->buf_end++] = (uint8_t) ((z) >> 16);\
00376                                     (x)->buf[(x)->buf_end++] = (uint8_t) ((z) >> 8);\
00377                                     (x)->buf[(x)->buf_end++] = (uint8_t) ((z));\
00378                                     _buffer_corruption_check(x);\
00379                                     } while(0)
00380 
00381 /** append 2 byte to data on little endian order or inverse*/
00382 #define buffer_push_uint16_i(x, z)  do {\
00383                                     (x)->buf[(x)->buf_end++] = (uint8_t)(z);\
00384                                     (x)->buf[(x)->buf_end++] = (uint8_t)((z) >> 8);\
00385                                     _buffer_corruption_check(x);\
00386                                     } while(0)
00387 
00388 /** read 1 byte out of the buffer*/
00389 #define buffer_pull_uint8(x)  (x)->buf[(x)->buf_ptr++]
00390 
00391 /** read 2 byte out of the buffer*/
00392 #define buffer_pull_uint16(x) \
00393     ((x)->buf_ptr += 2,\
00394     ((uint16_t)(x)->buf[(x)->buf_ptr - 2] << 8 ) |\
00395      (uint16_t)(x)->buf[(x)->buf_ptr - 1])
00396 
00397 /** read 4 byte out of the buffer*/
00398 #define buffer_pull_uint32(x) \
00399     ((x)->buf_ptr += 4,\
00400     ((uint32_t)(x)->buf[(x)->buf_ptr - 4] << 24 ) |\
00401     ((uint32_t)(x)->buf[(x)->buf_ptr - 3] << 16 ) |\
00402     ((uint32_t)(x)->buf[(x)->buf_ptr - 2] << 8 ) |\
00403      (uint32_t)(x)->buf[(x)->buf_ptr - 1])
00404 
00405 
00406 #endif