Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Tue Jul 12 2022 12:45:37 by
