Import Mbed OS hard-float snapshot
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2010-2019, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* \file ns_address_internal.h
|
||||
* \brief address type definitions.
|
||||
*
|
||||
* nanoStack: supported address types and associated data structures.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NS_ADDRESS_H
|
||||
#define _NS_ADDRESS_H
|
||||
|
||||
#include "ns_list.h"
|
||||
|
||||
#define ADDR_MULTICAST_MAX 3
|
||||
#define ADDR_SIZE 16
|
||||
#define PAN_ID_LEN 2
|
||||
/** Address types */
|
||||
typedef enum {
|
||||
ADDR_NONE = 0, /*!< No address */
|
||||
ADDR_802_15_4_SHORT = 2, /*!< 16-bit PAN with 16-bit 802.15.4 address */
|
||||
ADDR_802_15_4_LONG = 3, /*!< 16-bit PAN with 64-bit 802.15.4 address */
|
||||
ADDR_IPV6 = 4, /*!< 128 bit IPv6 address containing both Prefix (high 64 bits) and Interface identifier (low 64 bits) */
|
||||
//ADDR_DATA=5, /*!< Attribute-based data-centric query */
|
||||
ADDR_BROADCAST = 6, /*!< Broadcast (inc RFC 4944 multicast) address (obsolescent) */
|
||||
ADDR_EUI_48 = 7, /*!< 48-bit Extended Unique Identifier (eg Ethernet) */
|
||||
} addrtype_t; /*!< Address types in the stack */
|
||||
|
||||
/** Address field */
|
||||
typedef uint8_t address_t[ADDR_SIZE];
|
||||
|
||||
/** Address structure */
|
||||
typedef struct ns_sockaddr {
|
||||
addrtype_t addr_type; /*!< Type of address */
|
||||
address_t address; /*!< Source or destination address */
|
||||
uint16_t port; /*!< Source or destination port */
|
||||
} sockaddr_t;
|
||||
|
||||
struct protocol_interface_info_entry;
|
||||
struct if_address_entry;
|
||||
struct socket;
|
||||
|
||||
typedef struct addr_multicast_fwd {
|
||||
uint8_t group[16];
|
||||
ns_list_link_t link;
|
||||
} addr_multicast_fwd_t;
|
||||
|
||||
typedef enum if_address_source_e {
|
||||
ADDR_SOURCE_UNKNOWN,
|
||||
ADDR_SOURCE_SLAAC,
|
||||
ADDR_SOURCE_DHCP,
|
||||
ADDR_SOURCE_STATIC,
|
||||
ADDR_SOURCE_THREAD_ALOC,
|
||||
ADDR_SOURCE_THREAD_DOMAIN
|
||||
} if_address_source_t;
|
||||
|
||||
typedef enum if_address_callback_e {
|
||||
ADDR_CALLBACK_DAD_COMPLETE, // Duplicate Address Detection complete - address now valid
|
||||
ADDR_CALLBACK_DAD_FAILED, // Duplicate Address Detection failed - address is a duplicate, about to be deleted
|
||||
ADDR_CALLBACK_PARENT_FULL, // Neighbour Cache full at parent or 6LBR - couldn't register address, about to be deleted
|
||||
ADDR_CALLBACK_TIMER, // state_timer reached 0
|
||||
ADDR_CALLBACK_DEPRECATED, // preferred lifetime reached 0
|
||||
ADDR_CALLBACK_INVALIDATED, // valid lifetime reached 0 - about to be deleted, unless callback increases lifetime
|
||||
ADDR_CALLBACK_REFRESHED, // valid lifetime updated (up or down, aside from usual expiry)
|
||||
ADDR_CALLBACK_DELETED, // address is deleted (no longer on interface at point of call)
|
||||
} if_address_callback_t;
|
||||
|
||||
typedef void if_address_callback_fn(struct protocol_interface_info_entry *interface, struct if_address_entry *addr, if_address_callback_t reason);
|
||||
typedef void if_address_notification_fn(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason);
|
||||
|
||||
typedef struct if_address_entry {
|
||||
uint8_t address[16]; // IPv6 (or IPv4-mapped IPv6 in future)
|
||||
uint8_t prefix_len; // length of prefix part
|
||||
uint32_t valid_lifetime; // seconds remaining; 0xffffffff = infinite
|
||||
uint32_t preferred_lifetime; // seconds remaining; 0 if deprecated, 0xffffffff = infinite
|
||||
uint32_t state_timer; // ticks to state change - used by DAD, then can be used by protocol
|
||||
uint8_t count; // general count field - used by DAD, then can be used by protocol
|
||||
bool temporary: 1; // RFC 4941 temporary address
|
||||
bool tentative: 1; // Tentative address (Duplicate Address Detection running)
|
||||
bool group_added: 1; // Solicited-Node group added
|
||||
if_address_source_t source; //
|
||||
if_address_callback_fn *cb; // Address protocol callback function
|
||||
void *data; // Address protocol data
|
||||
ns_list_link_t link;
|
||||
} if_address_entry_t;
|
||||
|
||||
typedef NS_LIST_HEAD(if_address_entry_t, link) if_address_list_t;
|
||||
|
||||
/* Groups we are a member of on an interface */
|
||||
typedef struct if_group_entry {
|
||||
uint8_t group[16];
|
||||
bool mld_last_reporter: 1;
|
||||
uint16_t mld_timer; // Or used by MLD alternative, eg Thread registration
|
||||
uint16_t ref_count;
|
||||
ns_list_link_t link;
|
||||
} if_group_entry_t;
|
||||
|
||||
typedef NS_LIST_HEAD(if_group_entry_t, link) if_group_list_t;
|
||||
|
||||
/* Groups we will forward onto an interface */
|
||||
typedef struct if_group_fwd_entry {
|
||||
uint8_t group[16];
|
||||
uint32_t lifetime;
|
||||
ns_list_link_t link;
|
||||
} if_group_fwd_entry_t;
|
||||
|
||||
typedef NS_LIST_HEAD(if_group_fwd_entry_t, link) if_group_fwd_list_t;
|
||||
|
||||
extern uint32_t addr_preferences_default; // default SOCKET_IPV6_ADDR_PREFERENCES
|
||||
|
||||
extern const uint8_t ADDR_SHORT_ADR_SUFFIC[6]; // 0000:00ff:fe00
|
||||
extern const uint8_t ADDR_LINK_LOCAL_PREFIX[8]; // fe80::/64
|
||||
extern const uint8_t ADDR_MULTICAST_SOLICITED[13]; // ff02::1:ffxx:xxxx/104
|
||||
extern const uint8_t ADDR_IF_LOCAL_ALL_NODES[16]; // ff01::1
|
||||
extern const uint8_t ADDR_IF_LOCAL_ALL_ROUTERS[16]; // ff01::2
|
||||
extern const uint8_t ADDR_LINK_LOCAL_ALL_NODES[16]; // ff02::1
|
||||
extern const uint8_t ADDR_LINK_LOCAL_ALL_ROUTERS[16]; // ff02::2
|
||||
extern const uint8_t ADDR_LINK_LOCAL_ALL_MLDV2_ROUTERS[16]; // ff02::16
|
||||
extern const uint8_t ADDR_LINK_LOCAL_MDNS[16]; // ff02::fb
|
||||
extern const uint8_t ADDR_REALM_LOCAL_ALL_NODES[16]; // ff03::1
|
||||
extern const uint8_t ADDR_REALM_LOCAL_ALL_ROUTERS[16]; // ff03::2
|
||||
extern const uint8_t ADDR_SITE_LOCAL_ALL_ROUTERS[16]; // ff05::2
|
||||
extern const uint8_t ADDR_ALL_MPL_FORWARDERS[16]; // ff03::fc
|
||||
extern const uint8_t ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS[16]; // ff02::1:2
|
||||
extern const uint8_t ADDR_LOOPBACK[16]; // ::1
|
||||
extern const uint8_t ADDR_UNSPECIFIED[16]; // ::
|
||||
|
||||
/* Don't bother having another 8 zero bytes for this - reuse ADDR_UNSPECIFIED */
|
||||
#define ADDR_EUI64_ZERO ADDR_UNSPECIFIED
|
||||
|
||||
/** Functions provided by address.c */
|
||||
uint8_t addr_check_broadcast(const address_t addr, addrtype_t addr_type);
|
||||
|
||||
void address_module_init(void);
|
||||
void addr_fast_timer(struct protocol_interface_info_entry *cur, uint_fast16_t ticks);
|
||||
void addr_slow_timer(struct protocol_interface_info_entry *cur, uint_fast16_t seconds);
|
||||
struct if_address_entry *addr_add(struct protocol_interface_info_entry *cur, const uint8_t address[__static 16], uint_fast8_t prefix_len, if_address_source_t source, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad);
|
||||
int_fast8_t addr_delete(struct protocol_interface_info_entry *cur, const uint8_t address[__static 16]);
|
||||
int_fast8_t addr_deprecate(struct protocol_interface_info_entry *cur, const uint8_t address[__static 16]);
|
||||
void addr_delete_matching(struct protocol_interface_info_entry *cur, const uint8_t *prefix, uint8_t prefix_len, if_address_source_t source);
|
||||
void addr_delete_entry(struct protocol_interface_info_entry *cur, if_address_entry_t *addr);
|
||||
void addr_set_non_preferred(struct protocol_interface_info_entry *cur, if_address_source_t source);
|
||||
void addr_max_slaac_entries_set(struct protocol_interface_info_entry *cur, uint8_t max_slaac_entries);
|
||||
|
||||
void addr_notification_register(if_address_notification_fn fn);
|
||||
void addr_cb(struct protocol_interface_info_entry *interface, if_address_entry_t *addr, if_address_callback_t reason);
|
||||
void addr_set_valid_lifetime(struct protocol_interface_info_entry *interface, if_address_entry_t *entry, uint32_t valid_lifetime);
|
||||
void addr_set_preferred_lifetime(struct protocol_interface_info_entry *interface, if_address_entry_t *entry, uint32_t preferred_lifetime);
|
||||
|
||||
void addr_lifetime_update(struct protocol_interface_info_entry *interface, if_address_entry_t *address, uint32_t valid_lifetime, uint32_t preferred_lifetime, uint32_t threshold);
|
||||
|
||||
int_fast8_t addr_policy_table_add_entry(const uint8_t *prefix, uint8_t len, uint8_t precedence, uint8_t label);
|
||||
int_fast8_t addr_policy_table_delete_entry(const uint8_t *prefix, uint8_t len);
|
||||
uint8_t addr_len_from_type(addrtype_t addr_type);
|
||||
char *trace_sockaddr(const sockaddr_t *addr, bool panid_prefix);
|
||||
|
||||
const uint8_t *addr_select_source(struct protocol_interface_info_entry *interface, const uint8_t dest[__static 16], uint32_t addr_preferences);
|
||||
const uint8_t *addr_select_with_prefix(struct protocol_interface_info_entry *cur, const uint8_t *prefix, uint8_t prefix_len, uint32_t addr_preferences);
|
||||
int8_t addr_interface_select_source(struct protocol_interface_info_entry *cur, uint8_t *src_ptr, const uint8_t *dest, uint32_t addr_preferences);
|
||||
struct if_address_entry *addr_get_entry(const struct protocol_interface_info_entry *interface, const uint8_t addr[__static 16]);
|
||||
bool addr_is_assigned_to_interface(const struct protocol_interface_info_entry *interface, const uint8_t addr[__static 16]);
|
||||
bool addr_is_tentative_for_interface(const struct protocol_interface_info_entry *interface, const uint8_t addr[__static 16]);
|
||||
|
||||
void addr_policy_remove_by_label(uint8_t label);
|
||||
|
||||
void addr_duplicate_detected(struct protocol_interface_info_entry *interface, const uint8_t addr[__static 16]);
|
||||
|
||||
struct if_group_entry *addr_add_group(struct protocol_interface_info_entry *interface, const uint8_t group[__static 16]);
|
||||
void addr_remove_group(struct protocol_interface_info_entry *interface, const uint8_t group[__static 16]);
|
||||
bool addr_am_group_member_on_interface(const struct protocol_interface_info_entry *interface, const uint8_t group[__static 16]);
|
||||
struct if_group_entry *addr_get_group_entry(const struct protocol_interface_info_entry *interface, const uint8_t group[__static 16]);
|
||||
void addr_delete_group(struct protocol_interface_info_entry *interface, const uint8_t group[__static 16]);
|
||||
void addr_delete_group_entry(struct protocol_interface_info_entry *interface, if_group_entry_t *entry);
|
||||
|
||||
void addr_add_router_groups(struct protocol_interface_info_entry *interface);
|
||||
|
||||
bool addr_multicast_fwd_add(struct protocol_interface_info_entry *interface, const uint8_t group[16], uint32_t lifetime);
|
||||
bool addr_multicast_fwd_remove(struct protocol_interface_info_entry *interface, const uint8_t group[16]);
|
||||
bool addr_multicast_fwd_check(struct protocol_interface_info_entry *interface, const uint8_t group[16]);
|
||||
void addr_multicast_fwd_adjust_upstream_full(struct protocol_interface_info_entry *upstream, bool add);
|
||||
void addr_multicast_fwd_set_forwarding(struct protocol_interface_info_entry *interface, bool enable);
|
||||
|
||||
#define addr_is_ipv6_unspecified(addr) (memcmp(addr, ADDR_UNSPECIFIED, 16) == 0)
|
||||
#define addr_is_ipv6_loopback(addr) (memcmp(addr, ADDR_LOOPBACK, 16) == 0)
|
||||
bool addr_is_ipv6_link_local(const uint8_t addr[__static 16]);
|
||||
#define addr_is_ipv6_multicast(addr) (*(addr) == 0xFF)
|
||||
uint_fast8_t addr_ipv6_scope(const uint8_t addr[__static 16], const struct protocol_interface_info_entry *interface);
|
||||
#define addr_ipv6_multicast_scope(addr) ((addr)[1] & 0x0F)
|
||||
bool addr_ipv6_equal(const uint8_t a[__static 16], const uint8_t b[__static 16]);
|
||||
bool addr_iid_matches_eui64(const uint8_t iid[__static 8], const uint8_t eui64[__static 8]);
|
||||
bool addr_iid_matches_lowpan_short(const uint8_t iid[__static 8], uint16_t short_addr);
|
||||
bool addr_iid_reserved(const uint8_t iid[__static 8]);
|
||||
int_fast8_t addr_opaque_iid_key_set(const void *secret_key, uint8_t key_len);
|
||||
int_fast8_t addr_opaque_initial_iid_set(const void *iid);
|
||||
bool addr_opaque_iid_key_is_set(void);
|
||||
void addr_generate_opaque_iid(struct protocol_interface_info_entry *cur, uint8_t addr[__static 16]);
|
||||
bool addr_iid_from_outer(uint8_t iid_out[__static 8], const sockaddr_t *addr_in);
|
||||
|
||||
uint8_t *addr_ipv6_write_from_lowpan_short(uint8_t dst[__static 16], const uint8_t prefix[__static 8], uint16_t short_addr);
|
||||
|
||||
void memswap(uint8_t *restrict a, uint8_t *restrict b, uint_fast8_t len);
|
||||
|
||||
int addr_interface_set_ll64(struct protocol_interface_info_entry *cur, if_address_callback_fn *cb);
|
||||
bool addr_interface_all_address_ready(struct protocol_interface_info_entry *cur);
|
||||
|
||||
/* address_type 0 means "any" address - we return short by preference */
|
||||
/* address_type 1 means long address - we ignore short addresses */
|
||||
int8_t addr_interface_get_ll_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, uint8_t address_type);
|
||||
int8_t addr_interface_gp_prefix_compare(struct protocol_interface_info_entry *cur, const uint8_t *prefix);
|
||||
int8_t addr_interface_address_compare(struct protocol_interface_info_entry *cur, const uint8_t *addr);
|
||||
#endif /*_NS_ADDRESS_H*/
|
||||
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2019, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* \file buffer.h
|
||||
* \brief buffer type definitions.
|
||||
*
|
||||
* nanoStack: buffer carrier structure.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NS_BUFFER_H
|
||||
#define _NS_BUFFER_H
|
||||
|
||||
#ifndef _NANOSTACK_SOURCE_CONFIG_H
|
||||
#error "Why haven't you included config.h before all other headers?"
|
||||
#endif
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "Core/include/ns_address_internal.h"
|
||||
#include "NWK_INTERFACE/Include/protocol_abstract.h"
|
||||
#include "ns_list.h"
|
||||
#include "ipv6_stack/ipv6_routing_table.h"
|
||||
|
||||
#ifndef BUFFERS_MAX
|
||||
#define BUFFERS_MAX 10
|
||||
#endif
|
||||
|
||||
#ifndef BUFFER_SIZE
|
||||
#define BUFFER_SIZE 128
|
||||
#endif
|
||||
|
||||
#ifndef ACK_BUFFER_SIZE
|
||||
#define ACK_BUFFER_SIZE 5
|
||||
#endif
|
||||
|
||||
/*
|
||||
* headroom given to buffers by default.
|
||||
* if buffer value is below 107 bytes then remaining value is allocated as headroom.
|
||||
*/
|
||||
#define BUFFER_DEFAULT_HEADROOM 40
|
||||
|
||||
/*
|
||||
* default minimum size for buffers.
|
||||
* if size is below this then extra space is allocated as headroom.
|
||||
*/
|
||||
#define BUFFER_DEFAULT_MIN_SIZE 127
|
||||
|
||||
/* The new, really-configurable default hop limit (RFC 4861 CurHopLimit);
|
||||
* this can be overridden at compile-time, or changed on a per-socket basis
|
||||
* with socket_setsockopt. It can also be overridden by Router Advertisements.
|
||||
*/
|
||||
#ifndef UNICAST_HOP_LIMIT_DEFAULT
|
||||
#define UNICAST_HOP_LIMIT_DEFAULT 64
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
B_SECURITY_KEY_ID_MODE_DEFAULT = 0,
|
||||
B_SECURITY_KEY_ID_2,
|
||||
B_SECURITY_KEY_ID_IMPLICIT,
|
||||
} buffer_security_key_id_mode;
|
||||
|
||||
/** link-specific buffer data */
|
||||
typedef struct buffer_link_ieee802_15_4 {
|
||||
bool fc_security: 1; // Security Enabled flag from frame control
|
||||
bool ack_fc_frame_pending: 1; // Frame Pending flag that was transmitted in Ack for this frame (used in Data Request)
|
||||
bool useDefaultPanId: 1; // Transmit to broadcast PAN ID (0xffff)
|
||||
bool indirectTxProcess: 1;
|
||||
bool requestAck: 1;
|
||||
bool rf_channel_switch: 1;
|
||||
buffer_security_key_id_mode key_id_mode;
|
||||
uint8_t selected_channel;
|
||||
uint32_t indirectTTL;
|
||||
uint16_t srcPanId;
|
||||
uint16_t dstPanId;
|
||||
} buffer_link_ieee802_15_4_t;
|
||||
|
||||
typedef union buffer_link_info {
|
||||
buffer_link_ieee802_15_4_t ieee802_15_4;
|
||||
} buffer_link_info_t;
|
||||
|
||||
/* Flags to indicate presence of extension headers in _current_ IP layer */
|
||||
/* (As opposed to, eg, rpl_option, which is any-layer metadata) */
|
||||
/* Placed as a non-bitfield in ip_extflags so that IP core can bulk clear */
|
||||
#define IPEXT_HBH_RPL 0x01 /*!< RPL hop-by-hop option */
|
||||
#define IPEXT_SRH_RPL 0x02 /*!< RPL Routing Header */
|
||||
#define IPEXT_HBH_ROUTER_ALERT 0x04 /*!< Router alert */
|
||||
#define IPEXT_HBH_MPL 0x08 /*!< MPL hop-by-hop option */
|
||||
#define IPEXT_HBH_MPL_UNFILLED 0x10 /*!< MPL option is unfilled */
|
||||
#define IPEXT_FRAGMENT 0x20 /*!< Fragment header present - if set on entry to IP parsing this was reassembled packet */
|
||||
|
||||
/** buffer option fields */
|
||||
typedef struct buffer_options {
|
||||
uint8_t lqi; /*!< LQI from RF */
|
||||
int8_t dbm; /*!< Signal level */
|
||||
uint8_t hop_limit; /*!< IPv6 hop limit */
|
||||
uint8_t type; /*!< ICMP type, IP next header, MAC frame type... */
|
||||
uint8_t code; /*!< ICMP code, TCP flags, MAC ack request... */
|
||||
uint8_t ip_extflags; /*!< IPv6 extension header flags */
|
||||
bool ll_security_bypass_tx: 1; /*!< Tx without link-layer security */
|
||||
bool ll_sec_bypass_frag_deny: 1; /*!< Deny ll_security_bypass_tx usage in fragmented packets */
|
||||
bool ll_security_bypass_rx: 1; /*!< Was received without link-layer security, when security was enabled */
|
||||
bool ll_broadcast_tx: 1; /*!< Tx as link-layer broadcast (set to override multicast-as-unicast) */
|
||||
bool ll_broadcast_rx: 1; /*!< Was received as link-layer broadcast */
|
||||
bool ll_multicast_rx: 1; /*!< Was received as link-layer multicast */
|
||||
bool ll_not_ours_rx: 1; /*!< Not addressed to us at link layer - snooped */
|
||||
bool lowpan_mesh_rx: 1; /*!< Had a 6LoWPAN mesh header */
|
||||
bool tunnelled: 1; /*!< We tunnelled it as part of (RPL?) routing */
|
||||
bool need_predecessor: 1; /*!< Used as an indicator that predecessor address needed */
|
||||
bool multicast_loop: 1; /*!< We want loopback if we're a group member (TX), or this IS the loopback if RX */
|
||||
bool mpl_permitted: 1; /*!< MPL will be used if enabled on interface and scope >=3 */
|
||||
#ifndef NO_IP_FRAGMENT_TX
|
||||
bool ipv6_dontfrag: 1; /*!< Don't IPv6 fragment (RFC 3542) */
|
||||
#endif
|
||||
#ifndef NO_IPV6_PMTUD
|
||||
signed ipv6_use_min_mtu: 2; /*!< Use minimum 1280-byte MTU (RFC 3542) - three settings +1, 0, -1 */
|
||||
#endif
|
||||
uint8_t traffic_class; /*!< Traffic class */
|
||||
int_least24_t flow_label; /*!< IPv6 flow label; -1 means unspecified (may auto-generate); -2 means auto-generate required */
|
||||
} buffer_options_t;
|
||||
|
||||
#define IPV6_FLOW_UNSPECIFIED (-1)
|
||||
#define IPV6_FLOW_AUTOGENERATE (-2)
|
||||
|
||||
typedef enum {
|
||||
B_TO_NONE = 0x0000,
|
||||
B_TO_MAC = 0x0001,
|
||||
B_TO_IPV6 = 0x0002,
|
||||
B_TO_UDP = 0x0003,
|
||||
B_TO_ICMP = 0x0004,
|
||||
B_TO_NAP = 0x0005,
|
||||
B_TO_FRAGMENTATION = 0x0006,
|
||||
B_TO_TCP = 0x0007,
|
||||
B_TO_MLME = 0x0008,
|
||||
B_TO_IPV6_TXRX = 0x0009,
|
||||
B_TO_DNSSD = 0x000A,
|
||||
B_TO_IPV6_FWD = 0x000B,
|
||||
B_TO_TLS = 0x000C,
|
||||
B_TO_MESH_ROUTING = 0x000D,
|
||||
B_TO_PHY = 0x000E,
|
||||
B_TO_APP = 0x000F,
|
||||
B_TO_MASK = 0x000F,
|
||||
B_FROM_NONE = 0x0000,
|
||||
B_FROM_MAC = 0x0010,
|
||||
B_FROM_IPV6 = 0x0020,
|
||||
B_FROM_UDP = 0x0030,
|
||||
B_FROM_ICMP = 0x0040,
|
||||
B_FROM_NAP = 0x0050,
|
||||
B_FROM_FRAGMENTATION = 0x0060,
|
||||
B_FROM_TCP = 0x0070,
|
||||
B_FROM_MLME = 0x0080,
|
||||
B_FROM_IPV6_TXRX = 0x0090,
|
||||
B_FROM_DNSSD = 0x00A0,
|
||||
B_FROM_IPV6_FWD = 0x00B0,
|
||||
B_FROM_LOCAL = 0x00C0,
|
||||
B_FROM_MESH_ROUTING = 0x00D0,
|
||||
B_FROM_APP = 0x00F0,
|
||||
B_FROM_MASK = 0x00F0,
|
||||
B_DIR_DOWN = 0x0000,
|
||||
B_DIR_UP = 0x0800,
|
||||
B_DIR_MASK = 0x0800,
|
||||
} buffer_info_t;
|
||||
|
||||
typedef enum {
|
||||
QOS_NORMAL = 0,
|
||||
QOS_HIGH = 1,
|
||||
QOS_MAC_BEACON = 2
|
||||
} buffer_priority_t;
|
||||
|
||||
#define B_TO_MAC_MLME_MASK (B_DIR_MASK + B_FROM_MASK + B_TO_MASK )
|
||||
#define B_TO_MAC_FROM_MAC (B_DIR_UP + B_FROM_MAC + B_TO_MAC )
|
||||
|
||||
struct socket;
|
||||
|
||||
typedef struct buffer_routing_info {
|
||||
ipv6_route_info_t route_info;
|
||||
const uint8_t *ip_dest;
|
||||
uint8_t ref_count;
|
||||
} buffer_routing_info_t;
|
||||
|
||||
/** buffer structure */
|
||||
/* If adding pointers to this, ensure buffer_free and buffer_copy_metadata are informed */
|
||||
typedef struct buffer {
|
||||
ns_list_link_t link;
|
||||
sockaddr_t dst_sa; /*!< Destination sockaddr */
|
||||
sockaddr_t src_sa; /*!< Source sockaddr */
|
||||
sockaddr_t *predecessor; /*!< Predecessor - used by RPL */
|
||||
protocol_interface_info_entry_t *interface; /*!< Pointer to interface */
|
||||
struct socket *socket; /*!< Indicate is data came trough socket */
|
||||
buffer_info_t info; /*!< Protocol information */
|
||||
uint8_t seq; /*!< Packet MAC header sequence number */
|
||||
uint16_t buf_ptr; /*!< Current pointer in the buffer */
|
||||
uint16_t buf_end; /*!< End pointer in the buffer */
|
||||
uint16_t size; /*!< Buffer size */
|
||||
uint16_t offset; /*!< Offset indicator (used in some upward paths) */
|
||||
//uint16_t queue_timer;
|
||||
uint16_t payload_length; /*!< Socket payload length */
|
||||
uint8_t IPHC_NH;
|
||||
uint8_t rpl_instance;
|
||||
bool rpl_instance_known: 1;
|
||||
bool ip_routed_up: 1;
|
||||
uint8_t rpl_flag_error;
|
||||
//uint8_t bc_sending_superframe; /*FHSS uses this randomly chosen superframe to send this packet (if broadcast)*/
|
||||
//uint8_t fhss_channel_retries_left;
|
||||
//uint8_t ip_transmission_prev_seq; /*!< XXX: this stores the data packet seq. number, which is needed for re-transmission. */
|
||||
//uint16_t bad_channel;
|
||||
void *session_ptr;
|
||||
uint8_t *rpl_option;
|
||||
buffer_priority_t priority;
|
||||
buffer_link_info_t link_specific;
|
||||
uint16_t mpl_option_data_offset;
|
||||
uint8_t trickle_data_len;
|
||||
uint8_t trickle_data_field[4];
|
||||
buffer_options_t options; /*!< Additional signal info etc */
|
||||
buffer_routing_info_t *route; /* A pointer last to try to get neat alignment for data */
|
||||
void (*ack_receive_cb)(struct buffer *buffer_ptr, uint8_t status); /*!< ACK receive callback. If set, will be called when TX is done */
|
||||
uint8_t buf[]; /*!< Trailing buffer data */
|
||||
} buffer_t;
|
||||
|
||||
typedef NS_LIST_HEAD(buffer_t, link) buffer_list_t;
|
||||
NS_STATIC_ASSERT(offsetof(buffer_t, link) == 0, "Some use NS_LIST_HEAD_INCOMPLETE")
|
||||
|
||||
#define SYST_WDCLEAR 0xff
|
||||
#define SYST_TX_TO 0xfe
|
||||
|
||||
/** Macro to check buffer corruptions with debug flagging. */
|
||||
#ifdef EXTRA_CONSISTENCY_CHECKS
|
||||
#define buffer_data_pointer_after_adjustment(x) buffer_corrupt_check(x)
|
||||
#define _buffer_corruption_check(x) buffer_corrupt_check(x)
|
||||
#else
|
||||
#define buffer_data_pointer_after_adjustment(x) buffer_data_pointer(x)
|
||||
#define _buffer_corruption_check(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/** Allocate memory for a buffer_t from the heap */
|
||||
extern buffer_t *buffer_get(uint16_t size);
|
||||
|
||||
/** Allocate memory for a buffer_t from the heap, with more detailed sizing */
|
||||
extern buffer_t *buffer_get_specific(uint16_t headroom, uint16_t size, uint16_t minspace);
|
||||
|
||||
/** Allocate memory for a minimal buffer (no headroom or extra space) */
|
||||
extern buffer_t *buffer_get_minimal(uint16_t size);
|
||||
|
||||
/** Free a buffer from the heap, and return NULL */
|
||||
extern buffer_t *buffer_free(buffer_t *buf);
|
||||
|
||||
/** Free a linked buffer list from the heap */
|
||||
void buffer_free_list(buffer_list_t *list);
|
||||
|
||||
/** Free any routing info in the buffer, returning the buffer pointer */
|
||||
extern buffer_t *buffer_free_route(buffer_t *buf);
|
||||
|
||||
/** Compute IPv6 checksum for buffer data + IPv6 pseudo-header */
|
||||
uint16_t buffer_ipv6_fcf(const buffer_t *buf, uint8_t next_header);
|
||||
|
||||
/** Check for corrupt buffers should only be used when testing.*/
|
||||
#ifdef EXTRA_CONSISTENCY_CHECKS
|
||||
uint8_t *buffer_corrupt_check(buffer_t *buf);
|
||||
#else
|
||||
#define buffer_corrupt_check(b) ((void)0)
|
||||
#endif
|
||||
/** Allocate header space in buffer */
|
||||
extern buffer_t *buffer_headroom(buffer_t *buf, uint16_t size);
|
||||
|
||||
/** Add buffer at the end of current buffer.
|
||||
* Modifies all pointer and indexes correctly.
|
||||
*
|
||||
*/
|
||||
void buffer_data_add(buffer_t *buf, const uint8_t *data_ptr, uint16_t data_len);
|
||||
|
||||
/** create new buffer and copy all fields and data
|
||||
*
|
||||
* Notice that data can have different headroom reserved. so the actual data might
|
||||
* be located in different part of buffer than in original.*/
|
||||
buffer_t *buffer_clone(buffer_t *buf);
|
||||
|
||||
/** prepare an input buffer to become a response - clear unwanted metadata */
|
||||
buffer_t *buffer_turnaround(buffer_t *buf);
|
||||
|
||||
/** copy metadata from src to dst - see definition for more info */
|
||||
void buffer_copy_metadata(buffer_t *dst, buffer_t *src, bool non_clonable_to_dst);
|
||||
|
||||
/** remember the predecessor address, if needed */
|
||||
void buffer_note_predecessor(buffer_t *buf, const sockaddr_t *addr);
|
||||
|
||||
/** set the socket pointer in the buffer (dealing with reference counting) */
|
||||
struct socket *buffer_socket_set(buffer_t *buf, struct socket *socket);
|
||||
|
||||
/** set buffer_priority */
|
||||
#define buffer_priority_set(x,z) ((x)->priority = (z))
|
||||
|
||||
/** get pointer to data*/
|
||||
#define buffer_data_pointer(x) (&(x)->buf[(x)->buf_ptr])
|
||||
|
||||
/** get pointer to end of data*/
|
||||
#define buffer_data_end(x) (&(x)->buf[(x)->buf_end])
|
||||
|
||||
/** get pointer to data*/
|
||||
#define buffer_data_pointer_set(x,new_start_ptr) ((x)->buf_ptr = (new_start_ptr) - (x)->buf)
|
||||
|
||||
/** get pointer to end of data*/
|
||||
#define buffer_data_end_set(x,new_end_ptr) do {\
|
||||
((x)->buf_end = (new_end_ptr) - (x)->buf);\
|
||||
_buffer_corruption_check(x);\
|
||||
} while(0)
|
||||
|
||||
/** get data length*/
|
||||
#define buffer_data_length(x) (int)(x->buf_end - x->buf_ptr)
|
||||
|
||||
/** get data length Set*/
|
||||
#define buffer_data_length_set(x,z) ((x)->buf_end = (x)->buf_ptr + (z))
|
||||
|
||||
/** free data bytes in buffer */
|
||||
#define buffer_data_free_length(x) ((x)->size - (x)->buf_end)
|
||||
|
||||
/** Clears buffer to initial value
|
||||
* uint8_t *buffer_data_clear(buffer_t *x)
|
||||
* */
|
||||
#define buffer_data_clear(x) ((x)->buf_ptr = (x)->buf_end = BUFFER_DEFAULT_HEADROOM, buffer_data_pointer_after_adjustment(x))
|
||||
|
||||
/** Clears buffer and sets the headroom */
|
||||
#define buffer_data_clear_with_headroom(x,z) ((x)->buf_ptr = (x)->buf_end = (z))
|
||||
|
||||
/** Removes z amount of bytes from the begining of buffer
|
||||
* uint8_t *buffer_data_strip_header(buffer_t *x, uint16_t z)
|
||||
* */
|
||||
static inline uint8_t *buffer_data_strip_header(buffer_t *x, uint16_t z)
|
||||
{
|
||||
x->buf_ptr += z;
|
||||
return buffer_data_pointer_after_adjustment(x);
|
||||
}
|
||||
|
||||
/** Adds z amount of bytes to the begining of buffer check if this is allowed using buffer_headroom method.
|
||||
* uint8_t *buffer_data_reserve_header(buffer_t *x, uint16_t z)
|
||||
* */
|
||||
static inline uint8_t *buffer_data_reserve_header(buffer_t *x, uint16_t z)
|
||||
{
|
||||
x->buf_ptr -= z;
|
||||
return buffer_data_pointer_after_adjustment(x);
|
||||
}
|
||||
|
||||
/** append 1 byte to data*/
|
||||
#define buffer_push_uint8(x, z) do {\
|
||||
(x)->buf[x->buf_end++] = (z);\
|
||||
_buffer_corruption_check(x);\
|
||||
} while(0)
|
||||
|
||||
/** append 2 byte to data*/
|
||||
#define buffer_push_uint16(x, z) do {\
|
||||
(x)->buf[x->buf_end++] = (uint8_t)( (z) >> 8);\
|
||||
(x)->buf[x->buf_end++] = (uint8_t) (z);\
|
||||
_buffer_corruption_check(x);\
|
||||
} while(0)
|
||||
|
||||
|
||||
/** append 4 byte to data*/
|
||||
#define buffer_push_uint32(x, z) do {\
|
||||
(x)->buf[(x)->buf_end++] = (uint8_t) ((z) >> 24);\
|
||||
(x)->buf[(x)->buf_end++] = (uint8_t) ((z) >> 16);\
|
||||
(x)->buf[(x)->buf_end++] = (uint8_t) ((z) >> 8);\
|
||||
(x)->buf[(x)->buf_end++] = (uint8_t) ((z));\
|
||||
_buffer_corruption_check(x);\
|
||||
} while(0)
|
||||
|
||||
/** append 2 byte to data on little endian order or inverse*/
|
||||
#define buffer_push_uint16_i(x, z) do {\
|
||||
(x)->buf[(x)->buf_end++] = (uint8_t)(z);\
|
||||
(x)->buf[(x)->buf_end++] = (uint8_t)((z) >> 8);\
|
||||
_buffer_corruption_check(x);\
|
||||
} while(0)
|
||||
|
||||
/** read 1 byte out of the buffer*/
|
||||
#define buffer_pull_uint8(x) (x)->buf[(x)->buf_ptr++]
|
||||
|
||||
/** read 2 byte out of the buffer*/
|
||||
#define buffer_pull_uint16(x) \
|
||||
((x)->buf_ptr += 2,\
|
||||
((uint16_t)(x)->buf[(x)->buf_ptr - 2] << 8 ) |\
|
||||
(uint16_t)(x)->buf[(x)->buf_ptr - 1])
|
||||
|
||||
/** read 4 byte out of the buffer*/
|
||||
#define buffer_pull_uint32(x) \
|
||||
((x)->buf_ptr += 4,\
|
||||
((uint32_t)(x)->buf[(x)->buf_ptr - 4] << 24 ) |\
|
||||
((uint32_t)(x)->buf[(x)->buf_ptr - 3] << 16 ) |\
|
||||
((uint32_t)(x)->buf[(x)->buf_ptr - 2] << 8 ) |\
|
||||
(uint32_t)(x)->buf[(x)->buf_ptr - 1])
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NS_ERROR_TYPES_H_
|
||||
#define NS_ERROR_TYPES_H_
|
||||
|
||||
/**
|
||||
* \enum error_t
|
||||
* \brief System generic error.
|
||||
*/
|
||||
typedef enum {
|
||||
eOK = 0, /*!< no error */
|
||||
eFALSE = 1, /*!< no result */
|
||||
eBUSY = 2, /*!< resource busy */
|
||||
eSYSTEM /*!< error code readable in sys_error */
|
||||
} socket_error_t;
|
||||
|
||||
#endif /* NS_ERROR_TYPES_H_ */
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file ns_monitor.h
|
||||
* \brief Utility functions concerning IPv6 stack monitoring.
|
||||
*
|
||||
* Module can monitor nanostack heap usage and release memory if heap usage is too high.
|
||||
* Mmeory monitoring can work if memory statistics are enabled in nsdynmemLIB.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NS_MONITOR_H
|
||||
#define _NS_MONITOR_H
|
||||
|
||||
int ns_monitor_init(void);
|
||||
|
||||
int ns_monitor_clear(void);
|
||||
|
||||
void ns_monitor_timer(uint16_t seconds);
|
||||
|
||||
int ns_monitor_heap_gc_threshold_set(uint8_t percentage_high, uint8_t percentage_critical);
|
||||
|
||||
int ns_monitor_packet_ingress_rate_limit_by_memory(uint8_t free_heap_percentage);
|
||||
|
||||
bool ns_monitor_packet_allocation_allowed(void);
|
||||
|
||||
|
||||
#endif // _NS_MONITOR_H
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2017, 2019, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* \file socket.h
|
||||
* \brief Socket API definitions.
|
||||
*
|
||||
* Socket API functions and relevant structures.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NS_SOCKET_H
|
||||
#define _NS_SOCKET_H
|
||||
|
||||
#include "Core/include/ns_error_types.h"
|
||||
#include "Core/include/ns_buffer.h"
|
||||
#include "Core/include/sockbuf.h"
|
||||
|
||||
#ifndef SOCKET_RX_LIMIT
|
||||
#define SOCKET_RX_LIMIT 3
|
||||
#endif
|
||||
|
||||
#ifndef SOCKETS_MAX
|
||||
#define SOCKETS_MAX 16
|
||||
#endif
|
||||
|
||||
#ifndef SOCKET_DEFAULT_STREAM_RCVBUF
|
||||
#define SOCKET_DEFAULT_STREAM_RCVBUF 2048
|
||||
#endif
|
||||
|
||||
#ifndef SOCKET_DEFAULT_STREAM_SNDBUF
|
||||
#define SOCKET_DEFAULT_STREAM_SNDBUF 2048
|
||||
#endif
|
||||
|
||||
#ifndef SOCKET_DEFAULT_STREAM_SNDLOWAT
|
||||
#define SOCKET_DEFAULT_STREAM_SNDLOWAT 512
|
||||
#endif
|
||||
|
||||
typedef enum socket_family_e {
|
||||
SOCKET_FAMILY_NONE,
|
||||
SOCKET_FAMILY_IPV6,
|
||||
} socket_family_t;
|
||||
|
||||
// This is always true because we currently have only 1 type
|
||||
// If we support more types in future it becomes "((socket)->family == SOCKET_FAMILY_IPV6)"
|
||||
#define socket_is_ipv6(socket) true
|
||||
|
||||
typedef enum socket_type_e {
|
||||
SOCKET_TYPE_DGRAM,
|
||||
SOCKET_TYPE_STREAM,
|
||||
SOCKET_TYPE_RAW
|
||||
} socket_type_t;
|
||||
|
||||
#define SOCKET_FLAG_CLOSED 128 /* Has been closed by application */
|
||||
#define SOCKET_FLAG_PENDING 64 /* Is waiting for accept on a listening socket */
|
||||
#define SOCKET_FLAG_CANT_RECV_MORE 32
|
||||
#define SOCKET_FLAG_SHUT_WR 16
|
||||
#define SOCKET_FLAG_CONNECTED 8 /* Connection completed (and possibly since broken) */
|
||||
#define SOCKET_LISTEN_STATE 4
|
||||
#define SOCKET_BUFFER_CB 2
|
||||
#define SOCKET_FLAG_CONNECTING 1 /* Connection in progress */
|
||||
|
||||
#ifndef SOCKET_IPV6_TCLASS_DEFAULT
|
||||
#define SOCKET_IPV6_TCLASS_DEFAULT 0 /** Default traffic class for a new socket */
|
||||
#endif
|
||||
|
||||
#ifndef SOCKET_LISTEN_BACKLOG_MAX
|
||||
#define SOCKET_LISTEN_BACKLOG_MAX 10
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ARM_SOCKET_INIT = 0,
|
||||
ARM_SOCKET_EVENT_CB = 1,
|
||||
ARM_SOCKET_DATA_CB = 2, // Original data event - one buffer stored in event
|
||||
ARM_SOCKET_DATA_QUEUED_CB = 3, // New data event - no buffer in event, buffer in queue
|
||||
ARM_SOCKET_TCP_TIMER_CB,
|
||||
} arm_socket_event_id_e;
|
||||
|
||||
typedef struct socket_buffer_callback_t {
|
||||
uint8_t event_type;
|
||||
int8_t socket_id;
|
||||
int8_t interface_id;
|
||||
buffer_t *buf;
|
||||
void *session_ptr;
|
||||
} socket_buffer_callback_t;
|
||||
|
||||
typedef enum {
|
||||
SOCKET_SRC_ADDRESS_PRIMARY = 0,
|
||||
SOCKET_SRC_ADDRESS_SECONDARY = 1,
|
||||
} socket_src_address_type;
|
||||
|
||||
struct inet_pcb_s;
|
||||
struct ns_msghdr;
|
||||
struct socket;
|
||||
typedef NS_LIST_HEAD_INCOMPLETE(struct socket) socket_queue_list_t;
|
||||
|
||||
struct socket_pending {
|
||||
ns_list_link_t link; /*!< Link as member of connection queue */
|
||||
struct socket *listen_head; /*!< Pointer to listening socket we're queued against */
|
||||
};
|
||||
|
||||
struct socket_live {
|
||||
socket_queue_list_t queue; /*!< Incoming connection queue */
|
||||
void (*fptr)(void *);
|
||||
};
|
||||
|
||||
/** Socket structure */
|
||||
typedef struct socket {
|
||||
/* This listen queue must be first, due to need to use incomplete list head */
|
||||
union {
|
||||
struct socket_pending pending; /* !< Info if PENDING flag set (pending connection) */
|
||||
struct socket_live live; /* !< Info if PENDING flag clear (normal socket) */
|
||||
} u;
|
||||
int8_t id; /*!< socket id */
|
||||
uint8_t flags; /*!< Socket option flags */
|
||||
int8_t tasklet; /*!< Receiver tasklet */
|
||||
uint8_t refcount;
|
||||
socket_family_t family;
|
||||
socket_type_t type;
|
||||
int8_t default_interface_id;
|
||||
int8_t broadcast_pan;
|
||||
uint8_t listen_backlog; /*!< Limit if pending connection queue */
|
||||
struct inet_pcb_s *inet_pcb; /*!< shortcut to Internet control block */
|
||||
sockbuf_t rcvq;
|
||||
sockbuf_t sndq;
|
||||
ns_list_link_t link; /*!< link */
|
||||
} socket_t;
|
||||
|
||||
NS_STATIC_ASSERT(offsetof(socket_t, u.pending.link) == 0, "Listen queue link must be first (NS_LIST_HEAD_INCOMPLETE)")
|
||||
|
||||
typedef struct inet_group {
|
||||
uint8_t group_addr[16];
|
||||
int8_t interface_id;
|
||||
ns_list_link_t link;
|
||||
} inet_group_t;
|
||||
|
||||
/** Internet protocol control block */
|
||||
typedef struct inet_pcb_s {
|
||||
socket_t *socket;
|
||||
#ifndef NO_TCP
|
||||
void *session; /*!< Session for transport protocol - only used by TCP at present */
|
||||
#endif
|
||||
uint8_t local_address[16]; /*!< Local address */
|
||||
uint8_t remote_address[16]; /*!< Destination address */
|
||||
uint16_t local_port; /*!< Local port */
|
||||
uint16_t remote_port; /*!< Destination port */
|
||||
int16_t unicast_hop_limit; /*!< May be -1, which will give per-interface default */
|
||||
uint8_t multicast_hop_limit;
|
||||
int8_t multicast_if;
|
||||
uint32_t addr_preferences;
|
||||
uint8_t protocol; /*!< IP type IPV6_NH_TCP, IPV6_NH_UDP, IPV6_NH_ICMPV6... */
|
||||
int8_t link_layer_security;
|
||||
#ifndef NO_IPV6_PMTUD
|
||||
int8_t use_min_mtu; /*!< RFC 3542 socket option */
|
||||
#endif
|
||||
#ifndef NO_IP_FRAGMENT_TX
|
||||
int8_t dontfrag;
|
||||
#endif
|
||||
uint8_t tclass;
|
||||
bool multicast_loop: 1;
|
||||
bool recvpktinfo: 1;
|
||||
bool recvhoplimit: 1;
|
||||
bool recvtclass: 1;
|
||||
int_least24_t flow_label;
|
||||
NS_LIST_HEAD(inet_group_t, link) mc_groups;
|
||||
} inet_pcb_t;
|
||||
|
||||
typedef NS_LIST_HEAD(socket_t, link) socket_list_t;
|
||||
extern socket_list_t socket_list;
|
||||
|
||||
extern const uint8_t ns_in6addr_any[16];
|
||||
|
||||
extern void socket_init(void);
|
||||
extern int8_t socket_event_handler_id_get(void);
|
||||
extern bool socket_data_queued_event_push(socket_t *socket);
|
||||
extern void socket_event_push(uint8_t sock_event, socket_t *socket, int8_t interface_id, void *session_ptr, uint16_t length);
|
||||
extern socket_error_t socket_create(socket_family_t family, socket_type_t type, uint8_t protocol, int8_t *sid, uint16_t port, void (*passed_fptr)(void *), bool buffer_type);
|
||||
extern socket_t *socket_new_incoming_connection(socket_t *listen_socket);
|
||||
void socket_connection_abandoned(socket_t *socket, int8_t interface_id, uint8_t reason);
|
||||
void socket_connection_complete(socket_t *socket, int8_t interface_id);
|
||||
extern void socket_leave_pending_state(socket_t *socket, void (*fptr)(void *));
|
||||
void socket_cant_recv_more(socket_t *socket, int8_t interface_id);
|
||||
extern int8_t socket_id_assign_and_attach(socket_t *socket);
|
||||
extern void socket_id_detach(int8_t sid);
|
||||
extern buffer_t *socket_buffer_read(socket_t *socket);
|
||||
extern socket_t *socket_lookup(socket_family_t family, uint8_t protocol, const sockaddr_t *local_addr, const sockaddr_t *remote_addr);
|
||||
extern socket_t *socket_lookup_ipv6(uint8_t protocol, const sockaddr_t *local_addr, const sockaddr_t *remote_addr, bool allow_wildcards);
|
||||
extern socket_error_t socket_port_validate(uint16_t port, uint8_t protocol);
|
||||
extern socket_error_t socket_up(buffer_t *buf);
|
||||
extern bool socket_message_validate_iov(const struct ns_msghdr *msg, uint16_t *length_out);
|
||||
extern int16_t socket_buffer_sendmsg(int8_t sid, buffer_t *buf, const struct ns_msghdr *msg, int flags);
|
||||
extern socket_t *socket_pointer_get(int8_t socket);
|
||||
extern void socket_inet_pcb_set_buffer_hop_limit(const inet_pcb_t *socket, buffer_t *buf, const int16_t *msg_hoplimit);
|
||||
extern bool socket_validate_listen_backlog(const socket_t *socket_ptr);
|
||||
extern void socket_list_print(route_print_fn_t *print_fn, char sep);
|
||||
extern socket_t *socket_reference(socket_t *);
|
||||
extern socket_t *socket_dereference(socket_t *);
|
||||
|
||||
extern void socket_release(socket_t *socket);
|
||||
|
||||
extern void socket_tx_buffer_event_and_free(buffer_t *buf, uint8_t status);
|
||||
extern buffer_t *socket_tx_buffer_event(buffer_t *buf, uint8_t status);
|
||||
|
||||
extern inet_pcb_t *socket_inet_pcb_allocate(void);
|
||||
extern inet_pcb_t *socket_inet_pcb_clone(const inet_pcb_t *orig);
|
||||
|
||||
/**
|
||||
* Free reserved inet_pcb
|
||||
*/
|
||||
extern inet_pcb_t *socket_inet_pcb_free(inet_pcb_t *inet_pcb);
|
||||
|
||||
extern int8_t socket_inet_pcb_join_group(inet_pcb_t *inet_pcb, int8_t interface_id, const uint8_t group[__static 16]);
|
||||
extern int8_t socket_inet_pcb_leave_group(inet_pcb_t *inet_pcb, int8_t interface_id, const uint8_t group[__static 16]);
|
||||
|
||||
/**
|
||||
* Determine interface based on socket_id and address
|
||||
*/
|
||||
extern struct protocol_interface_info_entry *socket_interface_determine(const socket_t *socket, buffer_t *buf);
|
||||
|
||||
extern uint16_t socket_generate_random_port(uint8_t protocol);
|
||||
|
||||
#endif /*_NS_SOCKET_H*/
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SOCKBUF_H_
|
||||
#define SOCKBUF_H_
|
||||
|
||||
#include "Core/include/ns_buffer.h"
|
||||
|
||||
typedef struct sockbuf {
|
||||
uint32_t data_bytes;
|
||||
uint32_t data_byte_limit;
|
||||
uint32_t buf_overhead_bytes;
|
||||
uint32_t buf_overhead_byte_limit;
|
||||
uint32_t low_water_mark;
|
||||
buffer_list_t bufs;
|
||||
} sockbuf_t;
|
||||
|
||||
void sockbuf_init(sockbuf_t *sb);
|
||||
void sockbuf_append(sockbuf_t *sb, buffer_t *buf);
|
||||
void sockbuf_append_and_compress(sockbuf_t *sb, buffer_t *buf);
|
||||
void sockbuf_alloc(sockbuf_t *sb, const buffer_t *buf);
|
||||
void sockbuf_free(sockbuf_t *sb, const buffer_t *buf);
|
||||
void sockbuf_drop(sockbuf_t *sb, uint32_t len);
|
||||
void sockbuf_drop_first(sockbuf_t *sb);
|
||||
void sockbuf_flush(sockbuf_t *sb);
|
||||
bool sockbuf_reserve(sockbuf_t *sb, uint32_t space);
|
||||
int32_t sockbuf_space(const sockbuf_t *sb);
|
||||
void sockbuf_check(sockbuf_t *sb);
|
||||
|
||||
#endif /* SOCKBUF_H_ */
|
||||
Reference in New Issue
Block a user