mirror of
https://github.com/sengeiou/realtek_ameba_mp_sdk.git
synced 2026-07-02 01:25:44 +00:00
ameba micropython sdk first commit
This commit is contained in:
commit
8508ee6139
5619 changed files with 1874619 additions and 0 deletions
738
sdk/component/common/network/coap/include/ns_list.h
Normal file
738
sdk/component/common/network/coap/include/ns_list.h
Normal file
|
|
@ -0,0 +1,738 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited. All rights reserved.
|
||||
* 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_LIST_H_
|
||||
#define NS_LIST_H_
|
||||
|
||||
#include "ns_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \file
|
||||
* \brief Linked list support library
|
||||
*
|
||||
* The ns_list.h file provides a doubly-linked list/queue, providing O(1)
|
||||
* performance for all insertion/removal operations, and access to either
|
||||
* end of the list.
|
||||
*
|
||||
* Memory footprint is two pointers for the list head, and two pointers in each
|
||||
* list entry. It is similar in concept to BSD's TAILQ.
|
||||
*
|
||||
* Although the API is symmetrical and O(1) in both directions, due to internal
|
||||
* pointer design, it is *slightly* more efficient to insert at the end when
|
||||
* used as a queue, and to iterate forwards rather than backwards.
|
||||
*
|
||||
* Example of an entry type that can be stored to this list.
|
||||
* ~~~
|
||||
* typedef struct example_entry
|
||||
* {
|
||||
* uint8_t *data;
|
||||
* uint32_t data_count;
|
||||
* ns_list_link_t link;
|
||||
* }
|
||||
* example_entry_t;
|
||||
*
|
||||
* static NS_LIST_HEAD(example_entry_t, link) my_list;
|
||||
* ns_list_init(&my_list);
|
||||
* ~~~
|
||||
* OR
|
||||
* ~~~
|
||||
* NS_LIST_HEAD(example_entry_t, link) my_list = NS_LIST_INIT(my_list);
|
||||
* ~~~
|
||||
* OR
|
||||
* ~~~
|
||||
* static NS_LIST_DEFINE(my_list, example_entry_t, link);
|
||||
* ~~~
|
||||
* OR
|
||||
* ~~~
|
||||
* typedef NS_LIST_HEAD(example_entry_t, link) example_list_t;
|
||||
* example_list_t NS_LIST_NAME_INIT(my_list);
|
||||
* ~~~
|
||||
* NOTE: the link field SHALL NOT be accessed by the user.
|
||||
*
|
||||
* An entry can exist on multiple lists by having multiple link fields.
|
||||
*
|
||||
* All the list operations are implemented as macros, most of which are backed
|
||||
* by optionally-inline functions. The macros do not evaluate any arguments more
|
||||
* than once, unless documented.
|
||||
*
|
||||
* In macro documentation, `list_t` refers to a list type defined using
|
||||
* NS_LIST_HEAD(), and `entry_t` to the entry type that was passed to it.
|
||||
*/
|
||||
|
||||
/** \brief Underlying generic linked list head.
|
||||
*
|
||||
* Users should not use this type directly, but use the NS_LIST_HEAD() macro.
|
||||
*/
|
||||
typedef struct ns_list {
|
||||
void *first_entry; ///< Pointer to first entry, or NULL if list is empty
|
||||
void **last_nextptr; ///< Pointer to last entry's `next` pointer, or
|
||||
///< to head's `first_entry` pointer if list is empty
|
||||
} ns_list_t;
|
||||
|
||||
/** \brief Declare a list head type
|
||||
*
|
||||
* This union stores the real list head, and also encodes as compile-time type
|
||||
* information the offset of the link pointer, and the type of the entry.
|
||||
*
|
||||
* Note that type information is compiler-dependent; this means
|
||||
* ns_list_get_first() could return either `void *`, or a pointer to the actual
|
||||
* entry type. So `ns_list_get_first()->data` is not a portable construct -
|
||||
* always assign returned entry pointers to a properly typed pointer variable.
|
||||
* This assignment will be then type-checked where the compiler supports it, and
|
||||
* will dereference correctly on compilers that don't support this extension.
|
||||
* ~~~
|
||||
* NS_LIST_HEAD(example_entry_t, link) my_list;
|
||||
*
|
||||
* example_entry_t *entry = ns_list_get_first(&my_list);
|
||||
* do_something(entry->data);
|
||||
* ~~~
|
||||
* Each use of this macro generates a new anonymous union, so these two lists
|
||||
* have different types:
|
||||
* ~~~
|
||||
* NS_LIST_HEAD(example_entry_t, link) my_list1;
|
||||
* NS_LIST_HEAD(example_entry_t, link) my_list2;
|
||||
* ~~~
|
||||
* If you need to use a list type in multiple places, eg as a function
|
||||
* parameter, use typedef:
|
||||
* ~~~
|
||||
* typedef NS_LIST_HEAD(example_entry_t, link) example_list_t;
|
||||
*
|
||||
* void example_function(example_list_t *);
|
||||
* ~~~
|
||||
*/
|
||||
#define NS_LIST_HEAD(entry_type, field) \
|
||||
NS_LIST_HEAD_BY_OFFSET_(entry_type, offsetof(entry_type, field))
|
||||
|
||||
/** \brief Declare a list head type for an incomplete entry type.
|
||||
*
|
||||
* This declares a list head, similarly to NS_LIST_HEAD(), but unlike that
|
||||
* this can be used in contexts where the entry type may be incomplete.
|
||||
*
|
||||
* To use this, the link pointer must be the first member in the
|
||||
* actual complete structure. This is NOT checked - the definition of the
|
||||
* element should probably test NS_STATIC_ASSERT(offsetof(type, link) == 0)
|
||||
* if outside users are known to be using NS_LIST_HEAD_INCOMPLETE().
|
||||
* ~~~
|
||||
* struct opaque;
|
||||
* NS_LIST_HEAD_INCOMPLETE(struct opaque) opaque_list;
|
||||
* ~~~
|
||||
*/
|
||||
#define NS_LIST_HEAD_INCOMPLETE(entry_type) \
|
||||
NS_LIST_HEAD_BY_OFFSET_(entry_type, 0)
|
||||
|
||||
/// \privatesection
|
||||
/** \brief Internal macro defining a list head, given the offset to the link pointer
|
||||
* The +1 allows for link_offset being 0 - we can't declare a 0-size array
|
||||
*/
|
||||
#define NS_LIST_HEAD_BY_OFFSET_(entry_type, link_offset) \
|
||||
union \
|
||||
{ \
|
||||
ns_list_t slist; \
|
||||
NS_FUNNY_COMPARE_OK \
|
||||
NS_STATIC_ASSERT(link_offset <= UINT_FAST8_MAX, "link offset too large") \
|
||||
NS_FUNNY_COMPARE_RESTORE \
|
||||
char (*offset)[link_offset + 1]; \
|
||||
entry_type *type; \
|
||||
}
|
||||
|
||||
/** \brief Get offset of link field in entry.
|
||||
* \return `(ns_list_offset_t)` The offset of the link field for entries on the specified list
|
||||
*/
|
||||
#define NS_LIST_OFFSET_(list) ((ns_list_offset_t) (sizeof *(list)->offset - 1))
|
||||
|
||||
/** \brief Get the entry pointer type.
|
||||
* \def NS_LIST_PTR_TYPE_
|
||||
*
|
||||
* \return An unqualified pointer type to an entry on the specified list.
|
||||
*
|
||||
* Only available if the compiler provides a "typeof" operator.
|
||||
*/
|
||||
#if defined __cplusplus && __cplusplus >= 201103L
|
||||
#define NS_LIST_PTR_TYPE_(list) decltype((list)->type)
|
||||
#elif defined __GNUC__
|
||||
#define NS_LIST_PTR_TYPE_(list) __typeof__((list)->type)
|
||||
#endif
|
||||
|
||||
/** \brief Check for compatible pointer types
|
||||
*
|
||||
* This test will produce a diagnostic about a pointer mismatch on
|
||||
* the == inside the sizeof operator. For example ARM/Norcroft C gives the error:
|
||||
*
|
||||
* operand types are incompatible ("entry_t *" and "other_t *")
|
||||
*/
|
||||
#ifdef CPPCHECK
|
||||
#define NS_PTR_MATCH_(a, b, str) ((void) 0)
|
||||
#else
|
||||
#define NS_PTR_MATCH_(a, b, str) ((void) sizeof ((a) == (b)))
|
||||
#endif
|
||||
|
||||
/** \brief Internal macro to cast returned entry pointers to correct type.
|
||||
*
|
||||
* Not portable in C, alas. With GCC or C++11, the "get entry" macros return
|
||||
* correctly-typed pointers. Otherwise, the macros return `void *`.
|
||||
*
|
||||
* The attempt at a portable version would work if the C `?:` operator wasn't
|
||||
* broken - `x ? (t *) : (void *)` should really have type `(t *)` in C, but
|
||||
* it has type `(void *)`, which only makes sense for C++. The `?:` is left in,
|
||||
* in case some day it works. Some compilers may still warn if this is
|
||||
* assigned to a different type.
|
||||
*/
|
||||
#ifdef NS_LIST_PTR_TYPE_
|
||||
#define NS_LIST_TYPECAST_(list, val) ((NS_LIST_PTR_TYPE_(list)) (val))
|
||||
#else
|
||||
#define NS_LIST_TYPECAST_(list, val) (0 ? (list)->type : (val))
|
||||
#endif
|
||||
|
||||
/** \brief Internal macro to check types of input entry pointer. */
|
||||
#define NS_LIST_TYPECHECK_(list, entry) \
|
||||
(NS_PTR_MATCH_((list)->type, (entry), "incorrect entry type for list"), (entry))
|
||||
|
||||
/** \brief Type used to pass link offset to underlying functions
|
||||
*
|
||||
* We could use size_t, but it would be unnecessarily large on 8-bit systems,
|
||||
* where we can be (pretty) confident we won't have next pointers more than
|
||||
* 256 bytes into a structure.
|
||||
*/
|
||||
typedef uint_fast8_t ns_list_offset_t;
|
||||
|
||||
/// \publicsection
|
||||
/** \brief The type for the link member in the user's entry structure.
|
||||
*
|
||||
* Users should not access this member directly - just pass its name to the
|
||||
* list head macros. The funny prev pointer simplifies common operations
|
||||
* (eg insertion, removal), at the expense of complicating rare reverse iteration.
|
||||
*
|
||||
* NB - the list implementation relies on next being the first member.
|
||||
*/
|
||||
typedef struct ns_list_link {
|
||||
void *next; ///< Pointer to next entry, or NULL if none
|
||||
void **prev; ///< Pointer to previous entry's (or head's) next pointer
|
||||
} ns_list_link_t;
|
||||
|
||||
/** \brief "Poison" value placed in unattached entries' link pointers.
|
||||
* \internal What are good values for this? Platform dependent, maybe just NULL
|
||||
*/
|
||||
#define NS_LIST_POISON ((void *) 0xDEADBEEF)
|
||||
|
||||
/** \brief Initialiser for an entry's link member
|
||||
*
|
||||
* This initialiser is not required by the library, but a user may want an
|
||||
* initialiser to include in their own entry initialiser. See
|
||||
* ns_list_link_init() for more discussion.
|
||||
*/
|
||||
#define NS_LIST_LINK_INIT(name) \
|
||||
NS_FUNNY_INTPTR_OK \
|
||||
{ NS_LIST_POISON, NS_LIST_POISON } \
|
||||
NS_FUNNY_INTPTR_RESTORE
|
||||
|
||||
/** \hideinitializer \brief Initialise an entry's list link
|
||||
*
|
||||
* This "initialises" an unattached entry's link by filling the fields with
|
||||
* poison. This is optional, as unattached entries field pointers are not
|
||||
* meaningful, and it is not valid to call ns_list_get_next or similar on
|
||||
* an unattached entry.
|
||||
*
|
||||
* \param entry Pointer to an entry
|
||||
* \param field The name of the link member to initialise
|
||||
*/
|
||||
#define ns_list_link_init(entry, field) ns_list_link_init_(&(entry)->field)
|
||||
|
||||
/** \hideinitializer \brief Initialise a list
|
||||
*
|
||||
* Initialise a list head before use. A list head must be initialised using this
|
||||
* function or one of the NS_LIST_INIT()-type macros before use. A zero-initialised
|
||||
* list head is *not* valid.
|
||||
*
|
||||
* If used on a list containing existing entries, those entries will
|
||||
* become detached. (They are not modified, but their links are now effectively
|
||||
* undefined).
|
||||
*
|
||||
* \param list Pointer to a NS_LIST_HEAD() structure.
|
||||
*/
|
||||
#define ns_list_init(list) ns_list_init_(&(list)->slist)
|
||||
|
||||
/** \brief Initialiser for an empty list
|
||||
*
|
||||
* Usage in an enclosing initialiser:
|
||||
* ~~~
|
||||
* static my_type_including_list_t x = {
|
||||
* "Something",
|
||||
* 23,
|
||||
* NS_LIST_INIT(x),
|
||||
* };
|
||||
* ~~~
|
||||
* NS_LIST_DEFINE() or NS_LIST_NAME_INIT() may provide a shorter alternative
|
||||
* in simpler cases.
|
||||
*/
|
||||
#define NS_LIST_INIT(name) { { NULL, &(name).slist.first_entry } }
|
||||
|
||||
/** \brief Name and initialiser for an empty list
|
||||
*
|
||||
* Usage:
|
||||
* ~~~
|
||||
* list_t NS_LIST_NAME_INIT(foo);
|
||||
* ~~~
|
||||
* acts as
|
||||
* ~~~
|
||||
* list_t foo = { empty list };
|
||||
* ~~~
|
||||
* Also useful with designated initialisers:
|
||||
* ~~~
|
||||
* .NS_LIST_NAME_INIT(foo),
|
||||
* ~~~
|
||||
* acts as
|
||||
* ~~~
|
||||
* .foo = { empty list },
|
||||
* ~~~
|
||||
*/
|
||||
#define NS_LIST_NAME_INIT(name) name = NS_LIST_INIT(name)
|
||||
|
||||
/** \brief Define a list, and initialise to empty.
|
||||
*
|
||||
* Usage:
|
||||
* ~~~
|
||||
* static NS_LIST_DEFINE(my_list, entry_t, link);
|
||||
* ~~~
|
||||
* acts as
|
||||
* ~~~
|
||||
* static list_type my_list = { empty list };
|
||||
* ~~~
|
||||
*/
|
||||
#define NS_LIST_DEFINE(name, type, field) \
|
||||
NS_LIST_HEAD(type, field) NS_LIST_NAME_INIT(name)
|
||||
|
||||
/** \hideinitializer \brief Add an entry to the start of the linked list.
|
||||
*
|
||||
* ns_list_add_to_end() is *slightly* more efficient than ns_list_add_to_start().
|
||||
*
|
||||
* \param list `(list_t *)` Pointer to list.
|
||||
* \param entry `(entry_t * restrict)` Pointer to new entry to add.
|
||||
*/
|
||||
#define ns_list_add_to_start(list, entry) \
|
||||
ns_list_add_to_start_(&(list)->slist, NS_LIST_OFFSET_(list), NS_LIST_TYPECHECK_(list, entry))
|
||||
|
||||
/** \hideinitializer \brief Add an entry to the end of the linked list.
|
||||
*
|
||||
* \param list `(list_t *)` Pointer to list.
|
||||
* \param entry `(entry_t * restrict)` Pointer to new entry to add.
|
||||
*/
|
||||
#define ns_list_add_to_end(list, entry) \
|
||||
ns_list_add_to_end_(&(list)->slist, NS_LIST_OFFSET_(list), NS_LIST_TYPECHECK_(list, entry))
|
||||
|
||||
/** \hideinitializer \brief Add an entry before a specified entry.
|
||||
*
|
||||
* \param list `(list_t *)` Pointer to list.
|
||||
* \param before `(entry_t *)` Existing entry before which to place the new entry.
|
||||
* \param entry `(entry_t * restrict)` Pointer to new entry to add.
|
||||
*/
|
||||
#define ns_list_add_before(list, before, entry) \
|
||||
ns_list_add_before_(NS_LIST_OFFSET_(list), NS_LIST_TYPECHECK_(list, before), NS_LIST_TYPECHECK_(list, entry))
|
||||
|
||||
/** \hideinitializer \brief Add an entry after a specified entry.
|
||||
*
|
||||
* ns_list_add_before() is *slightly* more efficient than ns_list_add_after().
|
||||
*
|
||||
* \param list `(list_t *)` Pointer to list.
|
||||
* \param after `(entry_t *)` Existing entry after which to place the new entry.
|
||||
* \param entry `(entry_t * restrict)` Pointer to new entry to add.
|
||||
*/
|
||||
#define ns_list_add_after(list, after, entry) \
|
||||
ns_list_add_after_(&(list)->slist, NS_LIST_OFFSET_(list), NS_LIST_TYPECHECK_(list, after), NS_LIST_TYPECHECK_(list, entry))
|
||||
|
||||
/** \brief Check if a list is empty.
|
||||
*
|
||||
* \param list `(const list_t *)` Pointer to list.
|
||||
*
|
||||
* \return `(bool)` true if the list is empty.
|
||||
*/
|
||||
#define ns_list_is_empty(list) ((bool) ((list)->slist.first_entry == NULL))
|
||||
|
||||
/** \brief Get the first entry.
|
||||
*
|
||||
* \param list `(const list_t *)` Pointer to list.
|
||||
*
|
||||
* \return `(entry_t *)` Pointer to first entry.
|
||||
* \return NULL if list is empty.
|
||||
*/
|
||||
#define ns_list_get_first(list) NS_LIST_TYPECAST_(list, (list)->slist.first_entry)
|
||||
|
||||
/** \hideinitializer \brief Get the previous entry.
|
||||
*
|
||||
* \param list `(const list_t *)` Pointer to list.
|
||||
* \param current `(const entry_t *)` Pointer to current entry.
|
||||
*
|
||||
* \return `(entry_t *)` Pointer to previous entry.
|
||||
* \return NULL if current entry is first.
|
||||
*/
|
||||
#define ns_list_get_previous(list, current) \
|
||||
NS_LIST_TYPECAST_(list, ns_list_get_previous_(&(list)->slist, NS_LIST_OFFSET_(list), NS_LIST_TYPECHECK_(list, current)))
|
||||
|
||||
/** \hideinitializer \brief Get the next entry.
|
||||
*
|
||||
* \param list `(const list_t *)` Pointer to list.
|
||||
* \param current `(const entry_t *)` Pointer to current entry.
|
||||
*
|
||||
* \return `(entry_t *)` Pointer to next entry.
|
||||
* \return NULL if current entry is last.
|
||||
*/
|
||||
#define ns_list_get_next(list, current) \
|
||||
NS_LIST_TYPECAST_(list, ns_list_get_next_(NS_LIST_OFFSET_(list), NS_LIST_TYPECHECK_(list, current)))
|
||||
|
||||
/** \hideinitializer \brief Get the last entry.
|
||||
*
|
||||
* \param list `(const list_t *)` Pointer to list.
|
||||
*
|
||||
* \return `(entry_t *)` Pointer to last entry.
|
||||
* \return NULL if list is empty.
|
||||
*/
|
||||
#define ns_list_get_last(list) \
|
||||
NS_LIST_TYPECAST_(list, ns_list_get_last_(&(list)->slist, NS_LIST_OFFSET_(list)))
|
||||
|
||||
/** \hideinitializer \brief Remove an entry.
|
||||
*
|
||||
* \param list `(list_t *)` Pointer to list.
|
||||
* \param entry `(entry_t *)` Entry on list to be removed.
|
||||
*/
|
||||
#define ns_list_remove(list, entry) \
|
||||
ns_list_remove_(&(list)->slist, NS_LIST_OFFSET_(list), NS_LIST_TYPECHECK_(list, entry))
|
||||
|
||||
/** \hideinitializer \brief Replace an entry.
|
||||
*
|
||||
* \param list `(list_t *)` Pointer to list.
|
||||
* \param current `(entry_t *)` Existing entry on list to be replaced.
|
||||
* \param replacement `(entry_t * restrict)` New entry to be the replacement.
|
||||
*/
|
||||
#define ns_list_replace(list, current, replacement) \
|
||||
ns_list_replace_(&(list)->slist, NS_LIST_OFFSET_(list), NS_LIST_TYPECHECK_(list, current), NS_LIST_TYPECHECK_(list, replacement))
|
||||
|
||||
/** \hideinitializer \brief Concatenate two lists.
|
||||
*
|
||||
* Attach the entries on the source list to the end of the destination
|
||||
* list, leaving the source list empty.
|
||||
*
|
||||
* \param dst `(list_t *)` Pointer to destination list.
|
||||
* \param src `(list_t *)` Pointer to source list.
|
||||
*
|
||||
*/
|
||||
#define ns_list_concatenate(dst, src) \
|
||||
(NS_PTR_MATCH_(dst, src, "concatenating different list types"), \
|
||||
ns_list_concatenate_(&(dst)->slist, &(src)->slist, NS_LIST_OFFSET_(src)))
|
||||
|
||||
/** \brief Iterate forwards over a list.
|
||||
*
|
||||
* Example:
|
||||
* ~~~
|
||||
* ns_list_foreach(const my_entry_t, cur, &my_list)
|
||||
* {
|
||||
* printf("%s\n", cur->name);
|
||||
* }
|
||||
* ~~~
|
||||
* Deletion of the current entry is not permitted as its next is checked after
|
||||
* running user code.
|
||||
*
|
||||
* The iteration pointer is declared inside the loop, using C99/C++, so it
|
||||
* is not accessible after the loop. This encourages good code style, and
|
||||
* matches the semantics of C++11's "ranged for", which only provides the
|
||||
* declaration form:
|
||||
* ~~~
|
||||
* for (const my_entry_t cur : my_list)
|
||||
* ~~~
|
||||
* If you need to see the value of the iteration pointer after a `break`,
|
||||
* you will need to assign it to a variable declared outside the loop before
|
||||
* breaking:
|
||||
* ~~~
|
||||
* my_entry_t *match = NULL;
|
||||
* ns_list_foreach(my_entry_t, cur, &my_list)
|
||||
* {
|
||||
* if (cur->id == id)
|
||||
* {
|
||||
* match = cur;
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* ~~~
|
||||
*
|
||||
* The user has to specify the entry type for the pointer definition, as type
|
||||
* extraction from the list argument isn't portable. On the other hand, this
|
||||
* also permits const qualifiers, as in the example above, and serves as
|
||||
* documentation. The entry type will be checked against the list type where the
|
||||
* compiler supports it.
|
||||
*
|
||||
* \param type Entry type `([const] entry_t)`.
|
||||
* \param e Name for iteration pointer to be defined
|
||||
* inside the loop.
|
||||
* \param list `(const list_t *)` Pointer to list - evaluated multiple times.
|
||||
*/
|
||||
#define ns_list_foreach(type, e, list) \
|
||||
for (type *e = ns_list_get_first(list); e; e = ns_list_get_next(list, e))
|
||||
|
||||
/** \brief Iterate forwards over a list, where user may delete.
|
||||
*
|
||||
* As ns_list_foreach(), but deletion of current entry is permitted as its
|
||||
* next pointer is recorded before running user code.
|
||||
*
|
||||
* Example:
|
||||
* ~~~
|
||||
* ns_list_foreach_safe(my_entry_t, cur, &my_list)
|
||||
* {
|
||||
* ns_list_remove(cur);
|
||||
* }
|
||||
* ~~~
|
||||
* \param type Entry type `(entry_t)`.
|
||||
* \param e Name for iteration pointer to be defined
|
||||
* inside the loop.
|
||||
* \param list `(list_t *)` Pointer to list - evaluated multiple times.
|
||||
*/
|
||||
#define ns_list_foreach_safe(type, e, list) \
|
||||
for (type *e = ns_list_get_first(list), *_next##e; \
|
||||
e && (_next##e = ns_list_get_next(list, e), true); e = _next##e)
|
||||
|
||||
/** \brief Iterate backwards over a list.
|
||||
*
|
||||
* As ns_list_foreach(), but going backwards - see its documentation.
|
||||
* Iterating forwards is *slightly* more efficient.
|
||||
*/
|
||||
#define ns_list_foreach_reverse(type, e, list) \
|
||||
for (type *e = ns_list_get_last(list); e; e = ns_list_get_previous(list, e))
|
||||
|
||||
/** \brief Iterate backwards over a list, where user may delete.
|
||||
*
|
||||
* As ns_list_foreach_safe(), but going backwards - see its documentation.
|
||||
* Iterating forwards is *slightly* more efficient.
|
||||
*/
|
||||
#define ns_list_foreach_reverse_safe(type, e, list) \
|
||||
for (type *e = ns_list_get_last(list), *_next##e; \
|
||||
e && (_next##e = ns_list_get_previous(list, e), true); e = _next##e)
|
||||
|
||||
/** \hideinitializer \brief Count entries on a list
|
||||
*
|
||||
* Unlike other operations, this is O(n). Note: if list might contain over
|
||||
* 65535 entries, this function **must not** be used to get the entry count.
|
||||
*
|
||||
* \param list `(const list_t *)` Pointer to list.
|
||||
|
||||
* \return `(uint_fast16_t)` Number of entries that are stored in list.
|
||||
*/
|
||||
#define ns_list_count(list) ns_list_count_(&(list)->slist, NS_LIST_OFFSET_(list))
|
||||
|
||||
/** \privatesection
|
||||
* Internal functions - designed to be accessed using corresponding macros above
|
||||
*/
|
||||
NS_INLINE void ns_list_init_(ns_list_t *list);
|
||||
NS_INLINE void ns_list_link_init_(ns_list_link_t *link);
|
||||
NS_INLINE void ns_list_add_to_start_(ns_list_t *list, ns_list_offset_t link_offset, void *restrict entry);
|
||||
NS_INLINE void ns_list_add_to_end_(ns_list_t *list, ns_list_offset_t link_offset, void *restrict entry);
|
||||
NS_INLINE void ns_list_add_before_(ns_list_offset_t link_offset, void *before, void *restrict entry);
|
||||
NS_INLINE void ns_list_add_after_(ns_list_t *list, ns_list_offset_t link_offset, void *after, void *restrict entry);
|
||||
NS_INLINE void *ns_list_get_next_(ns_list_offset_t link_offset, const void *current);
|
||||
NS_INLINE void *ns_list_get_previous_(const ns_list_t *list, ns_list_offset_t link_offset, const void *current);
|
||||
NS_INLINE void *ns_list_get_last_(const ns_list_t *list, ns_list_offset_t offset);
|
||||
NS_INLINE void ns_list_remove_(ns_list_t *list, ns_list_offset_t link_offset, void *entry);
|
||||
NS_INLINE void ns_list_replace_(ns_list_t *list, ns_list_offset_t link_offset, void *current, void *restrict replacement);
|
||||
NS_INLINE void ns_list_concatenate_(ns_list_t *dst, ns_list_t *src, ns_list_offset_t offset);
|
||||
NS_INLINE uint_fast16_t ns_list_count_(const ns_list_t *list, ns_list_offset_t link_offset);
|
||||
|
||||
/* Provide definitions, either for inlining, or for ns_list.c */
|
||||
#if defined NS_ALLOW_INLINING || defined NS_LIST_FN
|
||||
#ifndef NS_LIST_FN
|
||||
#define NS_LIST_FN NS_INLINE
|
||||
#endif
|
||||
|
||||
/* Pointer to the link member in entry e */
|
||||
#define NS_LIST_LINK_(e, offset) ((ns_list_link_t *)((char *)(e) + offset))
|
||||
|
||||
/* Lvalue of the next link pointer in entry e */
|
||||
#define NS_LIST_NEXT_(e, offset) (NS_LIST_LINK_(e, offset)->next)
|
||||
|
||||
/* Lvalue of the prev link pointer in entry e */
|
||||
#define NS_LIST_PREV_(e, offset) (NS_LIST_LINK_(e, offset)->prev)
|
||||
|
||||
/* Convert a pointer to a link member back to the entry;
|
||||
* works for linkptr either being a ns_list_link_t pointer, or its next pointer,
|
||||
* as the next pointer is first in the ns_list_link_t */
|
||||
#define NS_LIST_ENTRY_(linkptr, offset) ((void *)((char *)(linkptr) - offset))
|
||||
|
||||
NS_LIST_FN void ns_list_init_(ns_list_t *list)
|
||||
{
|
||||
list->first_entry = NULL;
|
||||
list->last_nextptr = &list->first_entry;
|
||||
}
|
||||
|
||||
NS_LIST_FN void ns_list_link_init_(ns_list_link_t *link)
|
||||
{
|
||||
NS_FUNNY_INTPTR_OK
|
||||
link->next = NS_LIST_POISON;
|
||||
link->prev = NS_LIST_POISON;
|
||||
NS_FUNNY_INTPTR_RESTORE
|
||||
}
|
||||
|
||||
NS_LIST_FN void ns_list_add_to_start_(ns_list_t *list, ns_list_offset_t offset, void *restrict entry)
|
||||
{
|
||||
void *next;
|
||||
|
||||
NS_LIST_PREV_(entry, offset) = &list->first_entry;
|
||||
NS_LIST_NEXT_(entry, offset) = next = list->first_entry;
|
||||
|
||||
if (next) {
|
||||
NS_LIST_PREV_(next, offset) = &NS_LIST_NEXT_(entry, offset);
|
||||
} else {
|
||||
list->last_nextptr = &NS_LIST_NEXT_(entry, offset);
|
||||
}
|
||||
|
||||
list->first_entry = entry;
|
||||
}
|
||||
|
||||
NS_LIST_FN void ns_list_add_after_(ns_list_t *list, ns_list_offset_t offset, void *current, void *restrict entry)
|
||||
{
|
||||
void *next;
|
||||
|
||||
NS_LIST_PREV_(entry, offset) = &NS_LIST_NEXT_(current, offset);
|
||||
NS_LIST_NEXT_(entry, offset) = next = NS_LIST_NEXT_(current, offset);
|
||||
|
||||
if (next) {
|
||||
NS_LIST_PREV_(next, offset) = &NS_LIST_NEXT_(entry, offset);
|
||||
} else {
|
||||
list->last_nextptr = &NS_LIST_NEXT_(entry, offset);
|
||||
}
|
||||
|
||||
NS_LIST_NEXT_(current, offset) = entry;
|
||||
}
|
||||
|
||||
NS_LIST_FN void ns_list_add_before_(ns_list_offset_t offset, void *current, void *restrict entry)
|
||||
{
|
||||
void **prev_nextptr;
|
||||
|
||||
NS_LIST_NEXT_(entry, offset) = current;
|
||||
NS_LIST_PREV_(entry, offset) = prev_nextptr = NS_LIST_PREV_(current, offset);
|
||||
*prev_nextptr = entry;
|
||||
NS_LIST_PREV_(current, offset) = &NS_LIST_NEXT_(entry, offset);
|
||||
}
|
||||
|
||||
NS_LIST_FN void ns_list_add_to_end_(ns_list_t *list, ns_list_offset_t offset, void *restrict entry)
|
||||
{
|
||||
void **prev_nextptr;
|
||||
|
||||
NS_LIST_NEXT_(entry, offset) = NULL;
|
||||
NS_LIST_PREV_(entry, offset) = prev_nextptr = list->last_nextptr;
|
||||
*prev_nextptr = entry;
|
||||
list->last_nextptr = &NS_LIST_NEXT_(entry, offset);
|
||||
}
|
||||
|
||||
NS_LIST_FN void *ns_list_get_next_(ns_list_offset_t offset, const void *current)
|
||||
{
|
||||
return NS_LIST_NEXT_(current, offset);
|
||||
}
|
||||
|
||||
NS_LIST_FN void *ns_list_get_previous_(const ns_list_t *list, ns_list_offset_t offset, const void *current)
|
||||
{
|
||||
if (current == list->first_entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Tricky. We don't have a direct previous pointer, but a pointer to the
|
||||
// pointer that points to us - ie &head->first_entry OR &{prev}->next.
|
||||
// This makes life easier on insertion and removal, but this is where we
|
||||
// pay the price.
|
||||
|
||||
// We have to check manually for being the first entry above, so we know it's
|
||||
// a real link's next pointer. Then next is the first field of
|
||||
// ns_list_link_t, so we can use the normal offset value.
|
||||
|
||||
return NS_LIST_ENTRY_(NS_LIST_PREV_(current, offset), offset);
|
||||
}
|
||||
|
||||
NS_LIST_FN void *ns_list_get_last_(const ns_list_t *list, ns_list_offset_t offset)
|
||||
{
|
||||
if (!list->first_entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// See comments in ns_list_get_previous_()
|
||||
return NS_LIST_ENTRY_(list->last_nextptr, offset);
|
||||
}
|
||||
|
||||
NS_LIST_FN void ns_list_remove_(ns_list_t *list, ns_list_offset_t offset, void *removed)
|
||||
{
|
||||
void *next;
|
||||
void **prev_nextptr;
|
||||
|
||||
next = NS_LIST_NEXT_(removed, offset);
|
||||
prev_nextptr = NS_LIST_PREV_(removed, offset);
|
||||
if (next) {
|
||||
NS_LIST_PREV_(next, offset) = prev_nextptr;
|
||||
} else {
|
||||
list->last_nextptr = prev_nextptr;
|
||||
}
|
||||
*prev_nextptr = next;
|
||||
|
||||
ns_list_link_init_(NS_LIST_LINK_(removed, offset));
|
||||
}
|
||||
|
||||
NS_LIST_FN void ns_list_replace_(ns_list_t *list, ns_list_offset_t offset, void *current, void *restrict replacement)
|
||||
{
|
||||
void *next;
|
||||
void **prev_nextptr;
|
||||
|
||||
NS_LIST_PREV_(replacement, offset) = prev_nextptr = NS_LIST_PREV_(current, offset);
|
||||
NS_LIST_NEXT_(replacement, offset) = next = NS_LIST_NEXT_(current, offset);
|
||||
|
||||
if (next) {
|
||||
NS_LIST_PREV_(next, offset) = &NS_LIST_NEXT_(replacement, offset);
|
||||
} else {
|
||||
list->last_nextptr = &NS_LIST_NEXT_(replacement, offset);
|
||||
}
|
||||
*prev_nextptr = replacement;
|
||||
|
||||
ns_list_link_init_(NS_LIST_LINK_(current, offset));
|
||||
}
|
||||
|
||||
NS_LIST_FN void ns_list_concatenate_(ns_list_t *dst, ns_list_t *src, ns_list_offset_t offset)
|
||||
{
|
||||
ns_list_link_t *src_first;
|
||||
|
||||
src_first = src->first_entry;
|
||||
if (!src_first) {
|
||||
return;
|
||||
}
|
||||
|
||||
*dst->last_nextptr = src_first;
|
||||
NS_LIST_PREV_(src_first, offset) = dst->last_nextptr;
|
||||
dst->last_nextptr = src->last_nextptr;
|
||||
|
||||
ns_list_init_(src);
|
||||
}
|
||||
|
||||
NS_LIST_FN uint_fast16_t ns_list_count_(const ns_list_t *list, ns_list_offset_t offset)
|
||||
{
|
||||
uint_fast16_t count = 0;
|
||||
|
||||
for (void *p = list->first_entry; p; p = NS_LIST_NEXT_(p, offset)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif /* defined NS_ALLOW_INLINING || defined NS_LIST_FN */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NS_LIST_H_ */
|
||||
|
||||
403
sdk/component/common/network/coap/include/ns_types.h
Normal file
403
sdk/component/common/network/coap/include/ns_types.h
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* ns_types.h - Basic compiler and type setup for Nanostack libraries.
|
||||
*/
|
||||
#ifndef NS_TYPES_H_
|
||||
#define NS_TYPES_H_
|
||||
|
||||
/** \file
|
||||
* \brief Basic compiler and type setup
|
||||
*
|
||||
* We currently assume C99 or later.
|
||||
*
|
||||
* C99 features being relied on:
|
||||
*
|
||||
* - <inttypes.h> and <stdbool.h>
|
||||
* - inline (with C99 semantics, not C++ as per default GCC);
|
||||
* - designated initialisers;
|
||||
* - compound literals;
|
||||
* - restrict;
|
||||
* - [static N] in array parameters;
|
||||
* - declarations in for statements;
|
||||
* - mixing declarations and statements
|
||||
*
|
||||
* Compilers should be set to C99 or later mode when building Nanomesh source.
|
||||
* For GCC this means "-std=gnu99" (C99 with usual GNU extensions).
|
||||
*
|
||||
* Also, a little extra care is required for public header files that could be
|
||||
* included from C++, especially as C++ lacks some C99 features.
|
||||
*
|
||||
* (TODO: as this is exposed to API users, do we need a predefine to distinguish
|
||||
* internal and external use, for finer control? Not yet, but maybe...)
|
||||
*/
|
||||
|
||||
/* Make sure <stdint.h> defines its macros if C++ */
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#endif
|
||||
#ifndef __STDC_CONSTANT_MACROS
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h> // includes <stdint.h>; debugf() users need PRIu32 etc
|
||||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
* Create the optional <stdint.h> 24-bit types if they don't exist (worth trying
|
||||
* to use them, as they could exist and be more efficient than 32-bit on 8-bit
|
||||
* systems...)
|
||||
*/
|
||||
#ifndef UINT24_LEAST_MAX
|
||||
typedef uint_least32_t uint_least24_t;
|
||||
#define UINT_LEAST24_MAX UINT_LEAST32_MAX
|
||||
#define UINT24_C(x) UINT32_C(x)
|
||||
#define PRIoLEAST24 PRIoLEAST32
|
||||
#define PRIuLEAST24 PRIuLEAST32
|
||||
#define PRIxLEAST24 PRIxLEAST32
|
||||
#define PRIXLEAST24 PRIXLEAST32
|
||||
#endif
|
||||
|
||||
#ifndef INT24_LEAST_MAX
|
||||
typedef int_least32_t int_least24_t;
|
||||
#define INT24_LEAST_MIN INT_LEAST32_MIN
|
||||
#define INT24_LEAST_MAX INT_LEAST32_MAX
|
||||
#define INT24_C(x) INT32_C(x)
|
||||
#define PRIdLEAST24 PRIdLEAST32
|
||||
#define PRIiLEAST24 PRIiLEAST32
|
||||
#endif
|
||||
|
||||
#ifndef UINT24_FAST_MAX
|
||||
typedef uint_fast32_t uint_fast24_t;
|
||||
#define UINT_FAST24_MAX UINT_FAST32_MAX
|
||||
#define PRIoFAST24 PRIoFAST32
|
||||
#define PRIuFAST24 PRIuFAST32
|
||||
#define PRIxFAST24 PRIxFAST32
|
||||
#define PRIXFAST24 PRIXFAST32
|
||||
#endif
|
||||
|
||||
#ifndef INT24_FAST_MAX
|
||||
typedef int_fast32_t int_fast24_t;
|
||||
#define INT_FAST24_MIN INT_FAST32_MIN
|
||||
#define INT_FAST24_MAX INT_FAST32_MAX
|
||||
#define PRIdFAST24 PRIdFAST32
|
||||
#define PRIiFAST24 PRIiFAST32
|
||||
#endif
|
||||
|
||||
/* Function attribute - C11 "noreturn" or C++11 "[[noreturn]]" */
|
||||
#ifndef NS_NORETURN
|
||||
#if defined __cplusplus && __cplusplus >= 201103L
|
||||
#define NS_NORETURN [[noreturn]]
|
||||
#elif !defined __cplusplus && __STDC_VERSION__ >= 201112L
|
||||
#define NS_NORETURN _Noreturn
|
||||
#elif defined __GNUC__
|
||||
#define NS_NORETURN __attribute__((__noreturn__))
|
||||
#elif defined __CC_ARM
|
||||
#define NS_NORETURN __declspec(noreturn)
|
||||
#elif defined __IAR_SYSTEMS_ICC__
|
||||
#define NS_NORETURN __noreturn
|
||||
#else
|
||||
#define NS_NORETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* C11's "alignas" macro, emulated for integer expressions if necessary */
|
||||
#ifndef __alignas_is_defined
|
||||
#if defined __CC_ARM || defined __TASKING__
|
||||
#define alignas(n) __align(n)
|
||||
#define __alignas_is_defined 1
|
||||
#elif (__STDC_VERSION__ >= 201112L) || (defined __cplusplus && __cplusplus >= 201103L)
|
||||
#include <stdalign.h>
|
||||
#elif defined __GNUC__
|
||||
#define alignas(n) __attribute__((__aligned__(n)))
|
||||
#define __alignas_is_defined 1
|
||||
#elif defined __IAR_SYSTEMS_ICC__
|
||||
/* Does this really just apply to the next variable? */
|
||||
#define alignas(n) __Alignas(data_alignment=n)
|
||||
#define __Alignas(x) _Pragma(#x)
|
||||
#define __alignas_is_defined 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Marker for functions or objects that may be unused, suppressing warnings.
|
||||
* Place after the identifier:
|
||||
* ~~~
|
||||
* static int X MAYBE_UNUSED = 3;
|
||||
* static int foo(void) MAYBE_UNUSED;
|
||||
* ~~~
|
||||
*/
|
||||
#if defined __CC_ARM || defined __GNUC__
|
||||
#define MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
/*
|
||||
* C++ (even C++11) doesn't provide restrict: define away or provide
|
||||
* alternative.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#ifdef __GNUC__
|
||||
#define restrict __restrict
|
||||
#else
|
||||
#define restrict
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/**
|
||||
* C++ doesn't allow "static" in function parameter types: ie
|
||||
* ~~~
|
||||
* entry_t *find_entry(const uint8_t address[static 16])
|
||||
* ~~~
|
||||
* If a header file may be included from C++, use this __static define instead.
|
||||
*
|
||||
* (Syntax introduced in C99 - `uint8_t address[16]` in a prototype was always
|
||||
* equivalent to `uint8_t *address`, but the C99 addition of static tells the
|
||||
* compiler that address is never NULL, and always points to at least 16
|
||||
* elements. This adds no new type-checking, but the information could aid
|
||||
* compiler optimisation, and it can serve as documentation).
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __static
|
||||
#else
|
||||
#define __static static
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define NS_GCC_VERSION (__GNUC__ * 10000 \
|
||||
+ __GNUC_MINOR__ * 100 \
|
||||
+ __GNUC_PATCHLEVEL__)
|
||||
#endif
|
||||
|
||||
/** \brief Compile-time assertion
|
||||
*
|
||||
* C11 provides _Static_assert, as does GCC even in C99 mode (and
|
||||
* as a freestanding implementation, we can't rely on <assert.h> to get
|
||||
* the static_assert macro).
|
||||
* C++11 provides static_assert as a keyword, as does G++ in C++0x mode.
|
||||
*
|
||||
* The assertion acts as a declaration that can be placed at file scope, in a
|
||||
* code block (except after a label), or as a member of a struct/union. It
|
||||
* produces a compiler error if "test" evaluates to 0.
|
||||
*
|
||||
* Note that this *includes* the required semicolon when defined, else it
|
||||
* is totally empty, permitting use in structs. (If the user provided the `;`,
|
||||
* it would leave an illegal stray `;` if unavailable).
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
# if __cplusplus >= 201103L || __cpp_static_assert >= 200410
|
||||
# define NS_STATIC_ASSERT(test, str) static_assert(test, str);
|
||||
# elif defined __GXX_EXPERIMENTAL_CXX0X__ && NS_GCC_VERSION >= 40300
|
||||
# define NS_STATIC_ASSERT(test, str) __extension__ static_assert(test, str);
|
||||
# else
|
||||
# define NS_STATIC_ASSERT(test, str)
|
||||
# endif
|
||||
#else /* C */
|
||||
# if __STDC_VERSION__ >= 201112L
|
||||
# define NS_STATIC_ASSERT(test, str) _Static_assert(test, str);
|
||||
# elif defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM
|
||||
# ifdef _Static_assert
|
||||
/*
|
||||
* Some versions of glibc cdefs.h (which comes in via <stdint.h> above)
|
||||
* attempt to define their own _Static_assert (if GCC < 4.6 or
|
||||
* __STRICT_ANSI__) using an extern declaration, which doesn't work in a
|
||||
* struct/union.
|
||||
*
|
||||
* For GCC >= 4.6 and __STRICT_ANSI__, we can do better - just use
|
||||
* the built-in _Static_assert with __extension__. We have to do this, as
|
||||
* ns_list.h needs to use it in a union. No way to get at it though, without
|
||||
* overriding their define.
|
||||
*/
|
||||
# undef _Static_assert
|
||||
# define _Static_assert(x, y) __extension__ _Static_assert(x, y)
|
||||
# endif
|
||||
# define NS_STATIC_ASSERT(test, str) __extension__ _Static_assert(test, str);
|
||||
# else
|
||||
# define NS_STATIC_ASSERT(test, str)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** \brief Pragma to suppress warnings about unusual pointer values.
|
||||
*
|
||||
* Useful if using "poison" values.
|
||||
*/
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#define NS_FUNNY_INTPTR_OK _Pragma("diag_suppress=Pe1053")
|
||||
#define NS_FUNNY_INTPTR_RESTORE _Pragma("diag_default=Pe1053")
|
||||
#else
|
||||
#define NS_FUNNY_INTPTR_OK
|
||||
#define NS_FUNNY_INTPTR_RESTORE
|
||||
#endif
|
||||
|
||||
/** \brief Pragma to suppress warnings about always true/false comparisons
|
||||
*/
|
||||
#if defined __GNUC__ && NS_GCC_VERSION >= 40600 && !defined __CC_ARM
|
||||
#define NS_FUNNY_COMPARE_OK _Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wtype-limits\"")
|
||||
#define NS_FUNNY_COMPARE_RESTORE _Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define NS_FUNNY_COMPARE_OK
|
||||
#define NS_FUNNY_COMPARE_RESTORE
|
||||
#endif
|
||||
|
||||
/** \brief Pragma to suppress warnings arising from dummy definitions.
|
||||
*
|
||||
* Useful when you have function-like macros that returning constants
|
||||
* in cut-down builds. Can be fairly cavalier about disabling as we
|
||||
* do not expect every build to use this macro. Generic builds of
|
||||
* components should ensure this is not included by only using it in
|
||||
* a ifdef blocks providing dummy definitions.
|
||||
*/
|
||||
#ifdef __CC_ARM
|
||||
// statement is unreachable(111), controlling expression is constant(236), expression has no effect(174),
|
||||
// function was declared but never referenced(177), variable was set but never used(550)
|
||||
#define NS_DUMMY_DEFINITIONS_OK _Pragma("diag_suppress=111,236,174,177,550")
|
||||
#elif defined __IAR_SYSTEMS_ICC__
|
||||
// controlling expression is constant
|
||||
#define NS_DUMMY_DEFINITIONS_OK _Pragma("diag_suppress=Pe236")
|
||||
#else
|
||||
#define NS_DUMMY_DEFINITIONS_OK
|
||||
#endif
|
||||
|
||||
/** \brief Convert pointer to member to pointer to containing structure */
|
||||
#define NS_CONTAINER_OF(ptr, type, member) \
|
||||
((type *) ((char *) (ptr) - offsetof(type, member)))
|
||||
|
||||
/*
|
||||
* Inlining could cause problems when mixing with C++; provide a mechanism to
|
||||
* disable it. This could also be turned off for other reasons (although
|
||||
* this can usually be done through a compiler flag, eg -O0 on gcc).
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
#define NS_ALLOW_INLINING
|
||||
#endif
|
||||
|
||||
/* There is inlining problem in GCC version 4.1.x and we know it works in 4.6.3 */
|
||||
#if defined __GNUC__ && NS_GCC_VERSION < 40600
|
||||
#undef NS_ALLOW_INLINING
|
||||
#endif
|
||||
|
||||
/** \brief Mark a potentially-inlineable function.
|
||||
*
|
||||
* We follow C99 semantics, which requires precisely one external definition.
|
||||
* To also allow inlining to be totally bypassed under control of
|
||||
* NS_ALLOW_INLINING, code can be structured as per the example of ns_list:
|
||||
*
|
||||
* foo.h
|
||||
* -----
|
||||
* ~~~
|
||||
* NS_INLINE int my_func(int);
|
||||
*
|
||||
* #if defined NS_ALLOW_INLINING || defined FOO_FN
|
||||
* #ifndef FOO_FN
|
||||
* #define FOO_FN NS_INLINE
|
||||
* #endif
|
||||
* FOO_FN int my_func(int a)
|
||||
* {
|
||||
* definition;
|
||||
* }
|
||||
* #endif
|
||||
* ~~~
|
||||
* foo.c
|
||||
* -----
|
||||
* ~~~
|
||||
* #define FOO_FN extern
|
||||
* #include "foo.h"
|
||||
* ~~~
|
||||
* Which generates:
|
||||
* ~~~
|
||||
* NS_ALLOW_INLINING set NS_ALLOW_INLINING unset
|
||||
* ===================== =======================
|
||||
* Include foo.h Include foo.h
|
||||
* ------------- -------------
|
||||
* inline int my_func(int); int my_func(int);
|
||||
*
|
||||
* // inline definition
|
||||
* inline int my_func(int a)
|
||||
* {
|
||||
* definition;
|
||||
* }
|
||||
*
|
||||
* Compile foo.c Compile foo.c
|
||||
* ------------- -------------
|
||||
* (from .h) inline int my_func(int); int my_func(int);
|
||||
*
|
||||
* // external definition
|
||||
* // because of no "inline" // normal external definition
|
||||
* extern int my_func(int a) extern int my_func(int a)
|
||||
* { {
|
||||
* definition; definition;
|
||||
* } }
|
||||
* ~~~
|
||||
*
|
||||
* Note that even with inline keywords, whether the compiler inlines or not is
|
||||
* up to it. For example, gcc at "-O0" will not inline at all, and will always
|
||||
* call the real functions in foo.o, just as if NS_ALLOW_INLINING was unset.
|
||||
* At "-O2", gcc could potentially inline everything, meaning that foo.o is not
|
||||
* referenced at all.
|
||||
*
|
||||
* Alternatively, you could use "static inline", which gives every caller its
|
||||
* own internal definition. This is compatible with C++ inlining (which expects
|
||||
* the linker to eliminate duplicates), but in C it's less efficient if the code
|
||||
* ends up non-inlined, and it's harder to breakpoint. I don't recommend it
|
||||
* except for the most trivial functions (which could then probably be macros).
|
||||
*/
|
||||
#ifdef NS_ALLOW_INLINING
|
||||
#define NS_INLINE inline
|
||||
#else
|
||||
#define NS_INLINE
|
||||
#endif
|
||||
|
||||
#if defined __SDCC_mcs51 || defined __ICC8051__ || defined __C51__
|
||||
|
||||
/* The 8051 environments: SDCC (historic), IAR (current), Keil (future?) */
|
||||
|
||||
#define NS_LARGE __xdata
|
||||
#define NS_LARGE_PTR __xdata
|
||||
#ifdef __ICC8051__
|
||||
#define NS_REENTRANT
|
||||
#define NS_REENTRANT_PREFIX __idata_reentrant
|
||||
#else
|
||||
#define NS_REENTRANT __reentrant
|
||||
#define NS_REENTRANT_PREFIX
|
||||
#endif
|
||||
#define NS_NEAR_FUNC __near_func
|
||||
|
||||
#else
|
||||
|
||||
/* "Normal" systems. Define it all away. */
|
||||
#define NS_LARGE
|
||||
#define NS_LARGE_PTR
|
||||
#define NS_REENTRANT
|
||||
#define NS_REENTRANT_PREFIX
|
||||
#define NS_NEAR_FUNC
|
||||
|
||||
#endif
|
||||
|
||||
/** \brief Scatter-gather descriptor
|
||||
*
|
||||
* Slightly optimised for small platforms - we assume we won't need any
|
||||
* element bigger than 64K.
|
||||
*/
|
||||
typedef struct ns_iovec {
|
||||
void *iov_base;
|
||||
uint_fast16_t iov_len;
|
||||
} ns_iovec_t;
|
||||
|
||||
#endif /* NS_TYPES_H */
|
||||
126
sdk/component/common/network/coap/include/sn_coap_ameba_port.h
Normal file
126
sdk/component/common/network/coap/include/sn_coap_ameba_port.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#ifndef SN_COAP_AMEBA_PORT
|
||||
#define SN_COAP_AMEBA_PORT
|
||||
|
||||
/** @addtogroup coap COAP
|
||||
* @ingroup network
|
||||
* @brief mbed CoAP APIs and Ameba wrappers
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "diag.h"
|
||||
#include "platform_stdlib.h"
|
||||
#include "osdep_service.h"
|
||||
#include "wifi_constants.h"
|
||||
#include "wifi_conf.h"
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sn_coap_protocol.h"
|
||||
|
||||
#define randLIB_seed_random() NULL /*!< Not used */
|
||||
|
||||
#define COAP_DBG_EN 0 /*!< Flag to enable / disable CoAP debug message in function **tr_debug()** */
|
||||
#define COAP_DBG_DETAIL 0 /*!< Flage to enable / disable detialed log in CoAP debug message in function **tr_debug()** */
|
||||
|
||||
/**
|
||||
* \brief print CoAP debug message
|
||||
*/
|
||||
#define tr_debug(fmat,...) \
|
||||
do { \
|
||||
if(COAP_DBG_EN){ \
|
||||
printf(fmat "\n", ##__VA_ARGS__); \
|
||||
if(COAP_DBG_DETAIL){\
|
||||
printf("Function: %s :: Line: %d\n\n",__FUNCTION__,__LINE__);\
|
||||
}\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* \brief This function is called in **sn_coap_protocol_init()** for ramdom message ID
|
||||
* \return A random 16bit unsigned value
|
||||
*/
|
||||
uint16_t randLIB_get_16bit(void);
|
||||
|
||||
/**
|
||||
* \brief Ameba **malloc()** function wrapper
|
||||
* \param size: memory size to be allocated
|
||||
* \return NULL = if memory allocation failed
|
||||
* \return void* pointer to allocated memory = if allocation success
|
||||
*/
|
||||
void* coap_malloc(uint16_t size);
|
||||
|
||||
/**
|
||||
* \brief Ameba **free()** function wrapper
|
||||
* \param *addr: memory address to be freed
|
||||
*/
|
||||
void coap_free(void* addr);
|
||||
|
||||
/**
|
||||
* \brief Ameba **calloc()** function wrapper, the effective result is the allocation of a zero-initialized memory block of *size* bytes
|
||||
* \param size: memory size to be allocated
|
||||
* \return NULL = if memory allocation failed
|
||||
* \return void* pointer to the allocated memory = if memory allocation success
|
||||
*/
|
||||
void* coap_calloc(uint32_t size);
|
||||
|
||||
/**
|
||||
* \brief Ameba **socket()** function wrapper, creates a **Datagrams type** i.e. *SOCK_DGRAM* socket
|
||||
* \return Non-negative Integer (socket file descriptor) = if successfully completion
|
||||
* \return -1 = if failed to create socket
|
||||
*/
|
||||
int coap_sock_open(void);
|
||||
|
||||
/**
|
||||
* \brief Ameba **close()** function wrapper, closes a socket file descriptor
|
||||
* \param sock_fd: the socket file descriptor is going to be closed.
|
||||
* \return -1 = if close operation failed
|
||||
* \return 0 = if close operation success
|
||||
*/
|
||||
int coap_sock_close(int socket_fd);
|
||||
|
||||
/**
|
||||
* \brief Ameba **sn_coap_protocol_init()** function wrapper, initializes CoAP Protocol part.
|
||||
* \param *coap_tx_callback : function callback pointer to tx function for sending coap messages
|
||||
* \param *coap_rx_callback : function callback pointer to rx function, used to return CoAP header struct with status COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED
|
||||
* when re-sendings exceeded. If set to NULL, no error message is returned.
|
||||
* \return pointer to CoAP handle = if success
|
||||
* \return NULL = if failed
|
||||
*/
|
||||
struct coap_s * coap_protocol_init(uint8_t (*coap_tx_callback)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *), int8_t (*coap_rx_callback)(sn_coap_hdr_s *, sn_nsdl_addr_s *, void *));
|
||||
|
||||
/**
|
||||
* \brief Send the constructed CoAP message to designated host address on the specific port number
|
||||
* \param *to_address : the host / domain / ip address that the message is targeted to
|
||||
* \param port : port number that the host is used to receive the message
|
||||
* \param socket : socket file descriptor used to send the message
|
||||
* \param *coap_msg_hdr : constructed CoAP message pointer
|
||||
* \return The number of bytes sent = if fuccess
|
||||
* \return -1 = if failed
|
||||
*/
|
||||
int coap_send(char *to_address, uint16_t port, int socket, sn_coap_hdr_s *coap_msg_hdr);
|
||||
|
||||
/**
|
||||
* \brief Receive the constructed CoAP message from host
|
||||
* \param socket : socket file descriptor used to receive the message
|
||||
* \param *from_address : an internet address pointer, which the sender address is to be stored into
|
||||
* \param *buf : memory buffer that used to store the received message
|
||||
* \param buf_size : specifies the length in bytes of the buffer pointed to by the *buf* argument.
|
||||
* \return The length of the message in bytes : if successful completion
|
||||
* \return 0 = If no messages are available to be received
|
||||
* \return -1 = receive message failed
|
||||
*/
|
||||
int coap_recv(int socket, struct sockaddr_in *from_address, void *buf, uint32_t buf_size);
|
||||
|
||||
/**
|
||||
* \brief Print CoAP message header (for debug use)
|
||||
* \param *parsed_hdr : pointer to constructed CoAP message header
|
||||
*/
|
||||
void coap_print_hdr(sn_coap_hdr_s* parsed_hdr);
|
||||
|
||||
/*\@}*/
|
||||
|
||||
#endif //SN_COAP_AMEBA_PORT
|
||||
443
sdk/component/common/network/coap/include/sn_coap_header.h
Normal file
443
sdk/component/common/network/coap/include/sn_coap_header.h
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2015 ARM Limited. All rights reserved.
|
||||
* 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 sn_coap_header.h
|
||||
*
|
||||
* \brief CoAP C-library User header interface header file
|
||||
*/
|
||||
|
||||
#ifndef SN_COAP_HEADER_H_
|
||||
#define SN_COAP_HEADER_H_
|
||||
|
||||
/** @addtogroup coap COAP
|
||||
* @ingroup network
|
||||
* @brief mbed CoAP APIs and Ameba wrappers
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Handle structure */
|
||||
struct coap_s;
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * ENUMERATIONS * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Version
|
||||
*/
|
||||
typedef enum coap_version_ {
|
||||
COAP_VERSION_1 = 0x40,
|
||||
COAP_VERSION_UNKNOWN = 0xFF
|
||||
} coap_version_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Message type, used in CoAP Header
|
||||
*/
|
||||
typedef enum sn_coap_msg_type_ {
|
||||
COAP_MSG_TYPE_CONFIRMABLE = 0x00, /**< Reliable Request messages */
|
||||
COAP_MSG_TYPE_NON_CONFIRMABLE = 0x10, /**< Non-reliable Request and Response messages */
|
||||
COAP_MSG_TYPE_ACKNOWLEDGEMENT = 0x20, /**< Response to a Confirmable Request */
|
||||
COAP_MSG_TYPE_RESET = 0x30 /**< Answer a Bad Request */
|
||||
} sn_coap_msg_type_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Message code, used in CoAP Header
|
||||
*/
|
||||
typedef enum sn_coap_msg_code_ {
|
||||
COAP_MSG_CODE_EMPTY = 0,
|
||||
COAP_MSG_CODE_REQUEST_GET = 1,
|
||||
COAP_MSG_CODE_REQUEST_POST = 2,
|
||||
COAP_MSG_CODE_REQUEST_PUT = 3,
|
||||
COAP_MSG_CODE_REQUEST_DELETE = 4,
|
||||
|
||||
COAP_MSG_CODE_RESPONSE_CREATED = 65,
|
||||
COAP_MSG_CODE_RESPONSE_DELETED = 66,
|
||||
COAP_MSG_CODE_RESPONSE_VALID = 67,
|
||||
COAP_MSG_CODE_RESPONSE_CHANGED = 68,
|
||||
COAP_MSG_CODE_RESPONSE_CONTENT = 69,
|
||||
COAP_MSG_CODE_RESPONSE_CONTINUE = 95,
|
||||
COAP_MSG_CODE_RESPONSE_BAD_REQUEST = 128,
|
||||
COAP_MSG_CODE_RESPONSE_UNAUTHORIZED = 129,
|
||||
COAP_MSG_CODE_RESPONSE_BAD_OPTION = 130,
|
||||
COAP_MSG_CODE_RESPONSE_FORBIDDEN = 131,
|
||||
COAP_MSG_CODE_RESPONSE_NOT_FOUND = 132,
|
||||
COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED = 133,
|
||||
COAP_MSG_CODE_RESPONSE_NOT_ACCEPTABLE = 134,
|
||||
COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE = 136,
|
||||
COAP_MSG_CODE_RESPONSE_PRECONDITION_FAILED = 140,
|
||||
COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE = 141,
|
||||
COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT = 143,
|
||||
COAP_MSG_CODE_RESPONSE_INTERNAL_SERVER_ERROR = 160,
|
||||
COAP_MSG_CODE_RESPONSE_NOT_IMPLEMENTED = 161,
|
||||
COAP_MSG_CODE_RESPONSE_BAD_GATEWAY = 162,
|
||||
COAP_MSG_CODE_RESPONSE_SERVICE_UNAVAILABLE = 163,
|
||||
COAP_MSG_CODE_RESPONSE_GATEWAY_TIMEOUT = 164,
|
||||
COAP_MSG_CODE_RESPONSE_PROXYING_NOT_SUPPORTED = 165
|
||||
} sn_coap_msg_code_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Option number, used in CoAP Header
|
||||
*/
|
||||
typedef enum sn_coap_option_numbers_ {
|
||||
COAP_OPTION_IF_MATCH = 1,
|
||||
COAP_OPTION_URI_HOST = 3,
|
||||
COAP_OPTION_ETAG = 4,
|
||||
COAP_OPTION_IF_NONE_MATCH = 5,
|
||||
COAP_OPTION_OBSERVE = 6,
|
||||
COAP_OPTION_URI_PORT = 7,
|
||||
COAP_OPTION_LOCATION_PATH = 8,
|
||||
COAP_OPTION_URI_PATH = 11,
|
||||
COAP_OPTION_CONTENT_FORMAT = 12,
|
||||
COAP_OPTION_MAX_AGE = 14,
|
||||
COAP_OPTION_URI_QUERY = 15,
|
||||
COAP_OPTION_ACCEPT = 17,
|
||||
COAP_OPTION_LOCATION_QUERY = 20,
|
||||
COAP_OPTION_BLOCK2 = 23,
|
||||
COAP_OPTION_BLOCK1 = 27,
|
||||
COAP_OPTION_SIZE2 = 28,
|
||||
COAP_OPTION_PROXY_URI = 35,
|
||||
COAP_OPTION_PROXY_SCHEME = 39,
|
||||
COAP_OPTION_SIZE1 = 60
|
||||
// 128 = (Reserved)
|
||||
// 132 = (Reserved)
|
||||
// 136 = (Reserved)
|
||||
} sn_coap_option_numbers_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Content Format codes
|
||||
*/
|
||||
typedef enum sn_coap_content_format_ {
|
||||
COAP_CT_NONE = -1, // internal
|
||||
COAP_CT_TEXT_PLAIN = 0,
|
||||
COAP_CT_LINK_FORMAT = 40,
|
||||
COAP_CT_XML = 41,
|
||||
COAP_CT_OCTET_STREAM = 42,
|
||||
COAP_CT_EXI = 47,
|
||||
COAP_CT_JSON = 50,
|
||||
COAP_CT__MAX = 0xffff
|
||||
} sn_coap_content_format_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP Observe option values
|
||||
*
|
||||
* draft-ietf-core-observe-16
|
||||
*/
|
||||
typedef enum sn_coap_observe_ {
|
||||
COAP_OBSERVE_NONE = -1, // internal
|
||||
|
||||
// Values for GET requests
|
||||
COAP_OBSERVE_REGISTER = 0,
|
||||
COAP_OBSERVE_DEREGISTER = 1,
|
||||
|
||||
// In responses, value is a 24-bit opaque sequence number
|
||||
COAP_OBSERVE__MAX = 0xffffff
|
||||
} sn_coap_observe_e;
|
||||
|
||||
/**
|
||||
* \brief Enumeration for CoAP status, used in CoAP Header
|
||||
*/
|
||||
typedef enum sn_coap_status_ {
|
||||
COAP_STATUS_OK = 0, /**< Default value is OK */
|
||||
COAP_STATUS_PARSER_ERROR_IN_HEADER = 1, /**< CoAP will send Reset message to invalid message sender */
|
||||
COAP_STATUS_PARSER_DUPLICATED_MSG = 2, /**< CoAP will send Acknowledgement message to duplicated message sender */
|
||||
COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING = 3, /**< User will get whole message after all message blocks received.
|
||||
User must release messages with this status. */
|
||||
COAP_STATUS_PARSER_BLOCKWISE_ACK = 4, /**< Acknowledgement for sent Blockwise message received */
|
||||
COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED = 5, /**< Blockwise message received but not supported by compiling switch */
|
||||
COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED = 6, /**< Blockwise message fully received and returned to app.
|
||||
User must take care of releasing whole payload of the blockwise messages */
|
||||
COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED = 7 /**< When re-transmissions have been done and ACK not received, CoAP library calls
|
||||
RX callback with this status */
|
||||
} sn_coap_status_e;
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * */
|
||||
/* * * * STRUCTURES * * * */
|
||||
/* * * * * * * * * * * * * */
|
||||
|
||||
/**
|
||||
* \brief Structure for CoAP Options
|
||||
*/
|
||||
typedef struct sn_coap_options_list_ {
|
||||
uint8_t etag_len; /**< 1-8 bytes. Repeatable */
|
||||
unsigned int use_size1:1;
|
||||
unsigned int use_size2:1;
|
||||
|
||||
uint16_t proxy_uri_len; /**< 1-1034 bytes. */
|
||||
uint16_t uri_host_len; /**< 1-255 bytes. */
|
||||
uint16_t location_path_len; /**< 0-255 bytes. Repeatable */
|
||||
uint16_t location_query_len; /**< 0-255 bytes. Repeatable */
|
||||
uint16_t uri_query_len; /**< 1-255 bytes. Repeatable */
|
||||
|
||||
sn_coap_content_format_e accept; /**< Value 0-65535. COAP_CT_NONE if not used */
|
||||
|
||||
uint32_t max_age; /**< Value in seconds (default is 60) */
|
||||
uint32_t size1; /**< 0-4 bytes. */
|
||||
uint32_t size2; /**< 0-4 bytes. */
|
||||
int32_t uri_port; /**< Value 0-65535. -1 if not used */
|
||||
int32_t observe; /**< Value 0-0xffffff. -1 if not used */
|
||||
int32_t block1; /**< Value 0-0xffffff. -1 if not used. Not for user */
|
||||
int32_t block2; /**< Value 0-0xffffff. -1 if not used. Not for user */
|
||||
|
||||
uint8_t *proxy_uri_ptr; /**< Must be set to NULL if not used */
|
||||
uint8_t *etag_ptr; /**< Must be set to NULL if not used */
|
||||
uint8_t *uri_host_ptr; /**< Must be set to NULL if not used */
|
||||
uint8_t *location_path_ptr; /**< Must be set to NULL if not used */
|
||||
uint8_t *location_query_ptr; /**< Must be set to NULL if not used */
|
||||
uint8_t *uri_query_ptr; /**< Must be set to NULL if not used */
|
||||
} sn_coap_options_list_s;
|
||||
|
||||
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
|
||||
/* !!! Main CoAP message struct !!! */
|
||||
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
|
||||
|
||||
/**
|
||||
* \brief Main CoAP message struct
|
||||
*/
|
||||
typedef struct sn_coap_hdr_ {
|
||||
uint8_t token_len; /**< 1-8 bytes. */
|
||||
|
||||
sn_coap_status_e coap_status; /**< Used for telling to User special cases when parsing message */
|
||||
sn_coap_msg_code_e msg_code; /**< Empty: 0; Requests: 1-31; Responses: 64-191 */
|
||||
|
||||
sn_coap_msg_type_e msg_type; /**< Confirmable, Non-Confirmable, Acknowledgement or Reset */
|
||||
sn_coap_content_format_e content_format; /**< Set to COAP_CT_NONE if not used */
|
||||
|
||||
uint16_t msg_id; /**< Message ID. Parser sets parsed message ID, builder sets message ID of built coap message */
|
||||
uint16_t uri_path_len; /**< 0-255 bytes. Repeatable. */
|
||||
uint16_t payload_len; /**< Must be set to zero if not used */
|
||||
|
||||
uint8_t *token_ptr; /**< Must be set to NULL if not used */
|
||||
uint8_t *uri_path_ptr; /**< Must be set to NULL if not used. E.g: temp1/temp2 */
|
||||
uint8_t *payload_ptr; /**< Must be set to NULL if not used */
|
||||
|
||||
/* Here are not so often used Options */
|
||||
sn_coap_options_list_s *options_list_ptr; /**< Must be set to NULL if not used */
|
||||
} sn_coap_hdr_s;
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * ENUMERATIONS * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Used protocol
|
||||
*/
|
||||
typedef enum sn_nsdl_capab_ {
|
||||
SN_NSDL_PROTOCOL_HTTP = 0x01, /**< Unsupported */
|
||||
SN_NSDL_PROTOCOL_HTTPS = 0x02, /**< Unsupported */
|
||||
SN_NSDL_PROTOCOL_COAP = 0x04 /**< Supported */
|
||||
} sn_nsdl_capab_e;
|
||||
|
||||
/* * * * * * * * * * * * * */
|
||||
/* * * * STRUCTURES * * * */
|
||||
/* * * * * * * * * * * * * */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Used for creating manually registration message with sn_coap_register()
|
||||
*/
|
||||
typedef struct registration_info_ {
|
||||
uint8_t endpoint_len;
|
||||
uint8_t endpoint_type_len;
|
||||
uint16_t links_len;
|
||||
|
||||
uint8_t *endpoint_ptr; /**< Endpoint name */
|
||||
uint8_t *endpoint_type_ptr; /**< Endpoint type */
|
||||
uint8_t *links_ptr; /**< Resource registration string */
|
||||
} registration_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Address type of given address
|
||||
*/
|
||||
typedef enum sn_nsdl_addr_type_ {
|
||||
SN_NSDL_ADDRESS_TYPE_IPV6 = 0x01, /**< Supported */
|
||||
SN_NSDL_ADDRESS_TYPE_IPV4 = 0x02, /**< Supported */
|
||||
SN_NSDL_ADDRESS_TYPE_HOSTNAME = 0x03, /**< Unsupported */
|
||||
SN_NSDL_ADDRESS_TYPE_NONE = 0xFF
|
||||
} sn_nsdl_addr_type_e;
|
||||
|
||||
/**
|
||||
* \brief Address structure of Packet data
|
||||
*/
|
||||
typedef struct sn_nsdl_addr_ {
|
||||
uint8_t addr_len;
|
||||
sn_nsdl_addr_type_e type;
|
||||
uint16_t port;
|
||||
uint8_t *addr_ptr;
|
||||
} sn_nsdl_addr_s;
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* * * * EXTERNAL FUNCTION PROTOTYPES * * * */
|
||||
/* * * * * * * * * * * * * * * * * * * * * * */
|
||||
/**
|
||||
* \fn sn_coap_hdr_s *sn_coap_parser(struct coap_s *handle, uint16_t packet_data_len, uint8_t *packet_data_ptr, coap_version_e *coap_version_ptr)
|
||||
*
|
||||
* \brief Parses CoAP message from given Packet data
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param packet_data_len is length of given Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *packet_data_ptr is source for Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *coap_version_ptr is destination for parsed CoAP specification version
|
||||
*
|
||||
* \return Return value is pointer to parsed CoAP message.\n
|
||||
* In following failure cases NULL is returned:\n
|
||||
* -Failure in given pointer (= NULL)\n
|
||||
* -Failure in memory allocation (malloc() returns NULL)
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_coap_parser(struct coap_s *handle, uint16_t packet_data_len, uint8_t *packet_data_ptr, coap_version_e *coap_version_ptr);
|
||||
|
||||
/**
|
||||
* \fn void sn_coap_parser_release_allocated_coap_msg_mem(struct coap_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr)
|
||||
*
|
||||
* \brief Releases memory of given CoAP message
|
||||
*
|
||||
* \note Does not release Payload part
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param *freed_coap_msg_ptr is pointer to released CoAP message
|
||||
*/
|
||||
extern void sn_coap_parser_release_allocated_coap_msg_mem(struct coap_s *handle, sn_coap_hdr_s *freed_coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \fn int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr)
|
||||
*
|
||||
* \brief Builds an outgoing message buffer from a CoAP header structure.
|
||||
*
|
||||
* \param *dst_packet_data_ptr is pointer to allocated destination to built CoAP packet
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to source structure for building Packet data
|
||||
*
|
||||
* \return Return value is byte count of built Packet data. In failure cases:\n
|
||||
* -1 = Failure in given CoAP header structure\n
|
||||
* -2 = Failure in given pointer (= NULL)
|
||||
*/
|
||||
extern int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \fn uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr)
|
||||
*
|
||||
* \brief Calculates needed Packet data memory size for given CoAP message
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to data which needed Packet
|
||||
* data length is calculated
|
||||
*
|
||||
* \return Return value is count of needed memory as bytes for build Packet data
|
||||
* Null if failed
|
||||
*/
|
||||
extern uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \fn int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_size)
|
||||
*
|
||||
* \brief Builds an outgoing message buffer from a CoAP header structure.
|
||||
*
|
||||
* \param *dst_packet_data_ptr is pointer to allocated destination to built CoAP packet
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to source structure for building Packet data
|
||||
*
|
||||
* \param blockwise_payload_size Blockwise message maximum payload size
|
||||
*
|
||||
* \return Return value is byte count of built Packet data. In failure cases:\n
|
||||
* -1 = Failure in given CoAP header structure\n
|
||||
* -2 = Failure in given pointer (= NULL)
|
||||
*/
|
||||
extern int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size);
|
||||
|
||||
/**
|
||||
* \fn uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size)
|
||||
*
|
||||
* \brief Calculates needed Packet data memory size for given CoAP message
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to data which needed Packet
|
||||
* data length is calculated
|
||||
* \param blockwise_payload_size Blockwise message maximum payload size
|
||||
*
|
||||
* \return Return value is count of needed memory as bytes for build Packet data
|
||||
* Null if failed
|
||||
*/
|
||||
extern uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size);
|
||||
|
||||
/**
|
||||
* \fn sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code)
|
||||
*
|
||||
* \brief Prepares generic response packet from a request packet. This function allocates memory for the resulting sn_coap_hdr_s
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
* \param *coap_packet_ptr The request packet pointer
|
||||
* \param msg_code response messages code
|
||||
*
|
||||
* \return *coap_packet_ptr The allocated and pre-filled response packet pointer
|
||||
* NULL Error in parsing the request
|
||||
*
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap_packet_ptr, uint8_t msg_code);
|
||||
|
||||
/**
|
||||
* \brief Initialise a message structure to empty
|
||||
*
|
||||
* \param *coap_msg_ptr is pointer to CoAP message to initialise
|
||||
*
|
||||
* \return Return value is pointer passed in
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_coap_parser_init_message(sn_coap_hdr_s *coap_msg_ptr);
|
||||
|
||||
/**
|
||||
* \brief Allocate an empty message structure
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \return Return value is pointer to an empty CoAP message.\n
|
||||
* In following failure cases NULL is returned:\n
|
||||
* -Failure in given pointer (= NULL)\n
|
||||
* -Failure in memory allocation (malloc() returns NULL)
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_coap_parser_alloc_message(struct coap_s *handle);
|
||||
|
||||
/**
|
||||
* \brief Allocates and initializes options list structure
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
* \param *coap_msg_ptr is pointer to CoAP message that will contain the options
|
||||
*
|
||||
* If the message already has a pointer to an option structure, that pointer
|
||||
* is returned, rather than a new structure being allocated.
|
||||
*
|
||||
* \return Return value is pointer to the CoAP options structure.\n
|
||||
* In following failure cases NULL is returned:\n
|
||||
* -Failure in given pointer (= NULL)\n
|
||||
* -Failure in memory allocation (malloc() returns NULL)
|
||||
*/
|
||||
extern sn_coap_options_list_s *sn_coap_parser_alloc_options(struct coap_s *handle, sn_coap_hdr_s *coap_msg_ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*\@}*/
|
||||
|
||||
#endif /* SN_COAP_HEADER_H_ */
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2015 ARM Limited. All rights reserved.
|
||||
* 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 sn_coap_header_internal.h
|
||||
*
|
||||
* \brief Header file for CoAP Header part
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_HEADER_INTERNAL_H_
|
||||
#define SN_COAP_HEADER_INTERNAL_H_
|
||||
|
||||
|
||||
/* * * * * * * * * * * */
|
||||
/* * * * DEFINES * * * */
|
||||
/* * * * * * * * * * * */
|
||||
|
||||
#define COAP_VERSION COAP_VERSION_1 /* Tells which IETF CoAP specification version the CoAP message supports. */
|
||||
/* This value is written to CoAP message header part. */
|
||||
|
||||
/* CoAP Header defines */
|
||||
#define COAP_HEADER_LENGTH 4 /* Fixed Header length of CoAP message as bytes */
|
||||
#define COAP_HEADER_VERSION_MASK 0xC0
|
||||
#define COAP_HEADER_MSG_TYPE_MASK 0x30
|
||||
#define COAP_HEADER_TOKEN_LENGTH_MASK 0x0F
|
||||
#define COAP_HEADER_MSG_ID_MSB_SHIFT 8
|
||||
|
||||
/* CoAP Options defines */
|
||||
#define COAP_OPTIONS_OPTION_NUMBER_SHIFT 4
|
||||
|
||||
/* * * * * * * * * * * * * * */
|
||||
/* * * * ENUMERATIONS * * * */
|
||||
/* * * * * * * * * * * * * * */
|
||||
|
||||
/* * * * * * * * * * * * * */
|
||||
/* * * * STRUCTURES * * * */
|
||||
/* * * * * * * * * * * * * */
|
||||
|
||||
/**
|
||||
* \brief This structure is returned by sn_coap_exec() for sending
|
||||
*/
|
||||
typedef struct sn_nsdl_transmit_ {
|
||||
sn_nsdl_addr_s *dst_addr_ptr;
|
||||
|
||||
sn_nsdl_capab_e protocol;
|
||||
|
||||
uint16_t packet_len;
|
||||
uint8_t *packet_ptr;
|
||||
} sn_nsdl_transmit_s;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* * * * EXTERNAL FUNCTION PROTOTYPES * * * */
|
||||
/* * * * * * * * * * * * * * * * * * * * * * */
|
||||
extern int8_t sn_coap_header_validity_check(sn_coap_hdr_s *src_coap_msg_ptr, coap_version_e coap_version);
|
||||
|
||||
#endif /* SN_COAP_HEADER_INTERNAL_H_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
231
sdk/component/common/network/coap/include/sn_coap_protocol.h
Normal file
231
sdk/component/common/network/coap/include/sn_coap_protocol.h
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2015 ARM Limited. All rights reserved.
|
||||
* 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 sn_coap_protocol.h
|
||||
*
|
||||
* \brief CoAP C-library User protocol interface header file
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_PROTOCOL_H_
|
||||
#define SN_COAP_PROTOCOL_H_
|
||||
|
||||
/** @addtogroup coap COAP
|
||||
* @ingroup network
|
||||
* @brief mbed CoAP APIs and Ameba wrappers
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "sn_coap_header.h"
|
||||
|
||||
/**
|
||||
* \fn struct coap_s *sn_coap_protocol_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *), uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *), int8_t (*used_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *, void *));
|
||||
*
|
||||
* \brief Initializes CoAP Protocol part. When using libNsdl, sn_nsdl_init() calls this function.
|
||||
*
|
||||
* \param *used_malloc_func_ptr is function pointer for used memory allocation function.
|
||||
*
|
||||
* \param *used_free_func_ptr is function pointer for used memory free function.
|
||||
*
|
||||
* \param *used_tx_callback_ptr function callback pointer to tx function for sending coap messages
|
||||
*
|
||||
* \param *used_rx_callback_ptr used to return CoAP header struct with status COAP_STATUS_BUILDER_MESSAGE_SENDING_FAILED
|
||||
* when re-sendings exceeded. If set to NULL, no error message is returned.
|
||||
*
|
||||
* \return Pointer to handle when success\n
|
||||
* Null if failed
|
||||
*/
|
||||
|
||||
extern struct coap_s *sn_coap_protocol_init(void *(*used_malloc_func_ptr)(uint16_t), void (*used_free_func_ptr)(void *),
|
||||
uint8_t (*used_tx_callback_ptr)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *),
|
||||
int8_t (*used_rx_callback_ptr)(sn_coap_hdr_s *, sn_nsdl_addr_s *, void *));
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_destroy(struct coap_s *handle)
|
||||
*
|
||||
* \brief Frees all memory from CoAP protocol part
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \return Return value is always 0
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_destroy(struct coap_s *handle);
|
||||
|
||||
/**
|
||||
* \fn int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, void *param)
|
||||
*
|
||||
* \brief Builds Packet data from given CoAP header structure to be sent
|
||||
*
|
||||
* \param *dst_addr_ptr is pointer to destination address where CoAP message
|
||||
* will be sent (CoAP builder needs that information for message resending purposes)
|
||||
*
|
||||
* \param *dst_packet_data_ptr is pointer to destination of built Packet data
|
||||
*
|
||||
* \param *src_coap_msg_ptr is pointer to source of built Packet data
|
||||
*
|
||||
* \param param void pointer that will be passed to tx/rx function callback when those are called.
|
||||
*
|
||||
* \note If message is blockwised, all payload is not sent at the same time
|
||||
*
|
||||
* \return Return value is byte count of built Packet data.\n
|
||||
* In failure cases:\n
|
||||
* -1 = Failure in CoAP header structure\n
|
||||
* -2 = Failure in given pointer (= NULL)\n
|
||||
* -3 = Failure in Reset message\n
|
||||
* -4 = Failure in Resending message store\n
|
||||
* If there is not enough memory (or User given limit exceeded) for storing
|
||||
* resending messages, situation is ignored.
|
||||
*/
|
||||
extern int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, void *param);
|
||||
|
||||
/**
|
||||
* \fn sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t packet_data_len, uint8_t *packet_data_ptr, void *param)
|
||||
*
|
||||
* \brief Parses received CoAP message from given Packet data
|
||||
*
|
||||
* \param *src_addr_ptr is pointer to source address of received CoAP message
|
||||
* (CoAP parser needs that information for Message acknowledgement)
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param packet_data_len is length of given Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *packet_data_ptr is pointer to source of Packet data to be parsed to CoAP message
|
||||
*
|
||||
* \param *param void pointer that will be passed to tx/rx function callback when those are called.
|
||||
*
|
||||
* \return Return value is pointer to parsed CoAP message structure. This structure includes also coap_status field.\n
|
||||
* In following failure cases NULL is returned:\n
|
||||
* -Given NULL pointer\n
|
||||
* -Failure in parsed header of non-confirmable message\n
|
||||
* -Out of memory (malloc() returns NULL)
|
||||
*/
|
||||
extern sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t packet_data_len, uint8_t *packet_data_ptr, void *param);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time)
|
||||
*
|
||||
* \brief Sends CoAP messages from re-sending queue, if there is any.
|
||||
* Cleans also old messages from the duplication list and from block receiving list
|
||||
*
|
||||
* This function can be called e.g. once in a second but also more frequently.
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \param current_time is System time in seconds. This time is
|
||||
* used for message re-sending timing and to identify old saved data.
|
||||
*
|
||||
* \return 0 = success\n
|
||||
* -1 = failed
|
||||
*/
|
||||
|
||||
extern int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_set_block_size(struct coap_s *handle, uint16_t block_size)
|
||||
*
|
||||
* \brief If block transfer is enabled, this function changes the block size.
|
||||
* \param handle Pointer to CoAP library handle
|
||||
* \param maximum size of CoAP payload. Valid sizes are 16, 32, 64, 128, 256, 512 and 1024 bytes
|
||||
* \return 0 = success\n
|
||||
* -1 = failure
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_set_block_size(struct coap_s *handle, uint16_t block_size);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_set_duplicate_buffer_size(struct coap_s *handle, uint8_t message_count)
|
||||
*
|
||||
* \brief If dublicate message detection is enabled, this function changes buffer size.
|
||||
* \param handle Pointer to CoAP library handle
|
||||
* \param message_count max number of messages saved for duplicate control
|
||||
* \return 0 = success\n
|
||||
* -1 = failure
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_set_duplicate_buffer_size(struct coap_s *handle, uint8_t message_count);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_set_retransmission_parameters(struct coap_s *handle, uint8_t resending_count, uint8_t resending_intervall)
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function changes resending count and interval.
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
* \param resending_count max number of resendings for message
|
||||
* \param resending_intervall message resending intervall in seconds
|
||||
* \return 0 = success\n
|
||||
* -1 = failure
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_set_retransmission_parameters(struct coap_s *handle,
|
||||
uint8_t resending_count, uint8_t resending_interval);
|
||||
|
||||
/**
|
||||
* \fn int8_t sn_coap_protocol_set_retransmission_buffer(struct coap_s *handle, uint8_t buffer_size_messages, uint16_t buffer_size_bytes)
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function changes message retransmission queue size.
|
||||
* Set size to '0' to disable feature. If both are set to '0', then re-sendings are disabled.
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
* \param buffer_size_messages queue size - maximum number of messages to be saved to queue
|
||||
* \param buffer_size_bytes queue size - maximum size of messages saved to queue
|
||||
* \return 0 = success\n
|
||||
* -1 = failure
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_set_retransmission_buffer(struct coap_s *handle,
|
||||
uint8_t buffer_size_messages, uint16_t buffer_size_bytes);
|
||||
|
||||
/**
|
||||
* \fn void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle)
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function removes all messages from the retransmission queue.
|
||||
*/
|
||||
extern void sn_coap_protocol_clear_retransmission_buffer(struct coap_s *handle);
|
||||
|
||||
/**
|
||||
* \fn sn_coap_protocol_block_remove(struct coap_s *handle, sn_nsdl_addr_s *source_address, uint16_t payload_length, void *payload)
|
||||
*
|
||||
* \brief Remove saved block data. Can be used to remove the data from RAM to enable storing it to other place.
|
||||
*
|
||||
* \param handle Pointer to CoAP library handle
|
||||
* \param source_address Addres from where the block has been received.
|
||||
* \param payload_length Length of the coap payload of the block.
|
||||
* \param payload Coap payload of the block.
|
||||
*
|
||||
*/
|
||||
extern void sn_coap_protocol_block_remove(struct coap_s *handle, sn_nsdl_addr_s *source_address, uint16_t payload_length, void *payload);
|
||||
|
||||
/**
|
||||
* \fn void sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t msg_id)
|
||||
*
|
||||
* \brief If re-transmissions are enabled, this function removes message from retransmission buffer.
|
||||
*
|
||||
* \param *handle Pointer to CoAP library handle
|
||||
* \param msg_id message ID to be removed
|
||||
* \return 0 = success\n
|
||||
* -1 = invalid parameter\n
|
||||
* -2 = message was not found
|
||||
*/
|
||||
extern int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t msg_id);
|
||||
|
||||
/*\@}*/
|
||||
|
||||
#endif /* SN_COAP_PROTOCOL_H_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2015 ARM Limited. All rights reserved.
|
||||
* 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 sn_coap_protocol_internal.h
|
||||
*
|
||||
* \brief Header file for CoAP Protocol part
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SN_COAP_PROTOCOL_INTERNAL_H_
|
||||
#define SN_COAP_PROTOCOL_INTERNAL_H_
|
||||
|
||||
#include "ns_list.h"
|
||||
#include "sn_coap_header_internal.h"
|
||||
#include "sn_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct sn_coap_hdr_;
|
||||
|
||||
/* * * * * * * * * * * */
|
||||
/* * * * DEFINES * * * */
|
||||
/* * * * * * * * * * * */
|
||||
|
||||
/* * For Message resending * */
|
||||
#define ENABLE_RESENDINGS 1 /**< Enable / Disable resending from library in building */
|
||||
|
||||
#define SN_COAP_RESENDING_MAX_COUNT 3 /**< Default number of re-sendings */
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_MSGS YOTTA_CFG_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_MSGS MBED_CONF_MBED_CLIENT_SN_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_MSGS 2 /**< Default re-sending queue size - defines how many messages can be stored. Setting this to 0 disables feature */
|
||||
#endif
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_BYTES YOTTA_CFG_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_BYTES MBED_CONF_MBED_CLIENT_SN_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_BYTES 0 /**< Default re-sending queue size - defines size of the re-sending buffer. Setting this to 0 disables feature */
|
||||
#endif
|
||||
|
||||
#define DEFAULT_RESPONSE_TIMEOUT 10 /**< Default re-sending timeout as seconds */
|
||||
|
||||
/* These parameters sets maximum values application can set with API */
|
||||
#define SN_COAP_MAX_ALLOWED_RESENDING_COUNT 6 /**< Maximum allowed count of re-sending */
|
||||
#define SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_MSGS 6 /**< Maximum allowed number of saved re-sending messages */
|
||||
#define SN_COAP_MAX_ALLOWED_RESENDING_BUFF_SIZE_BYTES 512 /**< Maximum allowed size of re-sending buffer */
|
||||
#define SN_COAP_MAX_ALLOWED_RESPONSE_TIMEOUT 40 /**< Maximum allowed re-sending timeout */
|
||||
|
||||
#define RESPONSE_RANDOM_FACTOR 1 /**< Resending random factor, value is specified in IETF CoAP specification */
|
||||
|
||||
/* * For Message duplication detecting * */
|
||||
|
||||
/* Init value for the maximum count of messages to be stored for duplication detection */
|
||||
/* Setting of this value to 0 will disable duplication check, also reduce use of ROM memory */
|
||||
|
||||
// Keep the old flag to maintain backward compatibility
|
||||
#ifndef SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#define SN_COAP_DUPLICATION_MAX_MSGS_COUNT 0
|
||||
#endif
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#define SN_COAP_DUPLICATION_MAX_MSGS_COUNT YOTTA_CFG_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#define SN_COAP_DUPLICATION_MAX_MSGS_COUNT MBED_CONF_MBED_CLIENT_SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Maximum allowed number of saved messages for duplicate searching */
|
||||
#define SN_COAP_MAX_ALLOWED_DUPLICATION_MESSAGE_COUNT 6
|
||||
|
||||
/* Maximum time in seconds of messages to be stored for duplication detection */
|
||||
#define SN_COAP_DUPLICATION_MAX_TIME_MSGS_STORED 60 /* RESPONSE_TIMEOUT * RESPONSE_RANDOM_FACTOR * (2 ^ MAX_RETRANSMIT - 1) + the expected maximum round trip time */
|
||||
|
||||
/* * For Message blockwising * */
|
||||
|
||||
/* Init value for the maximum payload size to be sent and received at one blockwise message */
|
||||
/* Setting of this value to 0 will disable this feature, and also reduce use of ROM memory */
|
||||
/* Note: This define is common for both received and sent Blockwise messages */
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE MBED_CONF_MBED_CLIENT_SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
#define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 0 /**< Must be 2^x and x is at least 4. Suitable values: 0, 16, 32, 64, 128, 256, 512 and 1024 */
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED
|
||||
#define SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED 10 /**< Maximum time in seconds of data (messages and payload) to be stored for blockwising */
|
||||
#endif
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE
|
||||
#define SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE YOTTA_CFG_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_MAX_INCOMING_MESSAGE_SIZE
|
||||
#define SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE MBED_CONF_MBED_CLIENT_SN_COAP_MAX_INCOMING_MESSAGE_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE
|
||||
#define SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE UINT16_MAX
|
||||
#endif
|
||||
|
||||
/* * For Option handling * */
|
||||
#define COAP_OPTION_MAX_AGE_DEFAULT 60 /**< Default value of Max-Age if option not present */
|
||||
#define COAP_OPTION_URI_PORT_NONE (-1) /**< Internal value to represent no Uri-Port option */
|
||||
#define COAP_OPTION_BLOCK_NONE (-1) /**< Internal value to represent no Block1/2 option */
|
||||
|
||||
|
||||
#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */
|
||||
int8_t prepare_blockwise_message(struct coap_s *handle, struct sn_coap_hdr_ *coap_hdr_ptr);
|
||||
#endif
|
||||
|
||||
/* Structure which is stored to Linked list for message sending purposes */
|
||||
typedef struct coap_send_msg_ {
|
||||
uint8_t resending_counter; /* Tells how many times message is still tried to resend */
|
||||
uint32_t resending_time; /* Tells next resending time */
|
||||
|
||||
sn_nsdl_transmit_s *send_msg_ptr;
|
||||
|
||||
struct coap_s *coap; /* CoAP library handle */
|
||||
void *param; /* Extra parameter that will be passed to TX/RX callback functions */
|
||||
|
||||
ns_list_link_t link;
|
||||
} coap_send_msg_s;
|
||||
|
||||
typedef NS_LIST_HEAD(coap_send_msg_s, link) coap_send_msg_list_t;
|
||||
|
||||
/* Structure which is stored to Linked list for message duplication detection purposes */
|
||||
typedef struct coap_duplication_info_ {
|
||||
uint32_t timestamp; /* Tells when duplication information is stored to Linked list */
|
||||
|
||||
uint8_t addr_len;
|
||||
uint8_t *addr_ptr;
|
||||
uint16_t port;
|
||||
|
||||
uint16_t msg_id;
|
||||
|
||||
struct coap_s *coap; /* CoAP library handle */
|
||||
|
||||
ns_list_link_t link;
|
||||
} coap_duplication_info_s;
|
||||
|
||||
typedef NS_LIST_HEAD(coap_duplication_info_s, link) coap_duplication_info_list_t;
|
||||
|
||||
/* Structure which is stored to Linked list for blockwise messages sending purposes */
|
||||
typedef struct coap_blockwise_msg_ {
|
||||
uint32_t timestamp; /* Tells when Blockwise message is stored to Linked list */
|
||||
|
||||
sn_coap_hdr_s *coap_msg_ptr;
|
||||
struct coap_s *coap; /* CoAP library handle */
|
||||
|
||||
ns_list_link_t link;
|
||||
} coap_blockwise_msg_s;
|
||||
|
||||
typedef NS_LIST_HEAD(coap_blockwise_msg_s, link) coap_blockwise_msg_list_t;
|
||||
|
||||
/* Structure which is stored to Linked list for blockwise messages receiving purposes */
|
||||
typedef struct coap_blockwise_payload_ {
|
||||
uint32_t timestamp; /* Tells when Payload is stored to Linked list */
|
||||
|
||||
uint8_t addr_len;
|
||||
uint8_t *addr_ptr;
|
||||
uint16_t port;
|
||||
|
||||
uint16_t payload_len;
|
||||
uint8_t *payload_ptr;
|
||||
struct coap_s *coap; /* CoAP library handle */
|
||||
|
||||
ns_list_link_t link;
|
||||
} coap_blockwise_payload_s;
|
||||
|
||||
typedef NS_LIST_HEAD(coap_blockwise_payload_s, link) coap_blockwise_payload_list_t;
|
||||
|
||||
struct coap_s {
|
||||
void *(*sn_coap_protocol_malloc)(uint16_t);
|
||||
void (*sn_coap_protocol_free)(void *);
|
||||
|
||||
uint8_t (*sn_coap_tx_callback)(uint8_t *, uint16_t, sn_nsdl_addr_s *, void *);
|
||||
int8_t (*sn_coap_rx_callback)(sn_coap_hdr_s *, sn_nsdl_addr_s *, void *);
|
||||
|
||||
#if ENABLE_RESENDINGS /* If Message resending is not used at all, this part of code will not be compiled */
|
||||
coap_send_msg_list_t linked_list_resent_msgs; /* Active resending messages are stored to this Linked list */
|
||||
uint16_t count_resent_msgs;
|
||||
#endif
|
||||
|
||||
#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* If Message duplication detection is not used at all, this part of code will not be compiled */
|
||||
coap_duplication_info_list_t linked_list_duplication_msgs; /* Messages for duplicated messages detection is stored to this Linked list */
|
||||
uint16_t count_duplication_msgs;
|
||||
#endif
|
||||
|
||||
#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwise is not used at all, this part of code will not be compiled */
|
||||
coap_blockwise_msg_list_t linked_list_blockwise_sent_msgs; /* Blockwise message to to be sent is stored to this Linked list */
|
||||
coap_blockwise_payload_list_t linked_list_blockwise_received_payloads; /* Blockwise payload to to be received is stored to this Linked list */
|
||||
#endif
|
||||
|
||||
uint32_t system_time; /* System time seconds */
|
||||
uint16_t sn_coap_block_data_size;
|
||||
uint8_t sn_coap_resending_queue_msgs;
|
||||
uint8_t sn_coap_resending_queue_bytes;
|
||||
uint8_t sn_coap_resending_count;
|
||||
uint8_t sn_coap_resending_intervall;
|
||||
uint8_t sn_coap_duplication_buffer_size;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SN_COAP_PROTOCOL_INTERNAL_H_ */
|
||||
|
||||
92
sdk/component/common/network/coap/include/sn_config.h
Normal file
92
sdk/component/common/network/coap/include/sn_config.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM Limited. All rights reserved.
|
||||
* 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 SN_CONFIG_H
|
||||
#define SN_CONFIG_H
|
||||
|
||||
#include "sn_coap_ameba_port.h"
|
||||
|
||||
/**
|
||||
* \brief Configuration options (set of defines and values)
|
||||
*
|
||||
* This lists set of compile-time options that needs to be used to enable
|
||||
* or disable features selectively, and set the values for the mandatory
|
||||
* parameters.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
* \brief For Message duplication detection
|
||||
* Init value for the maximum count of messages to be stored for duplication detection
|
||||
* Setting of this value to 0 will disable duplication check, also reduce use of ROM memory
|
||||
* Default is set to 1.
|
||||
*/
|
||||
#undef SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* 1 */
|
||||
|
||||
/**
|
||||
* \def SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
*
|
||||
* \brief For Message blockwising
|
||||
* Init value for the maximum payload size to be sent and received at one blockwise message
|
||||
* Setting of this value to 0 will disable this feature, and also reduce use of ROM memory
|
||||
* Note: This define is common for both received and sent Blockwise messages
|
||||
*/
|
||||
#undef SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* 0 */ // < Must be 2^x and x is at least 4. Suitable values: 0, 16, 32, 64, 128, 256, 512 and 1024
|
||||
|
||||
/**
|
||||
* \def COAP_DISABLE_OBS_FEATURE
|
||||
*
|
||||
* \brief Disables CoAP 'obs' sending feature
|
||||
* as part of registration message, this might be
|
||||
* needed to be enabled for some strict LWM2M server implementation.
|
||||
* By default, this feature is disabled.
|
||||
*/
|
||||
#undef COAP_DISABLE_OBS_FEATURE
|
||||
|
||||
/**
|
||||
* \def SN_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
*
|
||||
* \brief Sets the number of messages stored
|
||||
* in the resending queue. Default is 2
|
||||
*/
|
||||
#undef SN_COAP_RESENDING_QUEUE_SIZE_MSGS /* 2 */ // < Default re-sending queue size - defines how many messages can be stored. Setting this to 0 disables feature
|
||||
|
||||
/**
|
||||
* \def SN_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
*
|
||||
* \brief Sets the size of the re-sending buffer.
|
||||
* Setting this to 0 disables this feature.
|
||||
* By default, this feature is disabled.
|
||||
*/
|
||||
#undef SN_COAP_RESENDING_QUEUE_SIZE_BYTES /* 0 */ // Default re-sending queue size - defines size of the re-sending buffer. Setting this to 0 disables feature
|
||||
|
||||
/**
|
||||
* \def SN_COAP_MAX_INCOMING_MESSAGE_SIZE
|
||||
*
|
||||
* \brief Sets the maximum size (in bytes) that
|
||||
* mbed Client will allow to be handled while
|
||||
* receiving big payload in blockwise mode.
|
||||
* Application can set this value based on their
|
||||
* available storage capability.
|
||||
* By default, maximum size is UINT16_MAX, 65535 bytes.
|
||||
*/
|
||||
#undef SN_COAP_MAX_INCOMING_MESSAGE_SIZE /* UINT16_MAX */
|
||||
|
||||
#ifdef MBED_CLIENT_USER_CONFIG_FILE
|
||||
#include MBED_CLIENT_USER_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#endif // SN_CONFIG_H
|
||||
161
sdk/component/common/network/dhcp/dhcps.h
Normal file
161
sdk/component/common/network/dhcp/dhcps.h
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
|
||||
#ifndef __DHCPS_H__
|
||||
#define __DHCPS_H__
|
||||
|
||||
#include "lwip/arch.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "netif/etharp.h"
|
||||
|
||||
#include <platform/platform_stdlib.h>
|
||||
|
||||
#define CONFIG_DHCPS_KEPT_CLIENT_INFO
|
||||
|
||||
#define DHCP_POOL_START 100
|
||||
#define DHCP_POOL_END 200
|
||||
|
||||
#define DHCPS_MAX_CLIENT_NUM (DHCP_POOL_END-DHCP_POOL_START+1)
|
||||
|
||||
#define IS_USE_FIXED_IP 0
|
||||
#define debug_dhcps 0
|
||||
|
||||
/* dhcp server states */
|
||||
#define DHCP_SERVER_STATE_OFFER (1)
|
||||
#define DHCP_SERVER_STATE_DECLINE (2)
|
||||
#define DHCP_SERVER_STATE_ACK (3)
|
||||
#define DHCP_SERVER_STATE_NAK (4)
|
||||
#define DHCP_SERVER_STATE_IDLE (5)
|
||||
|
||||
|
||||
#define BOOTP_BROADCAST (0x8000)
|
||||
|
||||
#define DHCP_MESSAGE_OP_REQUEST (1)
|
||||
#define DHCP_MESSAGE_OP_REPLY (2)
|
||||
|
||||
#define DHCP_MESSAGE_HTYPE (1)
|
||||
#define DHCP_MESSAGE_HLEN (6)
|
||||
|
||||
#define DNS_SERVER_PORT (53)
|
||||
#define DHCP_SERVER_PORT (67)
|
||||
#define DHCP_CLIENT_PORT (68)
|
||||
|
||||
#define DHCP_MESSAGE_TYPE_DISCOVER (1)
|
||||
#define DHCP_MESSAGE_TYPE_OFFER (2)
|
||||
#define DHCP_MESSAGE_TYPE_REQUEST (3)
|
||||
#define DHCP_MESSAGE_TYPE_DECLINE (4)
|
||||
#define DHCP_MESSAGE_TYPE_ACK (5)
|
||||
#define DHCP_MESSAGE_TYPE_NAK (6)
|
||||
#define DHCP_MESSAGE_TYPE_RELEASE (7)
|
||||
|
||||
#define DHCP_OPTION_LENGTH_ONE (1)
|
||||
#define DHCP_OPTION_LENGTH_TWO (2)
|
||||
#define DHCP_OPTION_LENGTH_THREE (3)
|
||||
#define DHCP_OPTION_LENGTH_FOUR (4)
|
||||
#ifndef DHCP_MSG_LEN
|
||||
#define DHCP_MSG_LEN 236
|
||||
#endif
|
||||
#define DHCP_OPTION_TOTAL_LENGTH_MAX 312 //(51)= 4(magic)+3(type)+44(option code: 1,3,6,51,54,28,26,32,end)
|
||||
|
||||
#define DHCP_OPTION_CODE_SUBNET_MASK (1)
|
||||
#define DHCP_OPTION_CODE_ROUTER (3)
|
||||
#define DHCP_OPTION_CODE_DNS_SERVER (6)
|
||||
#define DHCP_OPTION_CODE_INTERFACE_MTU (26)
|
||||
#define DHCP_OPTION_CODE_BROADCAST_ADDRESS (28)
|
||||
#define DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY (31)
|
||||
#define DHCP_OPTION_CODE_REQUEST_IP_ADDRESS (50)
|
||||
#define DHCP_OPTION_CODE_LEASE_TIME (51)
|
||||
#define DHCP_OPTION_CODE_MSG_TYPE (53)
|
||||
#define DHCP_OPTION_CODE_SERVER_ID (54)
|
||||
#define DHCP_OPTION_CODE_REQ_LIST (55)
|
||||
#define DHCP_OPTION_CODE_END (255)
|
||||
|
||||
#define IP_FREE_TO_USE (1)
|
||||
#define IP_ALREADY_IN_USE (0)
|
||||
|
||||
#define HW_ADDRESS_LENGTH (6)
|
||||
|
||||
/* Reference by RFC 2131 */
|
||||
struct dhcp_msg {
|
||||
uint8_t op; /* Message op code/message type. 1 = BOOTREQUEST, 2 = BOOTREPLY */
|
||||
uint8_t htype; /* Hardware address type */
|
||||
uint8_t hlen; /* Hardware address length */
|
||||
uint8_t hops; /* Client sets to zero, optionally used by relay agents
|
||||
when booting via a relay agent */
|
||||
uint8_t xid[4]; /* Transaction ID, a random number chosen by the client,
|
||||
used by the client and server to associate messages and
|
||||
responses between a client and a server */
|
||||
uint16_t secs; /* Filled in by client, seconds elapsed since client began address
|
||||
acquisition or renewal process.*/
|
||||
uint16_t flags; /* bit 0: Broadcast flag, bit 1~15:MBZ must 0*/
|
||||
uint8_t ciaddr[4]; /* Client IP address; only filled in if client is in BOUND,
|
||||
RENEW or REBINDING state and can respond to ARP requests. */
|
||||
uint8_t yiaddr[4]; /* 'your' (client) IP address */
|
||||
uint8_t siaddr[4]; /* IP address of next server to use in bootstrap;
|
||||
returned in DHCPOFFER, DHCPACK by server. */
|
||||
uint8_t giaddr[4]; /* Relay agent IP address, used in booting via a relay agent.*/
|
||||
uint8_t chaddr[16]; /* Client hardware address */
|
||||
uint8_t sname[64]; /* Optional server host name, null terminated string.*/
|
||||
uint8_t file[128]; /* Boot file name, null terminated string; "generic" name or
|
||||
null in DHCPDISCOVER, fully qualified directory-path name in DHCPOFFER.*/
|
||||
uint8_t options[312]; /* Optional parameters field. reference the RFC 2132 */
|
||||
};
|
||||
|
||||
/* use this to check whether the message is dhcp related or not */
|
||||
static const uint8_t dhcp_magic_cookie[4] = {99, 130, 83, 99};
|
||||
static const uint8_t dhcp_option_lease_time[] = {0x00, 0x00, 0x1c, 0x20}; //1 day
|
||||
//static const uint8_t dhcp_option_lease_time[] = {0x00, 0x00, 0x0e, 0x10}; // one hour
|
||||
//static const uint8_t dhcp_option_interface_mtu_576[] = {0x02, 0x40};
|
||||
static const uint8_t dhcp_option_interface_mtu[] = {0x05, 0xDC};
|
||||
|
||||
struct table {
|
||||
uint32_t ip_range[8];
|
||||
#ifdef CONFIG_DHCPS_KEPT_CLIENT_INFO
|
||||
uint8_t client_mac[256][6];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct address_pool{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
};
|
||||
|
||||
PACK_STRUCT_BEGIN
|
||||
/** DNS message header */
|
||||
struct dns_hdr {
|
||||
PACK_STRUCT_FIELD(u16_t id);
|
||||
PACK_STRUCT_FIELD(u8_t flags1);
|
||||
PACK_STRUCT_FIELD(u8_t flags2);
|
||||
PACK_STRUCT_FIELD(u16_t numquestions);
|
||||
PACK_STRUCT_FIELD(u16_t numanswers);
|
||||
PACK_STRUCT_FIELD(u16_t numauthrr);
|
||||
PACK_STRUCT_FIELD(u16_t numextrarr);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
|
||||
/* 01~32 */
|
||||
#define MARK_RANGE1_IP_BIT(table, ip) ((table.ip_range[0]) | (1 << ((ip) - 1)))
|
||||
/* 33~64 */
|
||||
#define MARK_RANGE2_IP_BIT(table, ip) ((table.ip_range[1]) | (1 << ((ip) - 1)))
|
||||
/* 65~96 */
|
||||
#define MARK_RANGE3_IP_BIT(table, ip) ((table.ip_range[2]) | (1 << ((ip) - 1)))
|
||||
/* 97~128 */
|
||||
#define MARK_RANGE4_IP_BIT(table, ip) ((table.ip_range[3]) | (1 << ((ip) - 1)))
|
||||
/* 129~160 */
|
||||
#define MARK_RANGE5_IP_BIT(table, ip) ((table.ip_range[4]) | (1 << ((ip) - 1)))
|
||||
/* 161~192 */
|
||||
#define MARK_RANGE6_IP_BIT(table, ip) ((table.ip_range[5]) | (1 << ((ip) - 1)))
|
||||
/* 193~224 */
|
||||
#define MARK_RANGE7_IP_BIT(table, ip) ((table.ip_range[6]) | (1 << ((ip) - 1)))
|
||||
/* 225~255 */
|
||||
#define MARK_RANGE8_IP_BIT(table, ip) ((table.ip_range[7]) | (1 << ((ip) - 1)))
|
||||
|
||||
/* expose API */
|
||||
void dhcps_set_addr_pool(int addr_pool_set, struct ip_addr * addr_pool_start, struct ip_addr *addr_pool_end);
|
||||
void dhcps_init(struct netif * pnetif);
|
||||
void dhcps_deinit(void);
|
||||
|
||||
extern struct netif *netif_default;
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2VER_H
|
||||
#define NGHTTP2VER_H
|
||||
|
||||
/**
|
||||
* @macro
|
||||
* Version number of the nghttp2 library release
|
||||
*/
|
||||
#define NGHTTP2_VERSION "1.31.0"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
* Numerical representation of the version number of the nghttp2 library
|
||||
* release. This is a 24 bit number with 8 bits for major number, 8 bits
|
||||
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
|
||||
*/
|
||||
#define NGHTTP2_VERSION_NUM 0x013100
|
||||
|
||||
#endif /* NGHTTP2VER_H */
|
||||
412
sdk/component/common/network/http2/nghttp2-1.31.0/nghttp2_buf.h
Normal file
412
sdk/component/common/network/http2/nghttp2-1.31.0/nghttp2_buf.h
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_BUF_H
|
||||
#define NGHTTP2_BUF_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#include "nghttp2_int.h"
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
typedef struct {
|
||||
/* This points to the beginning of the buffer. The effective range
|
||||
of buffer is [begin, end). */
|
||||
uint8_t *begin;
|
||||
/* This points to the memory one byte beyond the end of the
|
||||
buffer. */
|
||||
uint8_t *end;
|
||||
/* The position indicator for effective start of the buffer. pos <=
|
||||
last must be hold. */
|
||||
uint8_t *pos;
|
||||
/* The position indicator for effective one beyond of the end of the
|
||||
buffer. last <= end must be hold. */
|
||||
uint8_t *last;
|
||||
/* Mark arbitrary position in buffer [begin, end) */
|
||||
uint8_t *mark;
|
||||
} nghttp2_buf;
|
||||
|
||||
#define nghttp2_buf_len(BUF) ((size_t)((BUF)->last - (BUF)->pos))
|
||||
#define nghttp2_buf_avail(BUF) ((size_t)((BUF)->end - (BUF)->last))
|
||||
#define nghttp2_buf_mark_avail(BUF) ((size_t)((BUF)->mark - (BUF)->last))
|
||||
#define nghttp2_buf_cap(BUF) ((size_t)((BUF)->end - (BUF)->begin))
|
||||
|
||||
#define nghttp2_buf_pos_offset(BUF) ((size_t)((BUF)->pos - (BUF)->begin))
|
||||
#define nghttp2_buf_last_offset(BUF) ((size_t)((BUF)->last - (BUF)->begin))
|
||||
|
||||
#define nghttp2_buf_shift_right(BUF, AMT) \
|
||||
do { \
|
||||
(BUF)->pos += AMT; \
|
||||
(BUF)->last += AMT; \
|
||||
} while (0)
|
||||
|
||||
#define nghttp2_buf_shift_left(BUF, AMT) \
|
||||
do { \
|
||||
(BUF)->pos -= AMT; \
|
||||
(BUF)->last -= AMT; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Initializes the |buf|. No memory is allocated in this function. Use
|
||||
* nghttp2_buf_reserve() to allocate memory.
|
||||
*/
|
||||
void nghttp2_buf_init(nghttp2_buf *buf);
|
||||
|
||||
/*
|
||||
* Initializes the |buf| and allocates at least |initial| bytes of
|
||||
* memory.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_buf_init2(nghttp2_buf *buf, size_t initial, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees buffer in |buf|.
|
||||
*/
|
||||
void nghttp2_buf_free(nghttp2_buf *buf, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Extends buffer so that nghttp2_buf_cap() returns at least
|
||||
* |new_cap|. If extensions took place, buffer pointers in |buf| will
|
||||
* change.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the followings
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Resets pos, last, mark member of |buf| to buf->begin.
|
||||
*/
|
||||
void nghttp2_buf_reset(nghttp2_buf *buf);
|
||||
|
||||
/*
|
||||
* Initializes |buf| using supplied buffer |begin| of length
|
||||
* |len|. Semantically, the application should not call *_reserve() or
|
||||
* nghttp2_free() functions for |buf|.
|
||||
*/
|
||||
void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len);
|
||||
|
||||
struct nghttp2_buf_chain;
|
||||
|
||||
typedef struct nghttp2_buf_chain nghttp2_buf_chain;
|
||||
|
||||
/* Chains 2 buffers */
|
||||
struct nghttp2_buf_chain {
|
||||
/* Points to the subsequent buffer. NULL if there is no such
|
||||
buffer. */
|
||||
nghttp2_buf_chain *next;
|
||||
nghttp2_buf buf;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* Points to the first buffer */
|
||||
nghttp2_buf_chain *head;
|
||||
/* Buffer pointer where write occurs. */
|
||||
nghttp2_buf_chain *cur;
|
||||
/* Memory allocator */
|
||||
nghttp2_mem *mem;
|
||||
/* The buffer capacity of each buf. This field may be 0 if
|
||||
nghttp2_bufs is initialized by nghttp2_bufs_wrap_init* family
|
||||
functions. */
|
||||
size_t chunk_length;
|
||||
/* The maximum number of nghttp2_buf_chain */
|
||||
size_t max_chunk;
|
||||
/* The number of nghttp2_buf_chain allocated */
|
||||
size_t chunk_used;
|
||||
/* The number of nghttp2_buf_chain to keep on reset */
|
||||
size_t chunk_keep;
|
||||
/* pos offset from begin in each buffers. On initialization and
|
||||
reset, buf->pos and buf->last are positioned at buf->begin +
|
||||
offset. */
|
||||
size_t offset;
|
||||
} nghttp2_bufs;
|
||||
|
||||
/*
|
||||
* This is the same as calling nghttp2_bufs_init2 with the given
|
||||
* arguments and offset = 0.
|
||||
*/
|
||||
int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length, size_t max_chunk,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* This is the same as calling nghttp2_bufs_init3 with the given
|
||||
* arguments and chunk_keep = max_chunk.
|
||||
*/
|
||||
int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
|
||||
size_t max_chunk, size_t offset, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes |bufs|. Each buffer size is given in the
|
||||
* |chunk_length|. The maximum number of buffers is given in the
|
||||
* |max_chunk|. On reset, first |chunk_keep| buffers are kept and
|
||||
* remaining buffers are deleted. Each buffer will have bufs->pos and
|
||||
* bufs->last shifted to left by |offset| bytes on creation and reset.
|
||||
*
|
||||
* This function allocates first buffer. bufs->head and bufs->cur
|
||||
* will point to the first buffer after this call.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* chunk_keep is 0; or max_chunk < chunk_keep; or offset is too
|
||||
* long.
|
||||
*/
|
||||
int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
|
||||
size_t max_chunk, size_t chunk_keep, size_t offset,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees any related resources to the |bufs|.
|
||||
*/
|
||||
void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Initializes |bufs| using supplied buffer |begin| of length |len|.
|
||||
* The first buffer bufs->head uses buffer |begin|. The buffer size
|
||||
* is fixed and no extra chunk buffer is allocated. In other
|
||||
* words, max_chunk = chunk_keep = 1. To free the resource allocated
|
||||
* for |bufs|, use nghttp2_bufs_wrap_free().
|
||||
*
|
||||
* Don't use the function which performs allocation, such as
|
||||
* nghttp2_bufs_realloc().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes |bufs| using supplied |veclen| size of buf vector
|
||||
* |vec|. The number of buffers is fixed and no extra chunk buffer is
|
||||
* allocated. In other words, max_chunk = chunk_keep = |in_len|. To
|
||||
* free the resource allocated for |bufs|, use
|
||||
* nghttp2_bufs_wrap_free().
|
||||
*
|
||||
* Don't use the function which performs allocation, such as
|
||||
* nghttp2_bufs_realloc().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
||||
size_t veclen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees any related resource to the |bufs|. This function does not
|
||||
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
||||
*/
|
||||
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Reallocates internal buffer using |chunk_length|. The max_chunk,
|
||||
* chunk_keep and offset do not change. After successful allocation
|
||||
* of new buffer, previous buffers are deallocated without copying
|
||||
* anything into new buffers. chunk_used is reset to 1.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* chunk_length < offset
|
||||
*/
|
||||
int nghttp2_bufs_realloc(nghttp2_bufs *bufs, size_t chunk_length);
|
||||
|
||||
/*
|
||||
* Appends the |data| of length |len| to the |bufs|. The write starts
|
||||
* at bufs->cur->buf.last. A new buffers will be allocated to store
|
||||
* all data.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len);
|
||||
|
||||
/*
|
||||
* Appends a single byte |b| to the |bufs|. The write starts at
|
||||
* bufs->cur->buf.last. A new buffers will be allocated to store all
|
||||
* data.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_bufs_addb(nghttp2_bufs *bufs, uint8_t b);
|
||||
|
||||
/*
|
||||
* Behaves like nghttp2_bufs_addb(), but this does not update
|
||||
* buf->last pointer.
|
||||
*/
|
||||
int nghttp2_bufs_addb_hold(nghttp2_bufs *bufs, uint8_t b);
|
||||
|
||||
#define nghttp2_bufs_fast_addb(BUFS, B) \
|
||||
do { \
|
||||
*(BUFS)->cur->buf.last++ = B; \
|
||||
} while (0)
|
||||
|
||||
#define nghttp2_bufs_fast_addb_hold(BUFS, B) \
|
||||
do { \
|
||||
*(BUFS)->cur->buf.last = B; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Performs bitwise-OR of |b| at bufs->cur->buf.last. A new buffers
|
||||
* will be allocated if necessary.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_bufs_orb(nghttp2_bufs *bufs, uint8_t b);
|
||||
|
||||
/*
|
||||
* Behaves like nghttp2_bufs_orb(), but does not update buf->last
|
||||
* pointer.
|
||||
*/
|
||||
int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
|
||||
|
||||
#define nghttp2_bufs_fast_orb(BUFS, B) \
|
||||
do { \
|
||||
uint8_t **p = &(BUFS)->cur->buf.last; \
|
||||
**p = (uint8_t)(**p | (B)); \
|
||||
++(*p); \
|
||||
} while (0)
|
||||
|
||||
#define nghttp2_bufs_fast_orb_hold(BUFS, B) \
|
||||
do { \
|
||||
uint8_t *p = (BUFS)->cur->buf.last; \
|
||||
*p = (uint8_t)(*p | (B)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Copies all data stored in |bufs| to the contiguous buffer. This
|
||||
* function allocates the contiguous memory to store all data in
|
||||
* |bufs| and assigns it to |*out|.
|
||||
*
|
||||
* The contents of |bufs| is left unchanged.
|
||||
*
|
||||
* This function returns the length of copied data and assigns the
|
||||
* pointer to copied data to |*out| if it succeeds, or one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
|
||||
|
||||
/*
|
||||
* Copies all data stored in |bufs| to |out|. This function assumes
|
||||
* that the buffer space pointed by |out| has at least
|
||||
* nghttp2_bufs(bufs) bytes.
|
||||
*
|
||||
* The contents of |bufs| is left unchanged.
|
||||
*
|
||||
* This function returns the length of copied data.
|
||||
*/
|
||||
size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out);
|
||||
|
||||
/*
|
||||
* Resets |bufs| and makes the buffers empty.
|
||||
*/
|
||||
void nghttp2_bufs_reset(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Moves bufs->cur to bufs->cur->next. If resulting bufs->cur is
|
||||
* NULL, this function allocates new buffers and bufs->cur points to
|
||||
* it.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_bufs_advance(nghttp2_bufs *bufs);
|
||||
|
||||
/* Sets bufs->cur to bufs->head */
|
||||
#define nghttp2_bufs_rewind(BUFS) \
|
||||
do { \
|
||||
(BUFS)->cur = (BUFS)->head; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Move bufs->cur, from the current position, using next member, to
|
||||
* the last buf which has nghttp2_buf_len(buf) > 0 without seeing buf
|
||||
* which satisfies nghttp2_buf_len(buf) == 0. If
|
||||
* nghttp2_buf_len(&bufs->cur->buf) == 0 or bufs->cur->next is NULL,
|
||||
* bufs->cur is unchanged.
|
||||
*/
|
||||
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Returns nonzero if bufs->cur->next is not empty.
|
||||
*/
|
||||
int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
|
||||
|
||||
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
|
||||
|
||||
/*
|
||||
* Returns the total buffer length of |bufs|.
|
||||
*/
|
||||
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
||||
|
||||
#endif /* NGHTTP2_BUF_H */
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_CALLBACKS_H
|
||||
#define NGHTTP2_CALLBACKS_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/*
|
||||
* Callback functions.
|
||||
*/
|
||||
struct nghttp2_session_callbacks {
|
||||
/**
|
||||
* Callback function invoked when the session wants to send data to
|
||||
* the remote peer. This callback is not necessary if the
|
||||
* application uses solely `nghttp2_session_mem_send()` to serialize
|
||||
* data to transmit.
|
||||
*/
|
||||
nghttp2_send_callback send_callback;
|
||||
/**
|
||||
* Callback function invoked when the session wants to receive data
|
||||
* from the remote peer. This callback is not necessary if the
|
||||
* application uses solely `nghttp2_session_mem_recv()` to process
|
||||
* received data.
|
||||
*/
|
||||
nghttp2_recv_callback recv_callback;
|
||||
/**
|
||||
* Callback function invoked by `nghttp2_session_recv()` when a
|
||||
* frame is received.
|
||||
*/
|
||||
nghttp2_on_frame_recv_callback on_frame_recv_callback;
|
||||
/**
|
||||
* Callback function invoked by `nghttp2_session_recv()` when an
|
||||
* invalid non-DATA frame is received.
|
||||
*/
|
||||
nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
|
||||
/**
|
||||
* Callback function invoked when a chunk of data in DATA frame is
|
||||
* received.
|
||||
*/
|
||||
nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
|
||||
/**
|
||||
* Callback function invoked before a non-DATA frame is sent.
|
||||
*/
|
||||
nghttp2_before_frame_send_callback before_frame_send_callback;
|
||||
/**
|
||||
* Callback function invoked after a frame is sent.
|
||||
*/
|
||||
nghttp2_on_frame_send_callback on_frame_send_callback;
|
||||
/**
|
||||
* The callback function invoked when a non-DATA frame is not sent
|
||||
* because of an error.
|
||||
*/
|
||||
nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
|
||||
/**
|
||||
* Callback function invoked when the stream is closed.
|
||||
*/
|
||||
nghttp2_on_stream_close_callback on_stream_close_callback;
|
||||
/**
|
||||
* Callback function invoked when the reception of header block in
|
||||
* HEADERS or PUSH_PROMISE is started.
|
||||
*/
|
||||
nghttp2_on_begin_headers_callback on_begin_headers_callback;
|
||||
/**
|
||||
* Callback function invoked when a header name/value pair is
|
||||
* received.
|
||||
*/
|
||||
nghttp2_on_header_callback on_header_callback;
|
||||
nghttp2_on_header_callback2 on_header_callback2;
|
||||
/**
|
||||
* Callback function invoked when a invalid header name/value pair
|
||||
* is received which is silently ignored if these callbacks are not
|
||||
* set.
|
||||
*/
|
||||
nghttp2_on_invalid_header_callback on_invalid_header_callback;
|
||||
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
|
||||
/**
|
||||
* Callback function invoked when the library asks application how
|
||||
* many padding bytes are required for the transmission of the given
|
||||
* frame.
|
||||
*/
|
||||
nghttp2_select_padding_callback select_padding_callback;
|
||||
/**
|
||||
* The callback function used to determine the length allowed in
|
||||
* `nghttp2_data_source_read_callback()`
|
||||
*/
|
||||
nghttp2_data_source_read_length_callback read_length_callback;
|
||||
/**
|
||||
* Sets callback function invoked when a frame header is received.
|
||||
*/
|
||||
nghttp2_on_begin_frame_callback on_begin_frame_callback;
|
||||
nghttp2_send_data_callback send_data_callback;
|
||||
nghttp2_pack_extension_callback pack_extension_callback;
|
||||
nghttp2_unpack_extension_callback unpack_extension_callback;
|
||||
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
|
||||
nghttp2_error_callback error_callback;
|
||||
nghttp2_error_callback2 error_callback2;
|
||||
};
|
||||
|
||||
#endif /* NGHTTP2_CALLBACKS_H */
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_DEBUG_H
|
||||
#define NGHTTP2_DEBUG_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
|
||||
void nghttp2_debug_vprintf(const char *format, ...);
|
||||
#else
|
||||
#define DEBUGF(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* NGHTTP2_DEBUG_H */
|
||||
|
|
@ -0,0 +1,575 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_FRAME_H
|
||||
#define NGHTTP2_FRAME_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_hd.h"
|
||||
#include "nghttp2_buf.h"
|
||||
|
||||
#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1)
|
||||
#define NGHTTP2_PRI_GROUP_ID_MASK ((1u << 31) - 1)
|
||||
#define NGHTTP2_PRIORITY_MASK ((1u << 31) - 1)
|
||||
#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1)
|
||||
#define NGHTTP2_SETTINGS_ID_MASK ((1 << 24) - 1)
|
||||
|
||||
/* The number of bytes of frame header. */
|
||||
#define NGHTTP2_FRAME_HDLEN 9
|
||||
|
||||
#define NGHTTP2_MAX_FRAME_SIZE_MAX ((1 << 24) - 1)
|
||||
#define NGHTTP2_MAX_FRAME_SIZE_MIN (1 << 14)
|
||||
|
||||
#define NGHTTP2_MAX_PAYLOADLEN 16384
|
||||
/* The one frame buffer length for tranmission. We may use several of
|
||||
them to support CONTINUATION. To account for Pad Length field, we
|
||||
allocate extra 1 byte, which saves extra large memcopying. */
|
||||
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
|
||||
(NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
|
||||
|
||||
/* The default length of DATA frame payload. */
|
||||
#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
|
||||
|
||||
/* Maximum headers block size to send, calculated using
|
||||
nghttp2_hd_deflate_bound(). This is the default value, and can be
|
||||
overridden by nghttp2_option_set_max_send_header_block_size(). */
|
||||
#define NGHTTP2_MAX_HEADERSLEN 65536
|
||||
|
||||
/* The number of bytes for each SETTINGS entry */
|
||||
#define NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH 6
|
||||
|
||||
/* Length of priority related fields in HEADERS/PRIORITY frames */
|
||||
#define NGHTTP2_PRIORITY_SPECLEN 5
|
||||
|
||||
/* Maximum length of padding in bytes. */
|
||||
#define NGHTTP2_MAX_PADLEN 256
|
||||
|
||||
/* Union of extension frame payload */
|
||||
typedef union {
|
||||
nghttp2_ext_altsvc altsvc;
|
||||
} nghttp2_ext_frame_payload;
|
||||
|
||||
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
|
||||
|
||||
void nghttp2_frame_unpack_frame_hd(nghttp2_frame_hd *hd, const uint8_t *buf);
|
||||
|
||||
/**
|
||||
* Initializes frame header |hd| with given parameters. Reserved bit
|
||||
* is set to 0.
|
||||
*/
|
||||
void nghttp2_frame_hd_init(nghttp2_frame_hd *hd, size_t length, uint8_t type,
|
||||
uint8_t flags, int32_t stream_id);
|
||||
|
||||
/**
|
||||
* Returns the number of priority field depending on the |flags|. If
|
||||
* |flags| has neither NGHTTP2_FLAG_PRIORITY_GROUP nor
|
||||
* NGHTTP2_FLAG_PRIORITY_DEPENDENCY set, return 0.
|
||||
*/
|
||||
size_t nghttp2_frame_priority_len(uint8_t flags);
|
||||
|
||||
/**
|
||||
* Packs the |pri_spec| in |buf|. This function assumes |buf| has
|
||||
* enough space for serialization.
|
||||
*/
|
||||
void nghttp2_frame_pack_priority_spec(uint8_t *buf,
|
||||
const nghttp2_priority_spec *pri_spec);
|
||||
|
||||
/**
|
||||
* Unpacks the priority specification from payload |payload| of length
|
||||
* |payloadlen| to |pri_spec|. The |flags| is used to determine what
|
||||
* kind of priority specification is in |payload|. This function
|
||||
* assumes the |payload| contains whole priority specification.
|
||||
*/
|
||||
void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Returns the offset from the HEADERS frame payload where the
|
||||
* compressed header block starts. The frame payload does not include
|
||||
* frame header.
|
||||
*/
|
||||
size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame);
|
||||
|
||||
/*
|
||||
* Packs HEADERS frame |frame| in wire format and store it in |bufs|.
|
||||
* This function expands |bufs| as necessary to store frame.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* frame->hd.length is assigned after length is determined during
|
||||
* packing process. CONTINUATION frames are also serialized in this
|
||||
* function. This function does not handle padding.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or returns one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* The deflate operation failed.
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_frame_pack_headers(nghttp2_bufs *bufs, nghttp2_headers *frame,
|
||||
nghttp2_hd_deflater *deflater);
|
||||
|
||||
/*
|
||||
* Unpacks HEADERS frame byte sequence into |frame|. This function
|
||||
* only unapcks bytes that come before name/value header block and
|
||||
* after possible Pad Length field.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Packs PRIORITY frame |frame| in wire format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame);
|
||||
|
||||
/*
|
||||
* Unpacks PRIORITY wire format into |frame|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Packs RST_STREAM frame |frame| in wire frame format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
|
||||
nghttp2_rst_stream *frame);
|
||||
|
||||
/*
|
||||
* Unpacks RST_STREAM frame byte sequence into |frame|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Packs SETTINGS frame |frame| in wire format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or returns one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The length of the frame is too large.
|
||||
*/
|
||||
int nghttp2_frame_pack_settings(nghttp2_bufs *bufs, nghttp2_settings *frame);
|
||||
|
||||
/*
|
||||
* Packs the |iv|, which includes |niv| entries, in the |buf|,
|
||||
* assuming the |buf| has at least 8 * |niv| bytes.
|
||||
*
|
||||
* Returns the number of bytes written into the |buf|.
|
||||
*/
|
||||
size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
|
||||
const nghttp2_settings_entry *iv,
|
||||
size_t niv);
|
||||
|
||||
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Initializes payload of frame->settings. The |frame| takes
|
||||
* ownership of |iv|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||
nghttp2_settings_entry *iv,
|
||||
size_t niv);
|
||||
|
||||
/*
|
||||
* Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are
|
||||
* assigned to the |*niv_ptr|. This function allocates enough memory
|
||||
* to store the result in |*iv_ptr|. The caller is responsible to free
|
||||
* |*iv_ptr| after its use.
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr,
|
||||
size_t *niv_ptr,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Packs PUSH_PROMISE frame |frame| in wire format and store it in
|
||||
* |bufs|. This function expands |bufs| as necessary to store
|
||||
* frame.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* frame->hd.length is assigned after length is determined during
|
||||
* packing process. CONTINUATION frames are also serialized in this
|
||||
* function. This function does not handle padding.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or returns one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* The deflate operation failed.
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
|
||||
nghttp2_push_promise *frame,
|
||||
nghttp2_hd_deflater *deflater);
|
||||
|
||||
/*
|
||||
* Unpacks PUSH_PROMISE frame byte sequence into |frame|. This
|
||||
* function only unapcks bytes that come before name/value header
|
||||
* block and after possible Pad Length field.
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_PROTO
|
||||
* TODO END_HEADERS flag is not set
|
||||
*/
|
||||
int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Packs PING frame |frame| in wire format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame);
|
||||
|
||||
/*
|
||||
* Unpacks PING wire format into |frame|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Packs GOAWAY frame |frame| in wire format and store it in |bufs|.
|
||||
* This function expands |bufs| as necessary to store frame.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The length of the frame is too large.
|
||||
*/
|
||||
int nghttp2_frame_pack_goaway(nghttp2_bufs *bufs, nghttp2_goaway *frame);
|
||||
|
||||
/*
|
||||
* Unpacks GOAWAY wire format into |frame|. The |payload| of length
|
||||
* |payloadlen| contains first 8 bytes of payload. The
|
||||
* |var_gift_payload| of length |var_gift_payloadlen| contains
|
||||
* remaining payload and its buffer is gifted to the function and then
|
||||
* |frame|. The |var_gift_payloadlen| must be freed by
|
||||
* nghttp2_frame_goaway_free().
|
||||
*/
|
||||
void nghttp2_frame_unpack_goaway_payload(nghttp2_goaway *frame,
|
||||
const uint8_t *payload,
|
||||
uint8_t *var_gift_payload,
|
||||
size_t var_gift_payloadlen);
|
||||
|
||||
/*
|
||||
* Unpacks GOAWAY wire format into |frame|. This function only exists
|
||||
* for unit test. After allocating buffer for debug data, this
|
||||
* function internally calls nghttp2_frame_unpack_goaway_payload().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Packs WINDOW_UPDATE frame |frame| in wire frame format and store it
|
||||
* in |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
|
||||
nghttp2_window_update *frame);
|
||||
|
||||
/*
|
||||
* Unpacks WINDOW_UPDATE frame byte sequence into |frame|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Packs ALTSVC frame |frame| in wire frame format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
|
||||
|
||||
/*
|
||||
* Unpacks ALTSVC wire format into |frame|. The |payload| of
|
||||
* |payloadlen| bytes contains frame payload. This function assumes
|
||||
* that frame->payload points to the nghttp2_ext_altsvc object.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
||||
size_t origin_len, uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Unpacks ALTSVC wire format into |frame|. This function only exists
|
||||
* for unit test. After allocating buffer for fields, this function
|
||||
* internally calls nghttp2_frame_unpack_altsvc_payload().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The payload is too small.
|
||||
*/
|
||||
int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
||||
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
||||
* not assigned yet, it must be -1.
|
||||
*/
|
||||
void nghttp2_frame_headers_init(nghttp2_headers *frame, uint8_t flags,
|
||||
int32_t stream_id, nghttp2_headers_category cat,
|
||||
const nghttp2_priority_spec *pri_spec,
|
||||
nghttp2_nv *nva, size_t nvlen);
|
||||
|
||||
void nghttp2_frame_headers_free(nghttp2_headers *frame, nghttp2_mem *mem);
|
||||
|
||||
void nghttp2_frame_priority_init(nghttp2_priority *frame, int32_t stream_id,
|
||||
const nghttp2_priority_spec *pri_spec);
|
||||
|
||||
void nghttp2_frame_priority_free(nghttp2_priority *frame);
|
||||
|
||||
void nghttp2_frame_rst_stream_init(nghttp2_rst_stream *frame, int32_t stream_id,
|
||||
uint32_t error_code);
|
||||
|
||||
void nghttp2_frame_rst_stream_free(nghttp2_rst_stream *frame);
|
||||
|
||||
/*
|
||||
* Initializes PUSH_PROMISE frame |frame| with given values. |frame|
|
||||
* takes ownership of |nva|, so caller must not free it.
|
||||
*/
|
||||
void nghttp2_frame_push_promise_init(nghttp2_push_promise *frame, uint8_t flags,
|
||||
int32_t stream_id,
|
||||
int32_t promised_stream_id,
|
||||
nghttp2_nv *nva, size_t nvlen);
|
||||
|
||||
void nghttp2_frame_push_promise_free(nghttp2_push_promise *frame,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes SETTINGS frame |frame| with given values. |frame| takes
|
||||
* ownership of |iv|, so caller must not free it. The |flags| are
|
||||
* bitwise-OR of one or more of nghttp2_settings_flag.
|
||||
*/
|
||||
void nghttp2_frame_settings_init(nghttp2_settings *frame, uint8_t flags,
|
||||
nghttp2_settings_entry *iv, size_t niv);
|
||||
|
||||
void nghttp2_frame_settings_free(nghttp2_settings *frame, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes PING frame |frame| with given values. If the
|
||||
* |opqeue_data| is not NULL, it must point to 8 bytes memory region
|
||||
* of data. The data pointed by |opaque_data| is copied. It can be
|
||||
* NULL. In this case, 8 bytes NULL is used.
|
||||
*/
|
||||
void nghttp2_frame_ping_init(nghttp2_ping *frame, uint8_t flags,
|
||||
const uint8_t *opque_data);
|
||||
|
||||
void nghttp2_frame_ping_free(nghttp2_ping *frame);
|
||||
|
||||
/*
|
||||
* Initializes GOAWAY frame |frame| with given values. On success,
|
||||
* this function takes ownership of |opaque_data|, so caller must not
|
||||
* free it. If the |opaque_data_len| is 0, opaque_data could be NULL.
|
||||
*/
|
||||
void nghttp2_frame_goaway_init(nghttp2_goaway *frame, int32_t last_stream_id,
|
||||
uint32_t error_code, uint8_t *opaque_data,
|
||||
size_t opaque_data_len);
|
||||
|
||||
void nghttp2_frame_goaway_free(nghttp2_goaway *frame, nghttp2_mem *mem);
|
||||
|
||||
void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
|
||||
uint8_t flags, int32_t stream_id,
|
||||
int32_t window_size_increment);
|
||||
|
||||
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
|
||||
|
||||
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
|
||||
uint8_t flags, int32_t stream_id,
|
||||
void *payload);
|
||||
|
||||
void nghttp2_frame_extension_free(nghttp2_extension *frame);
|
||||
|
||||
/*
|
||||
* Initializes ALTSVC frame |frame| with given values. This function
|
||||
* assumes that frame->payload points to nghttp2_ext_altsvc object.
|
||||
* Also |origin| and |field_value| are allocated in single buffer,
|
||||
* starting |origin|. On success, this function takes ownership of
|
||||
* |origin|, so caller must not free it.
|
||||
*/
|
||||
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
||||
uint8_t *origin, size_t origin_len,
|
||||
uint8_t *field_value, size_t field_value_len);
|
||||
|
||||
/*
|
||||
* Frees up resources under |frame|. This function does not free
|
||||
* nghttp2_ext_altsvc object pointed by frame->payload. This function
|
||||
* only frees origin pointed by nghttp2_ext_altsvc.origin. Therefore,
|
||||
* other fields must be allocated in the same buffer with origin.
|
||||
*/
|
||||
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Returns the number of padding bytes after payload. The total
|
||||
* padding length is given in the |padlen|. The returned value does
|
||||
* not include the Pad Length field. If |padlen| is 0, this function
|
||||
* returns 0, regardless of frame->hd.flags.
|
||||
*/
|
||||
size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen);
|
||||
|
||||
void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
|
||||
int32_t stream_id);
|
||||
|
||||
void nghttp2_frame_data_free(nghttp2_data *frame);
|
||||
|
||||
/*
|
||||
* Makes copy of |iv| and return the copy. The |niv| is the number of
|
||||
* entries in |iv|. This function returns the pointer to the copy if
|
||||
* it succeeds, or NULL.
|
||||
*/
|
||||
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
||||
size_t niv, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Sorts the |nva| in ascending order of name and value. If names are
|
||||
* equivalent, sort them by value.
|
||||
*/
|
||||
void nghttp2_nv_array_sort(nghttp2_nv *nva, size_t nvlen);
|
||||
|
||||
/*
|
||||
* Copies name/value pairs from |nva|, which contains |nvlen| pairs,
|
||||
* to |*nva_ptr|, which is dynamically allocated so that all items can
|
||||
* be stored. The resultant name and value in nghttp2_nv are
|
||||
* guaranteed to be NULL-terminated even if the input is not
|
||||
* null-terminated.
|
||||
*
|
||||
* The |*nva_ptr| must be freed using nghttp2_nv_array_del().
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
|
||||
size_t nvlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Returns nonzero if the name/value pair |a| equals to |b|. The name
|
||||
* is compared in case-sensitive, because we ensure that this function
|
||||
* is called after the name is lower-cased.
|
||||
*/
|
||||
int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b);
|
||||
|
||||
/*
|
||||
* Frees |nva|.
|
||||
*/
|
||||
void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Checks that the |iv|, which includes |niv| entries, does not have
|
||||
* invalid values.
|
||||
*
|
||||
* This function returns nonzero if it succeeds, or 0.
|
||||
*/
|
||||
int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
|
||||
|
||||
/*
|
||||
* Sets Pad Length field and flags and adjusts frame header position
|
||||
* of each buffers in |bufs|. The number of padding is given in the
|
||||
* |padlen| including Pad Length field. The |hd| is the frame header
|
||||
* for the serialized data. This function fills zeros padding region
|
||||
* unless framehd_only is nonzero.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The length of the resulting frame is too large.
|
||||
*/
|
||||
int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
||||
size_t padlen, int framehd_only);
|
||||
|
||||
#endif /* NGHTTP2_FRAME_H */
|
||||
432
sdk/component/common/network/http2/nghttp2-1.31.0/nghttp2_hd.h
Normal file
432
sdk/component/common/network/http2/nghttp2-1.31.0/nghttp2_hd.h
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2013 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_HD_H
|
||||
#define NGHTTP2_HD_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#include "nghttp2_hd_huffman.h"
|
||||
#include "nghttp2_buf.h"
|
||||
#include "nghttp2_mem.h"
|
||||
#include "nghttp2_rcbuf.h"
|
||||
|
||||
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
|
||||
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
|
||||
|
||||
/* The maximum length of one name/value pair. This is the sum of the
|
||||
length of name and value. This is not specified by the spec. We
|
||||
just chose the arbitrary size */
|
||||
#define NGHTTP2_HD_MAX_NV 65536
|
||||
|
||||
/* Default size of maximum table buffer size for encoder. Even if
|
||||
remote decoder notifies larger buffer size for its decoding,
|
||||
encoder only uses the memory up to this value. */
|
||||
#define NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE (1 << 12)
|
||||
|
||||
/* Exported for unit test */
|
||||
#define NGHTTP2_STATIC_TABLE_LENGTH 61
|
||||
|
||||
/* Generated by genlibtokenlookup.py */
|
||||
typedef enum {
|
||||
NGHTTP2_TOKEN__AUTHORITY = 0,
|
||||
NGHTTP2_TOKEN__METHOD = 1,
|
||||
NGHTTP2_TOKEN__PATH = 3,
|
||||
NGHTTP2_TOKEN__SCHEME = 5,
|
||||
NGHTTP2_TOKEN__STATUS = 7,
|
||||
NGHTTP2_TOKEN_ACCEPT_CHARSET = 14,
|
||||
NGHTTP2_TOKEN_ACCEPT_ENCODING = 15,
|
||||
NGHTTP2_TOKEN_ACCEPT_LANGUAGE = 16,
|
||||
NGHTTP2_TOKEN_ACCEPT_RANGES = 17,
|
||||
NGHTTP2_TOKEN_ACCEPT = 18,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN = 19,
|
||||
NGHTTP2_TOKEN_AGE = 20,
|
||||
NGHTTP2_TOKEN_ALLOW = 21,
|
||||
NGHTTP2_TOKEN_AUTHORIZATION = 22,
|
||||
NGHTTP2_TOKEN_CACHE_CONTROL = 23,
|
||||
NGHTTP2_TOKEN_CONTENT_DISPOSITION = 24,
|
||||
NGHTTP2_TOKEN_CONTENT_ENCODING = 25,
|
||||
NGHTTP2_TOKEN_CONTENT_LANGUAGE = 26,
|
||||
NGHTTP2_TOKEN_CONTENT_LENGTH = 27,
|
||||
NGHTTP2_TOKEN_CONTENT_LOCATION = 28,
|
||||
NGHTTP2_TOKEN_CONTENT_RANGE = 29,
|
||||
NGHTTP2_TOKEN_CONTENT_TYPE = 30,
|
||||
NGHTTP2_TOKEN_COOKIE = 31,
|
||||
NGHTTP2_TOKEN_DATE = 32,
|
||||
NGHTTP2_TOKEN_ETAG = 33,
|
||||
NGHTTP2_TOKEN_EXPECT = 34,
|
||||
NGHTTP2_TOKEN_EXPIRES = 35,
|
||||
NGHTTP2_TOKEN_FROM = 36,
|
||||
NGHTTP2_TOKEN_HOST = 37,
|
||||
NGHTTP2_TOKEN_IF_MATCH = 38,
|
||||
NGHTTP2_TOKEN_IF_MODIFIED_SINCE = 39,
|
||||
NGHTTP2_TOKEN_IF_NONE_MATCH = 40,
|
||||
NGHTTP2_TOKEN_IF_RANGE = 41,
|
||||
NGHTTP2_TOKEN_IF_UNMODIFIED_SINCE = 42,
|
||||
NGHTTP2_TOKEN_LAST_MODIFIED = 43,
|
||||
NGHTTP2_TOKEN_LINK = 44,
|
||||
NGHTTP2_TOKEN_LOCATION = 45,
|
||||
NGHTTP2_TOKEN_MAX_FORWARDS = 46,
|
||||
NGHTTP2_TOKEN_PROXY_AUTHENTICATE = 47,
|
||||
NGHTTP2_TOKEN_PROXY_AUTHORIZATION = 48,
|
||||
NGHTTP2_TOKEN_RANGE = 49,
|
||||
NGHTTP2_TOKEN_REFERER = 50,
|
||||
NGHTTP2_TOKEN_REFRESH = 51,
|
||||
NGHTTP2_TOKEN_RETRY_AFTER = 52,
|
||||
NGHTTP2_TOKEN_SERVER = 53,
|
||||
NGHTTP2_TOKEN_SET_COOKIE = 54,
|
||||
NGHTTP2_TOKEN_STRICT_TRANSPORT_SECURITY = 55,
|
||||
NGHTTP2_TOKEN_TRANSFER_ENCODING = 56,
|
||||
NGHTTP2_TOKEN_USER_AGENT = 57,
|
||||
NGHTTP2_TOKEN_VARY = 58,
|
||||
NGHTTP2_TOKEN_VIA = 59,
|
||||
NGHTTP2_TOKEN_WWW_AUTHENTICATE = 60,
|
||||
NGHTTP2_TOKEN_TE,
|
||||
NGHTTP2_TOKEN_CONNECTION,
|
||||
NGHTTP2_TOKEN_KEEP_ALIVE,
|
||||
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
||||
NGHTTP2_TOKEN_UPGRADE,
|
||||
} nghttp2_token;
|
||||
|
||||
struct nghttp2_hd_entry;
|
||||
typedef struct nghttp2_hd_entry nghttp2_hd_entry;
|
||||
|
||||
typedef struct {
|
||||
/* The buffer containing header field name. NULL-termination is
|
||||
guaranteed. */
|
||||
nghttp2_rcbuf *name;
|
||||
/* The buffer containing header field value. NULL-termination is
|
||||
guaranteed. */
|
||||
nghttp2_rcbuf *value;
|
||||
/* nghttp2_token value for name. It could be -1 if we have no token
|
||||
for that header field name. */
|
||||
int32_t token;
|
||||
/* Bitwise OR of one or more of nghttp2_nv_flag. */
|
||||
uint8_t flags;
|
||||
} nghttp2_hd_nv;
|
||||
|
||||
struct nghttp2_hd_entry {
|
||||
/* The header field name/value pair */
|
||||
nghttp2_hd_nv nv;
|
||||
/* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry
|
||||
APIs to keep backward compatibility. */
|
||||
nghttp2_nv cnv;
|
||||
/* The next entry which shares same bucket in hash table. */
|
||||
nghttp2_hd_entry *next;
|
||||
/* The sequence number. We will increment it by one whenever we
|
||||
store nghttp2_hd_entry to dynamic header table. */
|
||||
uint32_t seq;
|
||||
/* The hash value for header name (nv.name). */
|
||||
uint32_t hash;
|
||||
};
|
||||
|
||||
/* The entry used for static header table. */
|
||||
typedef struct {
|
||||
nghttp2_rcbuf name;
|
||||
nghttp2_rcbuf value;
|
||||
nghttp2_nv cnv;
|
||||
int32_t token;
|
||||
uint32_t hash;
|
||||
} nghttp2_hd_static_entry;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_hd_entry **buffer;
|
||||
size_t mask;
|
||||
size_t first;
|
||||
size_t len;
|
||||
} nghttp2_hd_ringbuf;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_HD_OPCODE_NONE,
|
||||
NGHTTP2_HD_OPCODE_INDEXED,
|
||||
NGHTTP2_HD_OPCODE_NEWNAME,
|
||||
NGHTTP2_HD_OPCODE_INDNAME
|
||||
} nghttp2_hd_opcode;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE,
|
||||
NGHTTP2_HD_STATE_INFLATE_START,
|
||||
NGHTTP2_HD_STATE_OPCODE,
|
||||
NGHTTP2_HD_STATE_READ_TABLE_SIZE,
|
||||
NGHTTP2_HD_STATE_READ_INDEX,
|
||||
NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN,
|
||||
NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN,
|
||||
NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF,
|
||||
NGHTTP2_HD_STATE_NEWNAME_READ_NAME,
|
||||
NGHTTP2_HD_STATE_CHECK_VALUELEN,
|
||||
NGHTTP2_HD_STATE_READ_VALUELEN,
|
||||
NGHTTP2_HD_STATE_READ_VALUEHUFF,
|
||||
NGHTTP2_HD_STATE_READ_VALUE
|
||||
} nghttp2_hd_inflate_state;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_HD_WITH_INDEXING,
|
||||
NGHTTP2_HD_WITHOUT_INDEXING,
|
||||
NGHTTP2_HD_NEVER_INDEXING
|
||||
} nghttp2_hd_indexing_mode;
|
||||
|
||||
typedef struct {
|
||||
/* dynamic header table */
|
||||
nghttp2_hd_ringbuf hd_table;
|
||||
/* Memory allocator */
|
||||
nghttp2_mem *mem;
|
||||
/* Abstract buffer size of hd_table as described in the spec. This
|
||||
is the sum of length of name/value in hd_table +
|
||||
NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */
|
||||
size_t hd_table_bufsize;
|
||||
/* The effective header table size. */
|
||||
size_t hd_table_bufsize_max;
|
||||
/* Next sequence number for nghttp2_hd_entry */
|
||||
uint32_t next_seq;
|
||||
/* If inflate/deflate error occurred, this value is set to 1 and
|
||||
further invocation of inflate/deflate will fail with
|
||||
NGHTTP2_ERR_HEADER_COMP. */
|
||||
uint8_t bad;
|
||||
} nghttp2_hd_context;
|
||||
|
||||
#define HD_MAP_SIZE 128
|
||||
|
||||
typedef struct {
|
||||
nghttp2_hd_entry *table[HD_MAP_SIZE];
|
||||
} nghttp2_hd_map;
|
||||
|
||||
struct nghttp2_hd_deflater {
|
||||
nghttp2_hd_context ctx;
|
||||
nghttp2_hd_map map;
|
||||
/* The upper limit of the header table size the deflater accepts. */
|
||||
size_t deflate_hd_table_bufsize_max;
|
||||
/* Minimum header table size notified in the next context update */
|
||||
size_t min_hd_table_bufsize_max;
|
||||
/* If nonzero, send header table size using encoding context update
|
||||
in the next deflate process */
|
||||
uint8_t notify_table_size_change;
|
||||
};
|
||||
|
||||
struct nghttp2_hd_inflater {
|
||||
nghttp2_hd_context ctx;
|
||||
/* Stores current state of huffman decoding */
|
||||
nghttp2_hd_huff_decode_context huff_decode_ctx;
|
||||
/* header buffer */
|
||||
nghttp2_buf namebuf, valuebuf;
|
||||
nghttp2_rcbuf *namercbuf, *valuercbuf;
|
||||
/* Pointer to the name/value pair which are used in the current
|
||||
header emission. */
|
||||
nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
|
||||
/* The number of bytes to read */
|
||||
size_t left;
|
||||
/* The index in indexed repr or indexed name */
|
||||
size_t index;
|
||||
/* The maximum header table size the inflater supports. This is the
|
||||
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
|
||||
size_t settings_hd_table_bufsize_max;
|
||||
/* Minimum header table size set by nghttp2_hd_inflate_change_table_size */
|
||||
size_t min_hd_table_bufsize_max;
|
||||
/* The number of next shift to decode integer */
|
||||
size_t shift;
|
||||
nghttp2_hd_opcode opcode;
|
||||
nghttp2_hd_inflate_state state;
|
||||
/* nonzero if string is huffman encoded */
|
||||
uint8_t huffman_encoded;
|
||||
/* nonzero if deflater requires that current entry is indexed */
|
||||
uint8_t index_required;
|
||||
/* nonzero if deflater requires that current entry must not be
|
||||
indexed */
|
||||
uint8_t no_index;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes the |ent| members. The reference counts of nv->name
|
||||
* and nv->value are increased by one for each.
|
||||
*/
|
||||
void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
|
||||
|
||||
/*
|
||||
* This function decreases the reference counts of nv->name and
|
||||
* nv->value.
|
||||
*/
|
||||
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
|
||||
|
||||
/*
|
||||
* Initializes |deflater| for deflating name/values pairs.
|
||||
*
|
||||
* The encoder only uses up to
|
||||
* NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE bytes for header table
|
||||
* even if the larger value is specified later in
|
||||
* nghttp2_hd_change_table_size().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes |deflater| for deflating name/values pairs.
|
||||
*
|
||||
* The encoder only uses up to |max_deflate_dynamic_table_size| bytes
|
||||
* for header table even if the larger value is specified later in
|
||||
* nghttp2_hd_change_table_size().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||
size_t max_deflate_dynamic_table_size,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |deflater|.
|
||||
*/
|
||||
void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
|
||||
|
||||
/*
|
||||
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
||||
* the |bufs|.
|
||||
*
|
||||
* This function expands |bufs| as necessary to store the result. If
|
||||
* buffers is full and the process still requires more space, this
|
||||
* function fails and returns NGHTTP2_ERR_HEADER_COMP.
|
||||
*
|
||||
* After this function returns, it is safe to delete the |nva|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* Deflation process has failed.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
||||
nghttp2_bufs *bufs, const nghttp2_nv *nva,
|
||||
size_t nvlen);
|
||||
|
||||
/*
|
||||
* Initializes |inflater| for inflating name/values pairs.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |inflater|.
|
||||
*/
|
||||
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
|
||||
|
||||
/*
|
||||
* Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
|
||||
* instead of nghttp2_nv as output parameter |nv_out|. Other than
|
||||
* that return values and semantics are the same as
|
||||
* nghttp2_hd_inflate_hd().
|
||||
*/
|
||||
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
|
||||
nghttp2_hd_nv *nv_out, int *inflate_flags,
|
||||
const uint8_t *in, size_t inlen, int in_final);
|
||||
|
||||
/* For unittesting purpose */
|
||||
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||
nghttp2_nv *nv, int indexing_mode);
|
||||
|
||||
/* For unittesting purpose */
|
||||
int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
||||
int indexing_mode);
|
||||
|
||||
/* For unittesting purpose */
|
||||
int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
|
||||
|
||||
/* For unittesting purpose */
|
||||
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
|
||||
|
||||
/* For unittesting purpose */
|
||||
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
|
||||
uint32_t initial, size_t shift, uint8_t *in,
|
||||
uint8_t *last, size_t prefix);
|
||||
|
||||
/* Huffman encoding/decoding functions */
|
||||
|
||||
/*
|
||||
* Counts the required bytes to encode |src| with length |len|.
|
||||
*
|
||||
* This function returns the number of required bytes to encode given
|
||||
* data, including padding of prefix of terminal symbol code. This
|
||||
* function always succeeds.
|
||||
*/
|
||||
size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len);
|
||||
|
||||
/*
|
||||
* Encodes the given data |src| with length |srclen| to the |bufs|.
|
||||
* This function expands extra buffers in |bufs| if necessary.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
|
||||
size_t srclen);
|
||||
|
||||
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
||||
|
||||
/*
|
||||
* Decodes the given data |src| with length |srclen|. The |ctx| must
|
||||
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
|
||||
* will be written to |buf|. This function assumes that |buf| has the
|
||||
* enough room to store the decoded byte string.
|
||||
*
|
||||
* The caller must set the |fin| to nonzero if the given input is the
|
||||
* final block.
|
||||
*
|
||||
* This function returns the number of read bytes from the |in|.
|
||||
*
|
||||
* If this function fails, it returns one of the following negative
|
||||
* return codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* Decoding process has failed.
|
||||
*/
|
||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||
nghttp2_buf *buf, const uint8_t *src,
|
||||
size_t srclen, int fin);
|
||||
|
||||
#endif /* NGHTTP2_HD_H */
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2013 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_HD_HUFFMAN_H
|
||||
#define NGHTTP2_HD_HUFFMAN_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
typedef enum {
|
||||
/* FSA accepts this state as the end of huffman encoding
|
||||
sequence. */
|
||||
NGHTTP2_HUFF_ACCEPTED = 1,
|
||||
/* This state emits symbol */
|
||||
NGHTTP2_HUFF_SYM = (1 << 1),
|
||||
/* If state machine reaches this state, decoding fails. */
|
||||
NGHTTP2_HUFF_FAIL = (1 << 2)
|
||||
} nghttp2_huff_decode_flag;
|
||||
|
||||
typedef struct {
|
||||
/* huffman decoding state, which is actually the node ID of internal
|
||||
huffman tree. We have 257 leaf nodes, but they are identical to
|
||||
root node other than emitting a symbol, so we have 256 internal
|
||||
nodes [1..255], inclusive. */
|
||||
uint8_t state;
|
||||
/* bitwise OR of zero or more of the nghttp2_huff_decode_flag */
|
||||
uint8_t flags;
|
||||
/* symbol if NGHTTP2_HUFF_SYM flag set */
|
||||
uint8_t sym;
|
||||
} nghttp2_huff_decode;
|
||||
|
||||
typedef nghttp2_huff_decode huff_decode_table_type[16];
|
||||
|
||||
typedef struct {
|
||||
/* Current huffman decoding state. We stripped leaf nodes, so the
|
||||
value range is [0..255], inclusive. */
|
||||
uint8_t state;
|
||||
/* nonzero if we can say that the decoding process succeeds at this
|
||||
state */
|
||||
uint8_t accept;
|
||||
} nghttp2_hd_huff_decode_context;
|
||||
|
||||
typedef struct {
|
||||
/* The number of bits in this code */
|
||||
uint32_t nbits;
|
||||
/* Huffman code aligned to LSB */
|
||||
uint32_t code;
|
||||
} nghttp2_huff_sym;
|
||||
|
||||
extern const nghttp2_huff_sym huff_sym_table[];
|
||||
extern const nghttp2_huff_decode huff_decode_table[][16];
|
||||
|
||||
#endif /* NGHTTP2_HD_HUFFMAN_H */
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_HELPER_H
|
||||
#define NGHTTP2_HELPER_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
#define nghttp2_min(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define nghttp2_max(A, B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
#define lstreq(A, B, N) ((sizeof((A)) - 1) == (N) && memcmp((A), (B), (N)) == 0)
|
||||
|
||||
#define nghttp2_struct_of(ptr, type, member) \
|
||||
((type *)(void *)((char *)(ptr)-offsetof(type, member)))
|
||||
|
||||
/*
|
||||
* Copies 2 byte unsigned integer |n| in host byte order to |buf| in
|
||||
* network byte order.
|
||||
*/
|
||||
void nghttp2_put_uint16be(uint8_t *buf, uint16_t n);
|
||||
|
||||
/*
|
||||
* Copies 4 byte unsigned integer |n| in host byte order to |buf| in
|
||||
* network byte order.
|
||||
*/
|
||||
void nghttp2_put_uint32be(uint8_t *buf, uint32_t n);
|
||||
|
||||
/*
|
||||
* Retrieves 2 byte unsigned integer stored in |data| in network byte
|
||||
* order and returns it in host byte order.
|
||||
*/
|
||||
uint16_t nghttp2_get_uint16(const uint8_t *data);
|
||||
|
||||
/*
|
||||
* Retrieves 4 byte unsigned integer stored in |data| in network byte
|
||||
* order and returns it in host byte order.
|
||||
*/
|
||||
uint32_t nghttp2_get_uint32(const uint8_t *data);
|
||||
|
||||
void nghttp2_downcase(uint8_t *s, size_t len);
|
||||
|
||||
/*
|
||||
* Adjusts |*local_window_size_ptr|, |*recv_window_size_ptr|,
|
||||
* |*recv_reduction_ptr| with |*delta_ptr| which is the
|
||||
* WINDOW_UPDATE's window_size_increment sent from local side. If
|
||||
* |delta| is strictly larger than |*recv_window_size_ptr|,
|
||||
* |*local_window_size_ptr| is increased by delta -
|
||||
* *recv_window_size_ptr. If |delta| is negative,
|
||||
* |*local_window_size_ptr| is decreased by delta.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_FLOW_CONTROL
|
||||
* local_window_size overflow or gets negative.
|
||||
*/
|
||||
int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
||||
int32_t *recv_window_size_ptr,
|
||||
int32_t *recv_reduction_ptr,
|
||||
int32_t *delta_ptr);
|
||||
|
||||
/*
|
||||
* This function works like nghttp2_adjust_local_window_size(). The
|
||||
* difference is that this function assumes *delta_ptr >= 0, and
|
||||
* *recv_window_size_ptr is not decreased by *delta_ptr.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_FLOW_CONTROL
|
||||
* local_window_size overflow or gets negative.
|
||||
*/
|
||||
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
||||
int32_t *recv_window_size_ptr,
|
||||
int32_t *recv_reduction_ptr,
|
||||
int32_t *delta_ptr);
|
||||
|
||||
/*
|
||||
* Returns non-zero if the function decided that WINDOW_UPDATE should
|
||||
* be sent.
|
||||
*/
|
||||
int nghttp2_should_send_window_update(int32_t local_window_size,
|
||||
int32_t recv_window_size);
|
||||
|
||||
/*
|
||||
* Copies the buffer |src| of length |len| to the destination pointed
|
||||
* by the |dest|, assuming that the |dest| is at lest |len| bytes long
|
||||
* . Returns dest + len.
|
||||
*/
|
||||
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
|
||||
|
||||
#endif /* NGHTTP2_HELPER_H */
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2015 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_HTTP_H
|
||||
#define NGHTTP2_HTTP_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_session.h"
|
||||
#include "nghttp2_stream.h"
|
||||
|
||||
/*
|
||||
* This function is called when HTTP header field |nv| in |frame| is
|
||||
* received for |stream|. This function will validate |nv| against
|
||||
* the current state of stream.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_HTTP_HEADER
|
||||
* Invalid HTTP header field was received.
|
||||
* NGHTTP2_ERR_IGN_HTTP_HEADER
|
||||
* Invalid HTTP header field was received but it can be treated as
|
||||
* if it was not received because of compatibility reasons.
|
||||
*/
|
||||
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||
nghttp2_frame *frame, nghttp2_hd_nv *nv,
|
||||
int trailer);
|
||||
|
||||
/*
|
||||
* This function is called when request header is received. This
|
||||
* function performs validation and returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_request_headers(nghttp2_stream *stream,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* This function is called when response header is received. This
|
||||
* function performs validation and returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_response_headers(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* This function is called trailer header (for both request and
|
||||
* response) is received. This function performs validation and
|
||||
* returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_trailer_headers(nghttp2_stream *stream,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* This function is called when END_STREAM flag is seen in incoming
|
||||
* frame. This function performs validation and returns 0 if it
|
||||
* succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_remote_end_stream(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* This function is called when chunk of data is received. This
|
||||
* function performs validation and returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_data_chunk(nghttp2_stream *stream, size_t n);
|
||||
|
||||
/*
|
||||
* This function inspects header field in |frame| and records its
|
||||
* method in stream->http_flags. If frame->hd.type is neither
|
||||
* NGHTTP2_HEADERS nor NGHTTP2_PUSH_PROMISE, this function does
|
||||
* nothing.
|
||||
*/
|
||||
void nghttp2_http_record_request_method(nghttp2_stream *stream,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
#endif /* NGHTTP2_HTTP_H */
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_INT_H
|
||||
#define NGHTTP2_INT_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/* Macros, types and constants for internal use */
|
||||
|
||||
/* "less" function, return nonzero if |lhs| is less than |rhs|. */
|
||||
typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
|
||||
|
||||
/* Internal error code. They must be in the range [-499, -100],
|
||||
inclusive. */
|
||||
typedef enum {
|
||||
NGHTTP2_ERR_CREDENTIAL_PENDING = -101,
|
||||
NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
|
||||
NGHTTP2_ERR_IGN_PAYLOAD = -104,
|
||||
/*
|
||||
* Invalid HTTP header field was received but it can be treated as
|
||||
* if it was not received because of compatibility reasons.
|
||||
*/
|
||||
NGHTTP2_ERR_IGN_HTTP_HEADER = -105,
|
||||
/*
|
||||
* Invalid HTTP header field was received, and it is ignored.
|
||||
* Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
|
||||
* nghttp2_on_invalid_header_callback.
|
||||
*/
|
||||
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
|
||||
} nghttp2_internal_error;
|
||||
|
||||
#endif /* NGHTTP2_INT_H */
|
||||
144
sdk/component/common/network/http2/nghttp2-1.31.0/nghttp2_map.h
Normal file
144
sdk/component/common/network/http2/nghttp2-1.31.0/nghttp2_map.h
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_MAP_H
|
||||
#define NGHTTP2_MAP_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_int.h"
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
/* Implementation of unordered map */
|
||||
|
||||
typedef int32_t key_type;
|
||||
|
||||
typedef struct nghttp2_map_entry {
|
||||
struct nghttp2_map_entry *next;
|
||||
key_type key;
|
||||
#if SIZEOF_INT_P == 4
|
||||
/* we requires 8 bytes aligment */
|
||||
int64_t pad;
|
||||
#endif
|
||||
} nghttp2_map_entry;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_map_entry **table;
|
||||
nghttp2_mem *mem;
|
||||
size_t size;
|
||||
uint32_t tablelen;
|
||||
} nghttp2_map;
|
||||
|
||||
/*
|
||||
* Initializes the map |map|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |map|. The stored entries
|
||||
* are not freed by this function. Use nghttp2_map_each_free() to free
|
||||
* each entries.
|
||||
*/
|
||||
void nghttp2_map_free(nghttp2_map *map);
|
||||
|
||||
/*
|
||||
* Deallocates each entries using |func| function and any resources
|
||||
* allocated for |map|. The |func| function is responsible for freeing
|
||||
* given the |entry| object. The |ptr| will be passed to the |func| as
|
||||
* send argument. The return value of the |func| will be ignored.
|
||||
*/
|
||||
void nghttp2_map_each_free(nghttp2_map *map,
|
||||
int (*func)(nghttp2_map_entry *entry, void *ptr),
|
||||
void *ptr);
|
||||
|
||||
/*
|
||||
* Initializes the |entry| with the |key|. All entries to be inserted
|
||||
* to the map must be initialized with this function.
|
||||
*/
|
||||
void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
|
||||
|
||||
/*
|
||||
* Inserts the new |entry| with the key |entry->key| to the map |map|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The item associated by |key| already exists.
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *entry);
|
||||
|
||||
/*
|
||||
* Returns the entry associated by the key |key|. If there is no such
|
||||
* entry, this function returns NULL.
|
||||
*/
|
||||
nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
|
||||
|
||||
/*
|
||||
* Removes the entry associated by the key |key| from the |map|. The
|
||||
* removed entry is not freed by this function.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The entry associated by |key| does not exist.
|
||||
*/
|
||||
int nghttp2_map_remove(nghttp2_map *map, key_type key);
|
||||
|
||||
/*
|
||||
* Returns the number of items stored in the map |map|.
|
||||
*/
|
||||
size_t nghttp2_map_size(nghttp2_map *map);
|
||||
|
||||
/*
|
||||
* Applies the function |func| to each entry in the |map| with the
|
||||
* optional user supplied pointer |ptr|.
|
||||
*
|
||||
* If the |func| returns 0, this function calls the |func| with the
|
||||
* next entry. If the |func| returns nonzero, it will not call the
|
||||
* |func| for further entries and return the return value of the
|
||||
* |func| immediately. Thus, this function returns 0 if all the
|
||||
* invocations of the |func| return 0, or nonzero value which the last
|
||||
* invocation of |func| returns.
|
||||
*
|
||||
* Don't use this function to free each entry. Use
|
||||
* nghttp2_map_each_free() instead.
|
||||
*/
|
||||
int nghttp2_map_each(nghttp2_map *map,
|
||||
int (*func)(nghttp2_map_entry *entry, void *ptr),
|
||||
void *ptr);
|
||||
|
||||
#endif /* NGHTTP2_MAP_H */
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_MEM_H
|
||||
#define NGHTTP2_MEM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/* The default, system standard memory allocator */
|
||||
nghttp2_mem *nghttp2_mem_default(void);
|
||||
|
||||
/* Convenient wrapper functions to call allocator function in
|
||||
|mem|. */
|
||||
void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size);
|
||||
void nghttp2_mem_free(nghttp2_mem *mem, void *ptr);
|
||||
void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
|
||||
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
|
||||
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
|
||||
|
||||
#endif /* NGHTTP2_MEM_H */
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_NET_H
|
||||
#define NGHTTP2_NET_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif /* HAVE_ARPA_INET_H */
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif /* HAVE_NETINET_IN_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
/* Windows requires ws2_32 library for ntonl family functions. We
|
||||
define inline functions for those function so that we don't have
|
||||
dependeny on that lib. */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STIN static __inline
|
||||
#else
|
||||
#define STIN static inline
|
||||
#endif
|
||||
|
||||
STIN uint32_t htonl(uint32_t hostlong) {
|
||||
uint32_t res;
|
||||
unsigned char *p = (unsigned char *)&res;
|
||||
*p++ = hostlong >> 24;
|
||||
*p++ = (hostlong >> 16) & 0xffu;
|
||||
*p++ = (hostlong >> 8) & 0xffu;
|
||||
*p = hostlong & 0xffu;
|
||||
return res;
|
||||
}
|
||||
|
||||
STIN uint16_t htons(uint16_t hostshort) {
|
||||
uint16_t res;
|
||||
unsigned char *p = (unsigned char *)&res;
|
||||
*p++ = hostshort >> 8;
|
||||
*p = hostshort & 0xffu;
|
||||
return res;
|
||||
}
|
||||
|
||||
STIN uint32_t ntohl(uint32_t netlong) {
|
||||
uint32_t res;
|
||||
unsigned char *p = (unsigned char *)&netlong;
|
||||
res = *p++ << 24;
|
||||
res += *p++ << 16;
|
||||
res += *p++ << 8;
|
||||
res += *p;
|
||||
return res;
|
||||
}
|
||||
|
||||
STIN uint16_t ntohs(uint16_t netshort) {
|
||||
uint16_t res;
|
||||
unsigned char *p = (unsigned char *)&netshort;
|
||||
res = *p++ << 8;
|
||||
res += *p;
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#endif /* NGHTTP2_NET_H */
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_NPN_H
|
||||
#define NGHTTP2_NPN_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#endif /* NGHTTP2_NPN_H */
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_OPTION_H
|
||||
#define NGHTTP2_OPTION_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/**
|
||||
* Configuration options
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* This option prevents the library from sending WINDOW_UPDATE for a
|
||||
* connection automatically. If this option is set to nonzero, the
|
||||
* library won't send WINDOW_UPDATE for DATA until application calls
|
||||
* nghttp2_session_consume() to indicate the amount of consumed
|
||||
* DATA. By default, this option is set to zero.
|
||||
*/
|
||||
NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE = 1,
|
||||
/**
|
||||
* This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of
|
||||
* remote endpoint as if it is received in SETTINGS frame. Without
|
||||
* specifying this option, before the local endpoint receives
|
||||
* SETTINGS_MAX_CONCURRENT_STREAMS in SETTINGS frame from remote
|
||||
* endpoint, SETTINGS_MAX_CONCURRENT_STREAMS is unlimited. This may
|
||||
* cause problem if local endpoint submits lots of requests
|
||||
* initially and sending them at once to the remote peer may lead to
|
||||
* the rejection of some requests. Specifying this option to the
|
||||
* sensible value, say 100, may avoid this kind of issue. This value
|
||||
* will be overwritten if the local endpoint receives
|
||||
* SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint.
|
||||
*/
|
||||
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 1,
|
||||
NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2,
|
||||
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
|
||||
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
|
||||
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
|
||||
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
|
||||
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7,
|
||||
NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
|
||||
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
|
||||
NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
|
||||
} nghttp2_option_flag;
|
||||
|
||||
/**
|
||||
* Struct to store option values for nghttp2_session.
|
||||
*/
|
||||
struct nghttp2_option {
|
||||
/**
|
||||
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
|
||||
*/
|
||||
size_t max_send_header_block_length;
|
||||
/**
|
||||
* NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE
|
||||
*/
|
||||
size_t max_deflate_dynamic_table_size;
|
||||
/**
|
||||
* Bitwise OR of nghttp2_option_flag to determine that which fields
|
||||
* are specified.
|
||||
*/
|
||||
uint32_t opt_set_mask;
|
||||
/**
|
||||
* NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS
|
||||
*/
|
||||
uint32_t peer_max_concurrent_streams;
|
||||
/**
|
||||
* NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS
|
||||
*/
|
||||
uint32_t max_reserved_remote_streams;
|
||||
/**
|
||||
* NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES
|
||||
*/
|
||||
uint32_t builtin_recv_ext_types;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE
|
||||
*/
|
||||
int no_auto_window_update;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC
|
||||
*/
|
||||
int no_recv_client_magic;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_HTTP_MESSAGING
|
||||
*/
|
||||
int no_http_messaging;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_AUTO_PING_ACK
|
||||
*/
|
||||
int no_auto_ping_ack;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_CLOSED_STREAMS
|
||||
*/
|
||||
int no_closed_streams;
|
||||
/**
|
||||
* NGHTTP2_OPT_USER_RECV_EXT_TYPES
|
||||
*/
|
||||
uint8_t user_recv_ext_types[32];
|
||||
};
|
||||
|
||||
#endif /* NGHTTP2_OPTION_H */
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_OUTBOUND_ITEM_H
|
||||
#define NGHTTP2_OUTBOUND_ITEM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_frame.h"
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
/* struct used for HEADERS and PUSH_PROMISE frame */
|
||||
typedef struct {
|
||||
nghttp2_data_provider data_prd;
|
||||
void *stream_user_data;
|
||||
/* error code when request HEADERS is canceled by RST_STREAM while
|
||||
it is in queue. */
|
||||
uint32_t error_code;
|
||||
/* nonzero if request HEADERS is canceled. The error code is stored
|
||||
in |error_code|. */
|
||||
uint8_t canceled;
|
||||
} nghttp2_headers_aux_data;
|
||||
|
||||
/* struct used for DATA frame */
|
||||
typedef struct {
|
||||
/**
|
||||
* The data to be sent for this DATA frame.
|
||||
*/
|
||||
nghttp2_data_provider data_prd;
|
||||
/**
|
||||
* The flags of DATA frame. We use separate flags here and
|
||||
* nghttp2_data frame. The latter contains flags actually sent to
|
||||
* peer. This |flags| may contain NGHTTP2_FLAG_END_STREAM and only
|
||||
* when |eof| becomes nonzero, flags in nghttp2_data has
|
||||
* NGHTTP2_FLAG_END_STREAM set.
|
||||
*/
|
||||
uint8_t flags;
|
||||
/**
|
||||
* The flag to indicate whether EOF was reached or not. Initially
|
||||
* |eof| is 0. It becomes 1 after all data were read.
|
||||
*/
|
||||
uint8_t eof;
|
||||
/**
|
||||
* The flag to indicate that NGHTTP2_DATA_FLAG_NO_COPY is used.
|
||||
*/
|
||||
uint8_t no_copy;
|
||||
} nghttp2_data_aux_data;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_GOAWAY_AUX_NONE = 0x0,
|
||||
/* indicates that session should be terminated after the
|
||||
transmission of this frame. */
|
||||
NGHTTP2_GOAWAY_AUX_TERM_ON_SEND = 0x1,
|
||||
/* indicates that this GOAWAY is just a notification for graceful
|
||||
shutdown. No nghttp2_session.goaway_flags should be updated on
|
||||
the reaction to this frame. */
|
||||
NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE = 0x2
|
||||
} nghttp2_goaway_aux_flag;
|
||||
|
||||
/* struct used for GOAWAY frame */
|
||||
typedef struct {
|
||||
/* bitwise-OR of one or more of nghttp2_goaway_aux_flag. */
|
||||
uint8_t flags;
|
||||
} nghttp2_goaway_aux_data;
|
||||
|
||||
/* struct used for extension frame */
|
||||
typedef struct {
|
||||
/* nonzero if this extension frame is serialized by library
|
||||
function, instead of user-defined callbacks. */
|
||||
uint8_t builtin;
|
||||
} nghttp2_ext_aux_data;
|
||||
|
||||
/* Additional data which cannot be stored in nghttp2_frame struct */
|
||||
typedef union {
|
||||
nghttp2_data_aux_data data;
|
||||
nghttp2_headers_aux_data headers;
|
||||
nghttp2_goaway_aux_data goaway;
|
||||
nghttp2_ext_aux_data ext;
|
||||
} nghttp2_aux_data;
|
||||
|
||||
struct nghttp2_outbound_item;
|
||||
typedef struct nghttp2_outbound_item nghttp2_outbound_item;
|
||||
|
||||
struct nghttp2_outbound_item {
|
||||
nghttp2_frame frame;
|
||||
/* Storage for extension frame payload. frame->ext.payload points
|
||||
to this structure to avoid frequent memory allocation. */
|
||||
nghttp2_ext_frame_payload ext_frame_payload;
|
||||
nghttp2_aux_data aux_data;
|
||||
/* The priority used in priority comparion. Smaller is served
|
||||
earlier. For PING, SETTINGS and non-DATA frames (excluding
|
||||
response HEADERS frame) have dedicated cycle value defined above.
|
||||
For DATA frame, cycle is computed by taking into account of
|
||||
effective weight and frame payload length previously sent, so
|
||||
that the amount of transmission is distributed across streams
|
||||
proportional to effective weight (inside a tree). */
|
||||
uint64_t cycle;
|
||||
nghttp2_outbound_item *qnext;
|
||||
/* nonzero if this object is queued, except for DATA or HEADERS
|
||||
which are attached to stream as item. */
|
||||
uint8_t queued;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes |item|. No memory allocation is done in this function.
|
||||
* Don't call nghttp2_outbound_item_free() until frame member is
|
||||
* initialized.
|
||||
*/
|
||||
void nghttp2_outbound_item_init(nghttp2_outbound_item *item);
|
||||
|
||||
/*
|
||||
* Deallocates resource for |item|. If |item| is NULL, this function
|
||||
* does nothing.
|
||||
*/
|
||||
void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* queue for nghttp2_outbound_item.
|
||||
*/
|
||||
typedef struct {
|
||||
nghttp2_outbound_item *head, *tail;
|
||||
/* number of items in this queue. */
|
||||
size_t n;
|
||||
} nghttp2_outbound_queue;
|
||||
|
||||
void nghttp2_outbound_queue_init(nghttp2_outbound_queue *q);
|
||||
|
||||
/* Pushes |item| into |q| */
|
||||
void nghttp2_outbound_queue_push(nghttp2_outbound_queue *q,
|
||||
nghttp2_outbound_item *item);
|
||||
|
||||
/* Pops |item| at the top from |q|. If |q| is empty, nothing
|
||||
happens. */
|
||||
void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q);
|
||||
|
||||
/* Returns the top item. */
|
||||
#define nghttp2_outbound_queue_top(Q) ((Q)->head)
|
||||
|
||||
/* Returns the size of the queue */
|
||||
#define nghttp2_outbound_queue_size(Q) ((Q)->n)
|
||||
|
||||
#endif /* NGHTTP2_OUTBOUND_ITEM_H */
|
||||
130
sdk/component/common/network/http2/nghttp2-1.31.0/nghttp2_pq.h
Normal file
130
sdk/component/common/network/http2/nghttp2-1.31.0/nghttp2_pq.h
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_PQ_H
|
||||
#define NGHTTP2_PQ_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_int.h"
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
/* Implementation of priority queue */
|
||||
|
||||
typedef struct {
|
||||
size_t index;
|
||||
} nghttp2_pq_entry;
|
||||
|
||||
typedef struct {
|
||||
/* The pointer to the pointer to the item stored */
|
||||
nghttp2_pq_entry **q;
|
||||
/* Memory allocator */
|
||||
nghttp2_mem *mem;
|
||||
/* The number of items stored */
|
||||
size_t length;
|
||||
/* The maximum number of items this pq can store. This is
|
||||
automatically extended when length is reached to this value. */
|
||||
size_t capacity;
|
||||
/* The less function between items */
|
||||
nghttp2_less less;
|
||||
} nghttp2_pq;
|
||||
|
||||
/*
|
||||
* Initializes priority queue |pq| with compare function |cmp|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |pq|. The stored items are
|
||||
* not freed by this function.
|
||||
*/
|
||||
void nghttp2_pq_free(nghttp2_pq *pq);
|
||||
|
||||
/*
|
||||
* Adds |item| to the priority queue |pq|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_pq_push(nghttp2_pq *pq, nghttp2_pq_entry *item);
|
||||
|
||||
/*
|
||||
* Returns item at the top of the queue |pq|. If the queue is empty,
|
||||
* this function returns NULL.
|
||||
*/
|
||||
nghttp2_pq_entry *nghttp2_pq_top(nghttp2_pq *pq);
|
||||
|
||||
/*
|
||||
* Pops item at the top of the queue |pq|. The popped item is not
|
||||
* freed by this function.
|
||||
*/
|
||||
void nghttp2_pq_pop(nghttp2_pq *pq);
|
||||
|
||||
/*
|
||||
* Returns nonzero if the queue |pq| is empty.
|
||||
*/
|
||||
int nghttp2_pq_empty(nghttp2_pq *pq);
|
||||
|
||||
/*
|
||||
* Returns the number of items in the queue |pq|.
|
||||
*/
|
||||
size_t nghttp2_pq_size(nghttp2_pq *pq);
|
||||
|
||||
typedef int (*nghttp2_pq_item_cb)(nghttp2_pq_entry *item, void *arg);
|
||||
|
||||
/*
|
||||
* Updates each item in |pq| using function |fun| and re-construct
|
||||
* priority queue. The |fun| must return non-zero if it modifies the
|
||||
* item in a way that it affects ordering in the priority queue. The
|
||||
* |arg| is passed to the 2nd parameter of |fun|.
|
||||
*/
|
||||
void nghttp2_pq_update(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg);
|
||||
|
||||
/*
|
||||
* Applys |fun| to each item in |pq|. The |arg| is passed as arg
|
||||
* parameter to callback function. This function must not change the
|
||||
* ordering key. If the return value from callback is nonzero, this
|
||||
* function returns 1 immediately without iterating remaining items.
|
||||
* Otherwise this function returns 0.
|
||||
*/
|
||||
int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg);
|
||||
|
||||
/*
|
||||
* Removes |item| from priority queue.
|
||||
*/
|
||||
void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item);
|
||||
|
||||
#endif /* NGHTTP2_PQ_H */
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_PRIORITY_SPEC_H
|
||||
#define NGHTTP2_PRIORITY_SPEC_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/*
|
||||
* This function normalizes pri_spec->weight if it is out of range.
|
||||
* If pri_spec->weight is less than NGHTTP2_MIN_WEIGHT, it is set to
|
||||
* NGHTTP2_MIN_WEIGHT. If pri_spec->weight is larger than
|
||||
* NGHTTP2_MAX_WEIGHT, it is set to NGHTTP2_MAX_WEIGHT.
|
||||
*/
|
||||
void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec);
|
||||
|
||||
#endif /* NGHTTP2_PRIORITY_SPEC_H */
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_QUEUE_H
|
||||
#define NGHTTP2_QUEUE_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
typedef struct nghttp2_queue_cell {
|
||||
void *data;
|
||||
struct nghttp2_queue_cell *next;
|
||||
} nghttp2_queue_cell;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_queue_cell *front, *back;
|
||||
} nghttp2_queue;
|
||||
|
||||
void nghttp2_queue_init(nghttp2_queue *queue);
|
||||
void nghttp2_queue_free(nghttp2_queue *queue);
|
||||
int nghttp2_queue_push(nghttp2_queue *queue, void *data);
|
||||
void nghttp2_queue_pop(nghttp2_queue *queue);
|
||||
void *nghttp2_queue_front(nghttp2_queue *queue);
|
||||
void *nghttp2_queue_back(nghttp2_queue *queue);
|
||||
int nghttp2_queue_empty(nghttp2_queue *queue);
|
||||
|
||||
#endif /* NGHTTP2_QUEUE_H */
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_RCBUF_H
|
||||
#define NGHTTP2_RCBUF_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
struct nghttp2_rcbuf {
|
||||
/* custom memory allocator belongs to the mem parameter when
|
||||
creating this object. */
|
||||
void *mem_user_data;
|
||||
nghttp2_free free;
|
||||
/* The pointer to the underlying buffer */
|
||||
uint8_t *base;
|
||||
/* Size of buffer pointed by |base|. */
|
||||
size_t len;
|
||||
/* Reference count */
|
||||
int32_t ref;
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocates nghttp2_rcbuf object with |size| as initial buffer size.
|
||||
* When the function succeeds, the reference count becomes 1.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM:
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_rcbuf_new(nghttp2_rcbuf **rcbuf_ptr, size_t size, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Like nghttp2_rcbuf_new(), but initializes the buffer with |src| of
|
||||
* length |srclen|. This function allocates additional byte at the
|
||||
* end and puts '\0' into it, so that the resulting buffer could be
|
||||
* used as NULL-terminated string. Still (*rcbuf_ptr)->len equals to
|
||||
* |srclen|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM:
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
|
||||
size_t srclen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees |rcbuf| itself, regardless of its reference cout.
|
||||
*/
|
||||
void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf);
|
||||
|
||||
#endif /* NGHTTP2_RCBUF_H */
|
||||
|
|
@ -0,0 +1,879 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_SESSION_H
|
||||
#define NGHTTP2_SESSION_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_map.h"
|
||||
#include "nghttp2_frame.h"
|
||||
#include "nghttp2_hd.h"
|
||||
#include "nghttp2_stream.h"
|
||||
#include "nghttp2_outbound_item.h"
|
||||
#include "nghttp2_int.h"
|
||||
#include "nghttp2_buf.h"
|
||||
#include "nghttp2_callbacks.h"
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
/* The global variable for tests where we want to disable strict
|
||||
preface handling. */
|
||||
extern int nghttp2_enable_strict_preface;
|
||||
|
||||
/*
|
||||
* Option flags.
|
||||
*/
|
||||
typedef enum {
|
||||
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0,
|
||||
NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
|
||||
NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
|
||||
NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3,
|
||||
NGHTTP2_OPTMASK_NO_CLOSED_STREAMS = 1 << 4
|
||||
} nghttp2_optmask;
|
||||
|
||||
/*
|
||||
* bitmask for built-in type to enable the default handling for that
|
||||
* type of the frame.
|
||||
*/
|
||||
typedef enum {
|
||||
NGHTTP2_TYPEMASK_NONE = 0,
|
||||
NGHTTP2_TYPEMASK_ALTSVC = 1 << 0
|
||||
} nghttp2_typemask;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_OB_POP_ITEM,
|
||||
NGHTTP2_OB_SEND_DATA,
|
||||
NGHTTP2_OB_SEND_NO_COPY,
|
||||
NGHTTP2_OB_SEND_CLIENT_MAGIC
|
||||
} nghttp2_outbound_state;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_outbound_item *item;
|
||||
nghttp2_bufs framebufs;
|
||||
nghttp2_outbound_state state;
|
||||
} nghttp2_active_outbound_item;
|
||||
|
||||
/* Buffer length for inbound raw byte stream used in
|
||||
nghttp2_session_recv(). */
|
||||
#define NGHTTP2_INBOUND_BUFFER_LENGTH 16384
|
||||
|
||||
/* The default maximum number of incoming reserved streams */
|
||||
#define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200
|
||||
|
||||
/* Even if we have less SETTINGS_MAX_CONCURRENT_STREAMS than this
|
||||
number, we keep NGHTTP2_MIN_IDLE_STREAMS streams in idle state */
|
||||
#define NGHTTP2_MIN_IDLE_STREAMS 16
|
||||
|
||||
/* The maximum number of items in outbound queue, which is considered
|
||||
as flooding caused by peer. All frames are not considered here.
|
||||
We only consider PING + ACK and SETTINGS + ACK. This is because
|
||||
they both are response to the frame initiated by peer and peer can
|
||||
send as many of them as they want. If peer does not read network,
|
||||
response frames are stacked up, which leads to memory exhaustion.
|
||||
The value selected here is arbitrary, but safe value and if we have
|
||||
these frames in this number, it is considered suspicious. */
|
||||
#define NGHTTP2_MAX_OBQ_FLOOD_ITEM 10000
|
||||
|
||||
/* The default value of maximum number of concurrent streams. */
|
||||
#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
|
||||
|
||||
/* Internal state when receiving incoming frame */
|
||||
typedef enum {
|
||||
/* Receiving frame header */
|
||||
NGHTTP2_IB_READ_CLIENT_MAGIC,
|
||||
NGHTTP2_IB_READ_FIRST_SETTINGS,
|
||||
NGHTTP2_IB_READ_HEAD,
|
||||
NGHTTP2_IB_READ_NBYTE,
|
||||
NGHTTP2_IB_READ_HEADER_BLOCK,
|
||||
NGHTTP2_IB_IGN_HEADER_BLOCK,
|
||||
NGHTTP2_IB_IGN_PAYLOAD,
|
||||
NGHTTP2_IB_FRAME_SIZE_ERROR,
|
||||
NGHTTP2_IB_READ_SETTINGS,
|
||||
NGHTTP2_IB_READ_GOAWAY_DEBUG,
|
||||
NGHTTP2_IB_EXPECT_CONTINUATION,
|
||||
NGHTTP2_IB_IGN_CONTINUATION,
|
||||
NGHTTP2_IB_READ_PAD_DATA,
|
||||
NGHTTP2_IB_READ_DATA,
|
||||
NGHTTP2_IB_IGN_DATA,
|
||||
NGHTTP2_IB_IGN_ALL,
|
||||
NGHTTP2_IB_READ_ALTSVC_PAYLOAD,
|
||||
NGHTTP2_IB_READ_EXTENSION_PAYLOAD
|
||||
} nghttp2_inbound_state;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_frame frame;
|
||||
/* Storage for extension frame payload. frame->ext.payload points
|
||||
to this structure to avoid frequent memory allocation. */
|
||||
nghttp2_ext_frame_payload ext_frame_payload;
|
||||
/* The received SETTINGS entry. For the standard settings entries,
|
||||
we only keep the last seen value. For
|
||||
SETTINGS_HEADER_TABLE_SIZE, we also keep minimum value in the
|
||||
last index. */
|
||||
nghttp2_settings_entry *iv;
|
||||
/* buffer pointers to small buffer, raw_sbuf */
|
||||
nghttp2_buf sbuf;
|
||||
/* buffer pointers to large buffer, raw_lbuf */
|
||||
nghttp2_buf lbuf;
|
||||
/* Large buffer, malloced on demand */
|
||||
uint8_t *raw_lbuf;
|
||||
/* The number of entry filled in |iv| */
|
||||
size_t niv;
|
||||
/* The number of entries |iv| can store. */
|
||||
size_t max_niv;
|
||||
/* How many bytes we still need to receive for current frame */
|
||||
size_t payloadleft;
|
||||
/* padding length for the current frame */
|
||||
size_t padlen;
|
||||
nghttp2_inbound_state state;
|
||||
/* Small buffer. Currently the largest contiguous chunk to buffer
|
||||
is frame header. We buffer part of payload, but they are smaller
|
||||
than frame header. */
|
||||
uint8_t raw_sbuf[NGHTTP2_FRAME_HDLEN];
|
||||
} nghttp2_inbound_frame;
|
||||
|
||||
typedef struct {
|
||||
uint32_t header_table_size;
|
||||
uint32_t enable_push;
|
||||
uint32_t max_concurrent_streams;
|
||||
uint32_t initial_window_size;
|
||||
uint32_t max_frame_size;
|
||||
uint32_t max_header_list_size;
|
||||
} nghttp2_settings_storage;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_GOAWAY_NONE = 0,
|
||||
/* Flag means that connection should be terminated after sending GOAWAY. */
|
||||
NGHTTP2_GOAWAY_TERM_ON_SEND = 0x1,
|
||||
/* Flag means GOAWAY to terminate session has been sent */
|
||||
NGHTTP2_GOAWAY_TERM_SENT = 0x2,
|
||||
/* Flag means GOAWAY was sent */
|
||||
NGHTTP2_GOAWAY_SENT = 0x4,
|
||||
/* Flag means GOAWAY was received */
|
||||
NGHTTP2_GOAWAY_RECV = 0x8
|
||||
} nghttp2_goaway_flag;
|
||||
|
||||
/* nghttp2_inflight_settings stores the SETTINGS entries which local
|
||||
endpoint has sent to the remote endpoint, and has not received ACK
|
||||
yet. */
|
||||
struct nghttp2_inflight_settings {
|
||||
struct nghttp2_inflight_settings *next;
|
||||
nghttp2_settings_entry *iv;
|
||||
size_t niv;
|
||||
};
|
||||
|
||||
typedef struct nghttp2_inflight_settings nghttp2_inflight_settings;
|
||||
|
||||
struct nghttp2_session {
|
||||
nghttp2_map /* <nghttp2_stream*> */ streams;
|
||||
/* root of dependency tree*/
|
||||
nghttp2_stream root;
|
||||
/* Queue for outbound urgent frames (PING and SETTINGS) */
|
||||
nghttp2_outbound_queue ob_urgent;
|
||||
/* Queue for non-DATA frames */
|
||||
nghttp2_outbound_queue ob_reg;
|
||||
/* Queue for outbound stream-creating HEADERS (request or push
|
||||
response) frame, which are subject to
|
||||
SETTINGS_MAX_CONCURRENT_STREAMS limit. */
|
||||
nghttp2_outbound_queue ob_syn;
|
||||
nghttp2_active_outbound_item aob;
|
||||
nghttp2_inbound_frame iframe;
|
||||
nghttp2_hd_deflater hd_deflater;
|
||||
nghttp2_hd_inflater hd_inflater;
|
||||
nghttp2_session_callbacks callbacks;
|
||||
/* Memory allocator */
|
||||
nghttp2_mem mem;
|
||||
/* Base value when we schedule next DATA frame write. This is
|
||||
updated when one frame was written. */
|
||||
uint64_t last_cycle;
|
||||
void *user_data;
|
||||
/* Points to the latest incoming closed stream. NULL if there is no
|
||||
closed stream. Only used when session is initialized as
|
||||
server. */
|
||||
nghttp2_stream *closed_stream_head;
|
||||
/* Points to the oldest incoming closed stream. NULL if there is no
|
||||
closed stream. Only used when session is initialized as
|
||||
server. */
|
||||
nghttp2_stream *closed_stream_tail;
|
||||
/* Points to the latest idle stream. NULL if there is no idle
|
||||
stream. Only used when session is initialized as server .*/
|
||||
nghttp2_stream *idle_stream_head;
|
||||
/* Points to the oldest idle stream. NULL if there is no idle
|
||||
stream. Only used when session is initialized as erver. */
|
||||
nghttp2_stream *idle_stream_tail;
|
||||
/* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not
|
||||
considered as in-flight. */
|
||||
nghttp2_inflight_settings *inflight_settings_head;
|
||||
/* The number of outgoing streams. This will be capped by
|
||||
remote_settings.max_concurrent_streams. */
|
||||
size_t num_outgoing_streams;
|
||||
/* The number of incoming streams. This will be capped by
|
||||
local_settings.max_concurrent_streams. */
|
||||
size_t num_incoming_streams;
|
||||
/* The number of incoming reserved streams. This is the number of
|
||||
streams in reserved (remote) state. RFC 7540 does not limit this
|
||||
number. nghttp2 offers
|
||||
nghttp2_option_set_max_reserved_remote_streams() to achieve this.
|
||||
If it is used, num_incoming_streams is capped by
|
||||
max_incoming_reserved_streams. Client application should
|
||||
consider to set this because without that server can send
|
||||
arbitrary number of PUSH_PROMISE, and exhaust client's memory. */
|
||||
size_t num_incoming_reserved_streams;
|
||||
/* The maximum number of incoming reserved streams (reserved
|
||||
(remote) state). RST_STREAM will be sent for the pushed stream
|
||||
which exceeds this limit. */
|
||||
size_t max_incoming_reserved_streams;
|
||||
/* The number of closed streams still kept in |streams| hash. The
|
||||
closed streams can be accessed through single linked list
|
||||
|closed_stream_head|. The current implementation only keeps
|
||||
incoming streams and session is initialized as server. */
|
||||
size_t num_closed_streams;
|
||||
/* The number of idle streams kept in |streams| hash. The idle
|
||||
streams can be accessed through doubly linked list
|
||||
|idle_stream_head|. The current implementation only keeps idle
|
||||
streams if session is initialized as server. */
|
||||
size_t num_idle_streams;
|
||||
/* The number of bytes allocated for nvbuf */
|
||||
size_t nvbuflen;
|
||||
/* Counter for detecting flooding in outbound queue */
|
||||
size_t obq_flood_counter_;
|
||||
/* The maximum length of header block to send. Calculated by the
|
||||
same way as nghttp2_hd_deflate_bound() does. */
|
||||
size_t max_send_header_block_length;
|
||||
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
|
||||
uint32_t next_stream_id;
|
||||
/* The last stream ID this session initiated. For client session,
|
||||
this is the last stream ID it has sent. For server session, it
|
||||
is the last promised stream ID sent in PUSH_PROMISE. */
|
||||
int32_t last_sent_stream_id;
|
||||
/* The largest stream ID received so far */
|
||||
int32_t last_recv_stream_id;
|
||||
/* The largest stream ID which has been processed in some way. This
|
||||
value will be used as last-stream-id when sending GOAWAY
|
||||
frame. */
|
||||
int32_t last_proc_stream_id;
|
||||
/* Counter of unique ID of PING. Wraps when it exceeds
|
||||
NGHTTP2_MAX_UNIQUE_ID */
|
||||
uint32_t next_unique_id;
|
||||
/* This is the last-stream-ID we have sent in GOAWAY */
|
||||
int32_t local_last_stream_id;
|
||||
/* This is the value in GOAWAY frame received from remote endpoint. */
|
||||
int32_t remote_last_stream_id;
|
||||
/* Current sender window size. This value is computed against the
|
||||
current initial window size of remote endpoint. */
|
||||
int32_t remote_window_size;
|
||||
/* Keep track of the number of bytes received without
|
||||
WINDOW_UPDATE. This could be negative after submitting negative
|
||||
value to WINDOW_UPDATE. */
|
||||
int32_t recv_window_size;
|
||||
/* The number of bytes consumed by the application and now is
|
||||
subject to WINDOW_UPDATE. This is only used when auto
|
||||
WINDOW_UPDATE is turned off. */
|
||||
int32_t consumed_size;
|
||||
/* The amount of recv_window_size cut using submitting negative
|
||||
value to WINDOW_UPDATE */
|
||||
int32_t recv_reduction;
|
||||
/* window size for local flow control. It is initially set to
|
||||
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE and could be
|
||||
increased/decreased by submitting WINDOW_UPDATE. See
|
||||
nghttp2_submit_window_update(). */
|
||||
int32_t local_window_size;
|
||||
/* Settings value received from the remote endpoint. We just use ID
|
||||
as index. The index = 0 is unused. */
|
||||
nghttp2_settings_storage remote_settings;
|
||||
/* Settings value of the local endpoint. */
|
||||
nghttp2_settings_storage local_settings;
|
||||
/* Option flags. This is bitwise-OR of 0 or more of nghttp2_optmask. */
|
||||
uint32_t opt_flags;
|
||||
/* Unacked local SETTINGS_MAX_CONCURRENT_STREAMS value. We use this
|
||||
to refuse the incoming stream if it exceeds this value. */
|
||||
uint32_t pending_local_max_concurrent_stream;
|
||||
/* The bitwise OR of zero or more of nghttp2_typemask to indicate
|
||||
that the default handling of extension frame is enabled. */
|
||||
uint32_t builtin_recv_ext_types;
|
||||
/* Unacked local ENABLE_PUSH value. We use this to refuse
|
||||
PUSH_PROMISE before SETTINGS ACK is received. */
|
||||
uint8_t pending_enable_push;
|
||||
/* Nonzero if the session is server side. */
|
||||
uint8_t server;
|
||||
/* Flags indicating GOAWAY is sent and/or received. The flags are
|
||||
composed by bitwise OR-ing nghttp2_goaway_flag. */
|
||||
uint8_t goaway_flags;
|
||||
/* This flag is used to reduce excessive queuing of WINDOW_UPDATE to
|
||||
this session. The nonzero does not necessarily mean
|
||||
WINDOW_UPDATE is not queued. */
|
||||
uint8_t window_update_queued;
|
||||
/* Bitfield of extension frame types that application is willing to
|
||||
receive. To designate the bit of given frame type i, use
|
||||
user_recv_ext_types[i / 8] & (1 << (i & 0x7)). First 10 frame
|
||||
types are standard frame types and not used in this bitfield. If
|
||||
bit is set, it indicates that incoming frame with that type is
|
||||
passed to user defined callbacks, otherwise they are ignored. */
|
||||
uint8_t user_recv_ext_types[32];
|
||||
};
|
||||
|
||||
/* Struct used when updating initial window size of each active
|
||||
stream. */
|
||||
typedef struct {
|
||||
nghttp2_session *session;
|
||||
int32_t new_window_size, old_window_size;
|
||||
} nghttp2_update_window_size_arg;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_session *session;
|
||||
/* linked list of streams to close */
|
||||
nghttp2_stream *head;
|
||||
int32_t last_stream_id;
|
||||
/* nonzero if GOAWAY is sent to peer, which means we are going to
|
||||
close incoming streams. zero if GOAWAY is received from peer and
|
||||
we are going to close outgoing streams. */
|
||||
int incoming;
|
||||
} nghttp2_close_stream_on_goaway_arg;
|
||||
|
||||
/* TODO stream timeout etc */
|
||||
|
||||
/*
|
||||
* Returns nonzero value if |stream_id| is initiated by local
|
||||
* endpoint.
|
||||
*/
|
||||
int nghttp2_session_is_my_stream_id(nghttp2_session *session,
|
||||
int32_t stream_id);
|
||||
|
||||
/*
|
||||
* Adds |item| to the outbound queue in |session|. When this function
|
||||
* succeeds, it takes ownership of |item|. So caller must not free it
|
||||
* on success.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_STREAM_CLOSED
|
||||
* Stream already closed (DATA and PUSH_PROMISE frame only)
|
||||
*/
|
||||
int nghttp2_session_add_item(nghttp2_session *session,
|
||||
nghttp2_outbound_item *item);
|
||||
|
||||
/*
|
||||
* Adds RST_STREAM frame for the stream |stream_id| with the error
|
||||
* code |error_code|. This is a convenient function built on top of
|
||||
* nghttp2_session_add_frame() to add RST_STREAM easily.
|
||||
*
|
||||
* This function simply returns 0 without adding RST_STREAM frame if
|
||||
* given stream is in NGHTTP2_STREAM_CLOSING state, because multiple
|
||||
* RST_STREAM for a stream is redundant.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
|
||||
uint32_t error_code);
|
||||
|
||||
/*
|
||||
* Adds PING frame. This is a convenient functin built on top of
|
||||
* nghttp2_session_add_frame() to add PING easily.
|
||||
*
|
||||
* If the |opaque_data| is not NULL, it must point to 8 bytes memory
|
||||
* region of data. The data pointed by |opaque_data| is copied. It can
|
||||
* be NULL. In this case, 8 bytes NULL is used.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FLOODED
|
||||
* There are too many items in outbound queue; this only happens
|
||||
* if NGHTTP2_FLAG_ACK is set in |flags|
|
||||
*/
|
||||
int nghttp2_session_add_ping(nghttp2_session *session, uint8_t flags,
|
||||
const uint8_t *opaque_data);
|
||||
|
||||
/*
|
||||
* Adds GOAWAY frame with the last-stream-ID |last_stream_id| and the
|
||||
* error code |error_code|. This is a convenient function built on top
|
||||
* of nghttp2_session_add_frame() to add GOAWAY easily. The
|
||||
* |aux_flags| are bitwise-OR of one or more of
|
||||
* nghttp2_goaway_aux_flag.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The |opaque_data_len| is too large.
|
||||
*/
|
||||
int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id,
|
||||
uint32_t error_code, const uint8_t *opaque_data,
|
||||
size_t opaque_data_len, uint8_t aux_flags);
|
||||
|
||||
/*
|
||||
* Adds WINDOW_UPDATE frame with stream ID |stream_id| and
|
||||
* window-size-increment |window_size_increment|. This is a convenient
|
||||
* function built on top of nghttp2_session_add_frame() to add
|
||||
* WINDOW_UPDATE easily.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_session_add_window_update(nghttp2_session *session, uint8_t flags,
|
||||
int32_t stream_id,
|
||||
int32_t window_size_increment);
|
||||
|
||||
/*
|
||||
* Adds SETTINGS frame.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FLOODED
|
||||
* There are too many items in outbound queue; this only happens
|
||||
* if NGHTTP2_FLAG_ACK is set in |flags|
|
||||
*/
|
||||
int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
|
||||
const nghttp2_settings_entry *iv, size_t niv);
|
||||
|
||||
/*
|
||||
* Creates new stream in |session| with stream ID |stream_id|,
|
||||
* priority |pri_spec| and flags |flags|. The |flags| is bitwise OR
|
||||
* of nghttp2_stream_flag. Since this function is called when initial
|
||||
* HEADERS is sent or received, these flags are taken from it. The
|
||||
* state of stream is set to |initial_state|. The |stream_user_data|
|
||||
* is a pointer to the arbitrary user supplied data to be associated
|
||||
* to this stream.
|
||||
*
|
||||
* If |initial_state| is NGHTTP2_STREAM_RESERVED, this function sets
|
||||
* NGHTTP2_STREAM_FLAG_PUSH flag set.
|
||||
*
|
||||
* This function returns a pointer to created new stream object, or
|
||||
* NULL.
|
||||
*
|
||||
* This function adjusts neither the number of closed streams or idle
|
||||
* streams. The caller should manually call
|
||||
* nghttp2_session_adjust_closed_stream() or
|
||||
* nghttp2_session_adjust_idle_stream() respectively.
|
||||
*/
|
||||
nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
|
||||
int32_t stream_id, uint8_t flags,
|
||||
nghttp2_priority_spec *pri_spec,
|
||||
nghttp2_stream_state initial_state,
|
||||
void *stream_user_data);
|
||||
|
||||
/*
|
||||
* Closes stream whose stream ID is |stream_id|. The reason of closure
|
||||
* is indicated by the |error_code|. When closing the stream,
|
||||
* on_stream_close_callback will be called.
|
||||
*
|
||||
* If the session is initialized as server and |stream| is incoming
|
||||
* stream, stream is just marked closed and this function calls
|
||||
* nghttp2_session_keep_closed_stream() with |stream|. Otherwise,
|
||||
* |stream| will be deleted from memory.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The specified stream does not exist.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The callback function failed.
|
||||
*/
|
||||
int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
|
||||
uint32_t error_code);
|
||||
|
||||
/*
|
||||
* Deletes |stream| from memory. After this function returns, stream
|
||||
* cannot be accessed.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_session_destroy_stream(nghttp2_session *session,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Tries to keep incoming closed stream |stream|. Due to the
|
||||
* limitation of maximum number of streams in memory, |stream| is not
|
||||
* closed and just deleted from memory (see
|
||||
* nghttp2_session_destroy_stream).
|
||||
*/
|
||||
void nghttp2_session_keep_closed_stream(nghttp2_session *session,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Appends |stream| to linked list |session->idle_stream_head|. We
|
||||
* apply fixed limit for list size. To fit into that limit, one or
|
||||
* more oldest streams are removed from list as necessary.
|
||||
*/
|
||||
void nghttp2_session_keep_idle_stream(nghttp2_session *session,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Detaches |stream| from idle streams linked list.
|
||||
*/
|
||||
void nghttp2_session_detach_idle_stream(nghttp2_session *session,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Deletes closed stream to ensure that number of incoming streams
|
||||
* including active and closed is in the maximum number of allowed
|
||||
* stream.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_session_adjust_closed_stream(nghttp2_session *session);
|
||||
|
||||
/*
|
||||
* Deletes idle stream to ensure that number of idle streams is in
|
||||
* certain limit.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_session_adjust_idle_stream(nghttp2_session *session);
|
||||
|
||||
/*
|
||||
* If further receptions and transmissions over the stream |stream_id|
|
||||
* are disallowed, close the stream with error code NGHTTP2_NO_ERROR.
|
||||
*
|
||||
* This function returns 0 if it
|
||||
* succeeds, or one of the following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The specified stream does not exist.
|
||||
*/
|
||||
int nghttp2_session_close_stream_if_shut_rdwr(nghttp2_session *session,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
int nghttp2_session_on_request_headers_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
int nghttp2_session_on_response_headers_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
int nghttp2_session_on_push_response_headers_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Called when HEADERS is received, assuming |frame| is properly
|
||||
* initialized. This function does first validate received frame and
|
||||
* then open stream and call callback functions.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_IGN_HEADER_BLOCK
|
||||
* Frame was rejected and header block must be decoded but
|
||||
* result must be ignored.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The read_callback failed
|
||||
*/
|
||||
int nghttp2_session_on_headers_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Called when PRIORITY is received, assuming |frame| is properly
|
||||
* initialized.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The read_callback failed
|
||||
*/
|
||||
int nghttp2_session_on_priority_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* Called when RST_STREAM is received, assuming |frame| is properly
|
||||
* initialized.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The read_callback failed
|
||||
*/
|
||||
int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* Called when SETTINGS is received, assuming |frame| is properly
|
||||
* initialized. If |noack| is non-zero, SETTINGS with ACK will not be
|
||||
* submitted. If |frame| has NGHTTP2_FLAG_ACK flag set, no SETTINGS
|
||||
* with ACK will not be submitted regardless of |noack|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The read_callback failed
|
||||
* NGHTTP2_ERR_FLOODED
|
||||
* There are too many items in outbound queue, and this is most
|
||||
* likely caused by misbehaviour of peer.
|
||||
*/
|
||||
int nghttp2_session_on_settings_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame, int noack);
|
||||
|
||||
/*
|
||||
* Called when PUSH_PROMISE is received, assuming |frame| is properly
|
||||
* initialized.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_IGN_HEADER_BLOCK
|
||||
* Frame was rejected and header block must be decoded but
|
||||
* result must be ignored.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The read_callback failed
|
||||
*/
|
||||
int nghttp2_session_on_push_promise_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* Called when PING is received, assuming |frame| is properly
|
||||
* initialized.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The callback function failed.
|
||||
* NGHTTP2_ERR_FLOODED
|
||||
* There are too many items in outbound queue, and this is most
|
||||
* likely caused by misbehaviour of peer.
|
||||
*/
|
||||
int nghttp2_session_on_ping_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* Called when GOAWAY is received, assuming |frame| is properly
|
||||
* initialized.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The callback function failed.
|
||||
*/
|
||||
int nghttp2_session_on_goaway_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* Called when WINDOW_UPDATE is received, assuming |frame| is properly
|
||||
* initialized.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The callback function failed.
|
||||
*/
|
||||
int nghttp2_session_on_window_update_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* Called when ALTSVC is received, assuming |frame| is properly
|
||||
* initialized.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The callback function failed.
|
||||
*/
|
||||
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* Called when DATA is received, assuming |frame| is properly
|
||||
* initialized.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The callback function failed.
|
||||
*/
|
||||
int nghttp2_session_on_data_received(nghttp2_session *session,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* Returns nghttp2_stream* object whose stream ID is |stream_id|. It
|
||||
* could be NULL if such stream does not exist. This function returns
|
||||
* NULL if stream is marked as closed.
|
||||
*/
|
||||
nghttp2_stream *nghttp2_session_get_stream(nghttp2_session *session,
|
||||
int32_t stream_id);
|
||||
|
||||
/*
|
||||
* This function behaves like nghttp2_session_get_stream(), but it
|
||||
* returns stream object even if it is marked as closed or in
|
||||
* NGHTTP2_STREAM_IDLE state.
|
||||
*/
|
||||
nghttp2_stream *nghttp2_session_get_stream_raw(nghttp2_session *session,
|
||||
int32_t stream_id);
|
||||
|
||||
/*
|
||||
* Packs DATA frame |frame| in wire frame format and stores it in
|
||||
* |bufs|. Payload will be read using |aux_data->data_prd|. The
|
||||
* length of payload is at most |datamax| bytes.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_DEFERRED
|
||||
* The DATA frame is postponed.
|
||||
* NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE
|
||||
* The read_callback failed (stream error).
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_CALLBACK_FAILURE
|
||||
* The read_callback failed (session error).
|
||||
*/
|
||||
int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
|
||||
size_t datamax, nghttp2_frame *frame,
|
||||
nghttp2_data_aux_data *aux_data,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Pops and returns next item to send. If there is no such item,
|
||||
* returns NULL. This function takes into account max concurrent
|
||||
* streams. That means if session->ob_syn has item and max concurrent
|
||||
* streams is reached, the even if other queues contain items, then
|
||||
* this function returns NULL.
|
||||
*/
|
||||
nghttp2_outbound_item *
|
||||
nghttp2_session_pop_next_ob_item(nghttp2_session *session);
|
||||
|
||||
/*
|
||||
* Returns next item to send. If there is no such item, this function
|
||||
* returns NULL. This function takes into account max concurrent
|
||||
* streams. That means if session->ob_syn has item and max concurrent
|
||||
* streams is reached, the even if other queues contain items, then
|
||||
* this function returns NULL.
|
||||
*/
|
||||
nghttp2_outbound_item *
|
||||
nghttp2_session_get_next_ob_item(nghttp2_session *session);
|
||||
|
||||
/*
|
||||
* Updates local settings with the |iv|. The number of elements in the
|
||||
* array pointed by the |iv| is given by the |niv|. This function
|
||||
* assumes that the all settings_id member in |iv| are in range 1 to
|
||||
* NGHTTP2_SETTINGS_MAX, inclusive.
|
||||
*
|
||||
* While updating individual stream's local window size, if the window
|
||||
* size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE,
|
||||
* RST_STREAM is issued against such a stream.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_session_update_local_settings(nghttp2_session *session,
|
||||
nghttp2_settings_entry *iv,
|
||||
size_t niv);
|
||||
|
||||
/*
|
||||
* Re-prioritize |stream|. The new priority specification is
|
||||
* |pri_spec|. Caller must ensure that stream->hd.stream_id !=
|
||||
* pri_spec->stream_id.
|
||||
*
|
||||
* This function does not adjust the number of idle streams. The
|
||||
* caller should call nghttp2_session_adjust_idle_stream() later.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_session_reprioritize_stream(nghttp2_session *session,
|
||||
nghttp2_stream *stream,
|
||||
const nghttp2_priority_spec *pri_spec);
|
||||
|
||||
/*
|
||||
* Terminates current |session| with the |error_code|. The |reason|
|
||||
* is NULL-terminated debug string.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The |reason| is too long.
|
||||
*/
|
||||
int nghttp2_session_terminate_session_with_reason(nghttp2_session *session,
|
||||
uint32_t error_code,
|
||||
const char *reason);
|
||||
|
||||
#endif /* NGHTTP2_SESSION_H */
|
||||
|
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_STREAM_H
|
||||
#define NGHTTP2_STREAM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_outbound_item.h"
|
||||
#include "nghttp2_map.h"
|
||||
#include "nghttp2_pq.h"
|
||||
#include "nghttp2_int.h"
|
||||
|
||||
/*
|
||||
* If local peer is stream initiator:
|
||||
* NGHTTP2_STREAM_OPENING : upon sending request HEADERS
|
||||
* NGHTTP2_STREAM_OPENED : upon receiving response HEADERS
|
||||
* NGHTTP2_STREAM_CLOSING : upon queuing RST_STREAM
|
||||
*
|
||||
* If remote peer is stream initiator:
|
||||
* NGHTTP2_STREAM_OPENING : upon receiving request HEADERS
|
||||
* NGHTTP2_STREAM_OPENED : upon sending response HEADERS
|
||||
* NGHTTP2_STREAM_CLOSING : upon queuing RST_STREAM
|
||||
*/
|
||||
typedef enum {
|
||||
/* Initial state */
|
||||
NGHTTP2_STREAM_INITIAL,
|
||||
/* For stream initiator: request HEADERS has been sent, but response
|
||||
HEADERS has not been received yet. For receiver: request HEADERS
|
||||
has been received, but it does not send response HEADERS yet. */
|
||||
NGHTTP2_STREAM_OPENING,
|
||||
/* For stream initiator: response HEADERS is received. For receiver:
|
||||
response HEADERS is sent. */
|
||||
NGHTTP2_STREAM_OPENED,
|
||||
/* RST_STREAM is received, but somehow we need to keep stream in
|
||||
memory. */
|
||||
NGHTTP2_STREAM_CLOSING,
|
||||
/* PUSH_PROMISE is received or sent */
|
||||
NGHTTP2_STREAM_RESERVED,
|
||||
/* Stream is created in this state if it is used as anchor in
|
||||
dependency tree. */
|
||||
NGHTTP2_STREAM_IDLE
|
||||
} nghttp2_stream_state;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_SHUT_NONE = 0,
|
||||
/* Indicates further receptions will be disallowed. */
|
||||
NGHTTP2_SHUT_RD = 0x01,
|
||||
/* Indicates further transmissions will be disallowed. */
|
||||
NGHTTP2_SHUT_WR = 0x02,
|
||||
/* Indicates both further receptions and transmissions will be
|
||||
disallowed. */
|
||||
NGHTTP2_SHUT_RDWR = NGHTTP2_SHUT_RD | NGHTTP2_SHUT_WR
|
||||
} nghttp2_shut_flag;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_STREAM_FLAG_NONE = 0,
|
||||
/* Indicates that this stream is pushed stream and not opened
|
||||
yet. */
|
||||
NGHTTP2_STREAM_FLAG_PUSH = 0x01,
|
||||
/* Indicates that this stream was closed */
|
||||
NGHTTP2_STREAM_FLAG_CLOSED = 0x02,
|
||||
/* Indicates the item is deferred due to flow control. */
|
||||
NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL = 0x04,
|
||||
/* Indicates the item is deferred by user callback */
|
||||
NGHTTP2_STREAM_FLAG_DEFERRED_USER = 0x08,
|
||||
/* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and
|
||||
NGHTTP2_STREAM_FLAG_DEFERRED_USER. */
|
||||
NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c
|
||||
|
||||
} nghttp2_stream_flag;
|
||||
|
||||
/* HTTP related flags to enforce HTTP semantics */
|
||||
typedef enum {
|
||||
NGHTTP2_HTTP_FLAG_NONE = 0,
|
||||
/* header field seen so far */
|
||||
NGHTTP2_HTTP_FLAG__AUTHORITY = 1,
|
||||
NGHTTP2_HTTP_FLAG__PATH = 1 << 1,
|
||||
NGHTTP2_HTTP_FLAG__METHOD = 1 << 2,
|
||||
NGHTTP2_HTTP_FLAG__SCHEME = 1 << 3,
|
||||
/* host is not pseudo header, but we require either host or
|
||||
:authority */
|
||||
NGHTTP2_HTTP_FLAG_HOST = 1 << 4,
|
||||
NGHTTP2_HTTP_FLAG__STATUS = 1 << 5,
|
||||
/* required header fields for HTTP request except for CONNECT
|
||||
method. */
|
||||
NGHTTP2_HTTP_FLAG_REQ_HEADERS = NGHTTP2_HTTP_FLAG__METHOD |
|
||||
NGHTTP2_HTTP_FLAG__PATH |
|
||||
NGHTTP2_HTTP_FLAG__SCHEME,
|
||||
NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED = 1 << 6,
|
||||
/* HTTP method flags */
|
||||
NGHTTP2_HTTP_FLAG_METH_CONNECT = 1 << 7,
|
||||
NGHTTP2_HTTP_FLAG_METH_HEAD = 1 << 8,
|
||||
NGHTTP2_HTTP_FLAG_METH_OPTIONS = 1 << 9,
|
||||
NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND = 1 << 10,
|
||||
NGHTTP2_HTTP_FLAG_METH_ALL = NGHTTP2_HTTP_FLAG_METH_CONNECT |
|
||||
NGHTTP2_HTTP_FLAG_METH_HEAD |
|
||||
NGHTTP2_HTTP_FLAG_METH_OPTIONS |
|
||||
NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND,
|
||||
/* :path category */
|
||||
/* path starts with "/" */
|
||||
NGHTTP2_HTTP_FLAG_PATH_REGULAR = 1 << 11,
|
||||
/* path "*" */
|
||||
NGHTTP2_HTTP_FLAG_PATH_ASTERISK = 1 << 12,
|
||||
/* scheme */
|
||||
/* "http" or "https" scheme */
|
||||
NGHTTP2_HTTP_FLAG_SCHEME_HTTP = 1 << 13,
|
||||
/* set if final response is expected */
|
||||
NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE = 1 << 14
|
||||
} nghttp2_http_flag;
|
||||
|
||||
struct nghttp2_stream {
|
||||
/* Intrusive Map */
|
||||
nghttp2_map_entry map_entry;
|
||||
/* Entry for dep_prev->obq */
|
||||
nghttp2_pq_entry pq_entry;
|
||||
/* Priority Queue storing direct descendant (nghttp2_stream). Only
|
||||
streams which itself has some data to send, or has a descendant
|
||||
which has some data to sent. */
|
||||
nghttp2_pq obq;
|
||||
/* Content-Length of request/response body. -1 if unknown. */
|
||||
int64_t content_length;
|
||||
/* Received body so far */
|
||||
int64_t recv_content_length;
|
||||
/* Base last_cycle for direct descendent streams. */
|
||||
uint32_t descendant_last_cycle;
|
||||
/* Next scheduled time to sent item */
|
||||
uint32_t cycle;
|
||||
/* Next seq used for direct descendant streams */
|
||||
uint64_t descendant_next_seq;
|
||||
/* Secondary key for prioritization to break a tie for cycle. This
|
||||
value is monotonically increased for single parent stream. */
|
||||
uint64_t seq;
|
||||
/* pointers to form dependency tree. If multiple streams depend on
|
||||
a stream, only one stream (left most) has non-NULL dep_prev which
|
||||
points to the stream it depends on. The remaining streams are
|
||||
linked using sib_prev and sib_next. The stream which has
|
||||
non-NULL dep_prev always NULL sib_prev. The right most stream
|
||||
has NULL sib_next. If this stream is a root of dependency tree,
|
||||
dep_prev and sib_prev are NULL. */
|
||||
nghttp2_stream *dep_prev, *dep_next;
|
||||
nghttp2_stream *sib_prev, *sib_next;
|
||||
/* When stream is kept after closure, it may be kept in doubly
|
||||
linked list pointed by nghttp2_session closed_stream_head.
|
||||
closed_next points to the next stream object if it is the element
|
||||
of the list. */
|
||||
nghttp2_stream *closed_prev, *closed_next;
|
||||
/* The arbitrary data provided by user for this stream. */
|
||||
void *stream_user_data;
|
||||
/* Item to send */
|
||||
nghttp2_outbound_item *item;
|
||||
/* Last written length of frame payload */
|
||||
size_t last_writelen;
|
||||
/* stream ID */
|
||||
int32_t stream_id;
|
||||
/* Current remote window size. This value is computed against the
|
||||
current initial window size of remote endpoint. */
|
||||
int32_t remote_window_size;
|
||||
/* Keep track of the number of bytes received without
|
||||
WINDOW_UPDATE. This could be negative after submitting negative
|
||||
value to WINDOW_UPDATE */
|
||||
int32_t recv_window_size;
|
||||
/* The number of bytes consumed by the application and now is
|
||||
subject to WINDOW_UPDATE. This is only used when auto
|
||||
WINDOW_UPDATE is turned off. */
|
||||
int32_t consumed_size;
|
||||
/* The amount of recv_window_size cut using submitting negative
|
||||
value to WINDOW_UPDATE */
|
||||
int32_t recv_reduction;
|
||||
/* window size for local flow control. It is initially set to
|
||||
NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by
|
||||
submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */
|
||||
int32_t local_window_size;
|
||||
/* weight of this stream */
|
||||
int32_t weight;
|
||||
/* This is unpaid penalty (offset) when calculating cycle. */
|
||||
uint32_t pending_penalty;
|
||||
/* sum of weight of direct descendants */
|
||||
int32_t sum_dep_weight;
|
||||
nghttp2_stream_state state;
|
||||
/* status code from remote server */
|
||||
int16_t status_code;
|
||||
/* Bitwise OR of zero or more nghttp2_http_flag values */
|
||||
uint16_t http_flags;
|
||||
/* This is bitwise-OR of 0 or more of nghttp2_stream_flag. */
|
||||
uint8_t flags;
|
||||
/* Bitwise OR of zero or more nghttp2_shut_flag values */
|
||||
uint8_t shut_flags;
|
||||
/* Nonzero if this stream has been queued to stream pointed by
|
||||
dep_prev. We maintain the invariant that if a stream is queued,
|
||||
then its ancestors, except for root, are also queued. This
|
||||
invariant may break in fatal error condition. */
|
||||
uint8_t queued;
|
||||
/* This flag is used to reduce excessive queuing of WINDOW_UPDATE to
|
||||
this stream. The nonzero does not necessarily mean WINDOW_UPDATE
|
||||
is not queued. */
|
||||
uint8_t window_update_queued;
|
||||
};
|
||||
|
||||
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
|
||||
uint8_t flags, nghttp2_stream_state initial_state,
|
||||
int32_t weight, int32_t remote_initial_window_size,
|
||||
int32_t local_initial_window_size,
|
||||
void *stream_user_data, nghttp2_mem *mem);
|
||||
|
||||
void nghttp2_stream_free(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Disallow either further receptions or transmissions, or both.
|
||||
* |flag| is bitwise OR of one or more of nghttp2_shut_flag.
|
||||
*/
|
||||
void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag);
|
||||
|
||||
/*
|
||||
* Defer |stream->item|. We won't call this function in the situation
|
||||
* where |stream->item| == NULL. The |flags| is bitwise OR of zero or
|
||||
* more of NGHTTP2_STREAM_FLAG_DEFERRED_USER and
|
||||
* NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL. The |flags| indicates
|
||||
* the reason of this action.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags);
|
||||
|
||||
/*
|
||||
* Put back deferred data in this stream to active state. The |flags|
|
||||
* are one or more of bitwise OR of the following values:
|
||||
* NGHTTP2_STREAM_FLAG_DEFERRED_USER and
|
||||
* NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are
|
||||
* cleared if they are set. So even if this function is called, if
|
||||
* one of flag is still set, data does not become active.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags);
|
||||
|
||||
/*
|
||||
* Returns nonzero if item is deferred by whatever reason.
|
||||
*/
|
||||
int nghttp2_stream_check_deferred_item(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Returns nonzero if item is deferred by flow control.
|
||||
*/
|
||||
int nghttp2_stream_check_deferred_by_flow_control(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Updates the remote window size with the new value
|
||||
* |new_initial_window_size|. The |old_initial_window_size| is used to
|
||||
* calculate the current window size.
|
||||
*
|
||||
* This function returns 0 if it succeeds or -1. The failure is due to
|
||||
* overflow.
|
||||
*/
|
||||
int nghttp2_stream_update_remote_initial_window_size(
|
||||
nghttp2_stream *stream, int32_t new_initial_window_size,
|
||||
int32_t old_initial_window_size);
|
||||
|
||||
/*
|
||||
* Updates the local window size with the new value
|
||||
* |new_initial_window_size|. The |old_initial_window_size| is used to
|
||||
* calculate the current window size.
|
||||
*
|
||||
* This function returns 0 if it succeeds or -1. The failure is due to
|
||||
* overflow.
|
||||
*/
|
||||
int nghttp2_stream_update_local_initial_window_size(
|
||||
nghttp2_stream *stream, int32_t new_initial_window_size,
|
||||
int32_t old_initial_window_size);
|
||||
|
||||
/*
|
||||
* Call this function if promised stream |stream| is replied with
|
||||
* HEADERS. This function makes the state of the |stream| to
|
||||
* NGHTTP2_STREAM_OPENED.
|
||||
*/
|
||||
void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Returns nonzero if |target| is an ancestor of |stream|.
|
||||
*/
|
||||
int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream,
|
||||
nghttp2_stream *target);
|
||||
|
||||
/*
|
||||
* Computes distributed weight of a stream of the |weight| under the
|
||||
* |stream| if |stream| is removed from a dependency tree.
|
||||
*/
|
||||
int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
|
||||
int32_t weight);
|
||||
|
||||
/*
|
||||
* Makes the |stream| depend on the |dep_stream|. This dependency is
|
||||
* exclusive. All existing direct descendants of |dep_stream| become
|
||||
* the descendants of the |stream|. This function assumes
|
||||
* |stream->item| is NULL.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Makes the |stream| depend on the |dep_stream|. This dependency is
|
||||
* not exclusive. This function assumes |stream->item| is NULL.
|
||||
*/
|
||||
void nghttp2_stream_dep_add(nghttp2_stream *dep_stream, nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Removes the |stream| from the current dependency tree. This
|
||||
* function assumes |stream->item| is NULL.
|
||||
*/
|
||||
int nghttp2_stream_dep_remove(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Attaches |item| to |stream|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_stream_attach_item(nghttp2_stream *stream,
|
||||
nghttp2_outbound_item *item);
|
||||
|
||||
/*
|
||||
* Detaches |stream->item|. This function does not free
|
||||
* |stream->item|. The caller must free it.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_stream_detach_item(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Makes the |stream| depend on the |dep_stream|. This dependency is
|
||||
* exclusive.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Makes the |stream| depend on the |dep_stream|. This dependency is
|
||||
* not exclusive.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
|
||||
nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Removes subtree whose root stream is |stream|. The
|
||||
* effective_weight of streams in removed subtree is not updated.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Returns nonzero if |stream| is in any dependency tree.
|
||||
*/
|
||||
int nghttp2_stream_in_dep_tree(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Schedules transmission of |stream|'s item, assuming stream->item is
|
||||
* attached, and stream->last_writelen was updated.
|
||||
*/
|
||||
void nghttp2_stream_reschedule(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* Changes |stream|'s weight to |weight|. If |stream| is queued, it
|
||||
* will be rescheduled based on new weight.
|
||||
*/
|
||||
void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight);
|
||||
|
||||
/*
|
||||
* Returns a stream which has highest priority, updating
|
||||
* descendant_last_cycle of selected stream's ancestors.
|
||||
*/
|
||||
nghttp2_outbound_item *
|
||||
nghttp2_stream_next_outbound_item(nghttp2_stream *stream);
|
||||
|
||||
#endif /* NGHTTP2_STREAM */
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_SUBMIT_H
|
||||
#define NGHTTP2_SUBMIT_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#endif /* NGHTTP2_SUBMIT_H */
|
||||
224
sdk/component/common/network/httpc/httpc.h
Normal file
224
sdk/component/common/network/httpc/httpc.h
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file httpc.h
|
||||
* @author
|
||||
* @version
|
||||
* @brief This file provides user interface for HTTP/HTTPS client.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and possession or use of this module requires written permission of RealTek.
|
||||
*
|
||||
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef _HTTPC_H_
|
||||
#define _HTTPC_H_
|
||||
|
||||
/** @addtogroup httpc HTTPC
|
||||
* @ingroup network
|
||||
* @brief HTTP/HTTPS client functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "platform_stdlib.h"
|
||||
#include "platform_opts.h"
|
||||
|
||||
#define HTTPC_SECURE_NONE 0 /*!< Running with HTTP client */
|
||||
#define HTTPC_SECURE_TLS 1 /*!< Running with HTTPS client */
|
||||
|
||||
#define HTTPC_DEBUG_OFF 0 /*!< Disable httpc debug log */
|
||||
#define HTTPC_DEBUG_ON 1 /*!< Enable httpc debug log */
|
||||
#define HTTPC_DEBUG_VERBOSE 2 /*!< Enable httpc verbose debug log */
|
||||
|
||||
#define HTTPC_TLS_POLARSSL 0 /*!< Use PolarSSL for TLS when HTTPS */
|
||||
#define HTTPC_TLS_MBEDTLS 1 /*!< Use mbedTLS for TLS when HTTPS */
|
||||
|
||||
#if CONFIG_USE_POLARSSL
|
||||
#define HTTPC_USE_TLS HTTPC_TLS_POLARSSL
|
||||
#elif CONFIG_USE_MBEDTLS
|
||||
#define HTTPC_USE_TLS HTTPC_TLS_MBEDTLS
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The structure is the context used for HTTP response header parsing.
|
||||
* @note Only header string includes string terminator.
|
||||
*/
|
||||
struct http_response {
|
||||
uint8_t *header; /*!< HTTP header string parsed in HTTP response */
|
||||
size_t header_len; /*!< HTTP header string length */
|
||||
uint8_t *version; /*!< Pointer to HTTP version in the parsed HTTP header string */
|
||||
size_t version_len; /*!< HTTP version data length */
|
||||
uint8_t *status; /*!< Pointer to HTTP status code in the parsed HTTP header string */
|
||||
size_t status_len; /*!< HTTP status code data length */
|
||||
uint8_t *content_type; /*!< Pointer to Content-Type header field in the parsed HTTP header string */
|
||||
size_t content_type_len; /*!< Content-Type header field data length */
|
||||
size_t content_len; /*!< Value of Content-Length header field parsed in HTTP header string */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The structure is the context used for connection.
|
||||
*/
|
||||
struct httpc_conn {
|
||||
int ignore_content_len;
|
||||
int sock; /*!< Client socket descriptor for connection */
|
||||
struct http_response response; /*!< Context for HTTP response */
|
||||
void *tls; /*!< Context for TLS connection */
|
||||
uint8_t *request_header; /*!< Pointer to transmission buffer of HTTP request header */
|
||||
char *host; /*!< String of server host name or IP */
|
||||
uint16_t port; /*!< Service port */
|
||||
char *user_password; /*!< Base64 string for HTTP basic authorization */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This function is used to generate connection context for an HTTP/HTTPS client.
|
||||
* @param[in] secure: security mode for HTTP or HTTPS. Must be HTTPC_SECURE_NONE, HTTPC_SECURE_TLS.
|
||||
* @param[in] client_cert: string of client certificate if required to be verified by server.
|
||||
* @param[in] client_key: string of client private key if required to be verified by server.
|
||||
* @param[in] ca_certs: string including certificates in CA trusted chain if want to verify server certificate.
|
||||
* @return pointer to the generated connection context
|
||||
*/
|
||||
struct httpc_conn *httpc_conn_new(uint8_t secure, char *client_cert, char *client_key, char *ca_certs);
|
||||
|
||||
/**
|
||||
* @brief This function is used to deallocate a connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return None
|
||||
*/
|
||||
void httpc_conn_free(struct httpc_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to connect to a server.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] host: string of server host name or IP
|
||||
* @param[in] port: service port
|
||||
* @param[in] timeout: connection timeout in seconds
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpc_conn_connect(struct httpc_conn *conn, char *host, uint16_t port, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief This function is used to close connection from a server.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return None
|
||||
*/
|
||||
void httpc_conn_close(struct httpc_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup authorization for connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] user: string of user name for authorization
|
||||
* @param[in] password: string of password for authorization
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
* @note Must be used before httpc_conn_connect() if basic authorization is used
|
||||
*/
|
||||
int httpc_conn_setup_user_password(struct httpc_conn *conn, char *user, char *password);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup httpc debug.
|
||||
* @param[in] debug: flag to enable/disable httpc debug. Must be HTTPC_DEBUG_OFF, HTTPC_DEBUG_ON, HTTPC_DEBUG_VERBOSE.
|
||||
* @return None
|
||||
*/
|
||||
void httpc_setup_debug(uint8_t debug);
|
||||
|
||||
/**
|
||||
* @brief This function is used to enable ignoring content_len eqauls 0.
|
||||
* @param[in] conn: pointer to connection context.
|
||||
* @return None
|
||||
*/
|
||||
void httpc_enable_ignore_content_len(struct httpc_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to free memory allocated by httpc API, such as httpc_response_get_header_field().
|
||||
* @param[in] ptr: pointer to memory to be deallocated
|
||||
* @return None
|
||||
*/
|
||||
void httpc_free(void *ptr);
|
||||
|
||||
/**
|
||||
* @brief This function is used to dump the parsed HTTP header of response in connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return None
|
||||
*/
|
||||
void httpc_conn_dump_header(struct httpc_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to start a HTTP request in connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] method: string of HTTP method in HTTP request
|
||||
* @param[in] resource: string including path and query string to identify a resource
|
||||
* @param[in] content_type: string of Content-Type header field written to HTTP request. No Content-Type in HTTP request if NULL.
|
||||
* @param[in] content_len: value of Content-Length header field written to HTTP request. No Content-Length in HTTP request if NULL.
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpc_request_write_header_start(struct httpc_conn *conn, char *method, char *resource, char *content_type, size_t content_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to add an HTTP header field to HTTP request.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] name: HTTP header field name string
|
||||
* @param[in] value: HTTP header field value
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpc_request_write_header(struct httpc_conn *conn, char *name, char *value);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write HTTP request header data to connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return return value of lwip socket write() for HTTP and PolarSSL ssl_write() for HTTPS
|
||||
*/
|
||||
int httpc_request_write_header_finish(struct httpc_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write HTTP request body data to connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] data: data to be written
|
||||
* @param[in] data_len: data length
|
||||
* @return return value of lwip socket write() for HTTP and PolarSSL ssl_write() for HTTPS
|
||||
*/
|
||||
int httpc_request_write_data(struct httpc_conn *conn, uint8_t *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to check HTTP status of response in connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] status: HTTP status string to compare with
|
||||
* @return 0 : if different
|
||||
* @return 1 : if matched
|
||||
*/
|
||||
int httpc_response_is_status(struct httpc_conn *conn, char *status);
|
||||
|
||||
/**
|
||||
* @brief This function is used to read HTTP header from client socket descriptor and parse content to connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpc_response_read_header(struct httpc_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to read data from HTTP/HTTPS connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[out] data: buffer for data read
|
||||
* @param[in] data_len: buffer length
|
||||
* @return return value of lwip socket read() for HTTP and PolarSSL ssl_read() for HTTPS
|
||||
*/
|
||||
int httpc_response_read_data(struct httpc_conn *conn, uint8_t *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to get a header field from HTTP header of connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] field: header field string to search
|
||||
* @param[out] value: search result stored in memory allocated
|
||||
* @return 0 : if found
|
||||
* @return -1 : if not found
|
||||
* @note The search result memory should be free by httpc_free().
|
||||
*/
|
||||
int httpc_response_get_header_field(struct httpc_conn *conn, char *field, char **value);
|
||||
|
||||
/*\@}*/
|
||||
|
||||
#endif /* _HTTPC_H_ */
|
||||
42
sdk/component/common/network/httpc/httpc_util.h
Normal file
42
sdk/component/common/network/httpc/httpc_util.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef _HTTPC_UTIL_H_
|
||||
#define _HTTPC_UTIL_H_
|
||||
|
||||
#include "httpc.h"
|
||||
|
||||
extern uint8_t httpc_debug;
|
||||
|
||||
#define httpc_log(...) \
|
||||
do { \
|
||||
if(httpc_debug) { \
|
||||
rtw_enter_critical(NULL, NULL); \
|
||||
printf("\n\r[HTTPC] "); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n\r"); \
|
||||
rtw_exit_critical(NULL, NULL); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define httpc_log_verbose(...) \
|
||||
do { \
|
||||
if(httpc_debug == HTTPC_DEBUG_VERBOSE) { \
|
||||
rtw_enter_critical(NULL, NULL); \
|
||||
printf("\n\r[HTTPC] "); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n\r"); \
|
||||
rtw_exit_critical(NULL, NULL); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
void *httpc_malloc(size_t size);
|
||||
int httpc_write(struct httpc_conn *conn, uint8_t *buf, size_t buf_len);
|
||||
int httpc_read(struct httpc_conn *conn, uint8_t *buf, size_t buf_len);
|
||||
|
||||
void *httpc_tls_new(int *sock, char *client_cert, char *client_key, char *ca_certs);
|
||||
void httpc_tls_free(void *tls_in);
|
||||
int httpc_tls_handshake(void *tls_in, char *host);
|
||||
void httpc_tls_close(void *tls_in);
|
||||
int httpc_tls_read(void *tls_in, uint8_t *buf, size_t buf_len);
|
||||
int httpc_tls_write(void *tls_in, uint8_t *buf, size_t buf_len);
|
||||
int httpc_base64_encode(uint8_t *data, size_t data_len, char *base64_buf, size_t buf_len);
|
||||
|
||||
#endif /* _HTTPD_UTIL_H_ */
|
||||
314
sdk/component/common/network/httpd/httpd.h
Normal file
314
sdk/component/common/network/httpd/httpd.h
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file httpd.h
|
||||
* @author
|
||||
* @version
|
||||
* @brief This file provides user interface for HTTP/HTTPS server.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and possession or use of this module requires written permission of RealTek.
|
||||
*
|
||||
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef _HTTPD_H_
|
||||
#define _HTTPD_H_
|
||||
|
||||
/** @addtogroup httpd HTTPD
|
||||
* @ingroup network
|
||||
* @brief HTTP/HTTPS server functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "platform_stdlib.h"
|
||||
#include "platform_opts.h"
|
||||
|
||||
#define HTTPD_SECURE_NONE 0 /*!< Running with HTTP server */
|
||||
#define HTTPD_SECURE_TLS 1 /*!< Running with HTTPS server */
|
||||
#define HTTPD_SECURE_TLS_VERIFY 2 /*!< Running with HTTPS server and verify client */
|
||||
|
||||
#define HTTPD_THREAD_SINGLE 0 /*!< Single-thread mode for request handling */
|
||||
#define HTTPD_THREAD_MULTIPLE 1 /*!< Multi-thread mode for request handling */
|
||||
|
||||
#define HTTPD_DEBUG_OFF 0 /*!< Disable httpd debug log */
|
||||
#define HTTPD_DEBUG_ON 1 /*!< Enable httpd debug log */
|
||||
#define HTTPD_DEBUG_VERBOSE 2 /*!< Enable httpd verbose debug log */
|
||||
|
||||
#define HTTPD_TLS_POLARSSL 0 /*!< Use PolarSSL for TLS when HTTPS */
|
||||
#define HTTPD_TLS_MBEDTLS 1 /*!< Use mbedTLS for TLS when HTTPS */
|
||||
|
||||
#if CONFIG_USE_POLARSSL
|
||||
#define HTTPD_USE_TLS HTTPD_TLS_POLARSSL
|
||||
#elif CONFIG_USE_MBEDTLS
|
||||
#define HTTPD_USE_TLS HTTPD_TLS_MBEDTLS
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The structure is the context used for HTTP request header parsing.
|
||||
* @note Only header string includes string terminator.
|
||||
*/
|
||||
struct http_request {
|
||||
uint8_t *header; /*!< HTTP header string parsed in HTTP request */
|
||||
size_t header_len; /*!< HTTP header string length */
|
||||
uint8_t *method; /*!< Pointer to HTTP method in the parsed HTTP header string */
|
||||
size_t method_len; /*!< HTTP method data length */
|
||||
uint8_t *path; /*!< Pointer to resource path in the parsed HTTP header string */
|
||||
size_t path_len; /*!< Resource path data length */
|
||||
uint8_t *query; /*!< Pointer to query string in the parsed HTTP header string */
|
||||
size_t query_len; /*!< Query string data length */
|
||||
uint8_t *version; /*!< Pointer to HTTP version in the parsed HTTP header string */
|
||||
size_t version_len; /*!< HTTP version data length */
|
||||
uint8_t *host; /*!< Pointer to Host header field in the parsed HTTP header string */
|
||||
size_t host_len; /*!< Host header field data length */
|
||||
uint8_t *content_type; /*!< Pointer to Content-Type header field in the parsed HTTP header string */
|
||||
size_t content_type_len; /*!< Content-Type header field data length */
|
||||
size_t content_len; /*!< Value of Content-Length header field parsed in HTTP header string */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The structure is the context used for client connection.
|
||||
*/
|
||||
struct httpd_conn {
|
||||
int sock; /*!< Client socket descriptor for connection */
|
||||
struct http_request request; /*!< Context for HTTP request */
|
||||
void *tls; /*!< Context for TLS connection */
|
||||
uint8_t *response_header; /*!< Pointer to transmission buffer of HTTP response header */
|
||||
uint32_t last_req_time; /*!< Last request time in system ticks */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This function is used to start an HTTP or HTTPS server.
|
||||
* @param[in] port: service port
|
||||
* @param[in] max_conn: max client connections allowed
|
||||
* @param[in] stack_bytes: thread stack size in bytes
|
||||
* @param[in] thread_mode: server running thread mode. Must be HTTPD_THREAD_SINGLE, HTTPD_THREAD_MULTIPLE.
|
||||
* @param[in] secure: security mode for HTTP or HTTPS. Must be HTTPD_SECURE_NONE, HTTPD_SECURE_TLS, HTTPD_SECURE_TLS_VERIFY.
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpd_start(uint16_t port, uint8_t max_conn, uint32_t stack_bytes, uint8_t thread_mode, uint8_t secure);
|
||||
|
||||
/**
|
||||
* @brief This function is used to stop a running server
|
||||
* @return None
|
||||
*/
|
||||
void httpd_stop(void);
|
||||
|
||||
/**
|
||||
* @brief This function is used to check whether httpd server is running
|
||||
* @return 1 : if is running
|
||||
* @return 0 : if is not running
|
||||
*/
|
||||
int httpd_is_running(void);
|
||||
|
||||
/**
|
||||
* @brief This function is used to register a callback function for a Web page request handling.
|
||||
* @param[in] path: resource path for a page
|
||||
* @param[in] callback: callback function to handle the request to page
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpd_reg_page_callback(char *path, void (*callback)(struct httpd_conn *conn));
|
||||
|
||||
/**
|
||||
* @brief This function is used to clear all registered page callback functions.
|
||||
* @return None
|
||||
* @note All page callback will be cleared automatically if httpd_stop().
|
||||
*/
|
||||
void httpd_clear_page_callbacks(void);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup httpd debug.
|
||||
* @param[in] debug: flag to enable/disable httpd debug. Must be HTTPD_DEBUG_OFF, HTTPD_DEBUG_ON, HTTPD_DEBUG_VERBOSE.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_setup_debug(uint8_t debug);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup connection idle timeout for server.
|
||||
* @param[in] idle_timeout: timeout in seconds
|
||||
* @return None
|
||||
*/
|
||||
void httpd_setup_idle_timeout(int idle_timeout);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup certificate and key for server before starting with HTTPS.
|
||||
* @param[in] server_cert: string of server certificate
|
||||
* @param[in] server_key: string of server private key
|
||||
* @param[in] ca_certs: string including certificates in CA trusted chain
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
* @note Must be used before httpd_start() if staring HTTPS server
|
||||
*/
|
||||
int httpd_setup_cert(const char *server_cert, const char *server_key, const char *ca_certs);
|
||||
|
||||
/**
|
||||
* @brief This function is used to setup authorization for server.
|
||||
* @param[in] user: string of user name for authorization
|
||||
* @param[in] password: string of password for authorization
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
* @note Must be used before httpd_start() if basic authorization is used
|
||||
*/
|
||||
int httpd_setup_user_password(char *user, char *password);
|
||||
|
||||
/**
|
||||
* @brief This function is used to free memory allocated by httpd API, such as httpd_request_get_header_field() and httpd_request_get_query_key().
|
||||
* @param[in] ptr: pointer to memory to be deallocated
|
||||
* @return None
|
||||
*/
|
||||
void httpd_free(void *ptr);
|
||||
|
||||
/**
|
||||
* @brief This function is used to close a client connection and release context resource.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return None
|
||||
* @note Multiple requests/response can be handled in a connection before connection closed. All connections will be closed automatically if httpd_stop().
|
||||
*/
|
||||
void httpd_conn_close(struct httpd_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to dump the parsed HTTP header of request in connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return None
|
||||
*/
|
||||
void httpd_conn_dump_header(struct httpd_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to check HTTP method of request in connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] method: HTTP method string to compare with
|
||||
* @return 0 : if different
|
||||
* @return 1 : if matched
|
||||
*/
|
||||
int httpd_request_is_method(struct httpd_conn *conn, char *method);
|
||||
|
||||
/**
|
||||
* @brief This function is used to read HTTP header from client socket descriptor and parse content to connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
* @note httpd_request_read_header() is automatically invoked by httpd server to parse request before executing page callback
|
||||
*/
|
||||
int httpd_request_read_header(struct httpd_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to read data from HTTP/HTTPS connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[out] data: buffer for data read
|
||||
* @param[in] data_len: buffer length
|
||||
* @return return value of lwip socket read() for HTTP and PolarSSL ssl_read() for HTTPS
|
||||
*/
|
||||
int httpd_request_read_data(struct httpd_conn *conn, uint8_t *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to get a header field from HTTP header of connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] field: header field string to search
|
||||
* @param[out] value: search result stored in memory allocated
|
||||
* @return 0 : if found
|
||||
* @return -1 : if not found
|
||||
* @note The search result memory should be free by httpd_free().
|
||||
*/
|
||||
int httpd_request_get_header_field(struct httpd_conn *conn, char *field, char **value);
|
||||
|
||||
/**
|
||||
* @brief This function is used to get a key value from query string in HTTP header of connection context.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] key: key name string to search
|
||||
* @param[out] value: search result stored in memory allocated
|
||||
* @return 0 : if found
|
||||
* @return -1 : if not found
|
||||
* @note The search result memory should be free by httpd_free().
|
||||
*/
|
||||
int httpd_request_get_query_key(struct httpd_conn *conn, char *key, char **value);
|
||||
|
||||
/**
|
||||
* @brief This function is used to start a HTTP response in connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] status: string of status code in HTTP response
|
||||
* @param[in] content_type: string of Content-Type header field written to HTTP response. No Content-Type in HTTP response if NULL.
|
||||
* @param[in] content_len: value of Content-Length header field written to HTTP response. No Content-Length in HTTP response if NULL.
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpd_response_write_header_start(struct httpd_conn *conn, char *status, char *content_type, size_t content_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to add an HTTP header field to HTTP response.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] name: HTTP header field name string
|
||||
* @param[in] value: HTTP header field value
|
||||
* @return 0 : if successful
|
||||
* @return -1 : if error occurred
|
||||
*/
|
||||
int httpd_response_write_header(struct httpd_conn *conn, char *name, char *value);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write HTTP response header data to connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @return return value of lwip socket write() for HTTP and PolarSSL ssl_write() for HTTPS
|
||||
*/
|
||||
int httpd_response_write_header_finish(struct httpd_conn *conn);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write HTTP response body data to connection.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] data: data to be written
|
||||
* @param[in] data_len: data length
|
||||
* @return return value of lwip socket write() for HTTP and PolarSSL ssl_write() for HTTPS
|
||||
*/
|
||||
int httpd_response_write_data(struct httpd_conn *conn, uint8_t *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 400 Bad Request.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_bad_request(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 401 Unauthorized.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_unauthorized(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 404 Not Found.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_not_found(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 405 Method Not Allowed.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_method_not_allowed(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 429 Too Many Requests.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_too_many_requests(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/**
|
||||
* @brief This function is used to write a default HTTP response for error of 500 Internal Server Error.
|
||||
* @param[in] conn: pointer to connection context
|
||||
* @param[in] msg: message write to HTTP response body. A default message will be used if NULL.
|
||||
* @return None
|
||||
*/
|
||||
void httpd_response_internal_server_error(struct httpd_conn *conn, char *msg);
|
||||
|
||||
/*\@}*/
|
||||
|
||||
#endif /* _HTTPD_H_ */
|
||||
16
sdk/component/common/network/httpd/httpd_int.h
Normal file
16
sdk/component/common/network/httpd/httpd_int.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef _HTTPD_INT_H_
|
||||
#define _HTTPD_INT_H_
|
||||
|
||||
#include "httpd.h"
|
||||
|
||||
int httpd_init(void);
|
||||
void httpd_deinit(void);
|
||||
void httpd_setup(uint16_t port, uint8_t max_conn, uint8_t secure);
|
||||
int httpd_return_server_sock(void);
|
||||
int httpd_accept(int server_sock, struct httpd_conn **client_conn, int accept_timeout);
|
||||
|
||||
int httpd_write(struct httpd_conn *conn, uint8_t *buf, size_t buf_len);
|
||||
int httpd_read(struct httpd_conn *conn, uint8_t *buf, size_t buf_len);
|
||||
int httpd_read_with_timeout(struct httpd_conn *conn, uint8_t *buf, uint16_t buf_len, int recv_timeout);
|
||||
|
||||
#endif /* _HTTPD_INT_H_ */
|
||||
57
sdk/component/common/network/httpd/httpd_util.h
Normal file
57
sdk/component/common/network/httpd/httpd_util.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef _HTTPD_UTIL_H_
|
||||
#define _HTTPD_UTIL_H_
|
||||
|
||||
#include "httpd.h"
|
||||
|
||||
extern uint8_t httpd_debug;
|
||||
|
||||
#define httpd_log(...) \
|
||||
do { \
|
||||
if(httpd_debug) { \
|
||||
taskENTER_CRITICAL(); \
|
||||
printf("\n\r[HTTPD] "); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n\r"); \
|
||||
taskEXIT_CRITICAL(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define httpd_log_verbose(...) \
|
||||
do { \
|
||||
if(httpd_debug == HTTPD_DEBUG_VERBOSE) { \
|
||||
taskENTER_CRITICAL(); \
|
||||
printf("\n\r[HTTPD] "); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n\r"); \
|
||||
taskEXIT_CRITICAL(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
struct httpd_page {
|
||||
struct httpd_page *next;
|
||||
char *path;
|
||||
void (*callback)(struct httpd_conn *conn);
|
||||
};
|
||||
|
||||
void *httpd_malloc(size_t size);
|
||||
int httpd_page_add(char *path, void (*callback)(struct httpd_conn *conn));
|
||||
void httpd_page_remove(struct httpd_page *page);
|
||||
void httpd_page_clear(void);
|
||||
struct httpd_conn *httpd_conn_add(int sock);
|
||||
void httpd_conn_remove(struct httpd_conn *conn);
|
||||
void httpd_conn_clear(void);
|
||||
void httpd_query_remove_special(uint8_t *input, size_t input_len, uint8_t *output, size_t output_len);
|
||||
int httpd_write(struct httpd_conn *conn, uint8_t *buf, size_t buf_len);
|
||||
int httpd_read(struct httpd_conn *conn, uint8_t *buf, size_t buf_len);
|
||||
int httpd_read_with_timeout(struct httpd_conn *conn, uint8_t *buf, uint16_t buf_len, int recv_timeout);
|
||||
|
||||
int httpd_tls_setup_init(const char *server_cert,const char *server_key, const char *ca_certs);
|
||||
void httpd_tls_setup_free(void);
|
||||
void *httpd_tls_new_handshake(int *sock, uint8_t secure);
|
||||
void httpd_tls_free(void *tls_in);
|
||||
void httpd_tls_close(void *tls_in);
|
||||
int httpd_tls_read(void *tls_in, uint8_t *buf, size_t buf_len);
|
||||
int httpd_tls_write(void *tls_in, uint8_t *buf, size_t buf_len);
|
||||
int httpd_base64_encode(uint8_t *data, size_t data_len, char *base64_buf, size_t buf_len);
|
||||
|
||||
#endif /* _HTTPD_UTIL_H_ */
|
||||
228
sdk/component/common/network/libcoap/include/coap/address.h
Normal file
228
sdk/component/common/network/libcoap/include/coap/address.h
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/* address.h -- representation of network addresses
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file address.h
|
||||
* @brief representation of network addresses
|
||||
*/
|
||||
|
||||
#ifndef _COAP_ADDRESS_H_
|
||||
#define _COAP_ADDRESS_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_ASSERT_H
|
||||
#include <assert.h>
|
||||
#else
|
||||
#ifndef assert
|
||||
#warning "assertions are disabled"
|
||||
# define assert(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ARDUINO
|
||||
#define DEV_ADDR_SIZE_MAX (16)
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LWIP
|
||||
#include <lwip/ip_addr.h>
|
||||
|
||||
typedef struct coap_address_t
|
||||
{
|
||||
uint16_t port;
|
||||
ip_addr_t addr;
|
||||
}coap_address_t;
|
||||
|
||||
#if defined(AMEBA)
|
||||
#define _coap_address_equals_impl(A, B) ((ip_addr_cmp(&(A)->addr, &(B)->addr)) && (A->port == B->port))
|
||||
#define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr)
|
||||
#else
|
||||
/* FIXME oversimplification: just assuming it's an ipv4 address instead of
|
||||
* looking up the appropraite lwip function */
|
||||
|
||||
#define _coap_address_equals_impl(A, B) ((A)->addr.addr == (B)->addr.addr && A->port == B->port)
|
||||
|
||||
/* FIXME sure there is something in lwip */
|
||||
|
||||
#define _coap_is_mcast_impl(Address) 0
|
||||
#endif
|
||||
#endif /* WITH_LWIP */
|
||||
#ifdef WITH_CONTIKI
|
||||
#include "uip.h"
|
||||
|
||||
typedef struct coap_address_t
|
||||
{
|
||||
unsigned char size;
|
||||
uip_ipaddr_t addr;
|
||||
unsigned short port;
|
||||
}coap_address_t;
|
||||
|
||||
#define _coap_address_equals_impl(A,B) \
|
||||
((A)->size == (B)->size \
|
||||
&& (A)->port == (B)->port \
|
||||
&& uip_ipaddr_cmp(&((A)->addr),&((B)->addr)))
|
||||
|
||||
#define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr))
|
||||
#endif /* WITH_CONTIKI */
|
||||
#if defined(WITH_POSIX) || defined(_WIN32)
|
||||
|
||||
/** multi-purpose address abstraction */
|
||||
typedef struct coap_address_t
|
||||
{
|
||||
socklen_t size; /**< size of addr */
|
||||
union
|
||||
{
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_storage st;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
}addr;
|
||||
}coap_address_t;
|
||||
|
||||
INLINE_API int
|
||||
_coap_address_equals_impl(const coap_address_t *a,
|
||||
const coap_address_t *b)
|
||||
{
|
||||
if (a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family)
|
||||
return 0;
|
||||
|
||||
/* need to compare only relevant parts of sockaddr_in6 */
|
||||
switch (a->addr.sa.sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
return
|
||||
a->addr.sin.sin_port == b->addr.sin.sin_port &&
|
||||
memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr,
|
||||
sizeof(struct in_addr)) == 0;
|
||||
case AF_INET6:
|
||||
return a->addr.sin6.sin6_port == b->addr.sin6.sin6_port &&
|
||||
memcmp(&a->addr.sin6.sin6_addr, &b->addr.sin6.sin6_addr,
|
||||
sizeof(struct in6_addr)) == 0;
|
||||
default: /* fall through and signal error */
|
||||
;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
INLINE_API int
|
||||
_coap_is_mcast_impl(const coap_address_t *a)
|
||||
{
|
||||
if (!a)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
switch (a->addr.sa.sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
return IN_MULTICAST(a->addr.sin.sin_addr.s_addr);
|
||||
case AF_INET6:
|
||||
return IN6_IS_ADDR_MULTICAST(&a->addr.sin6.sin6_addr);
|
||||
default: /* fall through and signal error */
|
||||
;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_POSIX */
|
||||
|
||||
#ifdef WITH_ARDUINO
|
||||
typedef struct coap_address_t
|
||||
{
|
||||
uint32_t size; /**< length of the address stored in addr field. */
|
||||
uint8_t addr[DEV_ADDR_SIZE_MAX]; /**< device address. */
|
||||
} coap_address_t;
|
||||
|
||||
INLINE_API int
|
||||
_coap_address_equals_impl(const coap_address_t *a,
|
||||
const coap_address_t *b)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if ((a == NULL) || (b == NULL))
|
||||
return 0;
|
||||
|
||||
if (a->size != b->size)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
{
|
||||
if (a->addr[i] != b->addr[i])
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
INLINE_API int
|
||||
_coap_is_mcast_impl(const coap_address_t *a)
|
||||
{
|
||||
if (!a)
|
||||
return 0;
|
||||
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WITH_ARDUINO */
|
||||
|
||||
/**
|
||||
* Resets the given coap_address_t object @p addr to its default
|
||||
* values. In particular, the member size must be initialized to the
|
||||
* available size for storing addresses.
|
||||
*
|
||||
* @param addr The coap_address_t object to initialize.
|
||||
*/
|
||||
INLINE_API void coap_address_init(coap_address_t *addr)
|
||||
{
|
||||
assert(addr);
|
||||
memset(addr, 0, sizeof(coap_address_t));
|
||||
#ifndef WITH_LWIP
|
||||
/* lwip has constandt address sizes and doesn't need the .size part */
|
||||
addr->size = sizeof(addr->addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares given address objects @p a and @p b. This function returns
|
||||
* @c 1 if addresses are equal, @c 0 otherwise. The parameters @p a
|
||||
* and @p b must not be @c NULL;
|
||||
*/
|
||||
INLINE_API int coap_address_equals(const coap_address_t *a, const coap_address_t *b)
|
||||
{
|
||||
assert(a);
|
||||
assert(b);
|
||||
return _coap_address_equals_impl(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given address @p a denotes a multicast address. This
|
||||
* function returns @c 1 if @p a is multicast, @c 0 otherwise.
|
||||
*/
|
||||
INLINE_API int coap_is_mcast(const coap_address_t *a)
|
||||
{
|
||||
return a && _coap_is_mcast_impl(a);
|
||||
}
|
||||
|
||||
#endif /* _COAP_ADDRESS_H_ */
|
||||
148
sdk/component/common/network/libcoap/include/coap/async.h
Normal file
148
sdk/component/common/network/libcoap/include/coap/async.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/* async.h -- state management for asynchronous messages
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file async.h
|
||||
* @brief state management for asynchronous messages
|
||||
*/
|
||||
|
||||
#ifndef _COAP_ASYNC_H_
|
||||
#define _COAP_ASYNC_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "net.h"
|
||||
|
||||
#ifndef WITHOUT_ASYNC
|
||||
|
||||
/**
|
||||
* @defgroup coap_async Asynchronous Messaging
|
||||
* @{
|
||||
* Structure for managing asynchronous state of CoAP resources. A
|
||||
* coap_resource_t object holds a list of coap_async_state_t objects
|
||||
* that can be used to generate a separate response in case a result
|
||||
* of an operation cannot be delivered in time, or the resource has
|
||||
* been explicitly subscribed to with the option @c observe.
|
||||
*/
|
||||
typedef struct coap_async_state_t
|
||||
{
|
||||
unsigned char flags; /**< holds the flags to control behaviour */
|
||||
|
||||
/**
|
||||
* Holds the internal time when the object was registered with a
|
||||
* resource. This field will be updated whenever
|
||||
* coap_register_async() is called for a specific resource.
|
||||
*/
|
||||
coap_tick_t created;
|
||||
|
||||
/**
|
||||
* This field can be used to register opaque application data with
|
||||
* the asynchronous state object. */
|
||||
void *appdata;
|
||||
|
||||
unsigned short message_id; /**< id of last message seen */
|
||||
coap_tid_t id; /**< transaction id */
|
||||
|
||||
struct coap_async_state_t *next; /**< internally used for linking */
|
||||
|
||||
coap_address_t peer; /**< the peer to notify */
|
||||
size_t tokenlen; /**< length of the token */
|
||||
unsigned char token[]; /**< the token to use in a response */
|
||||
} coap_async_state_t;
|
||||
|
||||
/* Definitions for Async Status Flags These flags can be used to
|
||||
* control the behaviour of asynchronous response generation. */
|
||||
#define COAP_ASYNC_CONFIRM 0x01 /**< send confirmable response */
|
||||
#define COAP_ASYNC_SEPARATE 0x02 /**< send separate response */
|
||||
#define COAP_ASYNC_OBSERVED 0x04 /**< the resource is being observed */
|
||||
|
||||
/** release application data on destruction */
|
||||
#define COAP_ASYNC_RELEASE_DATA 0x08
|
||||
|
||||
/**
|
||||
* Allocates a new coap_async_state_t object and fills its fields
|
||||
* according to the given @p request. The @p flags are used to control
|
||||
* generation of empty ACK responses to stop retransmissions and to
|
||||
* release registered @p data when the resource is deleted by
|
||||
* coap_free_async(). This function returns a pointer to the registered
|
||||
* coap_async_t object or @c NULL on error. Note that this function will
|
||||
* return @c NULL in case that an object with the same identifier is
|
||||
* already registered.
|
||||
*
|
||||
* @param context The context to use.
|
||||
* @param peer The remote peer that is to be asynchronously notified.
|
||||
* @param request The request that is handled asynchronously.
|
||||
* @param flags Flags to control state management.
|
||||
* @param data Opaque application data to register. Note that the
|
||||
* storage occupied by @p data is released on destruction
|
||||
* only if flag COAP_ASYNC_RELEASE_DATA is set.
|
||||
*
|
||||
* @return A pointer to the registered coap_async_state_t object or
|
||||
* @c NULL in case of an error.
|
||||
*/
|
||||
coap_async_state_t *
|
||||
coap_register_async(coap_context_t *context, coap_address_t *peer, coap_pdu_t *request,
|
||||
unsigned char flags, void *data);
|
||||
|
||||
/**
|
||||
* Removes the state object identified by @p id from @p context. The
|
||||
* removed object is returned in @p s, if found. Otherwise, @p s is
|
||||
* undefined. This function returns @c 1 if the object was removed, @c
|
||||
* 0 otherwise. Note that the storage allocated for the stored object
|
||||
* is not released by this functions. You will have to call
|
||||
* coap_free_async() to do so.
|
||||
*
|
||||
* @param context The context where the async object is registered.
|
||||
* @param id The identifier of the asynchronous transaction.
|
||||
* @param s Will be set to the object identified by @p id
|
||||
* after removal.
|
||||
*
|
||||
* @return @c 1 if object was removed and @p s updated, or @c 0 if no
|
||||
* object was found with the given id. @p s is valid only if the
|
||||
* return value is @c 1.
|
||||
*/
|
||||
int coap_remove_async(coap_context_t *context, coap_tid_t id, coap_async_state_t **s);
|
||||
|
||||
/**
|
||||
* Releases the memory that was allocated by coap_async_state_init()
|
||||
* for the object @p s. The registered application data will be
|
||||
* released automatically if COAP_ASYNC_RELEASE_DATA is set.
|
||||
*
|
||||
* @param s The object to delete.
|
||||
*/
|
||||
void
|
||||
coap_free_async(coap_async_state_t *state);
|
||||
|
||||
/**
|
||||
* Retrieves the object identified by @p id from the list of asynchronous
|
||||
* transactions that are registered with @p context. This function returns
|
||||
* a pointer to that object or @c NULL if not found.
|
||||
*
|
||||
* @param context The context where the asynchronous objects are
|
||||
* registered with.
|
||||
* @param id The id of the object to retrieve.
|
||||
*
|
||||
* @return A pointer to the object identified by @p id or @c NULL if
|
||||
* not found.
|
||||
*/
|
||||
coap_async_state_t *coap_find_async(coap_context_t *context, coap_tid_t id);
|
||||
|
||||
/**
|
||||
* Updates the time stamp of @p s.
|
||||
*
|
||||
* @param s The state object to update.
|
||||
*/
|
||||
INLINE_API void coap_touch_async(coap_async_state_t *s)
|
||||
{
|
||||
coap_ticks(&s->created);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* WITHOUT_ASYNC */
|
||||
|
||||
#endif /* _COAP_ASYNC_H_ */
|
||||
83
sdk/component/common/network/libcoap/include/coap/bits.h
Normal file
83
sdk/component/common/network/libcoap/include/coap/bits.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* bits.h -- bit vector manipulation
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file bits.h
|
||||
* @brief bit vector manipulation
|
||||
*/
|
||||
|
||||
#ifndef _BITS_H_
|
||||
#define _BITS_H_
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#if AMEBA
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
/**
|
||||
* Sets the bit @p bit in bit-vector @p vec. This function returns @c
|
||||
* 1 if bit was set or @c -1 on error (i.e. when the given bit does
|
||||
* not fit in the vector).
|
||||
*
|
||||
* @param vec The bit-vector to change.
|
||||
* @param size The size of @p vec in bytes.
|
||||
* @param bit The bit to set in @p vec.
|
||||
*
|
||||
* @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise.
|
||||
*/
|
||||
INLINE_API int bits_setb(uint8_t *vec, size_t size, uint8_t bit)
|
||||
{
|
||||
if (size <= (size_t)(bit >> 3))
|
||||
return -1;
|
||||
|
||||
*(vec + (bit >> 3)) |= (uint8_t)(1 << (bit & 0x07));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the bit @p bit from bit-vector @p vec. This function returns
|
||||
* @c 1 if bit was cleared or @c -1 on error (i.e. when the given bit
|
||||
* does not fit in the vector).
|
||||
*
|
||||
* @param vec The bit-vector to change.
|
||||
* @param size The size of @p vec in bytes.
|
||||
* @param bit The bit to clear from @p vec.
|
||||
*
|
||||
* @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise.
|
||||
*/
|
||||
INLINE_API int bits_clrb(uint8_t *vec, size_t size, uint8_t bit)
|
||||
{
|
||||
if (size <= (size_t)(bit >> 3))
|
||||
return -1;
|
||||
|
||||
*(vec + (bit >> 3)) &= (uint8_t)(~(1 << (bit & 0x07)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status of bit @p bit from bit-vector @p vec. This function returns
|
||||
* @c 1 if the bit is set, @c 0 otherwise (even in case of an error)..
|
||||
*
|
||||
* @param vec The bit-vector to read from..
|
||||
* @param size The size of @p vec in bytes.
|
||||
* @param bit The bit to get from @p vec.
|
||||
*
|
||||
* @return @c 1 if the bit is set, @c 0 otherwise.
|
||||
*/
|
||||
INLINE_API int bits_getb(const uint8_t *vec, size_t size, uint8_t bit)
|
||||
{
|
||||
if (size <= (size_t)(bit >> 3))
|
||||
return -1;
|
||||
|
||||
return (*(vec + (bit >> 3)) & (1 << (bit & 0x07))) != 0;
|
||||
}
|
||||
|
||||
#endif /* _BITS_H_ */
|
||||
142
sdk/component/common/network/libcoap/include/coap/block.h
Normal file
142
sdk/component/common/network/libcoap/include/coap/block.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* block.h -- block transfer
|
||||
*
|
||||
* Copyright (C) 2010--2012,2014 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_BLOCK_H_
|
||||
#define _COAP_BLOCK_H_
|
||||
|
||||
#include "option.h"
|
||||
#include "encode.h"
|
||||
#include "pdu.h"
|
||||
|
||||
/**
|
||||
* @defgroup block Block Transfer
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_MAX_BLOCK_SZX
|
||||
/**
|
||||
* The largest value for the SZX component in a Block option. Note
|
||||
* that 1 << (COAP_MAX_BLOCK_SZX + 4) should not exceed
|
||||
* COAP_MAX_PDU_SIZE.
|
||||
*/
|
||||
#define COAP_MAX_BLOCK_SZX 4
|
||||
#endif /* COAP_MAX_BLOCK_SZX */
|
||||
|
||||
#if (COAP_MAX_PDU_SIZE - 6) < (1 << (COAP_MAX_BLOCK_SZX + 4))
|
||||
#error "COAP_MAX_BLOCK_SZX too large"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Structure of Block options.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#ifdef WITH_ARDUINO
|
||||
unsigned long int num : 20;
|
||||
#else
|
||||
unsigned int num : 20;
|
||||
#endif
|
||||
unsigned int m : 1; /**< 1 if more blocks follow, 0 otherwise */
|
||||
unsigned int szx : 3; /**< block size */
|
||||
} coap_block_t;
|
||||
|
||||
/**
|
||||
* Returns the value of the least significant byte of a Block option @p opt.
|
||||
* For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST
|
||||
* returns @c NULL.
|
||||
*/
|
||||
#define COAP_OPT_BLOCK_LAST(opt) \
|
||||
(COAP_OPT_LENGTH(opt) ? (COAP_OPT_VALUE(opt) + (COAP_OPT_LENGTH(opt)-1)) : 0)
|
||||
|
||||
/** Returns the value of the More-bit of a Block option @p opt. */
|
||||
#define COAP_OPT_BLOCK_MORE(opt) \
|
||||
(COAP_OPT_LENGTH(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x08) : 0)
|
||||
|
||||
/** Returns the value of the SZX-field of a Block option @p opt. */
|
||||
#define COAP_OPT_BLOCK_SZX(opt) \
|
||||
(COAP_OPT_LENGTH(opt) ? (*COAP_OPT_BLOCK_LAST(opt) & 0x07) : 0)
|
||||
|
||||
/**
|
||||
* Returns the value of field @c num in the given block option @p
|
||||
* block_opt.
|
||||
*/
|
||||
unsigned int coap_opt_block_num(const coap_opt_t *block_opt);
|
||||
|
||||
/**
|
||||
* Checks if more than @p num blocks are required to deliver @p data_len
|
||||
* bytes of data for a block size of 1 << (@p szx + 4).
|
||||
*/
|
||||
INLINE_API int coap_more_blocks(size_t data_len, unsigned int num, unsigned short szx)
|
||||
{
|
||||
return ((num + 1) << (szx + 4)) < data_len;
|
||||
}
|
||||
|
||||
/** Sets the More-bit in @p block_opt */
|
||||
INLINE_API void coap_opt_block_set_m(coap_opt_t *block_opt, int m)
|
||||
{
|
||||
if (m)
|
||||
*(COAP_OPT_VALUE(block_opt) + (COAP_OPT_LENGTH(block_opt) - 1)) |= 0x08;
|
||||
else
|
||||
*(COAP_OPT_VALUE(block_opt) + (COAP_OPT_LENGTH(block_opt) - 1)) &= ~0x08;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes @p block from @p pdu. @p type must be either COAP_OPTION_BLOCK1
|
||||
* or COAP_OPTION_BLOCK2. When option @p type was found in @p pdu, @p block
|
||||
* is initialized with values from this option and the function returns the
|
||||
* value @c 1. Otherwise, @c 0 is returned.
|
||||
*
|
||||
* @param pdu The pdu to search for option @p type.
|
||||
* @param type The option to search for (must be COAP_OPTION_BLOCK1 or
|
||||
* COAP_OPTION_BLOCK2)
|
||||
* @param block The block structure to initilize.
|
||||
* @return @c 1 on success, @c 0 otherwise.
|
||||
*/
|
||||
int coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block);
|
||||
|
||||
/**
|
||||
* Writes a block option of type @p type to message @p pdu. If the
|
||||
* requested block size is too large to fit in @p pdu, it is reduced
|
||||
* accordingly. An exception is made for the final block when less
|
||||
* space is required. The actual length of the resource is specified
|
||||
* in @p data_length.
|
||||
*
|
||||
* This function may change *block to reflect the values written to
|
||||
* @p pdu. As the function takes into consideration the remaining space
|
||||
* @p pdu, no more options should be added after coap_write_block_opt()
|
||||
* has returned.
|
||||
*
|
||||
* @param block The block structure to use. On return, this object
|
||||
* is updated according to the values that have been
|
||||
* written to @p pdu.
|
||||
* @param type COAP_OPTION_BLOCK1 or COAP_OPTION_BLOCK2
|
||||
* @param pdu The message where the block option should be
|
||||
* written.
|
||||
* @param data_length The length of the actual data that will be added
|
||||
* the @p pdu by calling coap_add_block().
|
||||
* @return @c 1 on success, or a negative value on error.
|
||||
*/
|
||||
int coap_write_block_opt(coap_block_t *block, unsigned short type, coap_pdu_t *pdu,
|
||||
size_t data_length);
|
||||
|
||||
/**
|
||||
* Adds the @p block_num block of size 1 << (@p block_szx + 4) from
|
||||
* source @p data to @p pdu.
|
||||
*
|
||||
* @param pdu The message to add the block
|
||||
* @param len The length of @p data.
|
||||
* @param data The source data to fill the block with
|
||||
* @param block_num The actual block number
|
||||
* @param block_szx Encoded size of block @p block_number
|
||||
* @return @c 1 on success, @c 0 otherwise.
|
||||
*/
|
||||
int coap_add_block(coap_pdu_t *pdu, unsigned int len, const unsigned char *data,
|
||||
unsigned int block_num, unsigned char block_szx);
|
||||
/**@}*/
|
||||
|
||||
#endif /* _COAP_BLOCK_H_ */
|
||||
37
sdk/component/common/network/libcoap/include/coap/coap.h
Normal file
37
sdk/component/common/network/libcoap/include/coap/coap.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* coap.h -- main header file for CoAP stack
|
||||
*
|
||||
* Copyright (C) 2010--2012 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_H_
|
||||
#define _COAP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "mem.h"
|
||||
#include "coap_list.h"
|
||||
#include "pdu.h"
|
||||
#include "option.h"
|
||||
#include "net.h"
|
||||
#include "encode.h"
|
||||
#include "str.h"
|
||||
#include "uri.h"
|
||||
#include "async.h"
|
||||
#include "resource.h"
|
||||
#include "subscribe.h"
|
||||
#include "block.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COAP_H_ */
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/* coap_list.h -- CoAP list structures
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_LIST_H_
|
||||
#define _COAP_LIST_H_
|
||||
|
||||
struct coap_linkedlistnode
|
||||
{
|
||||
struct coap_linkedlistnode *next;
|
||||
void *data;
|
||||
|
||||
/**
|
||||
* Callback function that is called from coap_delete to release
|
||||
* additional memory allocated by data Set to NULL if you do not
|
||||
* need this. Note that data is free'd automatically. */
|
||||
void (*delete_func)(void *);
|
||||
};
|
||||
|
||||
typedef struct coap_linkedlistnode coap_list_t;
|
||||
|
||||
/**
|
||||
* Adds node to given queue, ordered by specified order function. Returns 1
|
||||
* when insert was successful, 0 otherwise.
|
||||
*/
|
||||
int coap_insert(coap_list_t **queue, coap_list_t *node, int (*order)(void *, void *));
|
||||
|
||||
/* destroys specified node */
|
||||
int coap_delete(coap_list_t *node);
|
||||
|
||||
/* removes all items from given queue and frees the allocated storage */
|
||||
void coap_delete_list(coap_list_t *queue);
|
||||
|
||||
/**
|
||||
* Creates a new list node and adds the given data object. The memory allocated
|
||||
* by data will be released by coap_delete() with the new node. Returns the
|
||||
* new list node.
|
||||
*/
|
||||
coap_list_t *coap_new_listnode(void *data, void (*delete_func)(void *));
|
||||
|
||||
#endif /* _COAP_LIST_H_ */
|
||||
241
sdk/component/common/network/libcoap/include/coap/coap_time.h
Normal file
241
sdk/component/common/network/libcoap/include/coap/coap_time.h
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/* coap_time.h -- Clock Handling
|
||||
*
|
||||
* Copyright (C) 2010--2013 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file coap_time.h
|
||||
* @brief Clock Handling
|
||||
*/
|
||||
|
||||
#ifndef _COAP_TIME_H_
|
||||
#define _COAP_TIME_H_
|
||||
|
||||
/*
|
||||
** Make sure we can call this stuff from C++.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
* @defgroup clock Clock Handling
|
||||
* Default implementation of internal clock. You should redefine this if
|
||||
* you do not have time() and gettimeofday().
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef WITH_LWIP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <lwip/sys.h>
|
||||
|
||||
/* lwIP provides ms in sys_now */
|
||||
#define COAP_TICKS_PER_SECOND 1000
|
||||
|
||||
typedef uint32_t coap_tick_t;
|
||||
|
||||
INLINE_API void coap_ticks_impl(coap_tick_t *t)
|
||||
{
|
||||
*t = sys_now();
|
||||
}
|
||||
|
||||
INLINE_API void coap_clock_init_impl(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define coap_clock_init coap_clock_init_impl
|
||||
|
||||
#define coap_ticks coap_ticks_impl
|
||||
|
||||
#endif
|
||||
#ifdef WITH_CONTIKI
|
||||
#include "clock.h"
|
||||
|
||||
typedef clock_time_t coap_tick_t;
|
||||
|
||||
/**
|
||||
* This data type is used to represent the difference between two
|
||||
* clock_tick_t values. This data type must have the same size in
|
||||
* memory as coap_tick_t to allow wrapping.
|
||||
*/
|
||||
typedef int coap_tick_diff_t;
|
||||
|
||||
#define COAP_TICKS_PER_SECOND CLOCK_SECOND
|
||||
|
||||
/** Set at startup to initialize the internal clock (time in seconds). */
|
||||
extern clock_time_t clock_offset;
|
||||
|
||||
INLINE_API void
|
||||
contiki_clock_init_impl(void)
|
||||
{
|
||||
clock_init();
|
||||
clock_offset = clock_time();
|
||||
}
|
||||
|
||||
#define coap_clock_init contiki_clock_init_impl
|
||||
|
||||
INLINE_API void
|
||||
contiki_ticks_impl(coap_tick_t *t)
|
||||
{
|
||||
*t = clock_time();
|
||||
}
|
||||
|
||||
#define coap_ticks contiki_ticks_impl
|
||||
|
||||
#endif /* WITH_CONTIKI */
|
||||
#if defined(WITH_POSIX) || defined(_WIN32)
|
||||
typedef unsigned int coap_tick_t;
|
||||
|
||||
/**
|
||||
* This data type is used to represent the difference between two
|
||||
* clock_tick_t values. This data type must have the same size in
|
||||
* memory as coap_tick_t to allow wrapping.
|
||||
*/
|
||||
typedef int coap_tick_diff_t;
|
||||
|
||||
#define COAP_TICKS_PER_SECOND 1024
|
||||
|
||||
/** Set at startup to initialize the internal clock (time in seconds). */
|
||||
extern time_t clock_offset;
|
||||
#endif /* WITH_POSIX || _WIN32 */
|
||||
|
||||
#ifdef WITH_ARDUINO
|
||||
#include "Time.h"
|
||||
#ifdef ARDUINO_ARCH_SAM
|
||||
#include <sys/types.h> // time_t is defined in sys/types.h for ARM compiler
|
||||
#else
|
||||
typedef unsigned long time_t; //AVR compiler doesnt define time_t
|
||||
#endif
|
||||
typedef time_t coap_tick_t;
|
||||
|
||||
/**
|
||||
* This data type is used to represent the difference between two
|
||||
* clock_tick_t values. This data type must have the same size in
|
||||
* memory as coap_tick_t to allow wrapping.
|
||||
*/
|
||||
typedef int coap_tick_diff_t;
|
||||
|
||||
/* TODO: Ticks per second value for Arduino needs verification from
|
||||
* documentation */
|
||||
#define COAP_TICKS_PER_SECOND 1000
|
||||
|
||||
extern time_t clock_offset;
|
||||
|
||||
#endif /* WITH_ARDUINO */
|
||||
|
||||
#ifdef AMEBA
|
||||
|
||||
//typedef unsigned long time_t; //AVR compiler doesnt define time_t
|
||||
|
||||
//typedef time_t coap_tick_t;
|
||||
|
||||
/**
|
||||
* This data type is used to represent the difference between two
|
||||
* clock_tick_t values. This data type must have the same size in
|
||||
* memory as coap_tick_t to allow wrapping.
|
||||
*/
|
||||
typedef int coap_tick_diff_t;
|
||||
|
||||
/* TODO: Ticks per second value for Arduino needs verification from
|
||||
* documentation */
|
||||
#define COAP_TICKS_PER_SECOND 1000
|
||||
|
||||
extern time_t clock_offset;
|
||||
|
||||
#endif /* AMEBA */
|
||||
|
||||
#ifndef coap_clock_init
|
||||
INLINE_API void coap_clock_init_impl(void)
|
||||
{
|
||||
#ifdef HAVE_TIME_H
|
||||
clock_offset = time(NULL);
|
||||
#else
|
||||
# ifdef WITH_ARDUINO
|
||||
#ifdef __AVR__
|
||||
clock_offset = 1; //now();
|
||||
#else
|
||||
clock_offset = now();
|
||||
#endif
|
||||
# else
|
||||
# ifdef __GNUC__
|
||||
/* Issue a warning when using gcc. Other prepropressors do
|
||||
* not seem to have a similar feature. */
|
||||
# warning "cannot initialize clock"
|
||||
# endif
|
||||
clock_offset = 0;
|
||||
# endif /* WITH_ARDUINO */
|
||||
#endif /* HAVE_TIME */
|
||||
}
|
||||
#define coap_clock_init coap_clock_init_impl
|
||||
#endif /* coap_clock_init */
|
||||
|
||||
#ifndef coap_ticks
|
||||
INLINE_API void coap_ticks_impl(coap_tick_t *t)
|
||||
{
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
*t = (tv.tv_sec - clock_offset) * COAP_TICKS_PER_SECOND
|
||||
+ (tv.tv_usec * COAP_TICKS_PER_SECOND / 1000000);
|
||||
#else
|
||||
# ifdef WITH_ARDUINO
|
||||
coap_tick_t tv;
|
||||
#ifdef __AVR__
|
||||
tv = 1; //now();
|
||||
#else
|
||||
tv = now();
|
||||
#endif
|
||||
*t = (tv - clock_offset) * COAP_TICKS_PER_SECOND;
|
||||
# else
|
||||
#ifdef HAVE_TIME_H
|
||||
time_t tv = time(NULL);
|
||||
*t = difftime(tv, clock_offset) * COAP_TICKS_PER_SECOND;
|
||||
#else
|
||||
# error "clock not implemented"
|
||||
#endif /* HAVE_TIME_H */
|
||||
# endif /* WITH_ARDUINO */
|
||||
#endif /* HAVE_SYS_TIME_H */
|
||||
}
|
||||
#define coap_ticks coap_ticks_impl
|
||||
#endif /* coap_ticks */
|
||||
|
||||
/**
|
||||
* Returns @c 1 if and only if @p a is less than @p b where less is
|
||||
* defined on a signed data type.
|
||||
*/
|
||||
INLINE_API
|
||||
int coap_time_lt(coap_tick_t a, coap_tick_t b)
|
||||
{
|
||||
return ((coap_tick_diff_t)(a - b)) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns @c 1 if and only if @p a is less than or equal @p b where
|
||||
* less is defined on a signed data type.
|
||||
*/
|
||||
INLINE_API
|
||||
int coap_time_le(coap_tick_t a, coap_tick_t b)
|
||||
{
|
||||
return a == b || coap_time_lt(a, b);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COAP_TIME_H_ */
|
||||
172
sdk/component/common/network/libcoap/include/coap/config.h
Normal file
172
sdk/component/common/network/libcoap/include/coap/config.h
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
//Realtek add
|
||||
#define AMEBA 1
|
||||
#define WITH_LWIP 1
|
||||
#define LWIP_NOASSERT 1
|
||||
#define NO_DECLTYPE 1
|
||||
#define NDEBUG 1
|
||||
#ifdef __ICCARM__ //add for GCC compile error
|
||||
#define ssize_t int
|
||||
#define FILE void
|
||||
#endif
|
||||
//Realtek add end
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#define HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `coap' library (-lcoap). */
|
||||
/* #undef HAVE_LIBCOAP */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#if !defined(WITH_ARDUINO) && !defined(_WIN32) && !defined(AMEBA)
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strnlen' function. */
|
||||
#define HAVE_STRNLEN 1
|
||||
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#define HAVE_STRRCHR 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#if !defined(WITH_ARDUINO) && !defined(_WIN32) && !defined(AMEBA)
|
||||
#define HAVE_SYSLOG_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#if !defined(WITH_ARDUINO) && !defined(_WIN32) && !defined(AMEBA)
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <sys/unistd.h> header file. */
|
||||
#if !defined(WITH_ARDUINO) && !defined(_WIN32) && !defined(AMEBA)
|
||||
#define HAVE_SYS_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have <Ws2tcpip.h> header file. */
|
||||
#if defined(_WIN32)
|
||||
#define HAVE_WS2TCPIP_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have <Winsock2.h> header file. */
|
||||
#if defined(_WIN32)
|
||||
#define HAVE_WINSOCK2_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have <Windows.h> header file. */
|
||||
#if defined(_WIN32)
|
||||
#define HAVE_WINDOWS_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#if (!defined(WITH_ARDUINO) && !defined(AMEBA)) || (defined(WITH_LWIP) && defined(AMEBA))
|
||||
#define HAVE_TIME_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#if !defined(WITH_ARDUINO) && !defined(_WIN32) && !defined(AMEBA)
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "libcoap"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "libcoap 4.1.1"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "libcoap"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "4.1.1"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INLINE_API
|
||||
# if defined(__cplusplus)
|
||||
# define INLINE_API inline
|
||||
# else
|
||||
# ifdef _MSC_VER
|
||||
# define INLINE_API static __inline
|
||||
# else
|
||||
# define INLINE_API static inline
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef ssize_t */
|
||||
|
||||
77
sdk/component/common/network/libcoap/include/coap/debug.h
Normal file
77
sdk/component/common/network/libcoap/include/coap/debug.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/* debug.h -- debug utilities
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_DEBUG_H_
|
||||
#define _COAP_DEBUG_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef COAP_DEBUG_FD
|
||||
#define COAP_DEBUG_FD stdout
|
||||
#endif
|
||||
|
||||
#ifndef COAP_ERR_FD
|
||||
#define COAP_ERR_FD stderr
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
#include <syslog.h>
|
||||
typedef short coap_log_t;
|
||||
#else
|
||||
/** Pre-defined log levels akin to what is used in \b syslog. */
|
||||
typedef enum
|
||||
{ LOG_EMERG=0, LOG_ALERT, LOG_CRIT, LOG_WARNING,
|
||||
LOG_NOTICE, LOG_INFO, LOG_DEBUG
|
||||
}coap_log_t;
|
||||
#endif
|
||||
|
||||
/** Returns the current log level. */
|
||||
coap_log_t coap_get_log_level(void);
|
||||
|
||||
/** Sets the log level to the specified value. */
|
||||
void coap_set_log_level(coap_log_t level);
|
||||
|
||||
/**
|
||||
* Writes the given text to @c COAP_ERR_FD (for @p level <= @c
|
||||
* LOG_CRIT) or @c COAP_DEBUG_FD (for @p level >= @c LOG_WARNING). The
|
||||
* text is output only when @p level is below or equal to the log
|
||||
* level that set by coap_set_log_level().
|
||||
*/
|
||||
void coap_log_impl(coap_log_t level, const char *format, ...);
|
||||
|
||||
#ifndef coap_log
|
||||
#define coap_log(...) coap_log_impl(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
/* A set of convenience macros for common log levels. */
|
||||
#define info(...) coap_log(LOG_INFO, __VA_ARGS__)
|
||||
#define warn(...) coap_log(LOG_WARNING, __VA_ARGS__)
|
||||
#define debug(...) coap_log(LOG_DEBUG, __VA_ARGS__)
|
||||
|
||||
#include "pdu.h"
|
||||
void coap_show_pdu(const coap_pdu_t *);
|
||||
|
||||
struct coap_address_t;
|
||||
unsigned int print_readable(const unsigned char *data, unsigned int len, unsigned char *result,
|
||||
unsigned int buflen, int encode_always);
|
||||
size_t coap_print_addr(const struct coap_address_t *, unsigned char *, size_t);
|
||||
|
||||
#else
|
||||
|
||||
#define debug(...)
|
||||
#define info(...)
|
||||
#define warn(...)
|
||||
|
||||
#define coap_show_pdu(x)
|
||||
#define coap_print_addr(...)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _COAP_DEBUG_H_ */
|
||||
62
sdk/component/common/network/libcoap/include/coap/encode.h
Normal file
62
sdk/component/common/network/libcoap/include/coap/encode.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/* encode.h -- encoding and decoding of CoAP data types
|
||||
*
|
||||
* Copyright (C) 2010--2012 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_ENCODE_H_
|
||||
#define _COAP_ENCODE_H_
|
||||
|
||||
#if ((defined BSD)&&(BSD >= 199103)) || defined(WITH_CONTIKI)
|
||||
# include <string.h>
|
||||
#else
|
||||
#if !defined(WITH_ARDUINO) && !defined(_MSC_VER)&& !defined(AMEBA)
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "option.h"
|
||||
|
||||
#define Nn 8 /* duplicate definition of N if built on sky motes */
|
||||
#define E 4
|
||||
#define HIBIT (1 << (Nn - 1))
|
||||
#define EMASK ((1 << E) - 1)
|
||||
#define MMASK ((1 << Nn) - 1 - EMASK)
|
||||
#define MAX_VALUE ( (1 << Nn) - (1 << E) ) * (1 << ((1 << E) - 1))
|
||||
|
||||
#define COAP_PSEUDOFP_DECODE_8_4(r) (r < HIBIT ? r : (r & MMASK) << (r & EMASK))
|
||||
|
||||
#ifndef HAVE_FLS
|
||||
/* include this only if fls() is not available */
|
||||
extern int coap_fls(unsigned int i);
|
||||
#else
|
||||
#define coap_fls(i) fls(i)
|
||||
#endif
|
||||
|
||||
/* ls and s must be integer variables */
|
||||
#define COAP_PSEUDOFP_ENCODE_8_4_DOWN(v,ls) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (v >> ls) & MMASK) + ls)
|
||||
#define COAP_PSEUDOFP_ENCODE_8_4_UP(v,ls,s) (v < HIBIT ? v : (ls = coap_fls(v) - Nn, (s = (((v + ((1<<E<<ls)-1)) >> ls) & MMASK)), s == 0 ? HIBIT + ls + 1 : s + ls))
|
||||
|
||||
/**
|
||||
* Decodes multiple-length byte sequences. buf points to an input byte
|
||||
* sequence of length len. Returns the decoded value.
|
||||
*/
|
||||
unsigned int coap_decode_var_bytes(unsigned char *buf, unsigned int len);
|
||||
|
||||
/**
|
||||
* Encodes multiple-length byte sequences. buf points to an output
|
||||
* buffer of sufficient length to store the encoded bytes. val is
|
||||
* the value to encode. Returns the number of bytes used to encode
|
||||
* val or 0 on error.
|
||||
*/
|
||||
unsigned int coap_encode_var_bytes(unsigned char *buf, unsigned int val);
|
||||
|
||||
/**
|
||||
* Tests whether the option definition has a type that allows variable byte encoding.
|
||||
* Returns true when supported, false when not supported.
|
||||
*/
|
||||
bool coap_is_var_bytes(coap_option_def_t* def);
|
||||
|
||||
#endif /* _COAP_ENCODE_H_ */
|
||||
57
sdk/component/common/network/libcoap/include/coap/hashkey.h
Normal file
57
sdk/component/common/network/libcoap/include/coap/hashkey.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* hashkey.h -- definition of hash key type and helper functions
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hashkey.h
|
||||
* @brief definition of hash key type and helper functions
|
||||
*/
|
||||
|
||||
#ifndef _COAP_HASHKEY_H_
|
||||
#define _COAP_HASHKEY_H_
|
||||
|
||||
#include "str.h"
|
||||
|
||||
typedef unsigned char coap_key_t[4];
|
||||
|
||||
#ifndef coap_hash
|
||||
/**
|
||||
* Calculates a fast hash over the given string @p s of length @p len
|
||||
* and stores the result into @p h. Depending on the exact
|
||||
* implementation, this function cannot be used as one-way function to
|
||||
* check message integrity or simlar.
|
||||
*
|
||||
* @param s The string used for hash calculation.
|
||||
* @param len The length of @p s.
|
||||
* @param h The result buffer to store the calculated hash key.
|
||||
*/
|
||||
void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h);
|
||||
|
||||
#define coap_hash(String,Length,Result) \
|
||||
coap_hash_impl((String),(Length),(Result))
|
||||
|
||||
/* This is used to control the pre-set hash-keys for resources. */
|
||||
#define __COAP_DEFAULT_HASH
|
||||
#else
|
||||
#undef __COAP_DEFAULT_HASH
|
||||
#endif /* coap_hash */
|
||||
|
||||
/**
|
||||
* Calls coap_hash() with given @c str object as parameter.
|
||||
*
|
||||
* @param Str Must contain a pointer to a coap string object.
|
||||
* @param H A coap_key_t object to store the result.
|
||||
*
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define coap_str_hash(Str,H) { \
|
||||
assert(Str); \
|
||||
memset((H), 0, sizeof(coap_key_t)); \
|
||||
coap_hash((H), (Str)->s, (Str)->length); \
|
||||
}
|
||||
|
||||
#endif /* _COAP_HASHKEY_H_ */
|
||||
18
sdk/component/common/network/libcoap/include/coap/mem.h
Normal file
18
sdk/component/common/network/libcoap/include/coap/mem.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* mem.h -- CoAP memory handling
|
||||
* Currently, this is just a dummy for malloc/free
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_MEM_H_
|
||||
#define _COAP_MEM_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define coap_malloc(size) malloc(size)
|
||||
#define coap_free(size) free(size)
|
||||
|
||||
#endif /* _COAP_MEM_H_ */
|
||||
455
sdk/component/common/network/libcoap/include/coap/net.h
Normal file
455
sdk/component/common/network/libcoap/include/coap/net.h
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
/* net.h -- CoAP network interface
|
||||
*
|
||||
* Copyright (C) 2010--2013 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_NET_H_
|
||||
#define _COAP_NET_H_
|
||||
|
||||
#ifdef WITH_ARDUINO
|
||||
#include "Time.h"
|
||||
#endif /* WITH_ARDUINO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_ASSERT_H
|
||||
#include <assert.h>
|
||||
#else
|
||||
#ifndef assert
|
||||
#warning "assertions are disabled"
|
||||
# define assert(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LWIP
|
||||
#include <lwip/ip_addr.h>
|
||||
#endif
|
||||
|
||||
#include "option.h"
|
||||
#include "address.h"
|
||||
#include "prng.h"
|
||||
#include "pdu.h"
|
||||
#include "coap_time.h"
|
||||
|
||||
struct coap_queue_t;
|
||||
|
||||
typedef struct coap_queue_t
|
||||
{
|
||||
struct coap_queue_t *next;
|
||||
|
||||
coap_tick_t t; /**< when to send PDU for the next time */
|
||||
unsigned char retransmit_cnt; /**< retransmission counter, will be removed when zero */
|
||||
unsigned int timeout; /**< the randomized timeout value */
|
||||
|
||||
coap_address_t local; /**< local address */
|
||||
coap_address_t remote; /**< remote address */
|
||||
coap_tid_t id; /**< unique transaction id */
|
||||
|
||||
coap_pdu_t *pdu; /**< the CoAP PDU to send */
|
||||
} coap_queue_t;
|
||||
|
||||
/** Adds node to given queue, ordered by node->t. */
|
||||
int coap_insert_node(coap_queue_t **queue, coap_queue_t *node);
|
||||
|
||||
/** Destroys specified node. */
|
||||
int coap_delete_node(coap_queue_t *node);
|
||||
|
||||
/** Removes all items from given queue and frees the allocated storage. */
|
||||
void coap_delete_all(coap_queue_t *queue);
|
||||
|
||||
/** Creates a new node suitable for adding to the CoAP sendqueue. */
|
||||
coap_queue_t *coap_new_node(void);
|
||||
|
||||
struct coap_resource_t;
|
||||
struct coap_context_t;
|
||||
#ifndef WITHOUT_ASYNC
|
||||
struct coap_async_state_t;
|
||||
#endif
|
||||
|
||||
/** Message handler that is used as call-back in coap_context_t */
|
||||
typedef void (*coap_response_handler_t)(struct coap_context_t *, const coap_address_t *remote,
|
||||
coap_pdu_t *sent, coap_pdu_t *received, const coap_tid_t id);
|
||||
|
||||
#define COAP_MID_CACHE_SIZE 3
|
||||
typedef struct
|
||||
{
|
||||
unsigned char flags[COAP_MID_CACHE_SIZE];
|
||||
coap_key_t item[COAP_MID_CACHE_SIZE];
|
||||
} coap_mid_cache_t;
|
||||
|
||||
/** The CoAP stack's global state is stored in a coap_context_t object */
|
||||
typedef struct coap_context_t
|
||||
{
|
||||
coap_opt_filter_t known_options;
|
||||
#ifndef WITH_CONTIKI
|
||||
struct coap_resource_t *resources; /**< hash table or list of known resources */
|
||||
#endif /* WITH_CONTIKI */
|
||||
#ifndef WITHOUT_ASYNC
|
||||
/** list of asynchronous transactions */
|
||||
struct coap_async_state_t *async_state;
|
||||
#endif /* WITHOUT_ASYNC */
|
||||
/**
|
||||
* The time stamp in the first element of the sendqeue is relative
|
||||
* to sendqueue_basetime. */
|
||||
coap_tick_t sendqueue_basetime;
|
||||
coap_queue_t *sendqueue, *recvqueue;
|
||||
#if defined(WITH_POSIX) || defined(WITH_ARDUINO) || defined(_WIN32) || defined(AMEBA)
|
||||
int sockfd; /**< send/receive socket */
|
||||
#endif /* WITH_POSIX || WITH_ARDUINO */
|
||||
#ifdef WITH_CONTIKI
|
||||
struct uip_udp_conn *conn; /**< uIP connection object */
|
||||
|
||||
struct etimer retransmit_timer; /**< fires when the next packet must be sent */
|
||||
struct etimer notify_timer; /**< used to check resources periodically */
|
||||
#endif /* WITH_CONTIKI */
|
||||
#ifdef WITH_LWIP
|
||||
struct udp_pcb *pcb; /**< the underlying lwIP UDP PCB */
|
||||
struct pbuf *pending_package; /**< pbuf containing the last received package if not handled yet. This is only used to pass the package from the udp_recv callback into the coap_read function, which frees the pbuf and clears this field. */
|
||||
ip_addr_t pending_address; /**< the address associated with pending_package */
|
||||
u16_t pending_port; /**< the port associated with pending_package */
|
||||
|
||||
uint8_t timer_configured; /**< Set to 1 when a retransmission is scheduled using lwIP timers for this context, otherwise 0. */
|
||||
#endif /* WITH_LWIP */
|
||||
|
||||
/**
|
||||
* The last message id that was used is stored in this field. The
|
||||
* initial value is set by coap_new_context() and is usually a
|
||||
* random value. A new message id can be created with
|
||||
* coap_new_message_id().
|
||||
*/
|
||||
unsigned short message_id;
|
||||
|
||||
/**
|
||||
* The next value to be used for Observe. This field is global for
|
||||
* all resources and will be updated when notifications are created.
|
||||
*/
|
||||
unsigned int observe;
|
||||
|
||||
coap_response_handler_t response_handler;
|
||||
} coap_context_t;
|
||||
|
||||
/**
|
||||
* Registers a new message handler that is called whenever a response
|
||||
* was received that matches an ongoing transaction.
|
||||
*
|
||||
* @param context The context to register the handler for.
|
||||
* @param handler The response handler to register.
|
||||
*/
|
||||
INLINE_API void coap_register_response_handler(coap_context_t *context,
|
||||
coap_response_handler_t handler)
|
||||
{
|
||||
context->response_handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the option type @p type with the given context object @p
|
||||
* ctx.
|
||||
*
|
||||
* @param ctx The context to use.
|
||||
* @param type The option type to register.
|
||||
*/
|
||||
INLINE_API void coap_register_option(coap_context_t *ctx, unsigned char type)
|
||||
{
|
||||
coap_option_setb(ctx->known_options, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sendqueue_basetime in the given context object @p ctx to @p
|
||||
* now. This function returns the number of elements in the queue
|
||||
* head that have timed out.
|
||||
*/
|
||||
unsigned int coap_adjust_basetime(coap_context_t *ctx, coap_tick_t now);
|
||||
|
||||
/** Returns the next pdu to send without removing from sendqeue. */
|
||||
coap_queue_t *coap_peek_next(coap_context_t *context);
|
||||
|
||||
/** Returns the next pdu to send and removes it from the sendqeue. */
|
||||
coap_queue_t *coap_pop_next(coap_context_t *context);
|
||||
|
||||
/** Creates a new coap_context_t object that will hold the CoAP stack status. */
|
||||
coap_context_t *coap_new_context(const coap_address_t *listen_addr);
|
||||
|
||||
/**
|
||||
* Returns a new message id and updates @p context->message_id
|
||||
* accordingly. The message id is returned in network byte order
|
||||
* to make it easier to read in tracing tools.
|
||||
*
|
||||
* @param context the current coap_context_t object
|
||||
* @return incremented message id in network byte order
|
||||
*/
|
||||
INLINE_API unsigned short coap_new_message_id(coap_context_t *context)
|
||||
{
|
||||
++(context->message_id);
|
||||
#if defined(WITH_ARDUINO)
|
||||
return ((context->message_id << 8) | ((context->message_id >> 8) & (0xFF)));
|
||||
#elif defined(WITH_CONTIKI)
|
||||
return uip_htons(context->message_id);
|
||||
#else /* WITH_CONTIKI */
|
||||
return htons(context->message_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* CoAP stack context must be released with coap_free_context() */
|
||||
void coap_free_context(coap_context_t *context);
|
||||
|
||||
/**
|
||||
* Sends a confirmed CoAP message to given destination. The memory
|
||||
* that is allocated by pdu will not be released by
|
||||
* coap_send_confirmed(). The caller must release the memory.
|
||||
*
|
||||
* @param context The CoAP context to use.
|
||||
* @param dst The address to send to.
|
||||
* @param pdu The CoAP PDU to send.
|
||||
* @return The message id of the sent message or @c COAP_INVALID_TID on error.
|
||||
*/
|
||||
coap_tid_t coap_send_confirmed(coap_context_t *context, const coap_address_t *dst,
|
||||
coap_pdu_t *pdu);
|
||||
|
||||
/**
|
||||
* Creates a new ACK PDU with specified error @p code. The options
|
||||
* specified by the filter expression @p opts will be copied from the
|
||||
* original request contained in @p request. Unless @c
|
||||
* SHORT_ERROR_RESPONSE was defined at build time, the textual reason
|
||||
* phrase for @p code will be added as payload, with Content-Type @c
|
||||
* 0. This function returns a pointer to the new response message, or
|
||||
* @c NULL on error. The storage allocated for the new message must be
|
||||
* relased with coap_free().
|
||||
*
|
||||
* @param request Specification of the received (confirmable) request.
|
||||
* @param code The error code to set.
|
||||
* @param opts An option filter that specifies which options to copy
|
||||
* from the original request in @p node.
|
||||
*
|
||||
* @return A pointer to the new message or @c NULL on error.
|
||||
*/
|
||||
coap_pdu_t *coap_new_error_response(coap_pdu_t *request, unsigned char code,
|
||||
coap_opt_filter_t opts);
|
||||
/**
|
||||
* Sends a non-confirmed CoAP message to given destination. The memory
|
||||
* that is allocated by pdu will not be released by coap_send().
|
||||
* The caller must release the memory.
|
||||
*
|
||||
* @param context The CoAP context to use.
|
||||
* @param dst The address to send to.
|
||||
* @param pdu The CoAP PDU to send.
|
||||
* @return The message id of the sent message or @c COAP_INVALID_TID on error.
|
||||
*/
|
||||
coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu);
|
||||
|
||||
/**
|
||||
* Sends an error response with code @p code for request @p request to
|
||||
* @p dst. @p opts will be passed to coap_new_error_response() to
|
||||
* copy marked options from the request. This function returns the
|
||||
* transaction id if the message was sent, or @c COAP_INVALID_TID
|
||||
* otherwise.
|
||||
*
|
||||
* @param context The context to use.
|
||||
* @param request The original request to respond to.
|
||||
* @param dst The remote peer that sent the request.
|
||||
* @param code The reponse code.
|
||||
* @param opts A filter that specifies the options to copy from the
|
||||
* @p request.
|
||||
*
|
||||
* @return The transaction id if the message was sent, or @c
|
||||
* COAP_INVALID_TID otherwise.
|
||||
*/
|
||||
coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request,
|
||||
const coap_address_t *dst, unsigned char code, coap_opt_filter_t opts);
|
||||
|
||||
/**
|
||||
* Helper funktion to create and send a message with @p type (usually
|
||||
* ACK or RST). This function returns @c COAP_INVALID_TID when the
|
||||
* message was not sent, a valid transaction id otherwise.
|
||||
*
|
||||
* @param context The CoAP context.
|
||||
* @param dst Where to send the context.
|
||||
* @param request The request that should be responded to.
|
||||
* @param type Which type to set
|
||||
* @return transaction id on success or @c COAP_INVALID_TID otherwise.
|
||||
*/
|
||||
coap_tid_t
|
||||
coap_send_message_type(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *request,
|
||||
unsigned char type);
|
||||
/**
|
||||
* Sends an ACK message with code @c 0 for the specified @p request to
|
||||
* @p dst. This function returns the corresponding transaction id if
|
||||
* the message was sent or @c COAP_INVALID_TID on error.
|
||||
*
|
||||
* @param context The context to use.
|
||||
* @param dst The destination address.
|
||||
* @param request The request to be acknowledged.
|
||||
*
|
||||
* @return The transaction id if ACK was sent or @c COAP_INVALID_TID
|
||||
* on error.
|
||||
*/
|
||||
coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst,
|
||||
coap_pdu_t *request);
|
||||
|
||||
/**
|
||||
* Sends an RST message with code @c 0 for the specified @p request to
|
||||
* @p dst. This function returns the corresponding transaction id if
|
||||
* the message was sent or @c COAP_INVALID_TID on error.
|
||||
*
|
||||
* @param context The context to use.
|
||||
* @param dst The destination address.
|
||||
* @param request The request to be reset.
|
||||
*
|
||||
* @return The transaction id if RST was sent or @c COAP_INVALID_TID
|
||||
* on error.
|
||||
*/
|
||||
INLINE_API coap_tid_t coap_send_rst(coap_context_t *context, const coap_address_t *dst,
|
||||
coap_pdu_t *request)
|
||||
{
|
||||
return coap_send_message_type(context, dst, request, COAP_MESSAGE_RST);
|
||||
}
|
||||
|
||||
/** Handles retransmissions of confirmable messages */
|
||||
coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node);
|
||||
|
||||
/**
|
||||
* Reads data from the network and tries to parse as CoAP PDU. On success, 0 is returned
|
||||
* and a new node with the parsed PDU is added to the receive queue in the specified context
|
||||
* object.
|
||||
*/
|
||||
int coap_read(coap_context_t *context);
|
||||
|
||||
/**
|
||||
* Calculates a unique transaction id from given arguments @p peer and
|
||||
* @p pdu. The id is returned in @p id.
|
||||
*
|
||||
* @param peer The remote party who sent @p pdu.
|
||||
* @param pdu The message that initiated the transaction.
|
||||
* @param id Set to the new id.
|
||||
*/
|
||||
void coap_transaction_id(const coap_address_t *peer, const coap_pdu_t *pdu, coap_tid_t *id);
|
||||
|
||||
/**
|
||||
* This function removes the element with given @p id from the list
|
||||
* given list. If @p id was found, @p node is updated to point to the
|
||||
* removed element. Note that the storage allocated by @p node is
|
||||
* @b not released. The caller must do this manually using
|
||||
* coap_delete_node(). This function returns @c 1 if the element with
|
||||
* id @p id was found, @c 0 otherwise. For a return value of @c 0,
|
||||
* the contents of @p node is undefined.
|
||||
*
|
||||
* @param queue The queue to search for @p id.
|
||||
* @param id The node id to look for.
|
||||
* @param node If found, @p node is updated to point to the
|
||||
* removed node. You must release the storage pointed to by
|
||||
* @p node manually.
|
||||
*
|
||||
* @return @c 1 if @p id was found, @c 0 otherwise.
|
||||
*/
|
||||
int coap_remove_from_queue(coap_queue_t **queue, coap_tid_t id, coap_queue_t **node);
|
||||
|
||||
/**
|
||||
* Removes the transaction identified by @p id from given @p queue.
|
||||
* This is a convenience function for coap_remove_from_queue() with
|
||||
* automatic deletion of the removed node.
|
||||
*
|
||||
* @param queue The queue to search for @p id.
|
||||
* @param id The transaction id.
|
||||
*
|
||||
* @return @c 1 if node was found, removed and destroyed, @c 0 otherwise.
|
||||
*/
|
||||
INLINE_API int coap_remove_transaction(coap_queue_t **queue, coap_tid_t id)
|
||||
{
|
||||
coap_queue_t *node;
|
||||
if (!coap_remove_from_queue(queue, id, &node))
|
||||
return 0;
|
||||
|
||||
coap_delete_node(node);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves transaction from queue.
|
||||
* @queue The transaction queue to be searched
|
||||
* @id Unique key of the transaction to find.
|
||||
* @return A pointer to the transaction object or NULL if not found
|
||||
*/
|
||||
coap_queue_t *coap_find_transaction(coap_queue_t *queue, coap_tid_t id);
|
||||
|
||||
/**
|
||||
* Cancels all outstanding messages for peer @p dst that have the
|
||||
* specified token.
|
||||
*
|
||||
* @param context The context in use
|
||||
* @param dst Destination address of the messages to remove.
|
||||
* @param token Message token
|
||||
* @param token_length Actual length of @p token
|
||||
*/
|
||||
void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst,
|
||||
const unsigned char *token, size_t token_length);
|
||||
|
||||
/** Dispatches the PDUs from the receive queue in given context. */
|
||||
void coap_dispatch(coap_context_t *context, const char* responseData);
|
||||
|
||||
/** Returns 1 if there are no messages to send or to dispatch in the context's queues. */
|
||||
int coap_can_exit(coap_context_t *context);
|
||||
|
||||
/**
|
||||
* Returns the current value of an internal tick counter. The counter
|
||||
* counts \c COAP_TICKS_PER_SECOND ticks every second.
|
||||
*/
|
||||
void coap_ticks(coap_tick_t *);
|
||||
|
||||
/**
|
||||
* Verifies that @p pdu contains no unknown critical options. Options
|
||||
* must be registered at @p ctx, using the function
|
||||
* coap_register_option(). A basic set of options is registered
|
||||
* automatically by coap_new_context(). This function returns @c 1 if
|
||||
* @p pdu is ok, @c 0 otherwise. The given filter object @p unknown
|
||||
* will be updated with the unknown options. As only @c COAP_MAX_OPT
|
||||
* options can be signalled this way, remaining options must be
|
||||
* examined manually.
|
||||
*
|
||||
* @code
|
||||
coap_opt_filter_t f = COAP_OPT_NONE;
|
||||
coap_opt_iterator_t opt_iter;
|
||||
|
||||
if (coap_option_check_critical(ctx, pdu, f) == 0) {
|
||||
coap_option_iterator_init(pdu, &opt_iter, f);
|
||||
|
||||
while (coap_option_next(&opt_iter)) {
|
||||
if (opt_iter.type & 0x01) {
|
||||
... handle unknown critical option in opt_iter ...
|
||||
}
|
||||
}
|
||||
}
|
||||
* @endcode
|
||||
*
|
||||
* @param ctx The context where all known options are registered.
|
||||
* @param pdu The PDU to check.
|
||||
* @param unknown The output filter that will be updated to indicate the
|
||||
* unknown critical options found in @p pdu.
|
||||
*
|
||||
* @return @c 1 if everything was ok, @c 0 otherwise.
|
||||
*/
|
||||
int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu, coap_opt_filter_t unknown);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COAP_NET_H_ */
|
||||
363
sdk/component/common/network/libcoap/include/coap/option.h
Normal file
363
sdk/component/common/network/libcoap/include/coap/option.h
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* option.h -- helpers for handling options in CoAP PDUs
|
||||
*
|
||||
* Copyright (C) 2010-2013 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file option.h
|
||||
* @brief helpers for handling options in CoAP PDUs
|
||||
*/
|
||||
|
||||
#ifndef _OPTION_H_
|
||||
#define _OPTION_H_
|
||||
|
||||
#include "bits.h"
|
||||
#include "pdu.h"
|
||||
|
||||
/**
|
||||
* Use byte-oriented access methods here because sliding a complex
|
||||
* struct coap_opt_t over the data buffer may cause bus error on
|
||||
* certain platforms.
|
||||
*/
|
||||
typedef unsigned char coap_opt_t;
|
||||
#define PCHAR(p) ((coap_opt_t *)(p))
|
||||
|
||||
/** Representation of CoAP options. */
|
||||
typedef struct
|
||||
{
|
||||
unsigned short delta;
|
||||
size_t length;
|
||||
unsigned char *value;
|
||||
} coap_option_t;
|
||||
|
||||
|
||||
/** Representation of the association between a CoAP option key and its
|
||||
* data type and valid data length ranges.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned short key; /**< The ID of the option the following values apply to. */
|
||||
unsigned char type; /**< The type of the option: u=uint, s=string, o=opaque. */
|
||||
unsigned int min; /**< The minimum number of bytes allowed for the option data */
|
||||
unsigned int max; /**< The maximum number of bytes allowed for the option data */
|
||||
} coap_option_def_t;
|
||||
|
||||
/**
|
||||
* Parses the option pointed to by @p opt into @p result. This
|
||||
* function returns the number of bytes that have been parsed, or @c 0
|
||||
* on error. An error is signaled when illegal delta or length values
|
||||
* are encountered or when option parsing would result in reading past
|
||||
* the option (i.e. beyond opt + length).
|
||||
*
|
||||
* @param opt The beginning of the option to parse.
|
||||
* @param length The maximum length of @p opt.
|
||||
* @param result A pointer to the coap_option_t structure that is
|
||||
* filled with actual values iff coap_opt_parse() > 0.
|
||||
* @return The number of bytes parsed or @c 0 on error.
|
||||
*/
|
||||
size_t coap_opt_parse(const coap_opt_t *opt, size_t length, coap_option_t *result);
|
||||
|
||||
/**
|
||||
* Returns the size of the given option, taking into account a
|
||||
* possible option jump.
|
||||
*
|
||||
* @param opt An option jump or the beginning of the option.
|
||||
* @return The number of bytes between @p opt and the end of
|
||||
* the option starting at @p opt. In case of an error,
|
||||
* this function returns @c 0 as options need at least
|
||||
* one byte storage space.
|
||||
*/
|
||||
size_t coap_opt_size(const coap_opt_t *opt);
|
||||
|
||||
/** @deprecated { Use coap_opt_size() instead. } */
|
||||
#define COAP_OPT_SIZE(opt) coap_opt_size(opt)
|
||||
|
||||
/**
|
||||
* Calculates the beginning of the PDU's option section.
|
||||
*
|
||||
* @param pdu The PDU containing the options.
|
||||
* @return A pointer to the first option if available, or @c NULL otherwise.
|
||||
*/
|
||||
coap_opt_t *options_start(coap_pdu_t *pdu, coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Interprets @p opt as pointer to a CoAP option and advances to
|
||||
* the next byte past this option.
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define options_next(opt) \
|
||||
((coap_opt_t *)((unsigned char *)(opt) + COAP_OPT_SIZE(opt)))
|
||||
|
||||
/**
|
||||
* @defgroup opt_filter Option Filters
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fixed-size bit-vector we use for option filtering. It is large
|
||||
* enough to hold the highest option number known at build time (20 in
|
||||
* the core spec).
|
||||
*/
|
||||
typedef unsigned char coap_opt_filter_t[(COAP_MAX_OPT >> 3) + 1];
|
||||
|
||||
/** Pre-defined filter that includes all options. */
|
||||
#define COAP_OPT_ALL NULL
|
||||
|
||||
/**
|
||||
* Clears filter @p f.
|
||||
*
|
||||
* @param f The filter to clear.
|
||||
*/
|
||||
INLINE_API void coap_option_filter_clear(coap_opt_filter_t f)
|
||||
{
|
||||
memset(f, 0, sizeof(coap_opt_filter_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the corresponding bit for @p type in @p filter. This function
|
||||
* returns @c 1 if bit was set or @c -1 on error (i.e. when the given
|
||||
* type does not fit in the filter).
|
||||
*
|
||||
* @param filter The filter object to change.
|
||||
* @param type The type for which the bit should be set.
|
||||
*
|
||||
* @return @c 1 if bit was set, @c -1 otherwise.
|
||||
*/
|
||||
INLINE_API int coap_option_setb(coap_opt_filter_t filter, unsigned short type)
|
||||
{
|
||||
return bits_setb((uint8_t *) filter, sizeof(coap_opt_filter_t), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the corresponding bit for @p type in @p filter. This function
|
||||
* returns @c 1 if bit was cleared or @c -1 on error (i.e. when the given
|
||||
* type does not fit in the filter).
|
||||
*
|
||||
* @param filter The filter object to change.
|
||||
* @param type The type for which the bit should be cleared.
|
||||
*
|
||||
* @return @c 1 if bit was set, @c -1 otherwise.
|
||||
*/
|
||||
INLINE_API int coap_option_clrb(coap_opt_filter_t filter, unsigned short type)
|
||||
{
|
||||
return bits_clrb((uint8_t *) filter, sizeof(coap_opt_filter_t), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the corresponding bit for @p type in @p filter. This function
|
||||
* returns @c 1 if the bit is set @c 0 if not, or @c -1 on error (i.e.
|
||||
* when the given type does not fit in the filter).
|
||||
*
|
||||
* @param filter The filter object to read bit from..
|
||||
* @param type The type for which the bit should be read.
|
||||
*
|
||||
* @return @c 1 if bit was set, @c 0 if not, @c -1 on error.
|
||||
*/
|
||||
INLINE_API int coap_option_getb(const coap_opt_filter_t filter, unsigned short type)
|
||||
{
|
||||
return bits_getb((uint8_t *) filter, sizeof(coap_opt_filter_t), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator to run through PDU options. This object must be
|
||||
* initialized with coap_option_iterator_init(). Call
|
||||
* coap_option_next() to walk through the list of options until
|
||||
* coap_option_next() returns @c NULL.
|
||||
*
|
||||
* @code
|
||||
* coap_opt_t *option;
|
||||
* coap_opt_iterator_t opt_iter;
|
||||
* coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL);
|
||||
*
|
||||
* while ((option = coap_option_next(&opt_iter))) {
|
||||
* ... do something with option ...
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
size_t length; /**< remaining length of PDU */
|
||||
unsigned short type; /**< decoded option type */
|
||||
unsigned int bad :1; /**< iterator object is ok if not set */
|
||||
unsigned int filtered :1; /**< denotes whether or not filter is used */
|
||||
coap_opt_t *next_option; /**< pointer to the unparsed next option */
|
||||
coap_opt_filter_t filter; /**< option filter */
|
||||
} coap_opt_iterator_t;
|
||||
|
||||
/**
|
||||
* Initializes the given option iterator @p oi to point to the beginning of the
|
||||
* @p pdu's option list. This function returns @p oi on success, @c NULL
|
||||
* otherwise (i.e. when no options exist). Note that a length check on the
|
||||
* option list must be performed before coap_option_iterator_init() is called.
|
||||
*
|
||||
* @param pdu The PDU the options of which should be walked through.
|
||||
* @param oi An iterator object that will be initilized.
|
||||
* @param filter An optional option type filter.
|
||||
* With @p type != @c COAP_OPT_ALL, coap_option_next()
|
||||
* will return only options matching this bitmask.
|
||||
* Fence-post options @c 14, @c 28, @c 42, ... are always
|
||||
* skipped.
|
||||
*
|
||||
* @return The iterator object @p oi on success, @c NULL otherwise.
|
||||
*/
|
||||
coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu,
|
||||
coap_opt_iterator_t *oi,
|
||||
const coap_opt_filter_t filter);
|
||||
|
||||
/**
|
||||
* Initializes the given option iterator @p oi to point to the
|
||||
* beginning of the @p pdu's option list. This function returns @p oi
|
||||
* on success, @c NULL otherwise (i.e. when no options exist).
|
||||
* Note that a length check on the option list must be performed before
|
||||
* coap_option_iterator_init() is called.
|
||||
*
|
||||
* @param pdu The PDU the options of which should be walked through.
|
||||
* @param oi An iterator object that will be initilized.
|
||||
* @param filter An optional option type filter.
|
||||
* With @p type != @c COAP_OPT_ALL, coap_option_next()
|
||||
* will return only options matching this bitmask.
|
||||
* Fence-post options @c 14, @c 28, @c 42, ... are always
|
||||
* skipped.
|
||||
*
|
||||
* @return The iterator object @p oi on success, @c NULL otherwise.
|
||||
*/
|
||||
coap_opt_iterator_t *coap_option_iterator_init2(coap_pdu_t *pdu, coap_opt_iterator_t *oi,
|
||||
const coap_opt_filter_t filter, coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Updates the iterator @p oi to point to the next option. This
|
||||
* function returns a pointer to that option or @c NULL if no more
|
||||
* options exist. The contents of @p oi will be updated. In
|
||||
* particular, @c oi->n specifies the current option's ordinal number
|
||||
* (counted from @c 1), @c oi->type is the option's type code, and @c
|
||||
* oi->option points to the beginning of the current option
|
||||
* itself. When advanced past the last option, @c oi->option will be
|
||||
* @c NULL.
|
||||
*
|
||||
* Note that options are skipped whose corresponding bits in the
|
||||
* filter specified with coap_option_iterator_init() are @c 0. Options
|
||||
* with type codes that do not fit in this filter hence will always be
|
||||
* returned.
|
||||
*
|
||||
* @param oi The option iterator to update.
|
||||
*
|
||||
* @return The next option or @c NULL if no more options exist.
|
||||
*/
|
||||
coap_opt_t *coap_option_next(coap_opt_iterator_t *oi);
|
||||
|
||||
/**
|
||||
* Retrieves the first option of type @p type from @p pdu. @p oi must
|
||||
* point to a coap_opt_iterator_t object that will be initialized by
|
||||
* this function to filter only options with code @p type. This
|
||||
* function returns the first option with this type, or @c NULL if not
|
||||
* found.
|
||||
*
|
||||
* @param pdu The PDU to parse for options.
|
||||
* @param type The option type code to search for.
|
||||
* @param oi An iterator object to use.
|
||||
*
|
||||
* @return A pointer to the first option of type @p type, or @c NULL
|
||||
* if not found.
|
||||
*/
|
||||
coap_opt_t *coap_check_option(coap_pdu_t *pdu, unsigned char type, coap_opt_iterator_t *oi);
|
||||
|
||||
/**
|
||||
* Encodes the given delta and length values into @p opt. This
|
||||
* function returns the number of bytes that were required to encode
|
||||
* @p delta and @p length or @c 0 on error. Note that the result
|
||||
* indicates by how many bytes @p opt must be advanced to encode the
|
||||
* option value.
|
||||
*
|
||||
* @param opt The option buffer space where @p delta and @p length are
|
||||
* written
|
||||
* @param maxlen The maximum length of @p opt
|
||||
* @param delta The actual delta value to encode.
|
||||
* @param length The actual length value to encode.
|
||||
* @return The number of bytes used or @c 0 on error.
|
||||
*/
|
||||
size_t coap_opt_setheader(coap_opt_t *opt, size_t maxlen, unsigned short delta, size_t length);
|
||||
|
||||
/**
|
||||
* Encodes option with given @p delta into @p opt. This function returns
|
||||
* the number of bytes written to @p opt or @c 0 on error. This happens
|
||||
* especially when @p opt does not provide sufficient space to store
|
||||
* the option value, delta, and option jumps when required.
|
||||
*
|
||||
* @param opt The option buffer space where @p val is written
|
||||
* @param n Maximum length of @p opt.
|
||||
* @param delta The option delta.
|
||||
* @param val The option value to copy into @p opt.
|
||||
* @param len The actual length of @p val.
|
||||
* @return The number of bytes that have been written to @p opt or
|
||||
* @c 0 on error. The return value will always be less than @p n.
|
||||
*/
|
||||
size_t coap_opt_encode(coap_opt_t *opt, size_t n, unsigned short delta, const unsigned char *val,
|
||||
size_t length);
|
||||
|
||||
/**
|
||||
* Decodes the delta value of the next option. This function returns
|
||||
* the number of bytes read or @c 0 on error. The caller of this
|
||||
* function must ensure that it does not read over the boundaries
|
||||
* of @p opt (e.g. by calling coap_opt_check_delta().
|
||||
*
|
||||
* @param opt The option to examine
|
||||
* @return The number of bytes read or @c 0 on error.
|
||||
*/
|
||||
unsigned short coap_opt_delta(const coap_opt_t *opt);
|
||||
|
||||
/** @deprecated { Use coap_opt_delta() instead. } */
|
||||
#define COAP_OPT_DELTA(opt) coap_opt_delta(opt)
|
||||
|
||||
/** @deprecated { Use coap_opt_encode() instead. } */
|
||||
#ifndef WITH_TCP
|
||||
#define COAP_OPT_SETDELTA(opt,val) \
|
||||
coap_opt_encode((opt), COAP_MAX_PDU_SIZE, (val), NULL, 0)
|
||||
#endif
|
||||
/**
|
||||
* Returns the length of the given option. @p opt must point to an
|
||||
* option jump or the beginning of the option. This function returns
|
||||
* @c 0 when @p opt is not an option or the actual length of @p opt
|
||||
* (which can be @c 0 as well).
|
||||
*
|
||||
* @note {The rationale for using @c 0 in case of an error is that in
|
||||
* most contexts, the result of this function is used to skip the next
|
||||
* coap_opt_length() bytes. }
|
||||
*
|
||||
* @param opt The option whose length should be returned.
|
||||
* @return The option's length or @c 0 when undefined.
|
||||
*/
|
||||
unsigned short coap_opt_length(const coap_opt_t *opt);
|
||||
|
||||
/** @deprecated { Use coap_opt_length() instead. } */
|
||||
#define COAP_OPT_LENGTH(opt) coap_opt_length(opt)
|
||||
|
||||
/**
|
||||
* Returns a pointer to the value of the given option. @p opt must
|
||||
* point to an option jump or the beginning of the option. This
|
||||
* function returns @c NULL if @p opt is not a valid option.
|
||||
*
|
||||
* @param opt The option whose value should be returned.
|
||||
* @return A pointer to the option value or @c NULL on error.
|
||||
*/
|
||||
unsigned char *coap_opt_value(coap_opt_t *opt);
|
||||
|
||||
/**
|
||||
* Returns a pointer to the coap option range definitions. @key
|
||||
* must be a valid option ID. This function returns @c NULL if
|
||||
* @p key is not a valid option ID.
|
||||
*
|
||||
* @param key The option ID whose definition should be returned.
|
||||
* @return A pointer to the option definition.
|
||||
*/
|
||||
coap_option_def_t* coap_opt_def(unsigned short key);
|
||||
|
||||
/** @deprecated { Use coap_opt_value() instead. } */
|
||||
#define COAP_OPT_VALUE(opt) coap_opt_value((coap_opt_t *)opt)
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _OPTION_H_ */
|
||||
660
sdk/component/common/network/libcoap/include/coap/pdu.h
Normal file
660
sdk/component/common/network/libcoap/include/coap/pdu.h
Normal file
|
|
@ -0,0 +1,660 @@
|
|||
/* pdu.h -- CoAP message structure
|
||||
*
|
||||
* Copyright (C) 2010--2012 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_PDU_H_
|
||||
#define _COAP_PDU_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "coap_list.h"
|
||||
#include "uri.h"
|
||||
|
||||
#ifdef WITH_LWIP
|
||||
#include <lwip/pbuf.h>
|
||||
#endif
|
||||
|
||||
/* pre-defined constants that reflect defaults for CoAP */
|
||||
|
||||
#define COAP_DEFAULT_RESPONSE_TIMEOUT 2 /* response timeout in seconds */
|
||||
#define COAP_DEFAULT_MAX_RETRANSMIT 4 /* max number of retransmissions */
|
||||
#define COAP_DEFAULT_PORT 5683 /* CoAP default UDP port */
|
||||
#define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */
|
||||
#ifndef COAP_MAX_PDU_SIZE
|
||||
#ifdef WITH_ARDUINO
|
||||
#define COAP_MAX_PDU_SIZE 320 /* maximum size of a CoAP PDU for embedded platforms*/
|
||||
#else
|
||||
#define COAP_MAX_PDU_SIZE 1400 /* maximum size of a CoAP PDU for big platforms*/
|
||||
#endif
|
||||
#endif /* COAP_MAX_PDU_SIZE */
|
||||
|
||||
#define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */
|
||||
#define COAP_DEFAULT_SCHEME "coap" /* the default scheme for CoAP URIs */
|
||||
|
||||
/** well-known resources URI */
|
||||
#define COAP_DEFAULT_URI_WELLKNOWN ".well-known/core"
|
||||
|
||||
#ifdef __COAP_DEFAULT_HASH
|
||||
/* pre-calculated hash key for the default well-known URI */
|
||||
#define COAP_DEFAULT_WKC_HASHKEY "\345\130\144\245"
|
||||
#endif
|
||||
|
||||
/* CoAP message types */
|
||||
|
||||
#define COAP_MESSAGE_CON 0 /* confirmable message (requires ACK/RST) */
|
||||
#define COAP_MESSAGE_NON 1 /* non-confirmable message (one-shot message) */
|
||||
#define COAP_MESSAGE_ACK 2 /* used to acknowledge confirmable messages */
|
||||
#define COAP_MESSAGE_RST 3 /* indicates error in received messages */
|
||||
|
||||
/* CoAP request methods */
|
||||
|
||||
#define COAP_REQUEST_GET 1
|
||||
#define COAP_REQUEST_POST 2
|
||||
#define COAP_REQUEST_PUT 3
|
||||
#define COAP_REQUEST_DELETE 4
|
||||
|
||||
/* CoAP option types (be sure to update check_critical when adding options */
|
||||
|
||||
#define COAP_OPTION_IF_MATCH 1 /* C, opaque, 0-8 B, (none) */
|
||||
#define COAP_OPTION_URI_HOST 3 /* C, String, 1-255 B, destination address */
|
||||
#define COAP_OPTION_ETAG 4 /* E, opaque, 1-8 B, (none) */
|
||||
#define COAP_OPTION_IF_NONE_MATCH 5 /* empty, 0 B, (none) */
|
||||
#define COAP_OPTION_URI_PORT 7 /* C, uint, 0-2 B, destination port */
|
||||
#define COAP_OPTION_LOCATION_PATH 8 /* E, String, 0-255 B, - */
|
||||
#define COAP_OPTION_URI_PATH 11 /* C, String, 0-255 B, (none) */
|
||||
#define COAP_OPTION_CONTENT_FORMAT 12 /* E, uint, 0-2 B, (none) */
|
||||
#define COAP_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT
|
||||
#define COAP_OPTION_MAXAGE 14 /* E, uint, 0--4 B, 60 Seconds */
|
||||
#define COAP_OPTION_URI_QUERY 15 /* C, String, 1-255 B, (none) */
|
||||
#define COAP_OPTION_ACCEPT 17 /* C, uint, 0-2 B, (none) */
|
||||
#define COAP_OPTION_LOCATION_QUERY 20 /* E, String, 0-255 B, (none) */
|
||||
#define COAP_OPTION_PROXY_URI 35 /* C, String, 1-1034 B, (none) */
|
||||
#define COAP_OPTION_PROXY_SCHEME 39 /* C, String, 1-255 B, (none) */
|
||||
#define COAP_OPTION_SIZE1 60 /* E, uint, 0-4 B, (none) */
|
||||
#define COAP_OPTION_SIZE2 28 /* E, uint, 0-4 B, (none) */
|
||||
|
||||
/* option types from draft-ietf-coap-observe-09 */
|
||||
|
||||
#define COAP_OPTION_OBSERVE 6 /* E, empty/uint, 0 B/0-3 B, (none) */
|
||||
#define COAP_OPTION_SUBSCRIPTION COAP_OPTION_OBSERVE
|
||||
|
||||
/* selected option types from draft-core-block-04 */
|
||||
|
||||
#define COAP_OPTION_BLOCK2 23 /* C, uint, 0--3 B, (none) */
|
||||
#define COAP_OPTION_BLOCK1 27 /* C, uint, 0--3 B, (none) */
|
||||
|
||||
#define COAP_MAX_OPT 63 /**< the highest option number we know */
|
||||
|
||||
/* CoAP result codes (HTTP-Code / 100 * 40 + HTTP-Code % 100) */
|
||||
|
||||
/* As of draft-ietf-core-coap-04, response codes are encoded to base
|
||||
* 32, i.e. the three upper bits determine the response class while
|
||||
* the remaining five fine-grained information specific to that class.
|
||||
*/
|
||||
#define COAP_RESPONSE_CODE(N) (((N)/100 << 5) | (N)%100)
|
||||
|
||||
/* Determines the class of response code C */
|
||||
#define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF)
|
||||
|
||||
#ifndef SHORT_ERROR_RESPONSE
|
||||
/**
|
||||
* Returns a human-readable response phrase for the specified CoAP response @p
|
||||
* code. This function returns @c NULL if not found.
|
||||
*
|
||||
* @param code The response code for which the literal phrase should be
|
||||
* retrieved.
|
||||
*
|
||||
* @return A zero-terminated string describing the error, or @c NULL if not
|
||||
* found.
|
||||
*/
|
||||
char *coap_response_phrase(unsigned char code);
|
||||
|
||||
#define COAP_ERROR_PHRASE_LENGTH 32 /**< maximum length of error phrase */
|
||||
|
||||
#else
|
||||
#define coap_response_phrase(x) ((char *)NULL)
|
||||
|
||||
#define COAP_ERROR_PHRASE_LENGTH 0 /**< maximum length of error phrase */
|
||||
#endif /* SHORT_ERROR_RESPONSE */
|
||||
|
||||
/* The following definitions exist for backwards compatibility */
|
||||
#if 0 /* this does not exist any more */
|
||||
#define COAP_RESPONSE_100 40 /* 100 Continue */
|
||||
#endif
|
||||
#define COAP_RESPONSE_200 COAP_RESPONSE_CODE(200) /* 2.00 OK */
|
||||
#define COAP_RESPONSE_201 COAP_RESPONSE_CODE(201) /* 2.01 Created */
|
||||
#define COAP_RESPONSE_304 COAP_RESPONSE_CODE(203) /* 2.03 Valid */
|
||||
#define COAP_RESPONSE_400 COAP_RESPONSE_CODE(400) /* 4.00 Bad Request */
|
||||
#define COAP_RESPONSE_404 COAP_RESPONSE_CODE(404) /* 4.04 Not Found */
|
||||
#define COAP_RESPONSE_405 COAP_RESPONSE_CODE(405) /* 4.05 Method Not Allowed */
|
||||
#define COAP_RESPONSE_415 COAP_RESPONSE_CODE(415) /* 4.15 Unsupported Media Type */
|
||||
#define COAP_RESPONSE_500 COAP_RESPONSE_CODE(500) /* 5.00 Internal Server Error */
|
||||
#define COAP_RESPONSE_501 COAP_RESPONSE_CODE(501) /* 5.01 Not Implemented */
|
||||
#define COAP_RESPONSE_503 COAP_RESPONSE_CODE(503) /* 5.03 Service Unavailable */
|
||||
#define COAP_RESPONSE_504 COAP_RESPONSE_CODE(504) /* 5.04 Gateway Timeout */
|
||||
#if 0 /* these response codes do not have a valid code any more */
|
||||
# define COAP_RESPONSE_X_240 240 /* Token Option required by server */
|
||||
# define COAP_RESPONSE_X_241 241 /* Uri-Authority Option required by server */
|
||||
#endif
|
||||
#define COAP_RESPONSE_X_242 COAP_RESPONSE_CODE(402) /* Critical Option not supported */
|
||||
|
||||
/* CoAP media type encoding */
|
||||
|
||||
#define COAP_MEDIATYPE_TEXT_PLAIN 0 /* text/plain (UTF-8) */
|
||||
#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT 40 /* application/link-format */
|
||||
#define COAP_MEDIATYPE_APPLICATION_XML 41 /* application/xml */
|
||||
#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM 42 /* application/octet-stream */
|
||||
#define COAP_MEDIATYPE_APPLICATION_RDF_XML 43 /* application/rdf+xml */
|
||||
#define COAP_MEDIATYPE_APPLICATION_EXI 47 /* application/exi */
|
||||
#define COAP_MEDIATYPE_APPLICATION_JSON 50 /* application/json */
|
||||
#define COAP_MEDIATYPE_APPLICATION_CBOR 60 /* application/cbor */
|
||||
|
||||
/* Note that identifiers for registered media types are in the range 0-65535. We
|
||||
* use an unallocated type here and hope for the best. */
|
||||
#define COAP_MEDIATYPE_ANY 0xff /* any media type */
|
||||
|
||||
/**
|
||||
* coap_tid_t is used to store CoAP transaction id, i.e. a hash value
|
||||
* built from the remote transport address and the message id of a
|
||||
* CoAP PDU. Valid transaction ids are greater or equal zero.
|
||||
*/
|
||||
typedef int coap_tid_t;
|
||||
|
||||
/** Indicates an invalid transaction id. */
|
||||
#define COAP_INVALID_TID -1
|
||||
|
||||
#define COAP_TCP_HEADER_NO_FIELD 2
|
||||
#define COAP_TCP_HEADER_8_BIT 3
|
||||
#define COAP_TCP_HEADER_16_BIT 4
|
||||
#define COAP_TCP_HEADER_32_BIT 6
|
||||
|
||||
#define COAP_TCP_LENGTH_FIELD_8_BIT 13
|
||||
#define COAP_TCP_LENGTH_FIELD_16_BIT 269
|
||||
#define COAP_TCP_LENGTH_FIELD_32_BIT 65805
|
||||
|
||||
#define COAP_TCP_LENGTH_LIMIT_8_BIT 13
|
||||
#define COAP_TCP_LENGTH_LIMIT_16_BIT 256
|
||||
#define COAP_TCP_LENGTH_LIMIT_32_BIT 65536
|
||||
|
||||
#define COAP_TCP_LENGTH_FIELD_NUM_8_BIT 13
|
||||
#define COAP_TCP_LENGTH_FIELD_NUM_16_BIT 14
|
||||
#define COAP_TCP_LENGTH_FIELD_NUM_32_BIT 15
|
||||
|
||||
#define COAP_OPTION_FIELD_8_BIT 12
|
||||
#define COAP_OPTION_FIELD_16_BIT 256
|
||||
#define COAP_OPTION_FIELD_32_BIT 65536
|
||||
|
||||
typedef enum {
|
||||
COAP_UDP = 0,
|
||||
COAP_TCP,
|
||||
COAP_TCP_8BIT,
|
||||
COAP_TCP_16BIT,
|
||||
COAP_TCP_32BIT
|
||||
} coap_transport_t;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
typedef struct {
|
||||
unsigned short version:2; /* protocol version */
|
||||
unsigned short type:2; /* type flag */
|
||||
unsigned short token_length:4; /* length of Token */
|
||||
unsigned short code:8; /* request method (value 1--10) or response
|
||||
code (value 40-255) */
|
||||
unsigned short id; /* message id */
|
||||
unsigned char token[]; /* the actual token, if any */
|
||||
} coap_hdr_udp_t;
|
||||
#else
|
||||
typedef struct {
|
||||
unsigned short token_length:4; /* length of Token */
|
||||
unsigned short type:2; /* type flag */
|
||||
unsigned short version:2; /* protocol version */
|
||||
unsigned short code:8; /* request method (value 1--10) or response
|
||||
code (value 40-255) */
|
||||
unsigned short id; /* transaction id (network byte order!) */
|
||||
unsigned char token[]; /* the actual token, if any */
|
||||
} coap_hdr_udp_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned char header_data[COAP_TCP_HEADER_NO_FIELD];
|
||||
unsigned char token[]; /* the actual token, if any */
|
||||
} coap_hdr_tcp_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char header_data[COAP_TCP_HEADER_8_BIT];
|
||||
unsigned char token[]; /* the actual token, if any */
|
||||
} coap_hdr_tcp_8bit_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char header_data[COAP_TCP_HEADER_16_BIT];
|
||||
unsigned char token[]; /* the actual token, if any */
|
||||
} coap_hdr_tcp_16bit_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char header_data[6];
|
||||
unsigned char token[]; /* the actual token, if any */
|
||||
} coap_hdr_tcp_32bit_t;
|
||||
|
||||
typedef union {
|
||||
coap_hdr_udp_t udp;
|
||||
coap_hdr_tcp_t tcp;
|
||||
coap_hdr_tcp_8bit_t tcp_8bit;
|
||||
coap_hdr_tcp_16bit_t tcp_16bit;
|
||||
coap_hdr_tcp_32bit_t tcp_32bit;
|
||||
} coap_hdr_transport_t;
|
||||
|
||||
// Typedef for backwards compatibility.
|
||||
typedef coap_hdr_udp_t coap_hdr_t;
|
||||
|
||||
#define COAP_MESSAGE_IS_EMPTY(MSG) ((MSG).code == 0)
|
||||
#define COAP_MESSAGE_IS_REQUEST(MSG) (!COAP_MESSAGE_IS_EMPTY(MSG) \
|
||||
&& ((MSG).code < 32))
|
||||
#define COAP_MESSAGE_IS_RESPONSE(MSG) ((MSG).code >= 64 && (MSG).code <= 191)
|
||||
|
||||
#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list
|
||||
* in a CoAP message is limited by 0b11110000
|
||||
* marker */
|
||||
|
||||
#define COAP_OPT_END 0xF0 /* end marker */
|
||||
|
||||
#define COAP_PAYLOAD_START 0xFF /* payload marker */
|
||||
|
||||
/**
|
||||
* Structures for more convenient handling of options. (To be used with ordered
|
||||
* coap_list_t.) The option's data will be added to the end of the coap_option
|
||||
* structure (see macro COAP_OPTION_DATA).
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned short key; /* the option key (no delta coding) */
|
||||
unsigned int length;
|
||||
} coap_option;
|
||||
|
||||
#define COAP_OPTION_KEY(option) (option).key
|
||||
#define COAP_OPTION_LENGTH(option) (option).length
|
||||
#define COAP_OPTION_DATA(option) ((unsigned char *)&(option) + sizeof(coap_option))
|
||||
|
||||
/**
|
||||
* Header structure for CoAP PDUs
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
size_t max_size; /**< allocated storage for options and data */
|
||||
|
||||
union {
|
||||
coap_hdr_t *hdr; /**< Address of the first byte of the CoAP message.
|
||||
* This may or may not equal (coap_hdr_t*)(pdu+1)
|
||||
* depending on the memory management
|
||||
* implementation. */
|
||||
coap_hdr_transport_t *transport_hdr; /**< Address of the first byte of the CoAP message.
|
||||
* This may or may not equal (coap_hdr_t*)(pdu+1)
|
||||
* depending on the memory management
|
||||
* implementation. */
|
||||
};
|
||||
unsigned short max_delta; /**< highest option number */
|
||||
unsigned int length; /**< PDU length (including header, options, data) */
|
||||
unsigned char *data; /**< payload */
|
||||
|
||||
#ifdef WITH_LWIP
|
||||
struct pbuf *pbuf; /**< lwIP PBUF. The package data will always reside
|
||||
* inside the pbuf's payload, but this pointer
|
||||
* has to be kept because no exact offset can be
|
||||
* given. This field must not be accessed from
|
||||
* outside, because the pbuf's reference count
|
||||
* is checked to be 1 when the pbuf is assigned
|
||||
* to the pdu, and the pbuf stays exclusive to
|
||||
* this pdu. */
|
||||
#endif
|
||||
|
||||
} coap_pdu_t;
|
||||
|
||||
/**
|
||||
* Options in coap_pdu_t are accessed with the macro COAP_OPTION.
|
||||
*/
|
||||
#define COAP_OPTION(node) ((coap_option *)(node)->options)
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#ifdef WITH_LWIP
|
||||
/**
|
||||
* Creates a CoAP PDU from an lwIP @p pbuf, whose reference is passed on to this
|
||||
* function.
|
||||
*
|
||||
* The pbuf is checked for being contiguous, for having enough head space for
|
||||
* the PDU struct (which is located directly in front of the data, overwriting
|
||||
* the old other headers), and for having only one reference. The reference is
|
||||
* stored in the PDU and will be freed when the PDU is freed.
|
||||
*
|
||||
* (For now, these are fatal errors; in future, a new pbuf might be allocated,
|
||||
* the data copied and the passed pbuf freed).
|
||||
*
|
||||
* This behaves like coap_pdu_init(0, 0, 0, pbuf->tot_len), and afterwards
|
||||
* copying the contents of the pbuf to the pdu.
|
||||
*
|
||||
* @return A pointer to the new PDU object or @c NULL on error.
|
||||
*/
|
||||
coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates a new CoAP PDU of given @p size (must be large enough to hold the
|
||||
* basic CoAP message header (coap_hdr_t). The function returns a pointer to the
|
||||
* node coap_pdu_t object on success, or @c NULL on error. The storage allocated
|
||||
* for the result must be released with coap_delete_pdu().
|
||||
*
|
||||
* @param type The type of the PDU (one of COAP_MESSAGE_CON, COAP_MESSAGE_NON,
|
||||
* COAP_MESSAGE_ACK, COAP_MESSAGE_RST).
|
||||
* @param code The message code.
|
||||
* @param id The message id to set or COAP_INVALID_TID if unknown.
|
||||
* @param size The number of bytes to allocate for the actual message.
|
||||
*
|
||||
* @return A pointer to the new PDU object or @c NULL on error.
|
||||
*/
|
||||
coap_pdu_t *
|
||||
coap_pdu_init(unsigned char type,
|
||||
unsigned char code,
|
||||
unsigned short id,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* Creates a new CoAP PDU of given @p size (must be large enough to hold the
|
||||
* basic CoAP message header (coap_hdr_t). The function returns a pointer to
|
||||
* the node coap_pdu_t object on success, or @c NULL on error. The storage
|
||||
* allocated for the result must be released with coap_delete_pdu().
|
||||
*
|
||||
* @param type The type of the PDU (one of COAP_MESSAGE_CON,
|
||||
* COAP_MESSAGE_NON, COAP_MESSAGE_ACK, COAP_MESSAGE_RST).
|
||||
* @param code The message code.
|
||||
* @param id The message id to set or COAP_INVALID_TID if unknown.
|
||||
* @param size The number of bytes to allocate for the actual message.
|
||||
* @param transport The transport type.
|
||||
*
|
||||
* @return A pointer to the new PDU object or @c NULL on error.
|
||||
*/
|
||||
coap_pdu_t *
|
||||
coap_pdu_init2(unsigned char type, unsigned char code, unsigned short id,
|
||||
size_t size, coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Clears any contents from @p pdu and resets @c version field, @c
|
||||
* length and @c data pointers. @c max_size is set to @p size, any
|
||||
* other field is set to @c 0. Note that @p pdu must be a valid
|
||||
* pointer to a coap_pdu_t object created e.g. by coap_pdu_init().
|
||||
*/
|
||||
void coap_pdu_clear(coap_pdu_t *pdu, size_t size);
|
||||
|
||||
/**
|
||||
* Clears any contents from @p pdu and resets @c version field, @c
|
||||
* length and @c data pointers. @c max_size is set to @p size, any
|
||||
* other field is set to @c 0. Note that @p pdu must be a valid
|
||||
* pointer to a coap_pdu_t object created e.g. by coap_pdu_init().
|
||||
*/
|
||||
void coap_pdu_clear2(coap_pdu_t *pdu, size_t size, coap_transport_t transport,
|
||||
unsigned int length);
|
||||
|
||||
/**
|
||||
* Creates a new CoAP PDU.
|
||||
* The object is created on the heap and must be released using
|
||||
* coap_delete_pdu();
|
||||
*
|
||||
* @deprecated This function allocates the maximum storage for each
|
||||
* PDU. Use coap_pdu_init() instead.
|
||||
*/
|
||||
coap_pdu_t *coap_new_pdu(void);
|
||||
|
||||
/**
|
||||
* Creates a new CoAP PDU. The object is created on the heap and must be released
|
||||
* using coap_delete_pdu();
|
||||
*
|
||||
* @deprecated This function allocates the maximum storage for each
|
||||
* PDU. Use coap_pdu_init2() instead.
|
||||
*/
|
||||
coap_pdu_t *coap_new_pdu2(coap_transport_t transport, unsigned int size);
|
||||
|
||||
void coap_delete_pdu(coap_pdu_t *);
|
||||
|
||||
/**
|
||||
* Parses @p data into the CoAP PDU structure given in @p result.
|
||||
* This function returns @c 0 on error or a number greater than zero on success.
|
||||
*
|
||||
* @param data The raw data to parse as CoAP PDU
|
||||
* @param length The actual size of @p data
|
||||
* @param result The PDU structure to fill. Note that the structure must
|
||||
* provide space for at least @p length bytes to hold the
|
||||
* entire CoAP PDU.
|
||||
*
|
||||
* @return A value greater than zero on success or @c 0 on error.
|
||||
*/
|
||||
int coap_pdu_parse(unsigned char *data,
|
||||
size_t length,
|
||||
coap_pdu_t *result);
|
||||
|
||||
/**
|
||||
* Parses @p data into the CoAP PDU structure given in @p result.
|
||||
* This function returns @c 0 on error or a number greater than zero on success.
|
||||
*
|
||||
* @param data The raw data to parse as CoAP PDU
|
||||
* @param length The actual size of @p data
|
||||
* @param result The PDU structure to fill. Note that the structure must
|
||||
* provide space for at least @p length bytes to hold the
|
||||
* entire CoAP PDU.
|
||||
* @param transport The transport type.
|
||||
* @return A value greater than zero on success or @c 0 on error.
|
||||
*/
|
||||
int coap_pdu_parse2(unsigned char *data, size_t length, coap_pdu_t *pdu,
|
||||
coap_transport_t transport);
|
||||
|
||||
#ifdef WITH_TCP
|
||||
/**
|
||||
* Get total pdu size including header + option + payload (with marker) from pdu data.
|
||||
*
|
||||
* @param data The raw data to parse as CoAP PDU.
|
||||
* @param size payload size of pdu.
|
||||
* @return Total message length.
|
||||
*/
|
||||
size_t coap_get_total_message_length(const unsigned char *data, size_t size);
|
||||
|
||||
/**
|
||||
* Get transport type of coap header for coap over tcp
|
||||
* through payload size(including payload marker) + option size.
|
||||
*
|
||||
* @param size payload size of pdu.
|
||||
* @return The transport type.
|
||||
*/
|
||||
coap_transport_t coap_get_tcp_header_type_from_size(unsigned int size);
|
||||
|
||||
/**
|
||||
* Get transport type of coap header for coap over tcp
|
||||
* through first nibble(0~E) of init-byte .
|
||||
*
|
||||
* @param legnth length value of init byte.
|
||||
* @return The transport type.
|
||||
*/
|
||||
coap_transport_t coap_get_tcp_header_type_from_initbyte(unsigned int length);
|
||||
|
||||
/**
|
||||
* Add length of option/payload into 'Len+ byte...' field of coap header
|
||||
* for coap over tcp.
|
||||
*
|
||||
* @param pdu The pdu pointer.
|
||||
* @param transport The transport type.
|
||||
* @param length length value of init byte.
|
||||
*/
|
||||
void coap_add_length(const coap_pdu_t *pdu, coap_transport_t transport,
|
||||
unsigned int length);
|
||||
|
||||
/**
|
||||
* Get the length of option/payload field of coap header for coap over tcp.
|
||||
*
|
||||
* @param pdu The pdu pointer.
|
||||
* @param transport The transport type.
|
||||
* @return length value of init byte.
|
||||
*/
|
||||
unsigned int coap_get_length(const coap_pdu_t *pdu, coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Get the length of option/payload field of coap header for coap over tcp.
|
||||
*
|
||||
* @param header The header to parse.
|
||||
* @return transport The transport type.
|
||||
*/
|
||||
unsigned int coap_get_length_from_header(const unsigned char *header,
|
||||
coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Get length of header including len, TKL, Len+bytes, Code, token bytes for coap over tcp.
|
||||
*
|
||||
* @param data The raw data to parse as CoAP PDU
|
||||
* @return header length + token length
|
||||
*/
|
||||
unsigned int coap_get_tcp_header_length(unsigned char *data);
|
||||
|
||||
/**
|
||||
* Get length of header including len, TKL, Len+bytes, Code
|
||||
* without token bytes for coap over tcp.
|
||||
*
|
||||
* @param transport The transport type.
|
||||
* @return header length.
|
||||
*/
|
||||
unsigned int coap_get_tcp_header_length_for_transport(coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Get option length.
|
||||
*
|
||||
* @param key delta of option
|
||||
* @param length length of option
|
||||
* @return total option length
|
||||
*/
|
||||
size_t coap_get_opt_header_length(unsigned short key, size_t length);
|
||||
#endif /* WITH_TCP */
|
||||
|
||||
/**
|
||||
* Add code in coap header.
|
||||
*
|
||||
* @param pdu The pdu pointer.
|
||||
* @param transport The transport type.
|
||||
* @param code The message code.
|
||||
*/
|
||||
void coap_add_code(const coap_pdu_t *pdu, coap_transport_t transport,
|
||||
unsigned int code);
|
||||
|
||||
/**
|
||||
* Get message code from coap header
|
||||
*
|
||||
* @param pdu The pdu pointer.
|
||||
* @param transport The transport type.
|
||||
* @return The message code.
|
||||
*/
|
||||
unsigned int coap_get_code(const coap_pdu_t *pdu, coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Adds token of length @p len to @p pdu.
|
||||
* Adding the token destroys any following contents of the pdu. Hence options
|
||||
* and data must be added after coap_add_token() has been called. In @p pdu,
|
||||
* length is set to @p len + @c 4, and max_delta is set to @c 0. This funtion
|
||||
* returns @c 0 on error or a value greater than zero on success.
|
||||
*
|
||||
* @param pdu The PDU where the token is to be added.
|
||||
* @param len The length of the new token.
|
||||
* @param data The token to add.
|
||||
*
|
||||
* @return A value greater than zero on success, or @c 0 on error.
|
||||
*/
|
||||
int coap_add_token(coap_pdu_t *pdu,
|
||||
size_t len,
|
||||
const unsigned char *data);
|
||||
|
||||
/**
|
||||
* Adds token of length @p len to @p pdu. Adding the token destroys
|
||||
* any following contents of the pdu. Hence options and data must be
|
||||
* added after coap_add_token2() has been called. In @p pdu, length is
|
||||
* set to @p len + @c 4, and max_delta is set to @c 0. This funtion
|
||||
* returns @c 0 on error or a value greater than zero on success.
|
||||
*
|
||||
* @param pdu The pdu pointer.
|
||||
* @param len The length of the new token.
|
||||
* @param data The token to add.
|
||||
* @param transport The transport type.
|
||||
* @return A value greater than zero on success, or @c 0 on error.
|
||||
*/
|
||||
int coap_add_token2(coap_pdu_t *pdu, size_t len, const unsigned char *data,
|
||||
coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Get token from coap header
|
||||
*
|
||||
* @param pdu_hdr The header pointer of PDU.
|
||||
* @param token out parameter to get token.
|
||||
* @param token_length out parameter to get token length.
|
||||
*/
|
||||
void coap_get_token(const coap_hdr_t *pdu_hdr,
|
||||
unsigned char **token, unsigned int *token_length);
|
||||
|
||||
/**
|
||||
* Get token from coap header based on transport type
|
||||
*
|
||||
* @param pdu_hdr The header pointer of PDU.
|
||||
* @param transport The transport type.
|
||||
* @param token out parameter to get token.
|
||||
* @param token_length out parameter to get token length.
|
||||
*/
|
||||
void coap_get_token2(const coap_hdr_transport_t *pdu_hdr, coap_transport_t transport,
|
||||
unsigned char **token, unsigned int *token_length);
|
||||
|
||||
/**
|
||||
* Adds option of given type to pdu that is passed as first parameter.
|
||||
* coap_add_option() destroys the PDU's data, so coap_add_data() must be called
|
||||
* after all options have been added. As coap_add_token() destroys the options
|
||||
* following the token, the token must be added before coap_add_option() is
|
||||
* called. This function returns the number of bytes written or @c 0 on error.
|
||||
*/
|
||||
size_t coap_add_option(coap_pdu_t *pdu,
|
||||
unsigned short type,
|
||||
unsigned int len,
|
||||
const unsigned char *data);
|
||||
|
||||
/**
|
||||
* Adds option of given type to pdu that is passed as first
|
||||
* parameter. coap_add_option2() destroys the PDU's data, so
|
||||
* coap_add_data() must be called after all options have been added.
|
||||
* As coap_add_token2() destroys the options following the token,
|
||||
* the token must be added before coap_add_option2() is called.
|
||||
* This function returns the number of bytes written or @c 0 on error.
|
||||
*/
|
||||
size_t coap_add_option2(coap_pdu_t *pdu, unsigned short type, unsigned int len,
|
||||
const unsigned char *data, coap_transport_t transport);
|
||||
|
||||
/**
|
||||
* Adds option of given type to pdu that is passed as first parameter, but does
|
||||
* not write a value. It works like coap_add_option with respect to calling
|
||||
* sequence (i.e. after token and before data). This function returns a memory
|
||||
* address to which the option data has to be written before the PDU can be
|
||||
* sent, or @c NULL on error.
|
||||
*/
|
||||
unsigned char *coap_add_option_later(coap_pdu_t *pdu,
|
||||
unsigned short type,
|
||||
unsigned int len);
|
||||
|
||||
/**
|
||||
* Adds given data to the pdu that is passed as first parameter. Note that the
|
||||
* PDU's data is destroyed by coap_add_option(). coap_add_data() must be called
|
||||
* only once per PDU, otherwise the result is undefined.
|
||||
*/
|
||||
int coap_add_data(coap_pdu_t *pdu,
|
||||
unsigned int len,
|
||||
const unsigned char *data);
|
||||
|
||||
/**
|
||||
* Retrieves the length and data pointer of specified PDU. Returns 0 on error or
|
||||
* 1 if *len and *data have correct values. Note that these values are destroyed
|
||||
* with the pdu.
|
||||
*/
|
||||
int coap_get_data(const coap_pdu_t *pdu,
|
||||
size_t *len,
|
||||
unsigned char **data);
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* _COAP_PDU_H_ */
|
||||
87
sdk/component/common/network/libcoap/include/coap/prng.h
Normal file
87
sdk/component/common/network/libcoap/include/coap/prng.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* prng.h -- Pseudo Random Numbers
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file prng.h
|
||||
* @brief Pseudo Random Numbers
|
||||
*/
|
||||
|
||||
#ifndef _COAP_PRNG_H_
|
||||
#define _COAP_PRNG_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
* @defgroup prng Pseudo Random Numbers
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef WITH_CONTIKI
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Fills \p buf with \p len random bytes. This is the default
|
||||
* implementation for prng(). You might want to change prng() to use
|
||||
* a better PRNG on your specific platform.
|
||||
*/
|
||||
INLINE_API int coap_prng_impl(unsigned char *buf, size_t len)
|
||||
{
|
||||
while (len--)
|
||||
*buf++ = rand() & 0xFF;
|
||||
return 1;
|
||||
}
|
||||
#else /* WITH_CONTIKI */
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Fills \p buf with \p len random bytes. This is the default
|
||||
* implementation for prng(). You might want to change prng() to use
|
||||
* a better PRNG on your specific platform.
|
||||
*/
|
||||
INLINE_API int
|
||||
contiki_prng_impl(unsigned char *buf, size_t len)
|
||||
{
|
||||
unsigned short v = random_rand();
|
||||
while (len > sizeof(v))
|
||||
{
|
||||
memcpy(buf, &v, sizeof(v));
|
||||
len -= sizeof(v);
|
||||
buf += sizeof(v);
|
||||
v = random_rand();
|
||||
}
|
||||
|
||||
memcpy(buf, &v, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define prng(Buf,Length) contiki_prng_impl((Buf), (Length))
|
||||
#define prng_init(Value) random_init((unsigned short)(Value))
|
||||
#endif /* WITH_CONTIKI */
|
||||
|
||||
#ifndef prng
|
||||
/**
|
||||
* Fills \p Buf with \p Length bytes of random data.
|
||||
*
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define prng(Buf,Length) coap_prng_impl((Buf), (Length))
|
||||
#endif
|
||||
|
||||
#ifndef prng_init
|
||||
/**
|
||||
* Called to set the PRNG seed. You may want to re-define this to
|
||||
* allow for a better PRNG.
|
||||
*
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define prng_init(Value) srand((unsigned long)(Value))
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _COAP_PRNG_H_ */
|
||||
318
sdk/component/common/network/libcoap/include/coap/resource.h
Normal file
318
sdk/component/common/network/libcoap/include/coap/resource.h
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
/* resource.h -- generic resource handling
|
||||
*
|
||||
* Copyright (C) 2010,2011,2014 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file resource.h
|
||||
* @brief generic resource handling
|
||||
*/
|
||||
|
||||
#ifndef _COAP_RESOURCE_H_
|
||||
#define _COAP_RESOURCE_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "t_list.h"
|
||||
|
||||
#if defined(HAVE_ASSERT_H) && !defined(assert)
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#ifndef COAP_RESOURCE_CHECK_TIME
|
||||
/** The interval in seconds to check if resources have changed. */
|
||||
#define COAP_RESOURCE_CHECK_TIME 2
|
||||
#endif /* COAP_RESOURCE_CHECK_TIME */
|
||||
|
||||
#ifndef WITH_CONTIKI
|
||||
# ifdef COAP_RESOURCES_NOHASH
|
||||
# include "utlist.h"
|
||||
# else
|
||||
# include "uthash.h"
|
||||
# endif
|
||||
#else /* WITH_CONTIKI */
|
||||
#endif /* WITH_CONTIKI */
|
||||
#include "hashkey.h"
|
||||
#include "async.h"
|
||||
#include "str.h"
|
||||
#include "pdu.h"
|
||||
#include "net.h"
|
||||
#include "subscribe.h"
|
||||
|
||||
/** Definition of message handler function (@sa coap_resource_t). */
|
||||
typedef void (*coap_method_handler_t)(coap_context_t *, struct coap_resource_t *, coap_address_t *,
|
||||
coap_pdu_t *, str * /* token */, coap_pdu_t * /* response */);
|
||||
|
||||
#define COAP_ATTR_FLAGS_RELEASE_NAME 0x1
|
||||
#define COAP_ATTR_FLAGS_RELEASE_VALUE 0x2
|
||||
|
||||
typedef struct coap_attr_t
|
||||
{
|
||||
struct coap_attr_t *next;
|
||||
str name;
|
||||
str value;
|
||||
int flags;
|
||||
} coap_attr_t;
|
||||
|
||||
#define COAP_RESOURCE_FLAGS_RELEASE_URI 0x1
|
||||
|
||||
typedef struct coap_resource_t
|
||||
{
|
||||
unsigned int dirty :1; /**< set to 1 if resource has changed */
|
||||
unsigned int partiallydirty :1; /**< set to 1 if some subscribers have not yet been notified of the last change */
|
||||
unsigned int observable :1; /**< can be observed */
|
||||
unsigned int cacheable :1; /**< can be cached */
|
||||
|
||||
/**
|
||||
* Used to store handlers for the four coap methods @c GET, @c POST,
|
||||
* @c PUT, and @c DELETE. coap_dispatch() will pass incoming
|
||||
* requests to the handler that corresponds to its request method or
|
||||
* generate a 4.05 response if no handler is available.
|
||||
*/
|
||||
coap_method_handler_t handler[4];
|
||||
|
||||
coap_key_t key; /**< the actual key bytes for this resource */
|
||||
|
||||
#ifndef WITH_CONTIKI
|
||||
#ifdef COAP_RESOURCES_NOHASH
|
||||
struct coap_resource_t *next;
|
||||
#else
|
||||
UT_hash_handle hh;
|
||||
#endif
|
||||
#endif /* WITH_CONTIKI */
|
||||
|
||||
#ifndef WITH_CONTIKI
|
||||
coap_attr_t *link_attr; /**< attributes to be included with the link format */
|
||||
#else /* WITH_CONTIKI */
|
||||
LIST_STRUCT(link_attr); /**< attributes to be included with the link format */
|
||||
#endif /* WITH_CONTIKI */
|
||||
LIST_STRUCT(subscribers); /**< list of observers for this resource */
|
||||
|
||||
/**
|
||||
* Request URI for this resource. This field will point into the
|
||||
* static memory. */
|
||||
str uri;
|
||||
int flags;
|
||||
|
||||
} coap_resource_t;
|
||||
|
||||
/**
|
||||
* Creates a new resource object and initializes the link field to the
|
||||
* string of length @p len. This function returns the
|
||||
* new coap_resource_t object.
|
||||
*
|
||||
* @param uri The URI path of the new resource.
|
||||
* @param len The length of @p uri.
|
||||
* @param flags Flags for memory management (in particular release of memory)
|
||||
*
|
||||
* @return A pointer to the new object or @c NULL on error.
|
||||
*/
|
||||
coap_resource_t *coap_resource_init(const unsigned char *uri, size_t len, int flags);
|
||||
|
||||
/**
|
||||
* Registers the given @p resource for @p context. The resource must
|
||||
* have been created by coap_resource_init(), the storage allocated
|
||||
* for the resource will be released by coap_delete_resource().
|
||||
*
|
||||
* @param context The context to use.
|
||||
* @param resource The resource to store.
|
||||
*/
|
||||
void coap_add_resource(coap_context_t *context, coap_resource_t *resource);
|
||||
|
||||
/**
|
||||
* Deletes a resource identified by @p key. The storage allocated for
|
||||
* that resource is freed.
|
||||
*
|
||||
* @param context The context where the resources are stored.
|
||||
* @param key The unique key for the resource to delete.
|
||||
*
|
||||
* @return @c 1 if the resource was found (and destroyed), @c 0 otherwise.
|
||||
*/
|
||||
int coap_delete_resource(coap_context_t *context, coap_key_t key);
|
||||
|
||||
/**
|
||||
* Registers a new attribute with the given @p resource. As the
|
||||
* attributes str fields will point to @p name and @p val the
|
||||
* caller must ensure that these pointers are valid during the
|
||||
* attribute's lifetime.
|
||||
*
|
||||
* @param resource The resource to register the attribute with.
|
||||
* @param name The attribute's name.
|
||||
* @param nlen Length of @p name.
|
||||
* @param val The attribute's value or @c NULL if none.
|
||||
* @param vlen Length of @p val if specified.
|
||||
* @param flags Flags for memory management (in particular release of memory)
|
||||
*
|
||||
* @return A pointer to the new attribute or @c NULL on error.
|
||||
*/
|
||||
coap_attr_t *coap_add_attr(coap_resource_t *resource, const unsigned char *name, size_t nlen,
|
||||
const unsigned char *val, size_t vlen, int flags);
|
||||
|
||||
/**
|
||||
* Returns @p resource's coap_attr_t object with given @p name if
|
||||
* found, @c NULL otherwise.
|
||||
*
|
||||
* @param resource The resource to search for attribute @p name.
|
||||
* @param name Name of the requested attribute.
|
||||
* @param nlen Actual length of @p name.
|
||||
* @return The first attribute with specified @p name or @c NULL if
|
||||
* none was found.
|
||||
*/
|
||||
coap_attr_t *coap_find_attr(coap_resource_t *resource, const unsigned char *name, size_t nlen);
|
||||
|
||||
/**
|
||||
* Deletes an attribute
|
||||
*
|
||||
* @param attr Pointer to a previously created attribute
|
||||
*
|
||||
*/
|
||||
void coap_delete_attr(coap_attr_t *attr);
|
||||
|
||||
/**
|
||||
* Status word to encode the result of conditional print or copy
|
||||
* operations such as coap_print_link(). The lower 28 bits of
|
||||
* coap_print_status_t are used to encode the number of characters
|
||||
* that has actually been printed, bits 28 to 31 encode the status.
|
||||
* When COAP_PRINT_STATUS_ERROR is set, an error occurred during
|
||||
* output. In this case, the other bits are undefined.
|
||||
* COAP_PRINT_STATUS_TRUNC indicates that the output is truncated,
|
||||
* i.e. the printing would have exceeded the current buffer.
|
||||
*/
|
||||
typedef unsigned int coap_print_status_t;
|
||||
|
||||
#define COAP_PRINT_STATUS_MASK 0xF0000000u
|
||||
#define COAP_PRINT_OUTPUT_LENGTH(v) ((v) & ~COAP_PRINT_STATUS_MASK)
|
||||
#define COAP_PRINT_STATUS_ERROR 0x80000000u
|
||||
#define COAP_PRINT_STATUS_TRUNC 0x40000000u
|
||||
|
||||
/**
|
||||
* Writes a description of this resource in link-format to given text
|
||||
* buffer. @p len must be initialized to the maximum length of @p buf
|
||||
* and will be set to the number of characters actually written if
|
||||
* successful. This function returns @c 1 on success or @c 0 on
|
||||
* error.
|
||||
*
|
||||
* @param resource The resource to describe.
|
||||
* @param buf The output buffer to write the description to.
|
||||
* @param len Must be initialized to the length of @p buf and
|
||||
* will be set to the length of the printed link description.
|
||||
* @param offset The offset within the resource description where to
|
||||
* start writing into @p buf. This is useful for dealing
|
||||
* with the Block2 option. @p offset is updated during
|
||||
* output as it is consumed.
|
||||
*
|
||||
* @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise,
|
||||
* the lower 28 bits will indicate the number of characters that
|
||||
* have actually been output into @p buffer. The flag
|
||||
* COAP_PRINT_STATUS_TRUNC indicates that the output has been
|
||||
* truncated.
|
||||
*/
|
||||
coap_print_status_t coap_print_link(const coap_resource_t *resource, unsigned char *buf,
|
||||
size_t *len, size_t *offset);
|
||||
|
||||
/**
|
||||
* Registers the specified @p handler as message handler for the request type
|
||||
* @p method
|
||||
*
|
||||
* @param resource The resource for which the handler shall be registered.
|
||||
* @param method The CoAP request method to handle.
|
||||
* @param handler The handler to register with @p resource.
|
||||
*/
|
||||
INLINE_API void coap_register_handler(coap_resource_t *resource, unsigned char method,
|
||||
coap_method_handler_t handler)
|
||||
{
|
||||
assert(resource);
|
||||
assert(
|
||||
method > 0
|
||||
&& (size_t)(method - 1)
|
||||
< sizeof(resource->handler) / sizeof(coap_method_handler_t));
|
||||
resource->handler[method - 1] = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource identified by the unique string @p key. If no
|
||||
* resource was found, this function returns @c NULL.
|
||||
*
|
||||
* @param context The context to look for this resource.
|
||||
* @param key The unique key of the resource.
|
||||
*
|
||||
* @return A pointer to the resource or @c NULL if not found.
|
||||
*/
|
||||
coap_resource_t *coap_get_resource_from_key(coap_context_t *context, coap_key_t key);
|
||||
|
||||
/**
|
||||
* Calculates the hash key for the resource requested by the
|
||||
* Uri-Options of @p request. This function calls coap_hash() for
|
||||
* every path segment.
|
||||
*
|
||||
* @param request The requesting pdu.
|
||||
* @param key The resulting hash is stored in @p key
|
||||
*/
|
||||
void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key);
|
||||
|
||||
/**
|
||||
* @addtogroup observe
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds the specified peer as observer for @p resource. The
|
||||
* subscription is identified by the given @p token. This function
|
||||
* returns the registered subscription information if the @p observer
|
||||
* has been added, or @c NULL on error.
|
||||
*
|
||||
* @param resource The observed resource.
|
||||
* @param observer The remote peer that wants to received status updates.
|
||||
* @param token The token that identifies this subscription.
|
||||
* @param token_length The actual length of @p token. Must be @c 0 when
|
||||
* @p token is @c NULL.
|
||||
* @return A pointer to the added/updated subscription information or
|
||||
* @c NULL on error.
|
||||
*/
|
||||
coap_subscription_t *coap_add_observer(coap_resource_t *resource, const coap_address_t *observer,
|
||||
const str *token);
|
||||
|
||||
/**
|
||||
* Returns a subscription object for given @p peer.
|
||||
*
|
||||
* @param resource The observed resource.
|
||||
* @param peer The address to search for.
|
||||
* @param token The token that identifies this subscription or @c NULL for any
|
||||
* token.
|
||||
* @return A valid subscription if exists or @c NULL otherwise.
|
||||
*/
|
||||
coap_subscription_t *coap_find_observer(coap_resource_t *resource, const coap_address_t *peer,
|
||||
const str *token);
|
||||
|
||||
/**
|
||||
* Marks an observer as alive.
|
||||
*
|
||||
* @param context The CoAP context to use
|
||||
* @param observer The transport address of the observer
|
||||
* @param token The corresponding token that has been used for
|
||||
* the subscription
|
||||
*/
|
||||
void coap_touch_observer(coap_context_t *context, const coap_address_t *observer, const str *token);
|
||||
|
||||
/**
|
||||
* Removes any subscription for @p observer from @p resource and releases
|
||||
* the allocated storage.
|
||||
*
|
||||
* @param resource The observed resource.
|
||||
* @param observer The observer's address.
|
||||
* @param token The token that identifies this subscription or @c NULL for any
|
||||
* token.
|
||||
*/
|
||||
void coap_delete_observer(coap_resource_t *resource, const coap_address_t *observer,
|
||||
const str *token);
|
||||
|
||||
/**
|
||||
* Checks for all known resources, if they are dirty and notifies
|
||||
* subscribed observers.
|
||||
*/
|
||||
void coap_check_notify(coap_context_t *context);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _COAP_RESOURCE_H_ */
|
||||
31
sdk/component/common/network/libcoap/include/coap/str.h
Normal file
31
sdk/component/common/network/libcoap/include/coap/str.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* str.h -- strings to be used in the CoAP library
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_STR_H_
|
||||
#define _COAP_STR_H_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t length; /* length of string */
|
||||
unsigned char *s; /* string data */
|
||||
} str;
|
||||
|
||||
#define COAP_SET_STR(st,l,v) { (st)->length = (l), (st)->s = (v); }
|
||||
|
||||
/**
|
||||
* Returns a new string object with at least size bytes storage
|
||||
* allocated. The string must be released using coap_delete_string();
|
||||
*/
|
||||
str *coap_new_string(size_t size);
|
||||
|
||||
/** Deletes the given string and releases any memory allocated. */
|
||||
void coap_delete_string(str *);
|
||||
|
||||
#endif /* _COAP_STR_H_ */
|
||||
201
sdk/component/common/network/libcoap/include/coap/subscribe.h
Normal file
201
sdk/component/common/network/libcoap/include/coap/subscribe.h
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/* subscribe.h -- subscription handling for CoAP
|
||||
* see draft-hartke-coap-observe-03
|
||||
*
|
||||
* Copyright (C) 2010--2012 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_SUBSCRIBE_H_
|
||||
#define _COAP_SUBSCRIBE_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "address.h"
|
||||
|
||||
/**
|
||||
* @defgroup observe Resource observation
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_OBS_MAX_NON
|
||||
/**
|
||||
* Number of notifications that may be sent non-confirmable before a
|
||||
* confirmable message is sent to detect if observers are alive. The
|
||||
* maximum allowed value here is @c 15.
|
||||
*/
|
||||
#define COAP_OBS_MAX_NON 5
|
||||
#endif /* COAP_OBS_MAX_NON */
|
||||
|
||||
#ifndef COAP_OBS_MAX_FAIL
|
||||
/**
|
||||
* Number of confirmable notifications that may fail (i.e. time out
|
||||
* without being ACKed) before an observer is removed. The maximum
|
||||
* value for COAP_OBS_MAX_FAIL is @c 3.
|
||||
*/
|
||||
#define COAP_OBS_MAX_FAIL 3
|
||||
#endif /* COAP_OBS_MAX_FAIL */
|
||||
|
||||
/** Subscriber information */
|
||||
typedef struct coap_subscription_t
|
||||
{
|
||||
struct coap_subscription_t *next; /**< next element in linked list */
|
||||
coap_address_t subscriber; /**< address and port of subscriber */
|
||||
|
||||
unsigned int non :1; /**< send non-confirmable notifies if @c 1 */
|
||||
unsigned int non_cnt :4; /**< up to 15 non-confirmable notifies allowed */
|
||||
unsigned int fail_cnt :2; /**< up to 3 confirmable notifies can fail */
|
||||
unsigned int dirty :1; /**< set if the notification temporarily could not be sent (in that case, the resource's partiallydirty flag is set too) */
|
||||
|
||||
size_t token_length; /**< actual length of token */
|
||||
unsigned char token[8]; /**< token used for subscription */
|
||||
/* @todo CON/NON flag, block size */
|
||||
} coap_subscription_t;
|
||||
|
||||
void coap_subscription_init(coap_subscription_t *);
|
||||
|
||||
#if 0
|
||||
#include "uthash.h"
|
||||
#include "uri.h"
|
||||
#include "list.h"
|
||||
#include "pdu.h"
|
||||
#include "net.h"
|
||||
|
||||
#if 0
|
||||
typedef unsigned long coap_key_t;
|
||||
|
||||
/** Used to indicate that a hashkey is invalid. */
|
||||
#define COAP_INVALID_HASHKEY ((coap_key_t)-1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
coap_uri_t *uri; /* unique identifier; memory is released by coap_delete_resource() */
|
||||
UT_hash_handle hh; /**< hash handle (for internal use only) */
|
||||
str *name; /* display name of the resource */
|
||||
unsigned char mediatype; /* media type for resource representation */
|
||||
unsigned int dirty:1; /* set to 1 if resource has changed */
|
||||
unsigned int writable:1; /* set to 1 if resource can be changed using PUT */
|
||||
|
||||
/* cache-control */
|
||||
unsigned char etag[4]; /* version identifier for this resource
|
||||
* (zero terminated, first byte is zero if not set). */
|
||||
unsigned int maxage; /* maximum cache time (zero means no Max-age option) */
|
||||
|
||||
/**
|
||||
* Callback function that copies the resource representation into the provided data
|
||||
* buffer (PDU payload). finished is set to 1 to indicate that this was the last block
|
||||
* of buflen data for this resource representation, 0 means that data is not finished
|
||||
* and a subsequent call with offset updated by buflen would yield more data (i.e.
|
||||
* the M-bit of CoAP's block option must be set if offset and buflen are selected
|
||||
* accordingly.
|
||||
* When called, buflen must be set to the maximum length of buf that is to be filled
|
||||
* with the mediatype representation of the resource identified by uri.
|
||||
* The mediatype must be set to the requested mediatype of COAP_MEDIATYPE_ANY if
|
||||
* none was given. On return, the mediatype will be set to the type that is
|
||||
* actually used.
|
||||
* The return value indicates the result code that should be used in a response to
|
||||
* this function.
|
||||
*/
|
||||
int (*data)(coap_uri_t *uri, unsigned char *mediatype, unsigned int offset, unsigned char *buf, unsigned int *buflen, int *finished);
|
||||
}coap_resource_t;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
coap_key_t resource; /* hash key for subscribed resource */
|
||||
time_t expires; /* expiry time of subscription */
|
||||
|
||||
coap_address_t subscriber; /**< subscriber's address */
|
||||
|
||||
str token; /**< subscription token */
|
||||
}coap_subscription_t;
|
||||
|
||||
#define COAP_RESOURCE(node) ((coap_resource_t *)(node)->data)
|
||||
#define COAP_SUBSCRIPTION(node) ((coap_subscription_t *)(node)->data)
|
||||
|
||||
/** Checks subscribed resources for updates and notifies subscribers of changes. */
|
||||
void coap_check_resource_list(coap_context_t *context);
|
||||
|
||||
/** Removes expired subscriptions. */
|
||||
void coap_check_subscriptions(coap_context_t *context);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Adds specified resource to the resource observation list. Returns a
|
||||
* unique key for the resource. The alloceted memory is released when
|
||||
* the resource is destroyed with coap_delete_resource().
|
||||
*/
|
||||
coap_key_t coap_add_resource(coap_context_t *context, coap_resource_t *);
|
||||
|
||||
/**
|
||||
* Deletes the resource that is identified by key. Returns 1 if the resource was
|
||||
* removed, 0 on error (e.g. if no such resource exists).
|
||||
*/
|
||||
int coap_delete_resource(coap_context_t *context, coap_key_t key);
|
||||
#endif
|
||||
/**
|
||||
* Creates a new subscription object filled with the given data. The storage
|
||||
* allocated for this object must be released using coap_free(). */
|
||||
coap_subscription_t *coap_new_subscription(coap_context_t *context,
|
||||
const coap_uri_t *resource,
|
||||
const struct sockaddr *subscriber,
|
||||
socklen_t addrlen,
|
||||
time_t expiry);
|
||||
|
||||
/**
|
||||
* Adds the given subsription object to the observer list.
|
||||
* @param context The CoAP context
|
||||
* @param subscription A new subscription oobject created with coap_new_subscription()
|
||||
* @return A unique hash key for this resource or COAP_INVALID_HASHKEY on error.
|
||||
* The storage allocated for the subscription object is released when it is
|
||||
* removed from the subscription list, unless the function has returned
|
||||
* COAP_INVALID_HASHKEY. In this case, the storage must be released by the
|
||||
* caller of this function.
|
||||
*/
|
||||
coap_key_t coap_add_subscription(coap_context_t *context,
|
||||
coap_subscription_t *subscription);
|
||||
|
||||
/**
|
||||
* Returns the subscription from subscriber for the resource identified
|
||||
* by hashkey. When token is not NULL the subscription must have the
|
||||
* same token.
|
||||
* @param context The CoAP context
|
||||
* @param hashkey The unique key that identifies the subscription
|
||||
* @param subscriber The subscriber's transport address
|
||||
* @param token If not NULL, this specifies a token given by the
|
||||
* subscriber to identify its subscription.
|
||||
* @return The requested subscription object or NULL when not found.
|
||||
*/
|
||||
coap_subscription_t * coap_find_subscription(coap_context_t *context,
|
||||
coap_key_t hashkey,
|
||||
struct sockaddr *subscriber,
|
||||
str *token);
|
||||
/**
|
||||
* Removes a subscription from the subscription list stored in context and
|
||||
* releases the storage that was allocated for this subscription.
|
||||
* @param context The CoAP context.
|
||||
* @param haskey The unique key that identifies the subscription to remove.
|
||||
* @return 1 if a subscription was removed, 0 otherwise.
|
||||
*/
|
||||
int coap_delete_subscription(coap_context_t *context,
|
||||
coap_key_t hashkey,
|
||||
struct sockaddr *subscriber);
|
||||
|
||||
/** Returns a unique hash for the specified URI or COAP_INVALID_HASHKEY on error. */
|
||||
coap_key_t coap_uri_hash(const coap_uri_t *uri);
|
||||
|
||||
/** Returns a unique hash for the specified subscription or COAP_INVALID_HASHKEY on error. */
|
||||
coap_key_t coap_subscription_hash(coap_subscription_t *subscription);
|
||||
#if 0
|
||||
/** Returns the resource identified by key or NULL if not found. */
|
||||
coap_resource_t *coap_get_resource_from_key(coap_context_t *ctx, coap_key_t key);
|
||||
|
||||
/** Returns the resource identified by uri or NULL if not found. */
|
||||
coap_resource_t *coap_get_resource(coap_context_t *ctx, coap_uri_t *uri);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _COAP_SUBSCRIBE_H_ */
|
||||
156
sdk/component/common/network/libcoap/include/coap/t_list.h
Normal file
156
sdk/component/common/network/libcoap/include/coap/t_list.h
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/* t_list -- tinydtls lists
|
||||
*
|
||||
* Copyright (C) 2012 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file t_list.h
|
||||
* @brief Wrappers for list structures and functions
|
||||
*/
|
||||
|
||||
#ifndef _DTLS_LIST_H_
|
||||
#define _DTLS_LIST_H_
|
||||
|
||||
#ifndef WITH_CONTIKI
|
||||
#include "uthash.h"
|
||||
#include "utlist.h"
|
||||
|
||||
/* We define list structures and utility functions to be compatible
|
||||
* with Contiki list structures. The Contiki list API is part of the
|
||||
* Contiki operating system, and therefore the following licensing
|
||||
* terms apply (taken from contiki/core/lib/list.h):
|
||||
*
|
||||
* Copyright (c) 2004, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
* $ Id: list.h,v 1.5 2010/09/13 13:31:00 adamdunkels Exp $
|
||||
*/
|
||||
|
||||
typedef void **list_t;
|
||||
struct list
|
||||
{
|
||||
struct list *next;
|
||||
};
|
||||
|
||||
#define LIST_CONCAT(s1, s2) s1##s2
|
||||
|
||||
#define LIST_STRUCT(name) \
|
||||
void *LIST_CONCAT(name, _list); \
|
||||
list_t name
|
||||
|
||||
#define LIST_STRUCT_INIT(struct_ptr, name) { \
|
||||
(struct_ptr)->name = &((struct_ptr)->LIST_CONCAT(name,_list)); \
|
||||
(struct_ptr)->LIST_CONCAT(name,_list) = NULL; \
|
||||
}
|
||||
|
||||
INLINE_API void *
|
||||
list_head(list_t the_list)
|
||||
{
|
||||
return *the_list;
|
||||
}
|
||||
|
||||
INLINE_API void list_remove(list_t the_list, void *item)
|
||||
{
|
||||
if (list_head(the_list))
|
||||
LL_DELETE(*(struct list **)the_list, (struct list *)item);
|
||||
}
|
||||
|
||||
#if !AMEBA
|
||||
INLINE_API void list_add(list_t the_list, void *item)
|
||||
#else
|
||||
INLINE_API void coap_list_add(list_t the_list, void *item)
|
||||
#endif
|
||||
{
|
||||
list_remove(the_list, item);
|
||||
LL_APPEND(*(struct list **)the_list, (struct list *)item);
|
||||
}
|
||||
|
||||
INLINE_API void list_push(list_t the_list, void *item)
|
||||
{
|
||||
LL_PREPEND(*(struct list **)the_list, (struct list *)item);
|
||||
}
|
||||
|
||||
INLINE_API void *
|
||||
list_pop(list_t the_list)
|
||||
{
|
||||
struct list *l;
|
||||
l = (struct list*) *the_list;
|
||||
if (l)
|
||||
list_remove(the_list, l);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
INLINE_API void list_insert(list_t the_list, void *previtem, void *newitem)
|
||||
{
|
||||
if (previtem == NULL)
|
||||
{
|
||||
list_push(the_list, newitem);
|
||||
}
|
||||
else
|
||||
{
|
||||
((struct list *) newitem)->next = ((struct list *) previtem)->next;
|
||||
((struct list *) previtem)->next = (struct list*) newitem;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE_API void *
|
||||
list_item_next(void *item)
|
||||
{
|
||||
return item == NULL ? NULL : ((struct list *) item)->next;
|
||||
}
|
||||
|
||||
#else /* WITH_CONTIKI */
|
||||
#include "list.h"
|
||||
#endif /* WITH_CONTIKI */
|
||||
|
||||
#endif /* _DTLS_LIST_H_ */
|
||||
|
||||
174
sdk/component/common/network/libcoap/include/coap/uri.h
Normal file
174
sdk/component/common/network/libcoap/include/coap/uri.h
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/* uri.h -- helper functions for URI treatment
|
||||
*
|
||||
* Copyright (C) 2010,2011 Olaf Bergmann <bergmann@tzi.org>
|
||||
*
|
||||
* This file is part of the CoAP library libcoap. Please see
|
||||
* README for terms of use.
|
||||
*/
|
||||
|
||||
#ifndef _COAP_URI_H_
|
||||
#define _COAP_URI_H_
|
||||
|
||||
#include "hashkey.h"
|
||||
#include "str.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
///Separtor for multiple query string
|
||||
#define OC_QUERY_SEPARATOR "&;"
|
||||
|
||||
/** Representation of parsed URI. Components may be filled from a
|
||||
* string with coap_split_uri() and can be used as input for
|
||||
* option-creation functions. */
|
||||
typedef struct
|
||||
{
|
||||
str host; /**< host part of the URI */
|
||||
unsigned short port; /**< The port in host byte order */
|
||||
str path; /**< Beginning of the first path segment.
|
||||
Use coap_split_path() to create Uri-Path options */
|
||||
str query; /**< The query part if present */
|
||||
} coap_uri_t;
|
||||
|
||||
/**
|
||||
* Creates a new coap_uri_t object from the specified URI. Returns the new
|
||||
* object or NULL on error. The memory allocated by the new coap_uri_t
|
||||
* must be released using coap_free().
|
||||
* @param uri The URI path to copy.
|
||||
* @para length The length of uri.
|
||||
*
|
||||
* @return New URI object or NULL on error.
|
||||
*/
|
||||
coap_uri_t *coap_new_uri(const unsigned char *uri, unsigned int length);
|
||||
|
||||
/**
|
||||
* Clones the specified coap_uri_t object. Thie function allocates sufficient
|
||||
* memory to hold the coap_uri_t structure and its contents. The object must
|
||||
* be released with coap_free(). */
|
||||
coap_uri_t *coap_clone_uri(const coap_uri_t *uri);
|
||||
|
||||
/**
|
||||
* Calculates a hash over the given path and stores the result in
|
||||
* @p key. This function returns @c 0 on error or @c 1 on success.
|
||||
*
|
||||
* @param path The URI path to generate hash for.
|
||||
* @param len The length of @p path.
|
||||
* @param key The output buffer.
|
||||
*
|
||||
* @return @c 1 if @p key was set, @c 0 otherwise.
|
||||
*/
|
||||
int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key);
|
||||
|
||||
/**
|
||||
* @defgroup uri_parse URI Parsing Functions
|
||||
*
|
||||
* CoAP PDUs contain normalized URIs with their path and query split into
|
||||
* multiple segments. The functions in this module help splitting strings.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Iterator to for tokenizing a URI path or query. This structure must
|
||||
* be initialized with coap_parse_iterator_init(). Call
|
||||
* coap_parse_next() to walk through the tokens.
|
||||
*
|
||||
* @code
|
||||
* unsigned char *token;
|
||||
* coap_parse_iterator_t pi;
|
||||
* coap_parse_iterator_init(uri.path.s, uri.path.length, "/", "?#", 2, &pi);
|
||||
*
|
||||
* while ((token = coap_parse_next(&pi))) {
|
||||
* ... do something with token ...
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
size_t n; /**< number of remaining characters in buffer */
|
||||
unsigned char *separator; /**< segment separators */
|
||||
unsigned char *delim; /**< delimiters where to split the string */
|
||||
size_t dlen; /**< length of separator */
|
||||
unsigned char *pos; /**< current position in buffer */
|
||||
size_t segment_length; /**< length of current segment */
|
||||
} coap_parse_iterator_t;
|
||||
|
||||
/**
|
||||
* Initializes the given iterator @p pi.
|
||||
*
|
||||
* @param s The string to tokenize.
|
||||
* @param n The length of @p s.
|
||||
* @param separator The separator character that delimits tokens.
|
||||
* @param delim A set of characters that delimit @s.
|
||||
* @param dlen The length of @p delim.
|
||||
* @param pi The iterator object to initialize.
|
||||
*
|
||||
* @return The initialized iterator object @p pi.
|
||||
*/
|
||||
coap_parse_iterator_t *
|
||||
coap_parse_iterator_init(unsigned char *s, size_t n, unsigned char *separator, unsigned char *delim,
|
||||
size_t dlen, coap_parse_iterator_t *pi);
|
||||
|
||||
/**
|
||||
* Updates the iterator @p pi to point to the next token. This
|
||||
* function returns a pointer to that token or @c NULL if no more
|
||||
* tokens exist. The contents of @p pi will be updated. In particular,
|
||||
* @c pi->segment_length specifies the length of the current token, @c
|
||||
* pi->pos points to its beginning.
|
||||
*
|
||||
* @param pi The iterator to update.
|
||||
*
|
||||
* @return The next token or @c NULL if no more tokens exist.
|
||||
*/
|
||||
unsigned char *coap_parse_next(coap_parse_iterator_t *pi);
|
||||
|
||||
/**
|
||||
* Parses a given string into URI components. The identified syntactic
|
||||
* components are stored in the result parameter @p uri. Optional URI
|
||||
* components that are not specified will be set to { 0, 0 }, except
|
||||
* for the port which is set to @c COAP_DEFAULT_PORT. This function
|
||||
* returns @p 0 if parsing succeeded, a value less than zero
|
||||
* otherwise.
|
||||
*
|
||||
* @param str_var The string to split up.
|
||||
* @param len The actual length of @p str_var
|
||||
* @param uri The coap_uri_t object to store the result.
|
||||
* @return @c 0 on success, or < 0 on error.
|
||||
*
|
||||
* @note The host name part will be converted to lower case by this
|
||||
* function.
|
||||
*/
|
||||
int
|
||||
coap_split_uri(unsigned char *str_var, size_t len, coap_uri_t *uri);
|
||||
|
||||
/**
|
||||
* Splits the given URI path into segments. Each segment is preceded
|
||||
* by an option pseudo-header with delta-value 0 and the actual length
|
||||
* of the respective segment after percent-decoding.
|
||||
*
|
||||
* @param s The path string to split.
|
||||
* @param length The actual length of @p s.
|
||||
* @param buf Result buffer for parsed segments.
|
||||
* @param buflen Maximum length of @p buf. Will be set to the actual number
|
||||
* of bytes written into buf on success.
|
||||
*
|
||||
* @return The number of segments created or @c -1 on error.
|
||||
*/
|
||||
int coap_split_path(const unsigned char *s, size_t length, unsigned char *buf, size_t *buflen);
|
||||
|
||||
/**
|
||||
* Splits the given URI query into segments. Each segment is preceded
|
||||
* by an option pseudo-header with delta-value 0 and the actual length
|
||||
* of the respective query term.
|
||||
*
|
||||
* @param s The query string to split.
|
||||
* @param length The actual length of @p s.
|
||||
* @param buf Result buffer for parsed segments.
|
||||
* @param buflen Maximum length of @p buf. Will be set to the actual number
|
||||
* of bytes written into buf on success.
|
||||
*
|
||||
* @return The number of segments created or @c -1 on error.
|
||||
*
|
||||
* @bug This function does not reserve additional space for delta > 12.
|
||||
*/
|
||||
int coap_split_query(const unsigned char *s, size_t length, unsigned char *buf, size_t *buflen);
|
||||
|
||||
/** @} */
|
||||
#endif /* _COAP_URI_H_ */
|
||||
974
sdk/component/common/network/libcoap/include/coap/uthash.h
Normal file
974
sdk/component/common/network/libcoap/include/coap/uthash.h
Normal file
|
|
@ -0,0 +1,974 @@
|
|||
/*
|
||||
Copyright (c) 2003-2010, Troy D. Hanson http://uthash.sourceforge.net
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef UTHASH_H
|
||||
#define UTHASH_H
|
||||
|
||||
#include <string.h> /* memcmp,strlen */
|
||||
#include <stddef.h> /* ptrdiff_t */
|
||||
|
||||
/* These macros use decltype or the earlier __typeof GNU extension.
|
||||
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
|
||||
when compiling c++ source) this code uses whatever method is needed
|
||||
or, for VS2008 where neither is available, uses casting workarounds. */
|
||||
#ifdef _MSC_VER /* MS compiler */
|
||||
#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
|
||||
#define DECLTYPE(x) (decltype(x))
|
||||
#else /* VS2008 or older (or VS2010 in C mode) */
|
||||
#define NO_DECLTYPE
|
||||
#define DECLTYPE(x)
|
||||
#endif
|
||||
#else /* GNU, Sun and other compilers */
|
||||
#define DECLTYPE(x) (__typeof(x))
|
||||
#endif
|
||||
|
||||
#ifdef NO_DECLTYPE
|
||||
#define DECLTYPE_ASSIGN(dst,src) \
|
||||
do { \
|
||||
char **_da_dst = (char**)(&(dst)); \
|
||||
*_da_dst = (char*)(src); \
|
||||
} while(0)
|
||||
#else
|
||||
#define DECLTYPE_ASSIGN(dst,src) \
|
||||
do { \
|
||||
(dst) = DECLTYPE(dst)(src); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/* a number of the hash function use uint32_t which isn't defined on win32 */
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
#include <inttypes.h> /* uint32_t */
|
||||
#endif
|
||||
|
||||
#define UTHASH_VERSION 1.9.3
|
||||
|
||||
#ifndef uthash_fatal
|
||||
#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
|
||||
#endif
|
||||
#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
|
||||
#define uthash_free(ptr,sz) free(ptr) /* free fcn */
|
||||
|
||||
#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
|
||||
#define uthash_expand_fyi(tbl) /* can be defined to log expands */
|
||||
|
||||
/* initial number of buckets */
|
||||
#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
|
||||
#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
|
||||
#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
|
||||
|
||||
/* calculate the element whose hash handle address is hhe */
|
||||
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
|
||||
|
||||
#define HASH_FIND(hh,head,keyptr,keylen,out) \
|
||||
do { \
|
||||
unsigned _hf_bkt,_hf_hashv; \
|
||||
out=NULL; \
|
||||
if (head) { \
|
||||
HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
|
||||
if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
|
||||
HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
|
||||
keyptr,keylen,out); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef HASH_BLOOM
|
||||
#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
|
||||
#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
|
||||
#define HASH_BLOOM_MAKE(tbl) \
|
||||
do { \
|
||||
(tbl)->bloom_nbits = HASH_BLOOM; \
|
||||
(tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
|
||||
if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
|
||||
memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
|
||||
(tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
|
||||
} while (0);
|
||||
|
||||
#define HASH_BLOOM_FREE(tbl) \
|
||||
do { \
|
||||
uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \
|
||||
} while (0);
|
||||
|
||||
#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
|
||||
#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
|
||||
|
||||
#define HASH_BLOOM_ADD(tbl,hashv) \
|
||||
HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
|
||||
|
||||
#define HASH_BLOOM_TEST(tbl,hashv) \
|
||||
HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
|
||||
|
||||
#else
|
||||
#define HASH_BLOOM_MAKE(tbl)
|
||||
#define HASH_BLOOM_FREE(tbl)
|
||||
#define HASH_BLOOM_ADD(tbl,hashv)
|
||||
#define HASH_BLOOM_TEST(tbl,hashv) (1)
|
||||
#endif
|
||||
|
||||
#define HASH_MAKE_TABLE(hh,head) \
|
||||
do { \
|
||||
(head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
|
||||
sizeof(UT_hash_table)); \
|
||||
if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
|
||||
memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
|
||||
(head)->hh.tbl->tail = &((head)->hh); \
|
||||
(head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
|
||||
(head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
|
||||
(head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
|
||||
(head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
|
||||
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
|
||||
if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
|
||||
memset((head)->hh.tbl->buckets, 0, \
|
||||
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
|
||||
HASH_BLOOM_MAKE((head)->hh.tbl); \
|
||||
(head)->hh.tbl->signature = HASH_SIGNATURE; \
|
||||
} while(0)
|
||||
|
||||
#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
|
||||
HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add)
|
||||
|
||||
#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
|
||||
do { \
|
||||
unsigned _ha_bkt; \
|
||||
(add)->hh.next = NULL; \
|
||||
(add)->hh.key = (char*)keyptr; \
|
||||
(add)->hh.keylen = keylen_in; \
|
||||
if (!(head)) { \
|
||||
head = (add); \
|
||||
(head)->hh.prev = NULL; \
|
||||
HASH_MAKE_TABLE(hh,head); \
|
||||
} else { \
|
||||
(head)->hh.tbl->tail->next = (add); \
|
||||
(add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
|
||||
(head)->hh.tbl->tail = &((add)->hh); \
|
||||
} \
|
||||
(head)->hh.tbl->num_items++; \
|
||||
(add)->hh.tbl = (head)->hh.tbl; \
|
||||
HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
|
||||
(add)->hh.hashv, _ha_bkt); \
|
||||
HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
|
||||
HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
|
||||
HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
|
||||
HASH_FSCK(hh,head); \
|
||||
} while(0)
|
||||
|
||||
#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
|
||||
do { \
|
||||
bkt = ((hashv) & ((num_bkts) - 1)); \
|
||||
} while(0)
|
||||
|
||||
/* delete "delptr" from the hash table.
|
||||
* "the usual" patch-up process for the app-order doubly-linked-list.
|
||||
* The use of _hd_hh_del below deserves special explanation.
|
||||
* These used to be expressed using (delptr) but that led to a bug
|
||||
* if someone used the same symbol for the head and deletee, like
|
||||
* HASH_DELETE(hh,users,users);
|
||||
* We want that to work, but by changing the head (users) below
|
||||
* we were forfeiting our ability to further refer to the deletee (users)
|
||||
* in the patch-up process. Solution: use scratch space to
|
||||
* copy the deletee pointer, then the latter references are via that
|
||||
* scratch pointer rather than through the repointed (users) symbol.
|
||||
*/
|
||||
#define HASH_DELETE(hh,head,delptr) \
|
||||
do { \
|
||||
unsigned _hd_bkt; \
|
||||
struct UT_hash_handle *_hd_hh_del; \
|
||||
if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
|
||||
uthash_free((head)->hh.tbl->buckets, \
|
||||
(head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
|
||||
HASH_BLOOM_FREE((head)->hh.tbl); \
|
||||
uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
|
||||
head = NULL; \
|
||||
} else { \
|
||||
_hd_hh_del = &((delptr)->hh); \
|
||||
if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
|
||||
(head)->hh.tbl->tail = \
|
||||
(UT_hash_handle*)((char*)((delptr)->hh.prev) + \
|
||||
(head)->hh.tbl->hho); \
|
||||
} \
|
||||
if ((delptr)->hh.prev) { \
|
||||
((UT_hash_handle*)((char*)((delptr)->hh.prev) + \
|
||||
(head)->hh.tbl->hho))->next = (delptr)->hh.next; \
|
||||
} else { \
|
||||
DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
|
||||
} \
|
||||
if (_hd_hh_del->next) { \
|
||||
((UT_hash_handle*)((char*)_hd_hh_del->next + \
|
||||
(head)->hh.tbl->hho))->prev = \
|
||||
_hd_hh_del->prev; \
|
||||
} \
|
||||
HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
|
||||
HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
|
||||
(head)->hh.tbl->num_items--; \
|
||||
} \
|
||||
HASH_FSCK(hh,head); \
|
||||
} while (0)
|
||||
|
||||
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
|
||||
#define HASH_FIND_STR(head,findstr,out) \
|
||||
HASH_FIND(hh,head,findstr,strlen(findstr),out)
|
||||
#define HASH_ADD_STR(head,strfield,add) \
|
||||
HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
|
||||
#define HASH_FIND_INT(head,findint,out) \
|
||||
HASH_FIND(hh,head,findint,sizeof(int),out)
|
||||
#define HASH_ADD_INT(head,intfield,add) \
|
||||
HASH_ADD(hh,head,intfield,sizeof(int),add)
|
||||
#define HASH_FIND_PTR(head,findptr,out) \
|
||||
HASH_FIND(hh,head,findptr,sizeof(void *),out)
|
||||
#define HASH_ADD_PTR(head,ptrfield,add) \
|
||||
HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
|
||||
#define HASH_DEL(head,delptr) \
|
||||
HASH_DELETE(hh,head,delptr)
|
||||
|
||||
/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
|
||||
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
|
||||
*/
|
||||
#ifdef HASH_DEBUG
|
||||
#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
|
||||
#define HASH_FSCK(hh,head) \
|
||||
do { \
|
||||
unsigned _bkt_i; \
|
||||
unsigned _count, _bkt_count; \
|
||||
char *_prev; \
|
||||
struct UT_hash_handle *_thh; \
|
||||
if (head) { \
|
||||
_count = 0; \
|
||||
for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
|
||||
_bkt_count = 0; \
|
||||
_thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
|
||||
_prev = NULL; \
|
||||
while (_thh) { \
|
||||
if (_prev != (char*)(_thh->hh_prev)) { \
|
||||
HASH_OOPS("invalid hh_prev %p, actual %p\n", \
|
||||
_thh->hh_prev, _prev ); \
|
||||
} \
|
||||
_bkt_count++; \
|
||||
_prev = (char*)(_thh); \
|
||||
_thh = _thh->hh_next; \
|
||||
} \
|
||||
_count += _bkt_count; \
|
||||
if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
|
||||
HASH_OOPS("invalid bucket count %d, actual %d\n", \
|
||||
(head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
|
||||
} \
|
||||
} \
|
||||
if (_count != (head)->hh.tbl->num_items) { \
|
||||
HASH_OOPS("invalid hh item count %d, actual %d\n", \
|
||||
(head)->hh.tbl->num_items, _count ); \
|
||||
} \
|
||||
/* traverse hh in app order; check next/prev integrity, count */ \
|
||||
_count = 0; \
|
||||
_prev = NULL; \
|
||||
_thh = &(head)->hh; \
|
||||
while (_thh) { \
|
||||
_count++; \
|
||||
if (_prev !=(char*)(_thh->prev)) { \
|
||||
HASH_OOPS("invalid prev %p, actual %p\n", \
|
||||
_thh->prev, _prev ); \
|
||||
} \
|
||||
_prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
|
||||
_thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
|
||||
(head)->hh.tbl->hho) : NULL ); \
|
||||
} \
|
||||
if (_count != (head)->hh.tbl->num_items) { \
|
||||
HASH_OOPS("invalid app item count %d, actual %d\n", \
|
||||
(head)->hh.tbl->num_items, _count ); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define HASH_FSCK(hh,head)
|
||||
#endif
|
||||
|
||||
/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
|
||||
* the descriptor to which this macro is defined for tuning the hash function.
|
||||
* The app can #include <unistd.h> to get the prototype for write(2). */
|
||||
#ifdef HASH_EMIT_KEYS
|
||||
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
|
||||
do { \
|
||||
unsigned _klen = fieldlen; \
|
||||
write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
|
||||
write(HASH_EMIT_KEYS, keyptr, fieldlen); \
|
||||
} while (0)
|
||||
#else
|
||||
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
|
||||
#endif
|
||||
|
||||
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
|
||||
#ifdef HASH_FUNCTION
|
||||
#define HASH_FCN HASH_FUNCTION
|
||||
#else
|
||||
#define HASH_FCN HASH_JEN
|
||||
#endif
|
||||
|
||||
/* The Bernstein hash function, used in Perl prior to v5.6 */
|
||||
#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _hb_keylen=keylen; \
|
||||
char *_hb_key=(char*)(key); \
|
||||
(hashv) = 0; \
|
||||
while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
|
||||
bkt = (hashv) & (num_bkts-1); \
|
||||
} while (0)
|
||||
|
||||
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
|
||||
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
|
||||
#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _sx_i; \
|
||||
char *_hs_key=(char*)(key); \
|
||||
hashv = 0; \
|
||||
for(_sx_i=0; _sx_i < keylen; _sx_i++) \
|
||||
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _fn_i; \
|
||||
char *_hf_key=(char*)(key); \
|
||||
hashv = 2166136261UL; \
|
||||
for(_fn_i=0; _fn_i < keylen; _fn_i++) \
|
||||
hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0);
|
||||
|
||||
#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _ho_i; \
|
||||
char *_ho_key=(char*)(key); \
|
||||
hashv = 0; \
|
||||
for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
|
||||
hashv += _ho_key[_ho_i]; \
|
||||
hashv += (hashv << 10); \
|
||||
hashv ^= (hashv >> 6); \
|
||||
} \
|
||||
hashv += (hashv << 3); \
|
||||
hashv ^= (hashv >> 11); \
|
||||
hashv += (hashv << 15); \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
#define HASH_JEN_MIX(a,b,c) \
|
||||
do { \
|
||||
a -= b; a -= c; a ^= ( c >> 13 ); \
|
||||
b -= c; b -= a; b ^= ( a << 8 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 13 ); \
|
||||
a -= b; a -= c; a ^= ( c >> 12 ); \
|
||||
b -= c; b -= a; b ^= ( a << 16 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 5 ); \
|
||||
a -= b; a -= c; a ^= ( c >> 3 ); \
|
||||
b -= c; b -= a; b ^= ( a << 10 ); \
|
||||
c -= a; c -= b; c ^= ( b >> 15 ); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
unsigned _hj_i,_hj_j,_hj_k; \
|
||||
char *_hj_key=(char*)(key); \
|
||||
hashv = 0xfeedbeef; \
|
||||
_hj_i = _hj_j = 0x9e3779b9; \
|
||||
_hj_k = keylen; \
|
||||
while (_hj_k >= 12) { \
|
||||
_hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[2] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[3] << 24 ) ); \
|
||||
_hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[6] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[7] << 24 ) ); \
|
||||
hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \
|
||||
+ ( (unsigned)_hj_key[10] << 16 ) \
|
||||
+ ( (unsigned)_hj_key[11] << 24 ) ); \
|
||||
\
|
||||
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
||||
\
|
||||
_hj_key += 12; \
|
||||
_hj_k -= 12; \
|
||||
} \
|
||||
hashv += keylen; \
|
||||
switch ( _hj_k ) { \
|
||||
case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
|
||||
case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
|
||||
case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
|
||||
case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
|
||||
case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
|
||||
case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
|
||||
case 5: _hj_j += _hj_key[4]; \
|
||||
case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
|
||||
case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
|
||||
case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
|
||||
case 1: _hj_i += _hj_key[0]; \
|
||||
} \
|
||||
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
/* The Paul Hsieh hash function */
|
||||
#undef get16bits
|
||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
||||
#define get16bits(d) (*((const uint16_t *) (d)))
|
||||
#endif
|
||||
|
||||
#if !defined (get16bits)
|
||||
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
char *_sfh_key=(char*)(key); \
|
||||
uint32_t _sfh_tmp, _sfh_len = keylen; \
|
||||
\
|
||||
int _sfh_rem = _sfh_len & 3; \
|
||||
_sfh_len >>= 2; \
|
||||
hashv = 0xcafebabe; \
|
||||
\
|
||||
/* Main loop */ \
|
||||
for (;_sfh_len > 0; _sfh_len--) { \
|
||||
hashv += get16bits (_sfh_key); \
|
||||
_sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \
|
||||
hashv = (hashv << 16) ^ _sfh_tmp; \
|
||||
_sfh_key += 2*sizeof (uint16_t); \
|
||||
hashv += hashv >> 11; \
|
||||
} \
|
||||
\
|
||||
/* Handle end cases */ \
|
||||
switch (_sfh_rem) { \
|
||||
case 3: hashv += get16bits (_sfh_key); \
|
||||
hashv ^= hashv << 16; \
|
||||
hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \
|
||||
hashv += hashv >> 11; \
|
||||
break; \
|
||||
case 2: hashv += get16bits (_sfh_key); \
|
||||
hashv ^= hashv << 11; \
|
||||
hashv += hashv >> 17; \
|
||||
break; \
|
||||
case 1: hashv += *_sfh_key; \
|
||||
hashv ^= hashv << 10; \
|
||||
hashv += hashv >> 1; \
|
||||
} \
|
||||
\
|
||||
/* Force "avalanching" of final 127 bits */ \
|
||||
hashv ^= hashv << 3; \
|
||||
hashv += hashv >> 5; \
|
||||
hashv ^= hashv << 4; \
|
||||
hashv += hashv >> 17; \
|
||||
hashv ^= hashv << 25; \
|
||||
hashv += hashv >> 6; \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0);
|
||||
|
||||
#ifdef HASH_USING_NO_STRICT_ALIASING
|
||||
/* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads.
|
||||
* For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
|
||||
* So MurmurHash comes in two versions, the faster unaligned one and the slower
|
||||
* aligned one. We only use the faster one on CPU's where we know it's safe.
|
||||
*
|
||||
* Note the preprocessor built-in defines can be emitted using:
|
||||
*
|
||||
* gcc -m64 -dM -E - < /dev/null (on gcc)
|
||||
* cc -## a.c (where a.c is a simple test file) (Sun Studio)
|
||||
*/
|
||||
#if (defined(__i386__) || defined(__x86_64__))
|
||||
#define HASH_MUR HASH_MUR_UNALIGNED
|
||||
#else
|
||||
#define HASH_MUR HASH_MUR_ALIGNED
|
||||
#endif
|
||||
|
||||
/* Appleby's MurmurHash fast version for unaligned-tolerant archs like i386 */
|
||||
#define HASH_MUR_UNALIGNED(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
const unsigned int _mur_m = 0x5bd1e995; \
|
||||
const int _mur_r = 24; \
|
||||
hashv = 0xcafebabe ^ keylen; \
|
||||
char *_mur_key = (char *)(key); \
|
||||
uint32_t _mur_tmp, _mur_len = keylen; \
|
||||
\
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
_mur_tmp = *(uint32_t *)_mur_key; \
|
||||
_mur_tmp *= _mur_m; \
|
||||
_mur_tmp ^= _mur_tmp >> _mur_r; \
|
||||
_mur_tmp *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_tmp; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
\
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
}; \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
\
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
|
||||
/* Appleby's MurmurHash version for alignment-sensitive archs like Sparc */
|
||||
#define HASH_MUR_ALIGNED(key,keylen,num_bkts,hashv,bkt) \
|
||||
do { \
|
||||
const unsigned int _mur_m = 0x5bd1e995; \
|
||||
const int _mur_r = 24; \
|
||||
hashv = 0xcafebabe ^ (keylen); \
|
||||
char *_mur_key = (char *)(key); \
|
||||
uint32_t _mur_len = keylen; \
|
||||
int _mur_align = (int)_mur_key & 3; \
|
||||
\
|
||||
if (_mur_align && (_mur_len >= 4)) { \
|
||||
unsigned _mur_t = 0, _mur_d = 0; \
|
||||
switch(_mur_align) { \
|
||||
case 1: _mur_t |= _mur_key[2] << 16; \
|
||||
case 2: _mur_t |= _mur_key[1] << 8; \
|
||||
case 3: _mur_t |= _mur_key[0]; \
|
||||
} \
|
||||
_mur_t <<= (8 * _mur_align); \
|
||||
_mur_key += 4-_mur_align; \
|
||||
_mur_len -= 4-_mur_align; \
|
||||
int _mur_sl = 8 * (4-_mur_align); \
|
||||
int _mur_sr = 8 * _mur_align; \
|
||||
\
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
_mur_d = *(unsigned *)_mur_key; \
|
||||
_mur_t = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
unsigned _mur_k = _mur_t; \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_t = _mur_d; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
_mur_d = 0; \
|
||||
if(_mur_len >= _mur_align) { \
|
||||
switch(_mur_align) { \
|
||||
case 3: _mur_d |= _mur_key[2] << 16; \
|
||||
case 2: _mur_d |= _mur_key[1] << 8; \
|
||||
case 1: _mur_d |= _mur_key[0]; \
|
||||
} \
|
||||
unsigned _mur_k = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_k += _mur_align; \
|
||||
_mur_len -= _mur_align; \
|
||||
\
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
} else { \
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: _mur_d ^= _mur_key[2] << 16; \
|
||||
case 2: _mur_d ^= _mur_key[1] << 8; \
|
||||
case 1: _mur_d ^= _mur_key[0]; \
|
||||
case 0: hashv ^= (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
} else { \
|
||||
for (;_mur_len >= 4; _mur_len-=4) { \
|
||||
unsigned _mur_k = *(unsigned*)_mur_key; \
|
||||
_mur_k *= _mur_m; \
|
||||
_mur_k ^= _mur_k >> _mur_r; \
|
||||
_mur_k *= _mur_m; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= _mur_k; \
|
||||
_mur_key += 4; \
|
||||
} \
|
||||
switch(_mur_len) \
|
||||
{ \
|
||||
case 3: hashv ^= _mur_key[2] << 16; \
|
||||
case 2: hashv ^= _mur_key[1] << 8; \
|
||||
case 1: hashv ^= _mur_key[0]; \
|
||||
hashv *= _mur_m; \
|
||||
} \
|
||||
\
|
||||
hashv ^= hashv >> 13; \
|
||||
hashv *= _mur_m; \
|
||||
hashv ^= hashv >> 15; \
|
||||
} \
|
||||
bkt = hashv & (num_bkts-1); \
|
||||
} while(0)
|
||||
#endif /* HASH_USING_NO_STRICT_ALIASING */
|
||||
|
||||
/* key comparison function; return 0 if keys equal */
|
||||
#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
|
||||
|
||||
/* iterate over items in a known bucket to find desired item */
|
||||
#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
|
||||
do { \
|
||||
if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \
|
||||
else out=NULL; \
|
||||
while (out) { \
|
||||
if (out->hh.keylen == keylen_in) { \
|
||||
if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \
|
||||
} \
|
||||
if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \
|
||||
else out = NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* add an item to a bucket */
|
||||
#define HASH_ADD_TO_BKT(head,addhh) \
|
||||
do { \
|
||||
head.count++; \
|
||||
(addhh)->hh_next = head.hh_head; \
|
||||
(addhh)->hh_prev = NULL; \
|
||||
if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
|
||||
(head).hh_head=addhh; \
|
||||
if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
|
||||
&& (addhh)->tbl->noexpand != 1) { \
|
||||
HASH_EXPAND_BUCKETS((addhh)->tbl); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* remove an item from a given bucket */
|
||||
#define HASH_DEL_IN_BKT(hh,head,hh_del) \
|
||||
(head).count--; \
|
||||
if ((head).hh_head == hh_del) { \
|
||||
(head).hh_head = hh_del->hh_next; \
|
||||
} \
|
||||
if (hh_del->hh_prev) { \
|
||||
hh_del->hh_prev->hh_next = hh_del->hh_next; \
|
||||
} \
|
||||
if (hh_del->hh_next) { \
|
||||
hh_del->hh_next->hh_prev = hh_del->hh_prev; \
|
||||
}
|
||||
|
||||
/* Bucket expansion has the effect of doubling the number of buckets
|
||||
* and redistributing the items into the new buckets. Ideally the
|
||||
* items will distribute more or less evenly into the new buckets
|
||||
* (the extent to which this is true is a measure of the quality of
|
||||
* the hash function as it applies to the key domain).
|
||||
*
|
||||
* With the items distributed into more buckets, the chain length
|
||||
* (item count) in each bucket is reduced. Thus by expanding buckets
|
||||
* the hash keeps a bound on the chain length. This bounded chain
|
||||
* length is the essence of how a hash provides constant time lookup.
|
||||
*
|
||||
* The calculation of tbl->ideal_chain_maxlen below deserves some
|
||||
* explanation. First, keep in mind that we're calculating the ideal
|
||||
* maximum chain length based on the *new* (doubled) bucket count.
|
||||
* In fractions this is just n/b (n=number of items,b=new num buckets).
|
||||
* Since the ideal chain length is an integer, we want to calculate
|
||||
* ceil(n/b). We don't depend on floating point arithmetic in this
|
||||
* hash, so to calculate ceil(n/b) with integers we could write
|
||||
*
|
||||
* ceil(n/b) = (n/b) + ((n%b)?1:0)
|
||||
*
|
||||
* and in fact a previous version of this hash did just that.
|
||||
* But now we have improved things a bit by recognizing that b is
|
||||
* always a power of two. We keep its base 2 log handy (call it lb),
|
||||
* so now we can write this with a bit shift and logical AND:
|
||||
*
|
||||
* ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
|
||||
*
|
||||
*/
|
||||
#define HASH_EXPAND_BUCKETS(tbl) \
|
||||
do { \
|
||||
unsigned _he_bkt; \
|
||||
unsigned _he_bkt_i; \
|
||||
struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
|
||||
UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
|
||||
_he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
|
||||
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
|
||||
if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
|
||||
memset(_he_new_buckets, 0, \
|
||||
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
|
||||
tbl->ideal_chain_maxlen = \
|
||||
(tbl->num_items >> (tbl->log2_num_buckets+1)) + \
|
||||
((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
|
||||
tbl->nonideal_items = 0; \
|
||||
for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
|
||||
{ \
|
||||
_he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
|
||||
while (_he_thh) { \
|
||||
_he_hh_nxt = _he_thh->hh_next; \
|
||||
HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
|
||||
_he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
|
||||
if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
|
||||
tbl->nonideal_items++; \
|
||||
_he_newbkt->expand_mult = _he_newbkt->count / \
|
||||
tbl->ideal_chain_maxlen; \
|
||||
} \
|
||||
_he_thh->hh_prev = NULL; \
|
||||
_he_thh->hh_next = _he_newbkt->hh_head; \
|
||||
if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
|
||||
_he_thh; \
|
||||
_he_newbkt->hh_head = _he_thh; \
|
||||
_he_thh = _he_hh_nxt; \
|
||||
} \
|
||||
} \
|
||||
uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
|
||||
tbl->num_buckets *= 2; \
|
||||
tbl->log2_num_buckets++; \
|
||||
tbl->buckets = _he_new_buckets; \
|
||||
tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
|
||||
(tbl->ineff_expands+1) : 0; \
|
||||
if (tbl->ineff_expands > 1) { \
|
||||
tbl->noexpand=1; \
|
||||
uthash_noexpand_fyi(tbl); \
|
||||
} \
|
||||
uthash_expand_fyi(tbl); \
|
||||
} while(0)
|
||||
|
||||
/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
|
||||
/* Note that HASH_SORT assumes the hash handle name to be hh.
|
||||
* HASH_SRT was added to allow the hash handle name to be passed in. */
|
||||
#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
|
||||
#define HASH_SRT(hh,head,cmpfcn) \
|
||||
do { \
|
||||
unsigned _hs_i; \
|
||||
unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
|
||||
struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
|
||||
if (head) { \
|
||||
_hs_insize = 1; \
|
||||
_hs_looping = 1; \
|
||||
_hs_list = &((head)->hh); \
|
||||
while (_hs_looping) { \
|
||||
_hs_p = _hs_list; \
|
||||
_hs_list = NULL; \
|
||||
_hs_tail = NULL; \
|
||||
_hs_nmerges = 0; \
|
||||
while (_hs_p) { \
|
||||
_hs_nmerges++; \
|
||||
_hs_q = _hs_p; \
|
||||
_hs_psize = 0; \
|
||||
for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
|
||||
_hs_psize++; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
if (! (_hs_q) ) break; \
|
||||
} \
|
||||
_hs_qsize = _hs_insize; \
|
||||
while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
|
||||
if (_hs_psize == 0) { \
|
||||
_hs_e = _hs_q; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_qsize--; \
|
||||
} else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
|
||||
_hs_e = _hs_p; \
|
||||
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
|
||||
((void*)((char*)(_hs_p->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_psize--; \
|
||||
} else if (( \
|
||||
cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
|
||||
DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
|
||||
) <= 0) { \
|
||||
_hs_e = _hs_p; \
|
||||
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
|
||||
((void*)((char*)(_hs_p->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_psize--; \
|
||||
} else { \
|
||||
_hs_e = _hs_q; \
|
||||
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
|
||||
((void*)((char*)(_hs_q->next) + \
|
||||
(head)->hh.tbl->hho)) : NULL); \
|
||||
_hs_qsize--; \
|
||||
} \
|
||||
if ( _hs_tail ) { \
|
||||
_hs_tail->next = ((_hs_e) ? \
|
||||
ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
|
||||
} else { \
|
||||
_hs_list = _hs_e; \
|
||||
} \
|
||||
_hs_e->prev = ((_hs_tail) ? \
|
||||
ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
|
||||
_hs_tail = _hs_e; \
|
||||
} \
|
||||
_hs_p = _hs_q; \
|
||||
} \
|
||||
_hs_tail->next = NULL; \
|
||||
if ( _hs_nmerges <= 1 ) { \
|
||||
_hs_looping=0; \
|
||||
(head)->hh.tbl->tail = _hs_tail; \
|
||||
DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
|
||||
} \
|
||||
_hs_insize *= 2; \
|
||||
} \
|
||||
HASH_FSCK(hh,head); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* This function selects items from one hash into another hash.
|
||||
* The end result is that the selected items have dual presence
|
||||
* in both hashes. There is no copy of the items made; rather
|
||||
* they are added into the new hash through a secondary hash
|
||||
* hash handle that must be present in the structure. */
|
||||
#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
|
||||
do { \
|
||||
unsigned _src_bkt, _dst_bkt; \
|
||||
void *_last_elt=NULL, *_elt; \
|
||||
UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
|
||||
ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
|
||||
if (src) { \
|
||||
for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
|
||||
for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
|
||||
_src_hh; \
|
||||
_src_hh = _src_hh->hh_next) { \
|
||||
_elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
|
||||
if (cond(_elt)) { \
|
||||
_dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
|
||||
_dst_hh->key = _src_hh->key; \
|
||||
_dst_hh->keylen = _src_hh->keylen; \
|
||||
_dst_hh->hashv = _src_hh->hashv; \
|
||||
_dst_hh->prev = _last_elt; \
|
||||
_dst_hh->next = NULL; \
|
||||
if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
|
||||
if (!dst) { \
|
||||
DECLTYPE_ASSIGN(dst,_elt); \
|
||||
HASH_MAKE_TABLE(hh_dst,dst); \
|
||||
} else { \
|
||||
_dst_hh->tbl = (dst)->hh_dst.tbl; \
|
||||
} \
|
||||
HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
|
||||
HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
|
||||
(dst)->hh_dst.tbl->num_items++; \
|
||||
_last_elt = _elt; \
|
||||
_last_elt_hh = _dst_hh; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
HASH_FSCK(hh_dst,dst); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_CLEAR(hh,head) \
|
||||
do { \
|
||||
if (head) { \
|
||||
uthash_free((head)->hh.tbl->buckets, \
|
||||
(head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \
|
||||
uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
|
||||
(head)=NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#ifdef NO_DECLTYPE
|
||||
#define HASH_ITER(hh,head,el,tmp) \
|
||||
for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \
|
||||
el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
|
||||
#else
|
||||
#define HASH_ITER(hh,head,el,tmp) \
|
||||
for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \
|
||||
el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL))
|
||||
#endif
|
||||
|
||||
/* obtain a count of items in the hash */
|
||||
#define HASH_COUNT(head) HASH_CNT(hh,head)
|
||||
#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
|
||||
|
||||
typedef struct UT_hash_bucket
|
||||
{
|
||||
struct UT_hash_handle *hh_head;
|
||||
unsigned count;
|
||||
|
||||
/* expand_mult is normally set to 0. In this situation, the max chain length
|
||||
* threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
|
||||
* the bucket's chain exceeds this length, bucket expansion is triggered).
|
||||
* However, setting expand_mult to a non-zero value delays bucket expansion
|
||||
* (that would be triggered by additions to this particular bucket)
|
||||
* until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
|
||||
* (The multiplier is simply expand_mult+1). The whole idea of this
|
||||
* multiplier is to reduce bucket expansions, since they are expensive, in
|
||||
* situations where we know that a particular bucket tends to be overused.
|
||||
* It is better to let its chain length grow to a longer yet-still-bounded
|
||||
* value, than to do an O(n) bucket expansion too often.
|
||||
*/
|
||||
unsigned expand_mult;
|
||||
|
||||
} UT_hash_bucket;
|
||||
|
||||
/* random signature used only to find hash tables in external analysis */
|
||||
#define HASH_SIGNATURE 0xa0111fe1
|
||||
#define HASH_BLOOM_SIGNATURE 0xb12220f2
|
||||
|
||||
typedef struct UT_hash_table
|
||||
{
|
||||
UT_hash_bucket *buckets;
|
||||
unsigned num_buckets, log2_num_buckets;
|
||||
unsigned num_items;
|
||||
struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
|
||||
ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
|
||||
|
||||
/* in an ideal situation (all buckets used equally), no bucket would have
|
||||
* more than ceil(#items/#buckets) items. that's the ideal chain length. */
|
||||
unsigned ideal_chain_maxlen;
|
||||
|
||||
/* nonideal_items is the number of items in the hash whose chain position
|
||||
* exceeds the ideal chain maxlen. these items pay the penalty for an uneven
|
||||
* hash distribution; reaching them in a chain traversal takes >ideal steps */
|
||||
unsigned nonideal_items;
|
||||
|
||||
/* ineffective expands occur when a bucket doubling was performed, but
|
||||
* afterward, more than half the items in the hash had nonideal chain
|
||||
* positions. If this happens on two consecutive expansions we inhibit any
|
||||
* further expansion, as it's not helping; this happens when the hash
|
||||
* function isn't a good fit for the key domain. When expansion is inhibited
|
||||
* the hash will still work, albeit no longer in constant time. */
|
||||
unsigned ineff_expands, noexpand;
|
||||
|
||||
uint32_t signature; /* used only to find hash tables in external analysis */
|
||||
#ifdef HASH_BLOOM
|
||||
uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
|
||||
uint8_t *bloom_bv;
|
||||
char bloom_nbits;
|
||||
#endif
|
||||
|
||||
} UT_hash_table;
|
||||
|
||||
typedef struct UT_hash_handle
|
||||
{
|
||||
struct UT_hash_table *tbl;
|
||||
void *prev; /* prev element in app order */
|
||||
void *next; /* next element in app order */
|
||||
struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
|
||||
struct UT_hash_handle *hh_next; /* next hh in bucket order */
|
||||
void *key; /* ptr to enclosing struct's key */
|
||||
unsigned keylen; /* enclosing struct's key len */
|
||||
unsigned hashv; /* result of hash-fcn(key) */
|
||||
} UT_hash_handle;
|
||||
|
||||
#endif /* UTHASH_H */
|
||||
489
sdk/component/common/network/libcoap/include/coap/utlist.h
Normal file
489
sdk/component/common/network/libcoap/include/coap/utlist.h
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
/*
|
||||
Copyright (c) 2007-2010, Troy D. Hanson http://uthash.sourceforge.net
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef UTLIST_H
|
||||
#define UTLIST_H
|
||||
|
||||
#define UTLIST_VERSION 1.9.1
|
||||
|
||||
/*
|
||||
* This file contains macros to manipulate singly and doubly-linked lists.
|
||||
*
|
||||
* 1. LL_ macros: singly-linked lists.
|
||||
* 2. DL_ macros: doubly-linked lists.
|
||||
* 3. CDL_ macros: circular doubly-linked lists.
|
||||
*
|
||||
* To use singly-linked lists, your structure must have a "next" pointer.
|
||||
* To use doubly-linked lists, your structure must "prev" and "next" pointers.
|
||||
* Either way, the pointer to the head of the list must be initialized to NULL.
|
||||
*
|
||||
* ----------------.EXAMPLE -------------------------
|
||||
* struct item {
|
||||
* int id;
|
||||
* struct item *prev, *next;
|
||||
* }
|
||||
*
|
||||
* struct item *list = NULL:
|
||||
*
|
||||
* int main() {
|
||||
* struct item *item;
|
||||
* ... allocate and populate item ...
|
||||
* DL_APPEND(list, item);
|
||||
* }
|
||||
* --------------------------------------------------
|
||||
*
|
||||
* For doubly-linked lists, the append and delete macros are O(1)
|
||||
* For singly-linked lists, append and delete are O(n) but prepend is O(1)
|
||||
* The sort macro is O(n log(n)) for all types of single/double/circular lists.
|
||||
*/
|
||||
|
||||
/* These macros use decltype or the earlier __typeof GNU extension.
|
||||
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
|
||||
when compiling c++ code), this code uses whatever method is needed
|
||||
or, for VS2008 where neither is available, uses casting workarounds. */
|
||||
#ifdef _MSC_VER /* MS compiler */
|
||||
#if (_MSC_VER >= 1600) && (defined(__cplusplus) && (__cplusplus >= 201103L)) /* VS2010 and newer in C++ mode */
|
||||
#define LDECLTYPE(x) decltype(x)
|
||||
#else /* VS2008 or older (or VS2010 in C mode) */
|
||||
#define NO_DECLTYPE
|
||||
#define LDECLTYPE(x) char*
|
||||
#endif
|
||||
#else /* GNU, Sun and other compilers */
|
||||
#define LDECLTYPE(x) __typeof(x)
|
||||
#endif
|
||||
|
||||
/* for VS2008 we use some workarounds to get around the lack of decltype,
|
||||
* namely, we always reassign our tmp variable to the list head if we need
|
||||
* to dereference its prev/next pointers, and save/restore the real head.*/
|
||||
#ifdef NO_DECLTYPE
|
||||
#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); }
|
||||
#define _NEXT(elt,list) ((char*)((list)->next))
|
||||
#define _NEXTASGN(elt,list,to) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); }
|
||||
#define _PREV(elt,list) ((char*)((list)->prev))
|
||||
#define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); }
|
||||
#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; }
|
||||
#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); }
|
||||
#else
|
||||
#define _SV(elt,list)
|
||||
#define _NEXT(elt,list) ((elt)->next)
|
||||
#define _NEXTASGN(elt,list,to) ((elt)->next)=(to)
|
||||
#define _PREV(elt,list) ((elt)->prev)
|
||||
#define _PREVASGN(elt,list,to) ((elt)->prev)=(to)
|
||||
#define _RS(list)
|
||||
#define _CASTASGN(a,b) (a)=(b)
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort *
|
||||
* Unwieldy variable names used here to avoid shadowing passed-in variables. *
|
||||
*****************************************************************************/
|
||||
#define LL_SORT(list, cmp) \
|
||||
do { \
|
||||
LDECLTYPE(list) _ls_p; \
|
||||
LDECLTYPE(list) _ls_q; \
|
||||
LDECLTYPE(list) _ls_e; \
|
||||
LDECLTYPE(list) _ls_tail; \
|
||||
LDECLTYPE(list) _ls_oldhead; \
|
||||
LDECLTYPE(list) _tmp; \
|
||||
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
|
||||
if (list) { \
|
||||
_ls_insize = 1; \
|
||||
_ls_looping = 1; \
|
||||
while (_ls_looping) { \
|
||||
_CASTASGN(_ls_p,list); \
|
||||
_CASTASGN(_ls_oldhead,list); \
|
||||
list = NULL; \
|
||||
_ls_tail = NULL; \
|
||||
_ls_nmerges = 0; \
|
||||
while (_ls_p) { \
|
||||
_ls_nmerges++; \
|
||||
_ls_q = _ls_p; \
|
||||
_ls_psize = 0; \
|
||||
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
|
||||
_ls_psize++; \
|
||||
_SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \
|
||||
if (!_ls_q) break; \
|
||||
} \
|
||||
_ls_qsize = _ls_insize; \
|
||||
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
|
||||
if (_ls_psize == 0) { \
|
||||
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
|
||||
} else if (_ls_qsize == 0 || !_ls_q) { \
|
||||
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
|
||||
} else if (cmp(_ls_p,_ls_q) <= 0) { \
|
||||
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
|
||||
} else { \
|
||||
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
|
||||
} \
|
||||
if (_ls_tail) { \
|
||||
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
|
||||
} else { \
|
||||
_CASTASGN(list,_ls_e); \
|
||||
} \
|
||||
_ls_tail = _ls_e; \
|
||||
} \
|
||||
_ls_p = _ls_q; \
|
||||
} \
|
||||
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \
|
||||
if (_ls_nmerges <= 1) { \
|
||||
_ls_looping=0; \
|
||||
} \
|
||||
_ls_insize *= 2; \
|
||||
} \
|
||||
} else _tmp=NULL; /* quiet gcc unused variable warning */ \
|
||||
} while (0)
|
||||
|
||||
#define DL_SORT(list, cmp) \
|
||||
do { \
|
||||
LDECLTYPE(list) _ls_p; \
|
||||
LDECLTYPE(list) _ls_q; \
|
||||
LDECLTYPE(list) _ls_e; \
|
||||
LDECLTYPE(list) _ls_tail; \
|
||||
LDECLTYPE(list) _ls_oldhead; \
|
||||
LDECLTYPE(list) _tmp; \
|
||||
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
|
||||
if (list) { \
|
||||
_ls_insize = 1; \
|
||||
_ls_looping = 1; \
|
||||
while (_ls_looping) { \
|
||||
_CASTASGN(_ls_p,list); \
|
||||
_CASTASGN(_ls_oldhead,list); \
|
||||
list = NULL; \
|
||||
_ls_tail = NULL; \
|
||||
_ls_nmerges = 0; \
|
||||
while (_ls_p) { \
|
||||
_ls_nmerges++; \
|
||||
_ls_q = _ls_p; \
|
||||
_ls_psize = 0; \
|
||||
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
|
||||
_ls_psize++; \
|
||||
_SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \
|
||||
if (!_ls_q) break; \
|
||||
} \
|
||||
_ls_qsize = _ls_insize; \
|
||||
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
|
||||
if (_ls_psize == 0) { \
|
||||
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
|
||||
} else if (_ls_qsize == 0 || !_ls_q) { \
|
||||
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
|
||||
} else if (cmp(_ls_p,_ls_q) <= 0) { \
|
||||
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
|
||||
} else { \
|
||||
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
|
||||
} \
|
||||
if (_ls_tail) { \
|
||||
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
|
||||
} else { \
|
||||
_CASTASGN(list,_ls_e); \
|
||||
} \
|
||||
_SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \
|
||||
_ls_tail = _ls_e; \
|
||||
} \
|
||||
_ls_p = _ls_q; \
|
||||
} \
|
||||
_CASTASGN(list->prev, _ls_tail); \
|
||||
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \
|
||||
if (_ls_nmerges <= 1) { \
|
||||
_ls_looping=0; \
|
||||
} \
|
||||
_ls_insize *= 2; \
|
||||
} \
|
||||
} else _tmp=NULL; /* quiet gcc unused variable warning */ \
|
||||
} while (0)
|
||||
|
||||
#define CDL_SORT(list, cmp) \
|
||||
do { \
|
||||
LDECLTYPE(list) _ls_p; \
|
||||
LDECLTYPE(list) _ls_q; \
|
||||
LDECLTYPE(list) _ls_e; \
|
||||
LDECLTYPE(list) _ls_tail; \
|
||||
LDECLTYPE(list) _ls_oldhead; \
|
||||
LDECLTYPE(list) _tmp; \
|
||||
LDECLTYPE(list) _tmp2; \
|
||||
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
|
||||
if (list) { \
|
||||
_ls_insize = 1; \
|
||||
_ls_looping = 1; \
|
||||
while (_ls_looping) { \
|
||||
_CASTASGN(_ls_p,list); \
|
||||
_CASTASGN(_ls_oldhead,list); \
|
||||
list = NULL; \
|
||||
_ls_tail = NULL; \
|
||||
_ls_nmerges = 0; \
|
||||
while (_ls_p) { \
|
||||
_ls_nmerges++; \
|
||||
_ls_q = _ls_p; \
|
||||
_ls_psize = 0; \
|
||||
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
|
||||
_ls_psize++; \
|
||||
_SV(_ls_q,list); \
|
||||
if (_NEXT(_ls_q,list) == _ls_oldhead) { \
|
||||
_ls_q = NULL; \
|
||||
} else { \
|
||||
_ls_q = _NEXT(_ls_q,list); \
|
||||
} \
|
||||
_RS(list); \
|
||||
if (!_ls_q) break; \
|
||||
} \
|
||||
_ls_qsize = _ls_insize; \
|
||||
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
|
||||
if (_ls_psize == 0) { \
|
||||
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
|
||||
if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \
|
||||
} else if (_ls_qsize == 0 || !_ls_q) { \
|
||||
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
|
||||
if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \
|
||||
} else if (cmp(_ls_p,_ls_q) <= 0) { \
|
||||
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \
|
||||
if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \
|
||||
} else { \
|
||||
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \
|
||||
if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \
|
||||
} \
|
||||
if (_ls_tail) { \
|
||||
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \
|
||||
} else { \
|
||||
_CASTASGN(list,_ls_e); \
|
||||
} \
|
||||
_SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \
|
||||
_ls_tail = _ls_e; \
|
||||
} \
|
||||
_ls_p = _ls_q; \
|
||||
} \
|
||||
_CASTASGN(list->prev,_ls_tail); \
|
||||
_CASTASGN(_tmp2,list); \
|
||||
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp2); _RS(list); \
|
||||
if (_ls_nmerges <= 1) { \
|
||||
_ls_looping=0; \
|
||||
} \
|
||||
_ls_insize *= 2; \
|
||||
} \
|
||||
} else _tmp=NULL; /* quiet gcc unused variable warning */ \
|
||||
} while (0)
|
||||
|
||||
/******************************************************************************
|
||||
* singly linked list macros (non-circular) *
|
||||
*****************************************************************************/
|
||||
#define LL_PREPEND(head,add) \
|
||||
do { \
|
||||
(add)->next = head; \
|
||||
head = add; \
|
||||
} while (0)
|
||||
|
||||
#define LL_APPEND(head,add) \
|
||||
do { \
|
||||
LDECLTYPE(head) _tmp; \
|
||||
(add)->next=NULL; \
|
||||
if (head) { \
|
||||
_tmp = head; \
|
||||
while (_tmp->next) { _tmp = _tmp->next; } \
|
||||
_tmp->next=(add); \
|
||||
} else { \
|
||||
(head)=(add); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LL_DELETE(head,del) \
|
||||
do { \
|
||||
LDECLTYPE(head) _tmp; \
|
||||
if ((head) == (del)) { \
|
||||
(head)=(head)->next; \
|
||||
} else { \
|
||||
_tmp = head; \
|
||||
while (_tmp->next && (_tmp->next != (del))) { \
|
||||
_tmp = _tmp->next; \
|
||||
} \
|
||||
if (_tmp->next) { \
|
||||
_tmp->next = ((del)->next); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */
|
||||
#define LL_APPEND_VS2008(head,add) \
|
||||
do { \
|
||||
if (head) { \
|
||||
(add)->next = head; /* use add->next as a temp variable */ \
|
||||
while ((add)->next->next) { (add)->next = (add)->next->next; } \
|
||||
(add)->next->next=(add); \
|
||||
} else { \
|
||||
(head)=(add); \
|
||||
} \
|
||||
(add)->next=NULL; \
|
||||
} while (0)
|
||||
|
||||
#define LL_DELETE_VS2008(head,del) \
|
||||
do { \
|
||||
if ((head) == (del)) { \
|
||||
(head)=(head)->next; \
|
||||
} else { \
|
||||
char *_tmp = (char*)(head); \
|
||||
while ((head)->next && ((head)->next != (del))) { \
|
||||
(head) = (head)->next; \
|
||||
} \
|
||||
if ((head)->next) { \
|
||||
(head)->next = ((del)->next); \
|
||||
} \
|
||||
{ \
|
||||
char **_head_alias = (char**)&(head); \
|
||||
*_head_alias = _tmp; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#ifdef NO_DECLTYPE
|
||||
#undef LL_APPEND
|
||||
#define LL_APPEND LL_APPEND_VS2008
|
||||
#undef LL_DELETE
|
||||
#define LL_DELETE LL_DELETE_VS2008
|
||||
#endif
|
||||
/* end VS2008 replacements */
|
||||
|
||||
#define LL_FOREACH(head,el) \
|
||||
for(el=head;el;el=el->next)
|
||||
|
||||
#define LL_FOREACH_SAFE(head,el,tmp) \
|
||||
for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
|
||||
|
||||
#define LL_SEARCH_SCALAR(head,out,field,val) \
|
||||
do { \
|
||||
LL_FOREACH(head,out) { \
|
||||
if ((out)->field == (val)) break; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define LL_SEARCH(head,out,elt,cmp) \
|
||||
do { \
|
||||
LL_FOREACH(head,out) { \
|
||||
if ((cmp(out,elt))==0) break; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/******************************************************************************
|
||||
* doubly linked list macros (non-circular) *
|
||||
*****************************************************************************/
|
||||
#define DL_PREPEND(head,add) \
|
||||
do { \
|
||||
(add)->next = head; \
|
||||
if (head) { \
|
||||
(add)->prev = (head)->prev; \
|
||||
(head)->prev = (add); \
|
||||
} else { \
|
||||
(add)->prev = (add); \
|
||||
} \
|
||||
(head) = (add); \
|
||||
} while (0)
|
||||
|
||||
#define DL_APPEND(head,add) \
|
||||
do { \
|
||||
if (head) { \
|
||||
(add)->prev = (head)->prev; \
|
||||
(head)->prev->next = (add); \
|
||||
(head)->prev = (add); \
|
||||
(add)->next = NULL; \
|
||||
} else { \
|
||||
(head)=(add); \
|
||||
(head)->prev = (head); \
|
||||
(head)->next = NULL; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define DL_DELETE(head,del) \
|
||||
do { \
|
||||
if ((del)->prev == (del)) { \
|
||||
(head)=NULL; \
|
||||
} else if ((del)==(head)) { \
|
||||
(del)->next->prev = (del)->prev; \
|
||||
(head) = (del)->next; \
|
||||
} else { \
|
||||
(del)->prev->next = (del)->next; \
|
||||
if ((del)->next) { \
|
||||
(del)->next->prev = (del)->prev; \
|
||||
} else { \
|
||||
(head)->prev = (del)->prev; \
|
||||
} \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define DL_FOREACH(head,el) \
|
||||
for(el=head;el;el=el->next)
|
||||
|
||||
/* this version is safe for deleting the elements during iteration */
|
||||
#define DL_FOREACH_SAFE(head,el,tmp) \
|
||||
for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
|
||||
|
||||
/* these are identical to their singly-linked list counterparts */
|
||||
#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR
|
||||
#define DL_SEARCH LL_SEARCH
|
||||
|
||||
/******************************************************************************
|
||||
* circular doubly linked list macros *
|
||||
*****************************************************************************/
|
||||
#define CDL_PREPEND(head,add) \
|
||||
do { \
|
||||
if (head) { \
|
||||
(add)->prev = (head)->prev; \
|
||||
(add)->next = (head); \
|
||||
(head)->prev = (add); \
|
||||
(add)->prev->next = (add); \
|
||||
} else { \
|
||||
(add)->prev = (add); \
|
||||
(add)->next = (add); \
|
||||
} \
|
||||
(head)=(add); \
|
||||
} while (0)
|
||||
|
||||
#define CDL_DELETE(head,del) \
|
||||
do { \
|
||||
if ( ((head)==(del)) && ((head)->next == (head))) { \
|
||||
(head) = 0L; \
|
||||
} else { \
|
||||
(del)->next->prev = (del)->prev; \
|
||||
(del)->prev->next = (del)->next; \
|
||||
if ((del) == (head)) (head)=(del)->next; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define CDL_FOREACH(head,el) \
|
||||
for(el=head;el;el=(el->next==head ? 0L : el->next))
|
||||
|
||||
#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \
|
||||
for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \
|
||||
(el) && ((tmp2)=(el)->next, 1); \
|
||||
((el) = (((el)==(tmp1)) ? 0L : (tmp2))))
|
||||
|
||||
#define CDL_SEARCH_SCALAR(head,out,field,val) \
|
||||
do { \
|
||||
CDL_FOREACH(head,out) { \
|
||||
if ((out)->field == (val)) break; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define CDL_SEARCH(head,out,elt,cmp) \
|
||||
do { \
|
||||
CDL_FOREACH(head,out) { \
|
||||
if ((cmp(out,elt))==0) break; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif /* UTLIST_H */
|
||||
|
||||
4295
sdk/component/common/network/lwip/lwip_v2.0.2/CHANGELOG
Normal file
4295
sdk/component/common/network/lwip/lwip_v2.0.2/CHANGELOG
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
Modifications made by Realtek to patch lwip_v2.0.0 on Ameba's SDK which is originally based on lwip_v1.4.1
|
||||
|
||||
2017-01-10: Chris (chrisyang@realtek.com)
|
||||
* Add empty loopif.h into src/include/netif to avoid compile error
|
||||
33
sdk/component/common/network/lwip/lwip_v2.0.2/COPYING
Normal file
33
sdk/component/common/network/lwip/lwip_v2.0.2/COPYING
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
5
sdk/component/common/network/lwip/lwip_v2.0.2/FILES
Normal file
5
sdk/component/common/network/lwip/lwip_v2.0.2/FILES
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
src/ - The source code for the lwIP TCP/IP stack.
|
||||
doc/ - The documentation for lwIP.
|
||||
test/ - Some code to test whether the sources do what they should.
|
||||
|
||||
See also the FILES file in each subdirectory.
|
||||
100
sdk/component/common/network/lwip/lwip_v2.0.2/README
Normal file
100
sdk/component/common/network/lwip/lwip_v2.0.2/README
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
INTRODUCTION
|
||||
|
||||
lwIP is a small independent implementation of the TCP/IP protocol
|
||||
suite that has been developed by Adam Dunkels at the Computer and
|
||||
Networks Architectures (CNA) lab at the Swedish Institute of Computer
|
||||
Science (SICS).
|
||||
|
||||
The focus of the lwIP TCP/IP implementation is to reduce the RAM usage
|
||||
while still having a full scale TCP. This making lwIP suitable for use
|
||||
in embedded systems with tens of kilobytes of free RAM and room for
|
||||
around 40 kilobytes of code ROM.
|
||||
|
||||
|
||||
FEATURES
|
||||
|
||||
* IP (Internet Protocol, IPv4 and IPv6) including packet forwarding over
|
||||
multiple network interfaces
|
||||
* ICMP (Internet Control Message Protocol) for network maintenance and debugging
|
||||
* IGMP (Internet Group Management Protocol) for multicast traffic management
|
||||
* MLD (Multicast listener discovery for IPv6). Aims to be compliant with
|
||||
RFC 2710. No support for MLDv2
|
||||
* ND (Neighbor discovery and stateless address autoconfiguration for IPv6).
|
||||
Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862
|
||||
(Address autoconfiguration)
|
||||
* UDP (User Datagram Protocol) including experimental UDP-lite extensions
|
||||
* TCP (Transmission Control Protocol) with congestion control, RTT estimation
|
||||
and fast recovery/fast retransmit
|
||||
* raw/native API for enhanced performance
|
||||
* Optional Berkeley-like socket API
|
||||
* DNS (Domain names resolver)
|
||||
|
||||
|
||||
APPLICATIONS
|
||||
|
||||
* HTTP server with SSI and CGI
|
||||
* SNMPv2c agent with MIB compiler (Simple Network Management Protocol)
|
||||
* SNTP (Simple network time protocol)
|
||||
* NetBIOS name service responder
|
||||
* MDNS (Multicast DNS) responder
|
||||
* iPerf server implementation
|
||||
|
||||
|
||||
LICENSE
|
||||
|
||||
lwIP is freely available under a BSD license.
|
||||
|
||||
|
||||
DEVELOPMENT
|
||||
|
||||
lwIP has grown into an excellent TCP/IP stack for embedded devices,
|
||||
and developers using the stack often submit bug fixes, improvements,
|
||||
and additions to the stack to further increase its usefulness.
|
||||
|
||||
Development of lwIP is hosted on Savannah, a central point for
|
||||
software development, maintenance and distribution. Everyone can
|
||||
help improve lwIP by use of Savannah's interface, Git and the
|
||||
mailing list. A core team of developers will commit changes to the
|
||||
Git source tree.
|
||||
|
||||
The lwIP TCP/IP stack is maintained in the 'lwip' Git module and
|
||||
contributions (such as platform ports) are in the 'contrib' Git module.
|
||||
|
||||
See doc/savannah.txt for details on Git server access for users and
|
||||
developers.
|
||||
|
||||
The current Git trees are web-browsable:
|
||||
http://git.savannah.gnu.org/cgit/lwip.git
|
||||
http://git.savannah.gnu.org/cgit/lwip/lwip-contrib.git
|
||||
|
||||
Submit patches and bugs via the lwIP project page:
|
||||
http://savannah.nongnu.org/projects/lwip/
|
||||
|
||||
Continuous integration builds (GCC, clang):
|
||||
https://travis-ci.org/yarrick/lwip-merged
|
||||
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
Self documentation of the source code is regularly extracted from the current
|
||||
Git sources and is available from this web page:
|
||||
http://www.nongnu.org/lwip/
|
||||
|
||||
There is now a constantly growing wiki about lwIP at
|
||||
http://lwip.wikia.com/wiki/LwIP_Wiki
|
||||
|
||||
Also, there are mailing lists you can subscribe at
|
||||
http://savannah.nongnu.org/mail/?group=lwip
|
||||
plus searchable archives:
|
||||
http://lists.nongnu.org/archive/html/lwip-users/
|
||||
http://lists.nongnu.org/archive/html/lwip-devel/
|
||||
|
||||
lwIP was originally written by Adam Dunkels:
|
||||
http://dunkels.com/adam/
|
||||
|
||||
Reading Adam's papers, the files in docs/, browsing the source code
|
||||
documentation and browsing the mailing list archives is a good way to
|
||||
become familiar with the design of lwIP.
|
||||
|
||||
Adam Dunkels <adam@sics.se>
|
||||
Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||
243
sdk/component/common/network/lwip/lwip_v2.0.2/UPGRADING
Normal file
243
sdk/component/common/network/lwip/lwip_v2.0.2/UPGRADING
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
This file lists major changes between release versions that require
|
||||
ports or applications to be changed. Use it to update a port or an
|
||||
application written for an older version of lwIP to correctly work
|
||||
with newer versions.
|
||||
|
||||
|
||||
(git master)
|
||||
|
||||
* [Enter new changes just after this line - do not remove this line]
|
||||
|
||||
(2.0.2)
|
||||
|
||||
++ Application changes:
|
||||
|
||||
* slipif: The way to pass serial port number has changed. netif->num is not
|
||||
supported any more, netif->state is interpreted as an u8_t port number now
|
||||
(it's not a POINTER to an u8_t any more!)
|
||||
|
||||
(2.0.1)
|
||||
|
||||
++ Application changes:
|
||||
|
||||
* UDP does NOT receive multicast traffic from ALL netifs on an UDP PCB bound to a specific
|
||||
netif any more. Users need to bind to IP_ADDR_ANY to receive multicast traffic and compare
|
||||
ip_current_netif() to the desired netif for every packet.
|
||||
See bug #49662 for an explanation.
|
||||
|
||||
(2.0.0)
|
||||
|
||||
++ Application changes:
|
||||
|
||||
* Changed netif "up" flag handling to be an administrative flag (as opposed to the previous meaning of
|
||||
"ip4-address-valid", a netif will now not be used for transmission if not up) -> even a DHCP netif
|
||||
has to be set "up" before starting the DHCP client
|
||||
* Added IPv6 support (dual-stack or IPv4/IPv6 only)
|
||||
* Changed ip_addr_t to be a union in dual-stack mode (use ip4_addr_t where referring to IPv4 only).
|
||||
* Major rewrite of SNMP (added MIB parser that creates code stubs for custom MIBs);
|
||||
supports SNMPv2c (experimental v3 support)
|
||||
* Moved some core applications from contrib repository to src/apps (and include/lwip/apps)
|
||||
|
||||
+++ Raw API:
|
||||
* Changed TCP listen backlog: removed tcp_accepted(), added the function pair tcp_backlog_delayed()/
|
||||
tcp_backlog_accepted() to explicitly delay backlog handling on a connection pcb
|
||||
|
||||
+++ Socket API:
|
||||
* Added an implementation for posix sendmsg()
|
||||
* Added LWIP_FIONREAD_LINUXMODE that makes ioctl/FIONREAD return the size of the next pending datagram
|
||||
|
||||
++ Port changes
|
||||
|
||||
+++ new files:
|
||||
* MANY new and moved files!
|
||||
* Added src/Filelists.mk for use in Makefile projects
|
||||
* Continued moving stack-internal parts from abc.h to abc_priv.h in sub-folder "priv"
|
||||
to let abc.h only contain the actual application programmer's API
|
||||
|
||||
+++ sys layer:
|
||||
* Made LWIP_TCPIP_CORE_LOCKING==1 the default as it usually performs better than
|
||||
the traditional message passing (although with LWIP_COMPAT_MUTEX you are still
|
||||
open to priority inversion, so this is not recommended any more)
|
||||
* Added LWIP_NETCONN_SEM_PER_THREAD to use one "op_completed" semaphore per thread
|
||||
instead of using one per netconn (these semaphores are used even with core locking
|
||||
enabled as some longer lasting functions like big writes still need to delay)
|
||||
* Added generalized abstraction for itoa(), strnicmp(), stricmp() and strnstr()
|
||||
in def.h (to be overridden in cc.h) instead of config
|
||||
options for netbiosns, httpd, dns, etc. ...
|
||||
* New abstraction for hton* and ntoh* functions in def.h.
|
||||
To override them, use the following in cc.h:
|
||||
#define lwip_htons(x) <your_htons>
|
||||
#define lwip_htonl(x) <your_htonl>
|
||||
|
||||
+++ new options:
|
||||
* TODO
|
||||
|
||||
+++ new pools:
|
||||
* Added LWIP_MEMPOOL_* (declare/init/alloc/free) to declare private memp pools
|
||||
that share memp.c code but do not have to be made global via lwippools.h
|
||||
* Added pools for IPv6, MPU_COMPATIBLE, dns-api, netif-api, etc.
|
||||
* added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when a memp pool was empty and an item
|
||||
is now available
|
||||
|
||||
* Signature of LWIP_HOOK_VLAN_SET macro was changed
|
||||
|
||||
* LWIP_DECLARE_MEMORY_ALIGNED() may be used to declare aligned memory buffers (mem/memp)
|
||||
or to move buffers to dedicated memory using compiler attributes
|
||||
|
||||
* Standard C headers are used to define sized types and printf formatters
|
||||
(disable by setting LWIP_NO_STDINT_H=1 or LWIP_NO_INTTYPES_H=1 if your compiler
|
||||
does not support these)
|
||||
|
||||
|
||||
++ Major bugfixes/improvements
|
||||
|
||||
* Added IPv6 support (dual-stack or IPv4/IPv6 only)
|
||||
* Major rewrite of PPP (incl. keep-up with apache pppd)
|
||||
see doc/ppp.txt for an upgrading how-to
|
||||
* Major rewrite of SNMP (incl. MIB parser)
|
||||
* Fixed timing issues that might have lead to losing a DHCP lease
|
||||
* Made rx processing path more robust against crafted errors
|
||||
* TCP window scaling support
|
||||
* modification of api modules to support FreeRTOS-MPU (don't pass stack-pointers to other threads)
|
||||
* made DNS client more robust
|
||||
* support PBUF_REF for RX packets
|
||||
* LWIP_NETCONN_FULLDUPLEX allows netconn/sockets to be used for reading/writing from separate
|
||||
threads each (needs LWIP_NETCONN_SEM_PER_THREAD)
|
||||
* Moved and reordered stats (mainly memp/mib2)
|
||||
|
||||
(1.4.0)
|
||||
|
||||
++ Application changes:
|
||||
|
||||
* Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for
|
||||
compatibility to old applications, but will be removed in the future).
|
||||
|
||||
* Renamed mem_realloc() to mem_trim() to prevent confusion with realloc()
|
||||
|
||||
+++ Raw API:
|
||||
* Changed the semantics of tcp_close() (since it was rather a
|
||||
shutdown before): Now the application does *NOT* get any calls to the recv
|
||||
callback (aside from NULL/closed) after calling tcp_close()
|
||||
|
||||
* When calling tcp_abort() from a raw API TCP callback function,
|
||||
make sure you return ERR_ABRT to prevent accessing unallocated memory.
|
||||
(ERR_ABRT now means the applicaiton has called tcp_abort!)
|
||||
|
||||
+++ Netconn API:
|
||||
* Changed netconn_receive() and netconn_accept() to return
|
||||
err_t, not a pointer to new data/netconn.
|
||||
|
||||
+++ Socket API:
|
||||
* LWIP_SO_RCVTIMEO: when accept() or recv() time out, they
|
||||
now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT.
|
||||
|
||||
* Added a minimal version of posix fctl() to have a
|
||||
standardised way to set O_NONBLOCK for nonblocking sockets.
|
||||
|
||||
+++ all APIs:
|
||||
* correctly implemented SO(F)_REUSEADDR
|
||||
|
||||
++ Port changes
|
||||
|
||||
+++ new files:
|
||||
|
||||
* Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h:
|
||||
|
||||
* Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains
|
||||
the actual application programmer's API
|
||||
|
||||
* Separated timer implementation from sys.h/.c, moved to timers.h/.c;
|
||||
Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you
|
||||
still want to use your own timer implementation for NO_SYS==0 (as before).
|
||||
|
||||
+++ sys layer:
|
||||
|
||||
* Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/
|
||||
sys_sem_t;
|
||||
|
||||
* Converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
|
||||
|
||||
* Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use
|
||||
binary semaphores instead of mutexes - as before)
|
||||
|
||||
+++ new options:
|
||||
|
||||
* Don't waste memory when chaining segments, added option TCP_OVERSIZE to
|
||||
prevent creating many small pbufs when calling tcp_write with many small
|
||||
blocks of data. Instead, pbufs are allocated larger than needed and the
|
||||
space is used for later calls to tcp_write.
|
||||
|
||||
* Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs
|
||||
in tcp_write/udp_send.
|
||||
|
||||
* Added an additional option LWIP_ETHERNET to support ethernet without ARP
|
||||
(necessary for pure PPPoE)
|
||||
|
||||
* Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may
|
||||
be used to place these pools into user-defined memory by using external
|
||||
declaration.
|
||||
|
||||
* Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT
|
||||
|
||||
+++ new pools:
|
||||
|
||||
* Netdb uses a memp pool for allocating memory when getaddrinfo() is called,
|
||||
so MEMP_NUM_NETDB has to be set accordingly.
|
||||
|
||||
* DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so
|
||||
MEMP_NUM_LOCALHOSTLIST has to be set accordingly.
|
||||
|
||||
* Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have
|
||||
to be set accordingly.
|
||||
|
||||
* PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES
|
||||
has to be set accordingly
|
||||
|
||||
* Integrated loopif into netif.c - loopif does not have to be created by the
|
||||
port any more, just define LWIP_HAVE_LOOPIF to 1.
|
||||
|
||||
* Added define LWIP_RAND() for lwip-wide randomization (needs to be defined
|
||||
in cc.h, e.g. used by igmp)
|
||||
|
||||
* Added printf-formatter X8_F to printf u8_t as hex
|
||||
|
||||
* The heap now may be moved to user-defined memory by defining
|
||||
LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
|
||||
|
||||
* added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work
|
||||
with user-allocated structs instead of calling mem_malloc
|
||||
|
||||
* Added const char* name to mem- and memp-stats for easier debugging.
|
||||
|
||||
* Calculate the TCP/UDP checksum while copying to only fetch data once:
|
||||
Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
|
||||
|
||||
* Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
|
||||
more than one pcb.
|
||||
|
||||
* Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
|
||||
off any more, if this is set to 0, only one packet (the most recent one) is
|
||||
queued (like demanded by RFC 1122).
|
||||
|
||||
|
||||
++ Major bugfixes/improvements
|
||||
|
||||
* Implemented tcp_shutdown() to only shut down one end of a connection
|
||||
* Implemented shutdown() at socket- and netconn-level
|
||||
* Added errorset support to select() + improved select speed overhead
|
||||
* Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x)
|
||||
* Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1
|
||||
* Use macros defined in ip_addr.h to work with IP addresses
|
||||
* Implemented many nonblocking socket/netconn functions
|
||||
* Fixed ARP input processing: only add a new entry if a request was directed as us
|
||||
* mem_realloc() to mem_trim() to prevent confusion with realloc()
|
||||
* Some improvements for AutoIP (don't route/forward link-local addresses, don't break
|
||||
existing connections when assigning a routable address)
|
||||
* Correctly handle remote side overrunning our rcv_wnd in ooseq case
|
||||
* Removed packing from ip_addr_t, the packed version is now only used in protocol headers
|
||||
* Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0
|
||||
* Added support for static ARP table entries
|
||||
|
||||
(STABLE-1.3.2)
|
||||
|
||||
* initial version of this file
|
||||
9
sdk/component/common/network/lwip/lwip_v2.0.2/doc/FILES
Normal file
9
sdk/component/common/network/lwip/lwip_v2.0.2/doc/FILES
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
doxygen/ - Configuration files and scripts to create the lwIP doxygen source
|
||||
documentation (found at http://www.nongnu.org/lwip/)
|
||||
|
||||
savannah.txt - How to obtain the current development source code.
|
||||
contrib.txt - How to contribute to lwIP as a developer.
|
||||
rawapi.txt - The documentation for the core API of lwIP.
|
||||
Also provides an overview about the other APIs and multithreading.
|
||||
sys_arch.txt - The documentation for a system abstraction layer of lwIP.
|
||||
ppp.txt - Documentation of the PPP interface for lwIP.
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
1 Introduction
|
||||
|
||||
This document describes some guidelines for people participating
|
||||
in lwIP development.
|
||||
|
||||
2 How to contribute to lwIP
|
||||
|
||||
Here is a short list of suggestions to anybody working with lwIP and
|
||||
trying to contribute bug reports, fixes, enhancements, platform ports etc.
|
||||
First of all as you may already know lwIP is a volunteer project so feedback
|
||||
to fixes or questions might often come late. Hopefully the bug and patch tracking
|
||||
features of Savannah help us not lose users' input.
|
||||
|
||||
2.1 Source code style:
|
||||
|
||||
1. do not use tabs.
|
||||
2. indentation is two spaces per level (i.e. per tab).
|
||||
3. end debug messages with a trailing newline (\n).
|
||||
4. one space between keyword and opening bracket.
|
||||
5. no space between function and opening bracket.
|
||||
6. one space and no newline before opening curly braces of a block.
|
||||
7. closing curly brace on a single line.
|
||||
8. spaces surrounding assignment and comparisons.
|
||||
9. don't initialize static and/or global variables to zero, the compiler takes care of that.
|
||||
10. use current source code style as further reference.
|
||||
|
||||
2.2 Source code documentation style:
|
||||
|
||||
1. JavaDoc compliant and Doxygen compatible.
|
||||
2. Function documentation above functions in .c files, not .h files.
|
||||
(This forces you to synchronize documentation and implementation.)
|
||||
3. Use current documentation style as further reference.
|
||||
|
||||
2.3 Bug reports and patches:
|
||||
|
||||
1. Make sure you are reporting bugs or send patches against the latest
|
||||
sources. (From the latest release and/or the current Git sources.)
|
||||
2. If you think you found a bug make sure it's not already filed in the
|
||||
bugtracker at Savannah.
|
||||
3. If you have a fix put the patch on Savannah. If it is a patch that affects
|
||||
both core and arch specific stuff please separate them so that the core can
|
||||
be applied separately while leaving the other patch 'open'. The preferred way
|
||||
is to NOT touch archs you can't test and let maintainers take care of them.
|
||||
This is a good way to see if they are used at all - the same goes for unix
|
||||
netifs except tapif.
|
||||
4. Do not file a bug and post a fix to it to the patch area. Either a bug report
|
||||
or a patch will be enough.
|
||||
If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area.
|
||||
5. Patches should be specific to a single change or to related changes. Do not mix bugfixes with spelling and other
|
||||
trivial fixes unless the bugfix is trivial too. Do not reorganize code and rename identifiers in the same patch you
|
||||
change behaviour if not necessary. A patch is easier to read and understand if it's to the point and short than
|
||||
if it's not to the point and long :) so the chances for it to be applied are greater.
|
||||
|
||||
2.4 Platform porters:
|
||||
|
||||
1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and
|
||||
you think it could benefit others[1] you might want discuss this on the mailing list. You
|
||||
can also ask for Git access to submit and maintain your port in the contrib Git module.
|
||||
|
|
@ -0,0 +1 @@
|
|||
doxygen lwip.Doxyfile
|
||||
3
sdk/component/common/network/lwip/lwip_v2.0.2/doc/doxygen/generate.sh
Executable file
3
sdk/component/common/network/lwip/lwip_v2.0.2/doc/doxygen/generate.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
doxygen lwip.Doxyfile
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* @defgroup lwip lwIP
|
||||
*
|
||||
* @defgroup infrastructure Infrastructure
|
||||
*
|
||||
* @defgroup callbackstyle_api Callback-style APIs
|
||||
* Non thread-safe APIs, callback style for maximum performance and minimum
|
||||
* memory footprint.
|
||||
*
|
||||
* @defgroup sequential_api Sequential-style APIs
|
||||
* Sequential-style APIs, blocking functions. More overhead, but can be called
|
||||
* from any thread except TCPIP thread.
|
||||
*
|
||||
* @defgroup addons Addons
|
||||
*
|
||||
* @defgroup apps Applications
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage Overview
|
||||
* @verbinclude "README"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page upgrading Upgrading
|
||||
* @verbinclude "UPGRADING"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page changelog Changelog
|
||||
* @verbinclude "CHANGELOG"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page contrib How to contribute to lwIP
|
||||
* @verbinclude "contrib.txt"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page pitfalls Common pitfalls
|
||||
*
|
||||
* Multiple Execution Contexts in lwIP code
|
||||
* ========================================
|
||||
*
|
||||
* The most common source of lwIP problems is to have multiple execution contexts
|
||||
* inside the lwIP code.
|
||||
*
|
||||
* lwIP can be used in two basic modes: @ref lwip_nosys (no OS/RTOS
|
||||
* running on target system) or @ref lwip_os (there is an OS running
|
||||
* on the target system).
|
||||
*
|
||||
* Mainloop Mode
|
||||
* -------------
|
||||
* In mainloop mode, only @ref callbackstyle_api can be used.
|
||||
* The user has two possibilities to ensure there is only one
|
||||
* exection context at a time in lwIP:
|
||||
*
|
||||
* 1) Deliver RX ethernet packets directly in interrupt context to lwIP
|
||||
* by calling netif->input directly in interrupt. This implies all lwIP
|
||||
* callback functions are called in IRQ context, which may cause further
|
||||
* problems in application code: IRQ is blocked for a long time, multiple
|
||||
* execution contexts in application code etc. When the application wants
|
||||
* to call lwIP, it only needs to disable interrupts during the call.
|
||||
* If timers are involved, even more locking code is needed to lock out
|
||||
* timer IRQ and ethernet IRQ from each other, assuming these may be nested.
|
||||
*
|
||||
* 2) Run lwIP in a mainloop. There is example code here: @ref lwip_nosys.
|
||||
* lwIP is _ONLY_ called from mainloop callstacks here. The ethernet IRQ
|
||||
* has to put received telegrams into a queue which is polled in the
|
||||
* mainloop. Ensure lwIP is _NEVER_ called from an interrupt, e.g.
|
||||
* some SPI IRQ wants to forward data to udp_send() or tcp_write()!
|
||||
*
|
||||
* OS Mode
|
||||
* -------
|
||||
* In OS mode, @ref callbackstyle_api AND @ref sequential_api can be used.
|
||||
* @ref sequential_api are designed to be called from threads other than
|
||||
* the TCPIP thread, so there is nothing to consider here.
|
||||
* But @ref callbackstyle_api functions must _ONLY_ be called from
|
||||
* TCPIP thread. It is a common error to call these from other threads
|
||||
* or from IRQ contexts. Ethernet RX needs to deliver incoming packets
|
||||
* in the correct way by sending a message to TCPIP thread, this is
|
||||
* implemented in tcpip_input().
|
||||
* Again, ensure lwIP is _NEVER_ called from an interrupt, e.g.
|
||||
* some SPI IRQ wants to forward data to udp_send() or tcp_write()!
|
||||
*
|
||||
* 1) tcpip_callback() can be used get called back from TCPIP thread,
|
||||
* it is safe to call any @ref callbackstyle_api from there.
|
||||
*
|
||||
* 2) Use @ref LWIP_TCPIP_CORE_LOCKING. All @ref callbackstyle_api
|
||||
* functions can be called when lwIP core lock is aquired, see
|
||||
* @ref LOCK_TCPIP_CORE() and @ref UNLOCK_TCPIP_CORE().
|
||||
* These macros cannot be used in an interrupt context!
|
||||
* Note the OS must correctly handle priority inversion for this.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page bugs Reporting bugs
|
||||
* Please report bugs in the lwIP bug tracker at savannah.\n
|
||||
* BEFORE submitting, please check if the bug has already been reported!\n
|
||||
* https://savannah.nongnu.org/bugs/?group=lwip
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lwip_nosys Mainloop mode ("NO_SYS")
|
||||
* @ingroup lwip
|
||||
* Use this mode if you do not run an OS on your system. \#define NO_SYS to 1.
|
||||
* Feed incoming packets to netif->input(pbuf, netif) function from mainloop,
|
||||
* *not* *from* *interrupt* *context*. You can allocate a @ref pbuf in interrupt
|
||||
* context and put them into a queue which is processed from mainloop.\n
|
||||
* Call sys_check_timeouts() periodically in the mainloop.\n
|
||||
* Porting: implement all functions in @ref sys_time, @ref sys_prot and
|
||||
* @ref compiler_abstraction.\n
|
||||
* You can only use @ref callbackstyle_api in this mode.\n
|
||||
* Sample code:\n
|
||||
* @include NO_SYS_SampleCode.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup lwip_os OS mode (TCPIP thread)
|
||||
* @ingroup lwip
|
||||
* Use this mode if you run an OS on your system. It is recommended to
|
||||
* use an RTOS that correctly handles priority inversion and
|
||||
* to use @ref LWIP_TCPIP_CORE_LOCKING.\n
|
||||
* Porting: implement all functions in @ref sys_layer.\n
|
||||
* You can use @ref callbackstyle_api together with @ref tcpip_callback,
|
||||
* and all @ref sequential_api.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page raw_api lwIP API
|
||||
* @verbinclude "rawapi.txt"
|
||||
*/
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Redirection</title>
|
||||
<meta http-equiv="refresh" content="0; url=html/index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="html/index.html">index.html</a>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
113
sdk/component/common/network/lwip/lwip_v2.0.2/doc/mdns.txt
Normal file
113
sdk/component/common/network/lwip/lwip_v2.0.2/doc/mdns.txt
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
Multicast DNS for lwIP
|
||||
|
||||
Author: Erik Ekman
|
||||
|
||||
|
||||
Note! The MDNS responder does not have all features required by the standards.
|
||||
See notes in src/apps/mdns/mdns.c for what is left. It is however usable in normal
|
||||
cases - but watch out if many devices on the same network try to use the same
|
||||
host/service instance names.
|
||||
|
||||
|
||||
How to enable:
|
||||
==============
|
||||
|
||||
MDNS support does not depend on DNS.
|
||||
MDNS supports using IPv4 only, v6 only, or v4+v6.
|
||||
|
||||
To enable MDNS responder, set
|
||||
LWIP_MDNS_RESPONDER = 1
|
||||
in lwipopts.h and add src/apps/mdns/mdns.c to your list of files to build.
|
||||
|
||||
The max number of services supported per netif is defined by MDNS_MAX_SERVICES,
|
||||
default is 1.
|
||||
|
||||
Increase MEMP_NUM_UDP_PCB by 1. MDNS needs one PCB.
|
||||
Increase LWIP_NUM_NETIF_CLIENT_DATA by 1 (MDNS needs one entry on netif).
|
||||
|
||||
MDNS with IPv4 requires LWIP_IGMP = 1, and preferably LWIP_AUTOIP = 1.
|
||||
MDNS with IPv6 requires LWIP_IPV6_MLD = 1, and that a link-local address is
|
||||
generated.
|
||||
|
||||
The MDNS code puts its structs on the stack where suitable to reduce dynamic
|
||||
memory allocation. It may use up to 1kB of stack.
|
||||
|
||||
MDNS needs a strncasecmp() implementation. If you have one, define
|
||||
LWIP_MDNS_STRNCASECMP to it. Otherwise the code will provide an implementation
|
||||
for you.
|
||||
|
||||
|
||||
How to use:
|
||||
===========
|
||||
|
||||
Call mdns_resp_init() during system initialization.
|
||||
This opens UDP sockets on port 5353 for IPv4 and IPv6.
|
||||
|
||||
|
||||
To start responding on a netif, run
|
||||
mdns_resp_add_netif(struct netif *netif, char *hostname, u32_t dns_ttl)
|
||||
|
||||
The hostname will be copied. If this returns successfully, the netif will join
|
||||
the multicast groups and any MDNS/legacy DNS requests sent unicast or multicast
|
||||
to port 5353 will be handled:
|
||||
- <hostname>.local type A, AAAA or ANY returns relevant IP addresses
|
||||
- Reverse lookups (PTR in-addr.arpa, ip6.arpa) of netif addresses
|
||||
returns <hostname>.local
|
||||
Answers will use the supplied TTL (in seconds)
|
||||
MDNS allows UTF-8 names, but it is recommended to stay within ASCII,
|
||||
since the default case-insensitive comparison assumes this.
|
||||
|
||||
It is recommended to call this function after an IPv4 address has been set,
|
||||
since there is currently no check if the v4 address is valid.
|
||||
|
||||
Call mdns_resp_netif_settings_changed() every time the IP address
|
||||
on the netif has changed.
|
||||
|
||||
To stop responding on a netif, run
|
||||
mdns_resp_remove_netif(struct netif *netif)
|
||||
|
||||
|
||||
Adding services:
|
||||
================
|
||||
|
||||
The netif first needs to be registered. Then run
|
||||
mdns_resp_add_service(struct netif *netif, char *name, char *service,
|
||||
u16_t proto, u16_t port, u32_t dns_ttl,
|
||||
service_get_txt_fn_t txt_fn, void *txt_userdata);
|
||||
|
||||
The name and service pointers will be copied. Name refers to the name of the
|
||||
service instance, and service is the type of service, like _http
|
||||
proto can be DNSSD_PROTO_UDP or DNSSD_PROTO_TCP which represent _udp and _tcp.
|
||||
If this call returns successfully, the following queries will be answered:
|
||||
- _services._dns-sd._udp.local type PTR returns <service>.<proto>.local
|
||||
- <service>.<proto>.local type PTR returns <name>.<service>.<proto>.local
|
||||
- <name>.<service>.<proto>.local type SRV returns hostname and port of service
|
||||
- <name>.<service>.<proto>.local type TXT builds text strings by calling txt_fn
|
||||
with the supplied userdata. The callback adds strings to the reply by calling
|
||||
mdns_resp_add_service_txtitem(struct mdns_service *service, char *txt,
|
||||
int txt_len). Example callback method:
|
||||
|
||||
static void srv_txt(struct mdns_service *service, void *txt_userdata)
|
||||
{
|
||||
res = mdns_resp_add_service_txtitem(service, "path=/", 6);
|
||||
LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
|
||||
}
|
||||
|
||||
Since a hostname struct is used for TXT storage each single item can be max
|
||||
63 bytes long, and the total max length (including length bytes for each
|
||||
item) is 255 bytes.
|
||||
|
||||
If your device runs a webserver on port 80, an example call might be:
|
||||
|
||||
mdns_resp_add_service(netif, "myweb", "_http"
|
||||
DNSSD_PROTO_TCP, 80, 3600, srv_txt, NULL);
|
||||
|
||||
which will publish myweb._http._tcp.local for any hosts looking for web servers,
|
||||
and point them to <hostname>.local:80
|
||||
|
||||
Relevant information will be sent as additional records to reduce number of
|
||||
requests required from a client.
|
||||
|
||||
Removing services is currently not supported. Services are removed when the
|
||||
netif is removed.
|
||||
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
MQTT client for lwIP
|
||||
|
||||
Author: Erik Andersson
|
||||
|
||||
Details of the MQTT protocol can be found at:
|
||||
http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
|
||||
|
||||
-----------------------------------------------------------------
|
||||
1. Initial steps, reserve memory and make connection to server:
|
||||
|
||||
1.1: Provide storage
|
||||
|
||||
Static allocation:
|
||||
mqtt_client_t static_client;
|
||||
example_do_connect(&static_client);
|
||||
|
||||
Dynamic allocation:
|
||||
mqtt_client_t *client = mqtt_client_new();
|
||||
if(client != NULL) {
|
||||
example_do_connect(&client);
|
||||
}
|
||||
|
||||
1.2: Establish Connection with server
|
||||
|
||||
void example_do_connect(mqtt_client_t *client)
|
||||
{
|
||||
struct mqtt_connect_client_info_t ci;
|
||||
err_t err;
|
||||
|
||||
/* Setup an empty client info structure */
|
||||
memset(&ci, 0, sizeof(ci));
|
||||
|
||||
/* Minimal amount of information required is client identifier, so set it here */
|
||||
ci.client_id = "lwip_test";
|
||||
|
||||
/* Initiate client and connect to server, if this fails immediately an error code is returned
|
||||
otherwise mqtt_connection_cb will be called with connection result after attempting
|
||||
to establish a connection with the server.
|
||||
For now MQTT version 3.1.1 is always used */
|
||||
|
||||
err = mqtt_client_connect(client, ip_addr, MQTT_PORT, mqtt_connection_cb, 0, &ci);
|
||||
|
||||
/* For now just print the result code if something goes wrong
|
||||
if(err != ERR_OK) {
|
||||
printf("mqtt_connect return %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
Connection to server can also be probed by calling mqtt_client_is_connected(client)
|
||||
|
||||
-----------------------------------------------------------------
|
||||
2. Implementing the connection status callback
|
||||
|
||||
|
||||
static void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
|
||||
{
|
||||
err_t err;
|
||||
if(status == MQTT_CONNECT_ACCEPTED) {
|
||||
printf("mqtt_connection_cb: Successfully connected\n");
|
||||
|
||||
/* Setup callback for incoming publish requests */
|
||||
mqtt_set_inpub_callback(client, mqtt_incoming_publish_cb, mqtt_incoming_data_cb, arg);
|
||||
|
||||
/* Subscribe to a topic named "subtopic" with QoS level 1, call mqtt_sub_request_cb with result */
|
||||
err = mqtt_subscribe(client, "subtopic", 1, mqtt_sub_request_cb, arg);
|
||||
|
||||
if(err != ERR_OK) {
|
||||
printf("mqtt_subscribe return: %d\n", err);
|
||||
}
|
||||
} else {
|
||||
printf("mqtt_connection_cb: Disconnected, reason: %d\n", status);
|
||||
|
||||
/* Its more nice to be connected, so try to reconnect */
|
||||
example_do_connect(client);
|
||||
}
|
||||
}
|
||||
|
||||
static void mqtt_sub_request_cb(void *arg, err_t result)
|
||||
{
|
||||
/* Just print the result code here for simplicity,
|
||||
normal behaviour would be to take some action if subscribe fails like
|
||||
notifying user, retry subscribe or disconnect from server */
|
||||
printf("Subscribe result: %d\n", result);
|
||||
}
|
||||
|
||||
-----------------------------------------------------------------
|
||||
3. Implementing callbacks for incoming publish and data
|
||||
|
||||
/* The idea is to demultiplex topic and create some reference to be used in data callbacks
|
||||
Example here uses a global variable, better would be to use a member in arg
|
||||
If RAM and CPU budget allows it, the easiest implementation might be to just take a copy of
|
||||
the topic string and use it in mqtt_incoming_data_cb
|
||||
*/
|
||||
static int inpub_id;
|
||||
static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
|
||||
{
|
||||
printf("Incoming publish at topic %s with total length %u\n", topic, (unsigned int)tot_len);
|
||||
|
||||
/* Decode topic string into a user defined reference */
|
||||
if(strcmp(topic, "print_payload") == 0) {
|
||||
inpub_id = 0;
|
||||
} else if(topic[0] == 'A') {
|
||||
/* All topics starting with 'A' might be handled at the same way */
|
||||
inpub_id = 1;
|
||||
} else {
|
||||
/* For all other topics */
|
||||
inpub_id = 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
|
||||
{
|
||||
printf("Incoming publish payload with length %d, flags %u\n", len, (unsigned int)flags);
|
||||
|
||||
if(flags & MQTT_DATA_FLAG_LAST) {
|
||||
/* Last fragment of payload received (or whole part if payload fits receive buffer
|
||||
See MQTT_VAR_HEADER_BUFFER_LEN) */
|
||||
|
||||
/* Call function or do action depending on reference, in this case inpub_id */
|
||||
if(inpub_id == 0) {
|
||||
/* Don't trust the publisher, check zero termination */
|
||||
if(data[len-1] == 0) {
|
||||
printf("mqtt_incoming_data_cb: %s\n", (const char *)data);
|
||||
}
|
||||
} else if(inpub_id == 1) {
|
||||
/* Call an 'A' function... */
|
||||
} else {
|
||||
printf("mqtt_incoming_data_cb: Ignoring payload...\n");
|
||||
}
|
||||
} else {
|
||||
/* Handle fragmented payload, store in buffer, write to file or whatever */
|
||||
}
|
||||
}
|
||||
|
||||
-----------------------------------------------------------------
|
||||
4. Using outgoing publish
|
||||
|
||||
|
||||
void example_publish(mqtt_client_t *client, void *arg)
|
||||
{
|
||||
const char *pub_payload= "PubSubHubLubJub";
|
||||
err_t err;
|
||||
u8_t qos = 2; /* 0 1 or 2, see MQTT specification */
|
||||
u8_t retain = 0; /* No don't retain such crappy payload... */
|
||||
err = mqtt_publish(client, "pub_topic", pub_payload, strlen(pub_payload), qos, retain, mqtt_pub_request_cb, arg);
|
||||
if(err != ERR_OK) {
|
||||
printf("Publish err: %d\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when publish is complete either with sucess or failure */
|
||||
static void mqtt_pub_request_cb(void *arg, err_t result)
|
||||
{
|
||||
if(result != ERR_OK) {
|
||||
printf("Publish result: %d\n", result);
|
||||
}
|
||||
}
|
||||
|
||||
-----------------------------------------------------------------
|
||||
5. Disconnecting
|
||||
|
||||
Simply call mqtt_disconnect(client)
|
||||
529
sdk/component/common/network/lwip/lwip_v2.0.2/doc/ppp.txt
Normal file
529
sdk/component/common/network/lwip/lwip_v2.0.2/doc/ppp.txt
Normal file
|
|
@ -0,0 +1,529 @@
|
|||
PPP interface for lwIP
|
||||
|
||||
Author: Sylvain Rochet
|
||||
|
||||
Table of Contents:
|
||||
|
||||
1 - Supported PPP protocols and features
|
||||
2 - Raw API PPP example for all protocols
|
||||
3 - PPPoS input path (raw API, IRQ safe API, TCPIP API)
|
||||
4 - Thread safe PPP API (PPPAPI)
|
||||
5 - Notify phase callback (PPP_NOTIFY_PHASE)
|
||||
6 - Upgrading from lwIP <= 1.4.x to lwIP >= 2.0.x
|
||||
|
||||
|
||||
|
||||
1 Supported PPP protocols and features
|
||||
======================================
|
||||
|
||||
Supported Low level protocols:
|
||||
* PPP over serial using HDLC-like framing, such as wired dialup modems
|
||||
or mobile telecommunications GPRS/EDGE/UMTS/HSPA+/LTE modems
|
||||
* PPP over Ethernet, such as xDSL modems
|
||||
* PPP over L2TP (Layer 2 Tunneling Protocol) LAC (L2TP Access Concentrator),
|
||||
IP tunnel over UDP, such as VPN access
|
||||
|
||||
Supported auth protocols:
|
||||
* PAP, Password Authentication Protocol
|
||||
* CHAP, Challenge-Handshake Authentication Protocol, also known as CHAP-MD5
|
||||
* MSCHAPv1, Microsoft version of CHAP, version 1
|
||||
* MSCHAPv2, Microsoft version of CHAP, version 2
|
||||
* EAP, Extensible Authentication Protocol
|
||||
|
||||
Supported address protocols:
|
||||
* IPCP, IP Control Protocol, IPv4 addresses negotiation
|
||||
* IP6CP, IPv6 Control Protocol, IPv6 link-local addresses negotiation
|
||||
|
||||
Supported encryption protocols:
|
||||
* MPPE, Microsoft Point-to-Point Encryption
|
||||
|
||||
Supported compression or miscellaneous protocols, for serial links only:
|
||||
* PFC, Protocol Field Compression
|
||||
* ACFC, Address-and-Control-Field-Compression
|
||||
* ACCM, Asynchronous-Control-Character-Map
|
||||
* VJ, Van Jacobson TCP/IP Header Compression
|
||||
|
||||
|
||||
|
||||
2 Raw API PPP example for all protocols
|
||||
=======================================
|
||||
|
||||
As usual, raw API for lwIP means the lightweight API which *MUST* only be used
|
||||
for NO_SYS=1 systems or called inside lwIP core thread for NO_SYS=0 systems.
|
||||
|
||||
/*
|
||||
* Globals
|
||||
* =======
|
||||
*/
|
||||
|
||||
/* The PPP control block */
|
||||
ppp_pcb *ppp;
|
||||
|
||||
/* The PPP IP interface */
|
||||
struct netif ppp_netif;
|
||||
|
||||
|
||||
/*
|
||||
* PPP status callback
|
||||
* ===================
|
||||
*
|
||||
* PPP status callback is called on PPP status change (up, down, …) from lwIP
|
||||
* core thread
|
||||
*/
|
||||
|
||||
/* PPP status callback example */
|
||||
static void status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
|
||||
struct netif *pppif = ppp_netif(pcb);
|
||||
LWIP_UNUSED_ARG(ctx);
|
||||
|
||||
switch(err_code) {
|
||||
case PPPERR_NONE: {
|
||||
#if LWIP_DNS
|
||||
const ip_addr_t *ns;
|
||||
#endif /* LWIP_DNS */
|
||||
printf("status_cb: Connected\n");
|
||||
#if PPP_IPV4_SUPPORT
|
||||
printf(" our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr));
|
||||
printf(" his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw));
|
||||
printf(" netmask = %s\n", ipaddr_ntoa(&pppif->netmask));
|
||||
#if LWIP_DNS
|
||||
ns = dns_getserver(0);
|
||||
printf(" dns1 = %s\n", ipaddr_ntoa(ns));
|
||||
ns = dns_getserver(1);
|
||||
printf(" dns2 = %s\n", ipaddr_ntoa(ns));
|
||||
#endif /* LWIP_DNS */
|
||||
#endif /* PPP_IPV4_SUPPORT */
|
||||
#if PPP_IPV6_SUPPORT
|
||||
printf(" our6_ipaddr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0)));
|
||||
#endif /* PPP_IPV6_SUPPORT */
|
||||
break;
|
||||
}
|
||||
case PPPERR_PARAM: {
|
||||
printf("status_cb: Invalid parameter\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_OPEN: {
|
||||
printf("status_cb: Unable to open PPP session\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_DEVICE: {
|
||||
printf("status_cb: Invalid I/O device for PPP\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_ALLOC: {
|
||||
printf("status_cb: Unable to allocate resources\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_USER: {
|
||||
printf("status_cb: User interrupt\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_CONNECT: {
|
||||
printf("status_cb: Connection lost\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_AUTHFAIL: {
|
||||
printf("status_cb: Failed authentication challenge\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_PROTOCOL: {
|
||||
printf("status_cb: Failed to meet protocol\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_PEERDEAD: {
|
||||
printf("status_cb: Connection timeout\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_IDLETIMEOUT: {
|
||||
printf("status_cb: Idle Timeout\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_CONNECTTIME: {
|
||||
printf("status_cb: Max connect time reached\n");
|
||||
break;
|
||||
}
|
||||
case PPPERR_LOOPBACK: {
|
||||
printf("status_cb: Loopback detected\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
printf("status_cb: Unknown error code %d\n", err_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be in the switch case, this is put outside of the switch
|
||||
* case for example readability.
|
||||
*/
|
||||
|
||||
if (err_code == PPPERR_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* ppp_close() was previously called, don't reconnect */
|
||||
if (err_code == PPPERR_USER) {
|
||||
/* ppp_free(); -- can be called here */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to reconnect in 30 seconds, if you need a modem chatscript you have
|
||||
* to do a much better signaling here ;-)
|
||||
*/
|
||||
ppp_connect(pcb, 30);
|
||||
/* OR ppp_listen(pcb); */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creating a new PPPoS session
|
||||
* ============================
|
||||
*
|
||||
* In lwIP, PPPoS is not PPPoSONET, in lwIP PPPoS is PPPoSerial.
|
||||
*/
|
||||
|
||||
#include "netif/ppp/pppos.h"
|
||||
|
||||
/*
|
||||
* PPPoS serial output callback
|
||||
*
|
||||
* ppp_pcb, PPP control block
|
||||
* data, buffer to write to serial port
|
||||
* len, length of the data buffer
|
||||
* ctx, optional user-provided callback context pointer
|
||||
*
|
||||
* Return value: len if write succeed
|
||||
*/
|
||||
static u32_t output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) {
|
||||
return uart_write(UART, data, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new PPPoS interface
|
||||
*
|
||||
* ppp_netif, netif to use for this PPP link, i.e. PPP IP interface
|
||||
* output_cb, PPPoS serial output callback
|
||||
* status_cb, PPP status callback, called on PPP status change (up, down, …)
|
||||
* ctx_cb, optional user-provided callback context pointer
|
||||
*/
|
||||
ppp = pppos_create(&ppp_netif,
|
||||
output_cb, status_cb, ctx_cb);
|
||||
|
||||
|
||||
/*
|
||||
* Creating a new PPPoE session
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#include "netif/ppp/pppoe.h"
|
||||
|
||||
/*
|
||||
* Create a new PPPoE interface
|
||||
*
|
||||
* ppp_netif, netif to use for this PPP link, i.e. PPP IP interface
|
||||
* ethif, already existing and setup Ethernet interface to use
|
||||
* service_name, PPPoE service name discriminator (not supported yet)
|
||||
* concentrator_name, PPPoE concentrator name discriminator (not supported yet)
|
||||
* status_cb, PPP status callback, called on PPP status change (up, down, …)
|
||||
* ctx_cb, optional user-provided callback context pointer
|
||||
*/
|
||||
ppp = pppoe_create(&ppp_netif,
|
||||
ðif,
|
||||
service_name, concentrator_name,
|
||||
status_cb, ctx_cb);
|
||||
|
||||
|
||||
/*
|
||||
* Creating a new PPPoL2TP session
|
||||
* ===============================
|
||||
*/
|
||||
|
||||
#include "netif/ppp/pppol2tp.h"
|
||||
|
||||
/*
|
||||
* Create a new PPPoL2TP interface
|
||||
*
|
||||
* ppp_netif, netif to use for this PPP link, i.e. PPP IP interface
|
||||
* netif, optional already existing and setup output netif, necessary if you
|
||||
* want to set this interface as default route to settle the chicken
|
||||
* and egg problem with VPN links
|
||||
* ipaddr, IP to connect to
|
||||
* port, UDP port to connect to (usually 1701)
|
||||
* secret, L2TP secret to use
|
||||
* secret_len, size in bytes of the L2TP secret
|
||||
* status_cb, PPP status callback, called on PPP status change (up, down, …)
|
||||
* ctx_cb, optional user-provided callback context pointer
|
||||
*/
|
||||
ppp = pppol2tp_create(&ppp_netif,
|
||||
struct netif *netif, ip_addr_t *ipaddr, u16_t port,
|
||||
u8_t *secret, u8_t secret_len,
|
||||
ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
|
||||
|
||||
|
||||
/*
|
||||
* Initiate PPP client connection
|
||||
* ==============================
|
||||
*/
|
||||
|
||||
/* Set this interface as default route */
|
||||
ppp_set_default(ppp);
|
||||
|
||||
/*
|
||||
* Basic PPP client configuration. Can only be set if PPP session is in the
|
||||
* dead state (i.e. disconnected). We don't need to provide thread-safe
|
||||
* equivalents through PPPAPI because those helpers are only changing
|
||||
* structure members while session is inactive for lwIP core. Configuration
|
||||
* only need to be done once.
|
||||
*/
|
||||
|
||||
/* Ask the peer for up to 2 DNS server addresses. */
|
||||
ppp_set_usepeerdns(ppp, 1);
|
||||
|
||||
/* Auth configuration, this is pretty self-explanatory */
|
||||
ppp_set_auth(ppp, PPPAUTHTYPE_ANY, "login", "password");
|
||||
|
||||
/*
|
||||
* Initiate PPP negotiation, without waiting (holdoff=0), can only be called
|
||||
* if PPP session is in the dead state (i.e. disconnected).
|
||||
*/
|
||||
u16_t holdoff = 0;
|
||||
ppp_connect(ppp, holdoff);
|
||||
|
||||
|
||||
/*
|
||||
* Initiate PPP server listener
|
||||
* ============================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Basic PPP server configuration. Can only be set if PPP session is in the
|
||||
* dead state (i.e. disconnected). We don't need to provide thread-safe
|
||||
* equivalents through PPPAPI because those helpers are only changing
|
||||
* structure members while session is inactive for lwIP core. Configuration
|
||||
* only need to be done once.
|
||||
*/
|
||||
ip4_addr_t addr;
|
||||
|
||||
/* Set our address */
|
||||
IP4_ADDR(&addr, 192,168,0,1);
|
||||
ppp_set_ipcp_ouraddr(ppp, &addr);
|
||||
|
||||
/* Set peer(his) address */
|
||||
IP4_ADDR(&addr, 192,168,0,2);
|
||||
ppp_set_ipcp_hisaddr(ppp, &addr);
|
||||
|
||||
/* Set primary DNS server */
|
||||
IP4_ADDR(&addr, 192,168,10,20);
|
||||
ppp_set_ipcp_dnsaddr(ppp, 0, &addr);
|
||||
|
||||
/* Set secondary DNS server */
|
||||
IP4_ADDR(&addr, 192,168,10,21);
|
||||
ppp_set_ipcp_dnsaddr(ppp, 1, &addr);
|
||||
|
||||
/* Auth configuration, this is pretty self-explanatory */
|
||||
ppp_set_auth(ppp, PPPAUTHTYPE_ANY, "login", "password");
|
||||
|
||||
/* Require peer to authenticate */
|
||||
ppp_set_auth_required(ppp, 1);
|
||||
|
||||
/*
|
||||
* Only for PPPoS, the PPP session should be up and waiting for input.
|
||||
*
|
||||
* Note: for PPPoS, ppp_connect() and ppp_listen() are actually the same thing.
|
||||
* The listen call is meant for future support of PPPoE and PPPoL2TP server
|
||||
* mode, where we will need to negotiate the incoming PPPoE session or L2TP
|
||||
* session before initiating PPP itself. We need this call because there is
|
||||
* two passive modes for PPPoS, ppp_set_passive and ppp_set_silent.
|
||||
*/
|
||||
ppp_set_silent(pppos, 1);
|
||||
|
||||
/*
|
||||
* Initiate PPP listener (i.e. wait for an incoming connection), can only
|
||||
* be called if PPP session is in the dead state (i.e. disconnected).
|
||||
*/
|
||||
ppp_listen(ppp);
|
||||
|
||||
|
||||
/*
|
||||
* Closing PPP connection
|
||||
* ======================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initiate the end of the PPP session, without carrier lost signal
|
||||
* (nocarrier=0), meaning a clean shutdown of PPP protocols.
|
||||
* You can call this function at anytime.
|
||||
*/
|
||||
u8_t nocarrier = 0;
|
||||
ppp_close(ppp, nocarrier);
|
||||
/*
|
||||
* Then you must wait your status_cb() to be called, it may takes from a few
|
||||
* seconds to several tens of seconds depending on the current PPP state.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Freeing a PPP connection
|
||||
* ========================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Free the PPP control block, can only be called if PPP session is in the
|
||||
* dead state (i.e. disconnected). You need to call ppp_close() before.
|
||||
*/
|
||||
ppp_free(ppp);
|
||||
|
||||
|
||||
|
||||
3 PPPoS input path (raw API, IRQ safe API, TCPIP API)
|
||||
=====================================================
|
||||
|
||||
Received data on serial port should be sent to lwIP using the pppos_input()
|
||||
function or the pppos_input_tcpip() function.
|
||||
|
||||
If NO_SYS is 1 and if PPP_INPROC_IRQ_SAFE is 0 (the default), pppos_input()
|
||||
is not IRQ safe and then *MUST* only be called inside your main loop.
|
||||
|
||||
Whatever the NO_SYS value, if PPP_INPROC_IRQ_SAFE is 1, pppos_input() is IRQ
|
||||
safe and can be safely called from an interrupt context, using that is going
|
||||
to reduce your need of buffer if pppos_input() is called byte after byte in
|
||||
your rx serial interrupt.
|
||||
|
||||
if NO_SYS is 0, the thread safe way outside an interrupt context is to use
|
||||
the pppos_input_tcpip() function to pass input data to the lwIP core thread
|
||||
using the TCPIP API. This is thread safe in all cases but you should avoid
|
||||
passing data byte after byte because it uses heavy locking (mailbox) and it
|
||||
allocates pbuf, better fill them !
|
||||
|
||||
if NO_SYS is 0 and if PPP_INPROC_IRQ_SAFE is 1, you may also use pppos_input()
|
||||
from an RX thread, however pppos_input() is not thread safe by itself. You can
|
||||
do that *BUT* you should NEVER call pppos_connect(), pppos_listen() and
|
||||
ppp_free() if pppos_input() can still be running, doing this is NOT thread safe
|
||||
at all. Using PPP_INPROC_IRQ_SAFE from an RX thread is discouraged unless you
|
||||
really know what you are doing, your move ;-)
|
||||
|
||||
|
||||
/*
|
||||
* Fonction to call for received data
|
||||
*
|
||||
* ppp, PPP control block
|
||||
* buffer, input buffer
|
||||
* buffer_len, buffer length in bytes
|
||||
*/
|
||||
void pppos_input(ppp, buffer, buffer_len);
|
||||
|
||||
or
|
||||
|
||||
void pppos_input_tcpip(ppp, buffer, buffer_len);
|
||||
|
||||
|
||||
|
||||
4 Thread safe PPP API (PPPAPI)
|
||||
==============================
|
||||
|
||||
There is a thread safe API for all corresponding ppp_* functions, you have to
|
||||
enable LWIP_PPP_API in your lwipopts.h file, then see
|
||||
include/netif/ppp/pppapi.h, this is actually pretty obvious.
|
||||
|
||||
|
||||
|
||||
5 Notify phase callback (PPP_NOTIFY_PHASE)
|
||||
==========================================
|
||||
|
||||
Notify phase callback, enabled using the PPP_NOTIFY_PHASE config option, let
|
||||
you configure a callback that is called on each PPP internal state change.
|
||||
This is different from the status callback which only warns you about
|
||||
up(running) and down(dead) events.
|
||||
|
||||
Notify phase callback can be used, for example, to set a LED pattern depending
|
||||
on the current phase of the PPP session. Here is a callback example which
|
||||
tries to mimic what we usually see on xDSL modems while they are negotiating
|
||||
the link, which should be self-explanatory:
|
||||
|
||||
static void ppp_notify_phase_cb(ppp_pcb *pcb, u8_t phase, void *ctx) {
|
||||
switch (phase) {
|
||||
|
||||
/* Session is down (either permanently or briefly) */
|
||||
case PPP_PHASE_DEAD:
|
||||
led_set(PPP_LED, LED_OFF);
|
||||
break;
|
||||
|
||||
/* We are between two sessions */
|
||||
case PPP_PHASE_HOLDOFF:
|
||||
led_set(PPP_LED, LED_SLOW_BLINK);
|
||||
break;
|
||||
|
||||
/* Session just started */
|
||||
case PPP_PHASE_INITIALIZE:
|
||||
led_set(PPP_LED, LED_FAST_BLINK);
|
||||
break;
|
||||
|
||||
/* Session is running */
|
||||
case PPP_PHASE_RUNNING:
|
||||
led_set(PPP_LED, LED_ON);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
6 Upgrading from lwIP <= 1.4.x to lwIP >= 2.0.x
|
||||
===============================================
|
||||
|
||||
PPP API was fully reworked between 1.4.x and 2.0.x releases. However porting
|
||||
from previous lwIP version is pretty easy:
|
||||
|
||||
* Previous PPP API used an integer to identify PPP sessions, we are now
|
||||
using ppp_pcb* control block, therefore all functions changed from "int ppp"
|
||||
to "ppp_pcb *ppp"
|
||||
|
||||
* struct netif was moved outside the PPP structure, you have to provide a netif
|
||||
for PPP interface in pppoX_create() functions
|
||||
|
||||
* PPP session are not started automatically after you created them anymore,
|
||||
you have to call ppp_connect(), this way you can configure the session before
|
||||
starting it.
|
||||
|
||||
* Previous PPP API used CamelCase, we are now using snake_case.
|
||||
|
||||
* Previous PPP API mixed PPPoS and PPPoE calls, this isn't the case anymore,
|
||||
PPPoS functions are now prefixed pppos_ and PPPoE functions are now prefixed
|
||||
pppoe_, common functions are now prefixed ppp_.
|
||||
|
||||
* New PPPERR_ error codes added, check you have all of them in your status
|
||||
callback function
|
||||
|
||||
* Only the following include files should now be used in user application:
|
||||
#include "netif/ppp/pppapi.h"
|
||||
#include "netif/ppp/pppos.h"
|
||||
#include "netif/ppp/pppoe.h"
|
||||
#include "netif/ppp/pppol2tp.h"
|
||||
|
||||
Functions from ppp.h can be used, but you don't need to include this header
|
||||
file as it is already included by above header files.
|
||||
|
||||
* PPP_INPROC_OWNTHREAD was broken by design and was removed, you have to create
|
||||
your own serial rx thread
|
||||
|
||||
* PPP_INPROC_MULTITHREADED option was misnamed and confusing and was renamed
|
||||
PPP_INPROC_IRQ_SAFE, please read the "PPPoS input path" documentation above
|
||||
because you might have been fooled by that
|
||||
|
||||
* If you used tcpip_callback_with_block() on ppp_ functions you may wish to use
|
||||
the PPPAPI API instead.
|
||||
|
||||
* ppp_sighup and ppp_close functions were merged using an optional argument
|
||||
"nocarrier" on ppp_close.
|
||||
|
||||
* DNS servers are now only remotely asked if LWIP_DNS is set and if
|
||||
ppp_set_usepeerdns() is set to true, they are now automatically registered
|
||||
using the dns_setserver() function so you don't need to do that in the PPP
|
||||
callback anymore.
|
||||
|
||||
* PPPoS does not use the SIO API anymore, as such it now requires a serial
|
||||
output callback in place of sio_write
|
||||
|
||||
* PPP_MAXIDLEFLAG is now in ms instead of jiffies
|
||||
499
sdk/component/common/network/lwip/lwip_v2.0.2/doc/rawapi.txt
Normal file
499
sdk/component/common/network/lwip/lwip_v2.0.2/doc/rawapi.txt
Normal file
|
|
@ -0,0 +1,499 @@
|
|||
Raw TCP/IP interface for lwIP
|
||||
|
||||
Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons
|
||||
|
||||
lwIP provides three Application Program's Interfaces (APIs) for programs
|
||||
to use for communication with the TCP/IP code:
|
||||
* low-level "core" / "callback" or "raw" API.
|
||||
* higher-level "sequential" API.
|
||||
* BSD-style socket API.
|
||||
|
||||
The raw API (sometimes called native API) is an event-driven API designed
|
||||
to be used without an operating system that implements zero-copy send and
|
||||
receive. This API is also used by the core stack for interaction between
|
||||
the various protocols. It is the only API available when running lwIP
|
||||
without an operating system.
|
||||
|
||||
The sequential API provides a way for ordinary, sequential, programs
|
||||
to use the lwIP stack. It is quite similar to the BSD socket API. The
|
||||
model of execution is based on the blocking open-read-write-close
|
||||
paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP
|
||||
code and the application program must reside in different execution
|
||||
contexts (threads).
|
||||
|
||||
The socket API is a compatibility API for existing applications,
|
||||
currently it is built on top of the sequential API. It is meant to
|
||||
provide all functions needed to run socket API applications running
|
||||
on other platforms (e.g. unix / windows etc.). However, due to limitations
|
||||
in the specification of this API, there might be incompatibilities
|
||||
that require small modifications of existing programs.
|
||||
|
||||
** Multithreading
|
||||
|
||||
lwIP started targeting single-threaded environments. When adding multi-
|
||||
threading support, instead of making the core thread-safe, another
|
||||
approach was chosen: there is one main thread running the lwIP core
|
||||
(also known as the "tcpip_thread"). When running in a multithreaded
|
||||
environment, raw API functions MUST only be called from the core thread
|
||||
since raw API functions are not protected from concurrent access (aside
|
||||
from pbuf- and memory management functions). Application threads using
|
||||
the sequential- or socket API communicate with this main thread through
|
||||
message passing.
|
||||
|
||||
As such, the list of functions that may be called from
|
||||
other threads or an ISR is very limited! Only functions
|
||||
from these API header files are thread-safe:
|
||||
- api.h
|
||||
- netbuf.h
|
||||
- netdb.h
|
||||
- netifapi.h
|
||||
- pppapi.h
|
||||
- sockets.h
|
||||
- sys.h
|
||||
|
||||
Additionaly, memory (de-)allocation functions may be
|
||||
called from multiple threads (not ISR!) with NO_SYS=0
|
||||
since they are protected by SYS_LIGHTWEIGHT_PROT and/or
|
||||
semaphores.
|
||||
|
||||
Netconn or Socket API functions are thread safe against the
|
||||
core thread but they are not reentrant at the control block
|
||||
granularity level. That is, a UDP or TCP control block must
|
||||
not be shared among multiple threads without proper locking.
|
||||
|
||||
If SYS_LIGHTWEIGHT_PROT is set to 1 and
|
||||
LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1,
|
||||
pbuf_free() may also be called from another thread or
|
||||
an ISR (since only then, mem_free - for PBUF_RAM - may
|
||||
be called from an ISR: otherwise, the HEAP is only
|
||||
protected by semaphores).
|
||||
|
||||
|
||||
** The remainder of this document discusses the "raw" API. **
|
||||
|
||||
The raw TCP/IP interface allows the application program to integrate
|
||||
better with the TCP/IP code. Program execution is event based by
|
||||
having callback functions being called from within the TCP/IP
|
||||
code. The TCP/IP code and the application program both run in the same
|
||||
thread. The sequential API has a much higher overhead and is not very
|
||||
well suited for small systems since it forces a multithreaded paradigm
|
||||
on the application.
|
||||
|
||||
The raw TCP/IP interface is not only faster in terms of code execution
|
||||
time but is also less memory intensive. The drawback is that program
|
||||
development is somewhat harder and application programs written for
|
||||
the raw TCP/IP interface are more difficult to understand. Still, this
|
||||
is the preferred way of writing applications that should be small in
|
||||
code size and memory usage.
|
||||
|
||||
All APIs can be used simultaneously by different application
|
||||
programs. In fact, the sequential API is implemented as an application
|
||||
program using the raw TCP/IP interface.
|
||||
|
||||
Do not confuse the lwIP raw API with raw Ethernet or IP sockets.
|
||||
The former is a way of interfacing the lwIP network stack (including
|
||||
TCP and UDP), the later refers to processing raw Ethernet or IP data
|
||||
instead of TCP connections or UDP packets.
|
||||
|
||||
Raw API applications may never block since all packet processing
|
||||
(input and output) as well as timer processing (TCP mainly) is done
|
||||
in a single execution context.
|
||||
|
||||
--- Callbacks
|
||||
|
||||
Program execution is driven by callbacks functions, which are then
|
||||
invoked by the lwIP core when activity related to that application
|
||||
occurs. A particular application may register to be notified via a
|
||||
callback function for events such as incoming data available, outgoing
|
||||
data sent, error notifications, poll timer expiration, connection
|
||||
closed, etc. An application can provide a callback function to perform
|
||||
processing for any or all of these events. Each callback is an ordinary
|
||||
C function that is called from within the TCP/IP code. Every callback
|
||||
function is passed the current TCP or UDP connection state as an
|
||||
argument. Also, in order to be able to keep program specific state,
|
||||
the callback functions are called with a program specified argument
|
||||
that is independent of the TCP/IP state.
|
||||
|
||||
The function for setting the application connection state is:
|
||||
|
||||
- void tcp_arg(struct tcp_pcb *pcb, void *arg)
|
||||
|
||||
Specifies the program specific state that should be passed to all
|
||||
other callback functions. The "pcb" argument is the current TCP
|
||||
connection control block, and the "arg" argument is the argument
|
||||
that will be passed to the callbacks.
|
||||
|
||||
|
||||
--- TCP connection setup
|
||||
|
||||
The functions used for setting up connections is similar to that of
|
||||
the sequential API and of the BSD socket API. A new TCP connection
|
||||
identifier (i.e., a protocol control block - PCB) is created with the
|
||||
tcp_new() function. This PCB can then be either set to listen for new
|
||||
incoming connections or be explicitly connected to another host.
|
||||
|
||||
- struct tcp_pcb *tcp_new(void)
|
||||
|
||||
Creates a new connection identifier (PCB). If memory is not
|
||||
available for creating the new pcb, NULL is returned.
|
||||
|
||||
- err_t tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr,
|
||||
u16_t port)
|
||||
|
||||
Binds the pcb to a local IP address and port number. The IP address
|
||||
can be specified as IP_ADDR_ANY in order to bind the connection to
|
||||
all local IP addresses.
|
||||
|
||||
If another connection is bound to the same port, the function will
|
||||
return ERR_USE, otherwise ERR_OK is returned.
|
||||
|
||||
- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb)
|
||||
|
||||
Commands a pcb to start listening for incoming connections. When an
|
||||
incoming connection is accepted, the function specified with the
|
||||
tcp_accept() function will be called. The pcb will have to be bound
|
||||
to a local port with the tcp_bind() function.
|
||||
|
||||
The tcp_listen() function returns a new connection identifier, and
|
||||
the one passed as an argument to the function will be
|
||||
deallocated. The reason for this behavior is that less memory is
|
||||
needed for a connection that is listening, so tcp_listen() will
|
||||
reclaim the memory needed for the original connection and allocate a
|
||||
new smaller memory block for the listening connection.
|
||||
|
||||
tcp_listen() may return NULL if no memory was available for the
|
||||
listening connection. If so, the memory associated with the pcb
|
||||
passed as an argument to tcp_listen() will not be deallocated.
|
||||
|
||||
- struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
||||
|
||||
Same as tcp_listen, but limits the number of outstanding connections
|
||||
in the listen queue to the value specified by the backlog argument.
|
||||
To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h.
|
||||
|
||||
- void tcp_accept(struct tcp_pcb *pcb,
|
||||
err_t (* accept)(void *arg, struct tcp_pcb *newpcb,
|
||||
err_t err))
|
||||
|
||||
Specified the callback function that should be called when a new
|
||||
connection arrives on a listening connection.
|
||||
|
||||
- err_t tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr,
|
||||
u16_t port, err_t (* connected)(void *arg,
|
||||
struct tcp_pcb *tpcb,
|
||||
err_t err));
|
||||
|
||||
Sets up the pcb to connect to the remote host and sends the
|
||||
initial SYN segment which opens the connection.
|
||||
|
||||
The tcp_connect() function returns immediately; it does not wait for
|
||||
the connection to be properly setup. Instead, it will call the
|
||||
function specified as the fourth argument (the "connected" argument)
|
||||
when the connection is established. If the connection could not be
|
||||
properly established, either because the other host refused the
|
||||
connection or because the other host didn't answer, the "err"
|
||||
callback function of this pcb (registered with tcp_err, see below)
|
||||
will be called.
|
||||
|
||||
The tcp_connect() function can return ERR_MEM if no memory is
|
||||
available for enqueueing the SYN segment. If the SYN indeed was
|
||||
enqueued successfully, the tcp_connect() function returns ERR_OK.
|
||||
|
||||
|
||||
--- Sending TCP data
|
||||
|
||||
TCP data is sent by enqueueing the data with a call to
|
||||
tcp_write(). When the data is successfully transmitted to the remote
|
||||
host, the application will be notified with a call to a specified
|
||||
callback function.
|
||||
|
||||
- err_t tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len,
|
||||
u8_t apiflags)
|
||||
|
||||
Enqueues the data pointed to by the argument dataptr. The length of
|
||||
the data is passed as the len parameter. The apiflags can be one or more of:
|
||||
- TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated
|
||||
for the data to be copied into. If this flag is not given, no new memory
|
||||
should be allocated and the data should only be referenced by pointer. This
|
||||
also means that the memory behind dataptr must not change until the data is
|
||||
ACKed by the remote host
|
||||
- TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is omitted,
|
||||
the PSH flag is set in the last segment created by this call to tcp_write.
|
||||
If this flag is given, the PSH flag is not set.
|
||||
|
||||
The tcp_write() function will fail and return ERR_MEM if the length
|
||||
of the data exceeds the current send buffer size or if the length of
|
||||
the queue of outgoing segment is larger than the upper limit defined
|
||||
in lwipopts.h. The number of bytes available in the output queue can
|
||||
be retrieved with the tcp_sndbuf() function.
|
||||
|
||||
The proper way to use this function is to call the function with at
|
||||
most tcp_sndbuf() bytes of data. If the function returns ERR_MEM,
|
||||
the application should wait until some of the currently enqueued
|
||||
data has been successfully received by the other host and try again.
|
||||
|
||||
- void tcp_sent(struct tcp_pcb *pcb,
|
||||
err_t (* sent)(void *arg, struct tcp_pcb *tpcb,
|
||||
u16_t len))
|
||||
|
||||
Specifies the callback function that should be called when data has
|
||||
successfully been received (i.e., acknowledged) by the remote
|
||||
host. The len argument passed to the callback function gives the
|
||||
amount bytes that was acknowledged by the last acknowledgment.
|
||||
|
||||
|
||||
--- Receiving TCP data
|
||||
|
||||
TCP data reception is callback based - an application specified
|
||||
callback function is called when new data arrives. When the
|
||||
application has taken the data, it has to call the tcp_recved()
|
||||
function to indicate that TCP can advertise increase the receive
|
||||
window.
|
||||
|
||||
- void tcp_recv(struct tcp_pcb *pcb,
|
||||
err_t (* recv)(void *arg, struct tcp_pcb *tpcb,
|
||||
struct pbuf *p, err_t err))
|
||||
|
||||
Sets the callback function that will be called when new data
|
||||
arrives. The callback function will be passed a NULL pbuf to
|
||||
indicate that the remote host has closed the connection. If
|
||||
there are no errors and the callback function is to return
|
||||
ERR_OK, then it must free the pbuf. Otherwise, it must not
|
||||
free the pbuf so that lwIP core code can store it.
|
||||
|
||||
- void tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
||||
|
||||
Must be called when the application has received the data. The len
|
||||
argument indicates the length of the received data.
|
||||
|
||||
|
||||
--- Application polling
|
||||
|
||||
When a connection is idle (i.e., no data is either transmitted or
|
||||
received), lwIP will repeatedly poll the application by calling a
|
||||
specified callback function. This can be used either as a watchdog
|
||||
timer for killing connections that have stayed idle for too long, or
|
||||
as a method of waiting for memory to become available. For instance,
|
||||
if a call to tcp_write() has failed because memory wasn't available,
|
||||
the application may use the polling functionality to call tcp_write()
|
||||
again when the connection has been idle for a while.
|
||||
|
||||
- void tcp_poll(struct tcp_pcb *pcb,
|
||||
err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
|
||||
u8_t interval)
|
||||
|
||||
Specifies the polling interval and the callback function that should
|
||||
be called to poll the application. The interval is specified in
|
||||
number of TCP coarse grained timer shots, which typically occurs
|
||||
twice a second. An interval of 10 means that the application would
|
||||
be polled every 5 seconds.
|
||||
|
||||
|
||||
--- Closing and aborting connections
|
||||
|
||||
- err_t tcp_close(struct tcp_pcb *pcb)
|
||||
|
||||
Closes the connection. The function may return ERR_MEM if no memory
|
||||
was available for closing the connection. If so, the application
|
||||
should wait and try again either by using the acknowledgment
|
||||
callback or the polling functionality. If the close succeeds, the
|
||||
function returns ERR_OK.
|
||||
|
||||
The pcb is deallocated by the TCP code after a call to tcp_close().
|
||||
|
||||
- void tcp_abort(struct tcp_pcb *pcb)
|
||||
|
||||
Aborts the connection by sending a RST (reset) segment to the remote
|
||||
host. The pcb is deallocated. This function never fails.
|
||||
|
||||
ATTENTION: When calling this from one of the TCP callbacks, make
|
||||
sure you always return ERR_ABRT (and never return ERR_ABRT otherwise
|
||||
or you will risk accessing deallocated memory or memory leaks!
|
||||
|
||||
|
||||
If a connection is aborted because of an error, the application is
|
||||
alerted of this event by the err callback. Errors that might abort a
|
||||
connection are when there is a shortage of memory. The callback
|
||||
function to be called is set using the tcp_err() function.
|
||||
|
||||
- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg,
|
||||
err_t err))
|
||||
|
||||
The error callback function does not get the pcb passed to it as a
|
||||
parameter since the pcb may already have been deallocated.
|
||||
|
||||
|
||||
--- UDP interface
|
||||
|
||||
The UDP interface is similar to that of TCP, but due to the lower
|
||||
level of complexity of UDP, the interface is significantly simpler.
|
||||
|
||||
- struct udp_pcb *udp_new(void)
|
||||
|
||||
Creates a new UDP pcb which can be used for UDP communication. The
|
||||
pcb is not active until it has either been bound to a local address
|
||||
or connected to a remote address.
|
||||
|
||||
- void udp_remove(struct udp_pcb *pcb)
|
||||
|
||||
Removes and deallocates the pcb.
|
||||
|
||||
- err_t udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr,
|
||||
u16_t port)
|
||||
|
||||
Binds the pcb to a local address. The IP-address argument "ipaddr"
|
||||
can be IP_ADDR_ANY to indicate that it should listen to any local IP
|
||||
address. The function currently always return ERR_OK.
|
||||
|
||||
- err_t udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr,
|
||||
u16_t port)
|
||||
|
||||
Sets the remote end of the pcb. This function does not generate any
|
||||
network traffic, but only set the remote address of the pcb.
|
||||
|
||||
- err_t udp_disconnect(struct udp_pcb *pcb)
|
||||
|
||||
Remove the remote end of the pcb. This function does not generate
|
||||
any network traffic, but only removes the remote address of the pcb.
|
||||
|
||||
- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
|
||||
Sends the pbuf p. The pbuf is not deallocated.
|
||||
|
||||
- void udp_recv(struct udp_pcb *pcb,
|
||||
void (* recv)(void *arg, struct udp_pcb *upcb,
|
||||
struct pbuf *p,
|
||||
ip_addr_t *addr,
|
||||
u16_t port),
|
||||
void *recv_arg)
|
||||
|
||||
Specifies a callback function that should be called when a UDP
|
||||
datagram is received.
|
||||
|
||||
|
||||
--- System initalization
|
||||
|
||||
A truly complete and generic sequence for initializing the lwIP stack
|
||||
cannot be given because it depends on additional initializations for
|
||||
your runtime environment (e.g. timers).
|
||||
|
||||
We can give you some idea on how to proceed when using the raw API.
|
||||
We assume a configuration using a single Ethernet netif and the
|
||||
UDP and TCP transport layers, IPv4 and the DHCP client.
|
||||
|
||||
Call these functions in the order of appearance:
|
||||
|
||||
- lwip_init()
|
||||
|
||||
Initialize the lwIP stack and all of its subsystems.
|
||||
|
||||
- netif_add(struct netif *netif, const ip4_addr_t *ipaddr,
|
||||
const ip4_addr_t *netmask, const ip4_addr_t *gw,
|
||||
void *state, netif_init_fn init, netif_input_fn input)
|
||||
|
||||
Adds your network interface to the netif_list. Allocate a struct
|
||||
netif and pass a pointer to this structure as the first argument.
|
||||
Give pointers to cleared ip_addr structures when using DHCP,
|
||||
or fill them with sane numbers otherwise. The state pointer may be NULL.
|
||||
|
||||
The init function pointer must point to a initialization function for
|
||||
your Ethernet netif interface. The following code illustrates its use.
|
||||
|
||||
err_t netif_if_init(struct netif *netif)
|
||||
{
|
||||
u8_t i;
|
||||
|
||||
for (i = 0; i < ETHARP_HWADDR_LEN; i++) {
|
||||
netif->hwaddr[i] = some_eth_addr[i];
|
||||
}
|
||||
init_my_eth_device();
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
For Ethernet drivers, the input function pointer must point to the lwIP
|
||||
function ethernet_input() declared in "netif/etharp.h". Other drivers
|
||||
must use ip_input() declared in "lwip/ip.h".
|
||||
|
||||
- netif_set_default(struct netif *netif)
|
||||
|
||||
Registers the default network interface.
|
||||
|
||||
- netif_set_link_up(struct netif *netif)
|
||||
|
||||
This is the hardware link state; e.g. whether cable is plugged for wired
|
||||
Ethernet interface. This function must be called even if you don't know
|
||||
the current state. Having link up and link down events is optional but
|
||||
DHCP and IPv6 discover benefit well from those events.
|
||||
|
||||
- netif_set_up(struct netif *netif)
|
||||
|
||||
This is the administrative (= software) state of the netif, when the
|
||||
netif is fully configured this function must be called.
|
||||
|
||||
- dhcp_start(struct netif *netif)
|
||||
|
||||
Creates a new DHCP client for this interface on the first call.
|
||||
|
||||
You can peek in the netif->dhcp struct for the actual DHCP status.
|
||||
|
||||
- sys_check_timeouts()
|
||||
|
||||
When the system is running, you have to periodically call
|
||||
sys_check_timeouts() which will handle all timers for all protocols in
|
||||
the stack; add this to your main loop or equivalent.
|
||||
|
||||
|
||||
--- Optimalization hints
|
||||
|
||||
The first thing you want to optimize is the lwip_standard_checksum()
|
||||
routine from src/core/inet.c. You can override this standard
|
||||
function with the #define LWIP_CHKSUM <your_checksum_routine>.
|
||||
|
||||
There are C examples given in inet.c or you might want to
|
||||
craft an assembly function for this. RFC1071 is a good
|
||||
introduction to this subject.
|
||||
|
||||
Other significant improvements can be made by supplying
|
||||
assembly or inline replacements for htons() and htonl()
|
||||
if you're using a little-endian architecture.
|
||||
#define lwip_htons(x) <your_htons>
|
||||
#define lwip_htonl(x) <your_htonl>
|
||||
If you #define them to htons() and htonl(), you should
|
||||
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS to prevent lwIP from
|
||||
defining hton*/ntoh* compatibility macros.
|
||||
|
||||
Check your network interface driver if it reads at
|
||||
a higher speed than the maximum wire-speed. If the
|
||||
hardware isn't serviced frequently and fast enough
|
||||
buffer overflows are likely to occur.
|
||||
|
||||
E.g. when using the cs8900 driver, call cs8900if_service(ethif)
|
||||
as frequently as possible. When using an RTOS let the cs8900 interrupt
|
||||
wake a high priority task that services your driver using a binary
|
||||
semaphore or event flag. Some drivers might allow additional tuning
|
||||
to match your application and network.
|
||||
|
||||
For a production release it is recommended to set LWIP_STATS to 0.
|
||||
Note that speed performance isn't influenced much by simply setting
|
||||
high values to the memory options.
|
||||
|
||||
For more optimization hints take a look at the lwIP wiki.
|
||||
|
||||
--- Zero-copy MACs
|
||||
|
||||
To achieve zero-copy on transmit, the data passed to the raw API must
|
||||
remain unchanged until sent. Because the send- (or write-)functions return
|
||||
when the packets have been enqueued for sending, data must be kept stable
|
||||
after that, too.
|
||||
|
||||
This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions
|
||||
must *not* be reused by the application unless their ref-count is 1.
|
||||
|
||||
For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too,
|
||||
but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while
|
||||
PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change).
|
||||
|
||||
Also, data passed to tcp_write without the copy-flag must not be changed!
|
||||
|
||||
Therefore, be careful which type of PBUF you use and if you copy TCP data
|
||||
or not!
|
||||
120
sdk/component/common/network/lwip/lwip_v2.0.2/doc/savannah.txt
Normal file
120
sdk/component/common/network/lwip/lwip_v2.0.2/doc/savannah.txt
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
Daily Use Guide for using Savannah for lwIP
|
||||
|
||||
Table of Contents:
|
||||
|
||||
1 - Obtaining lwIP from the Git repository
|
||||
2 - Committers/developers Git access using SSH
|
||||
3 - Merging a development branch to master branch
|
||||
4 - How to release lwIP
|
||||
|
||||
|
||||
|
||||
1 Obtaining lwIP from the Git repository
|
||||
----------------------------------------
|
||||
|
||||
To perform an anonymous Git clone of the master branch (this is where
|
||||
bug fixes and incremental enhancements occur), do this:
|
||||
git clone git://git.savannah.nongnu.org/lwip.git
|
||||
|
||||
Or, obtain a stable branch (updated with bug fixes only) as follows:
|
||||
git clone --branch DEVEL-1_4_1 git://git.savannah.nongnu.org/lwip.git
|
||||
|
||||
Or, obtain a specific (fixed) release as follows:
|
||||
git clone --branch STABLE-1_4_1 git://git.savannah.nongnu.org/lwip.git
|
||||
|
||||
|
||||
2 Committers/developers Git access using SSH
|
||||
--------------------------------------------
|
||||
|
||||
The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption.
|
||||
As such, Git commits to the server occur through a SSH tunnel for project members.
|
||||
To create a SSH2 key pair in UNIX-like environments, do this:
|
||||
ssh-keygen -t dsa
|
||||
|
||||
Under Windows, a recommended SSH client is "PuTTY", freely available with good
|
||||
documentation and a graphic user interface. Use its key generator.
|
||||
|
||||
Now paste the id_dsa.pub contents into your Savannah account public key list. Wait
|
||||
a while so that Savannah can update its configuration (This can take minutes).
|
||||
|
||||
Try to login using SSH:
|
||||
ssh -v your_login@git.sv.gnu.org
|
||||
|
||||
If it tells you:
|
||||
Linux vcs.savannah.gnu.org 2.6.32-5-xen-686 #1 SMP Wed Jun 17 17:10:03 UTC 2015 i686
|
||||
|
||||
Interactive shell login is not possible for security reasons.
|
||||
VCS commands are allowed.
|
||||
Last login: Tue May 15 23:10:12 2012 from 82.245.102.129
|
||||
You tried to execute:
|
||||
Sorry, you are not allowed to execute that command.
|
||||
Shared connection to git.sv.gnu.org closed.
|
||||
|
||||
then you could login; Savannah refuses to give you a shell - which is OK, as we
|
||||
are allowed to use SSH for Git only. Now, you should be able to do this:
|
||||
git clone your_login@git.sv.gnu.org:/srv/git/lwip.git
|
||||
|
||||
After which you can edit your local files with bug fixes or new features and
|
||||
commit them. Make sure you know what you are doing when using Git to make
|
||||
changes on the repository. If in doubt, ask on the lwip-members mailing list.
|
||||
|
||||
(If SSH asks about authenticity of the host, you can check the key
|
||||
fingerprint against https://savannah.nongnu.org/git/?group=lwip
|
||||
|
||||
|
||||
3 - Merging a development branch to master branch
|
||||
-------------------------------------------------
|
||||
|
||||
Merging is a straightforward process in Git. How to merge all changes in a
|
||||
development branch since our last merge from main:
|
||||
|
||||
Checkout the master branch:
|
||||
git checkout master
|
||||
|
||||
Merge the development branch to master:
|
||||
git merge your-development-branch
|
||||
|
||||
Resolve any conflict.
|
||||
|
||||
Commit the merge result.
|
||||
git commit -a
|
||||
|
||||
Push your commits:
|
||||
git push
|
||||
|
||||
|
||||
4 How to release lwIP
|
||||
---------------------
|
||||
|
||||
First, tag the release using Git: (I use release number 1.4.1 throughout
|
||||
this example).
|
||||
git tag -a STABLE-1_4_1
|
||||
|
||||
Share the tag reference by pushing it to remote:
|
||||
git push origin STABLE-1_4_1
|
||||
|
||||
Prepare the release:
|
||||
cp -r lwip lwip-1.4.1
|
||||
rm -rf lwip-1.4.1/.git lwip-1.4.1/.gitattributes
|
||||
|
||||
Archive the current directory using tar, gzip'd, bzip2'd and zip'd.
|
||||
tar czvf lwip-1.4.1.tar.gz lwip-1.4.1
|
||||
tar cjvf lwip-1.4.1.tar.bz2 lwip-1.4.1
|
||||
zip -r lwip-1.4.1.zip lwip-1.4.1
|
||||
|
||||
Now, sign the archives with a detached GPG binary signature as follows:
|
||||
gpg -b lwip-1.4.1.tar.gz
|
||||
gpg -b lwip-1.4.1.tar.bz2
|
||||
gpg -b lwip-1.4.1.zip
|
||||
|
||||
Upload these files using anonymous FTP:
|
||||
ncftp ftp://savannah.gnu.org/incoming/savannah/lwip
|
||||
ncftp> mput *1.4.1.*
|
||||
|
||||
Additionally, you may post a news item on Savannah, like this:
|
||||
|
||||
A new 1.4.1 release is now available here:
|
||||
http://savannah.nongnu.org/files/?group=lwip&highlight=1.4.1
|
||||
|
||||
You will have to submit this via the user News interface, then approve
|
||||
this via the Administrator News interface.
|
||||
303
sdk/component/common/network/lwip/lwip_v2.0.2/doc/sys_arch.txt
Normal file
303
sdk/component/common/network/lwip/lwip_v2.0.2/doc/sys_arch.txt
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
sys_arch interface for lwIP
|
||||
|
||||
Author: Adam Dunkels
|
||||
Simon Goldschmidt
|
||||
|
||||
The operating system emulation layer provides a common interface
|
||||
between the lwIP code and the underlying operating system kernel. The
|
||||
general idea is that porting lwIP to new architectures requires only
|
||||
small changes to a few header files and a new sys_arch
|
||||
implementation. It is also possible to do a sys_arch implementation
|
||||
that does not rely on any underlying operating system.
|
||||
|
||||
The sys_arch provides semaphores, mailboxes and mutexes to lwIP. For the full
|
||||
lwIP functionality, multiple threads support can be implemented in the
|
||||
sys_arch, but this is not required for the basic lwIP
|
||||
functionality. Timer scheduling is implemented in lwIP, but can be implemented
|
||||
by the sys_arch port (LWIP_TIMERS_CUSTOM==1).
|
||||
|
||||
In addition to the source file providing the functionality of sys_arch,
|
||||
the OS emulation layer must provide several header files defining
|
||||
macros used throughout lwip. The files required and the macros they
|
||||
must define are listed below the sys_arch description.
|
||||
|
||||
Semaphores can be either counting or binary - lwIP works with both
|
||||
kinds. Mailboxes should be implemented as a queue which allows multiple messages
|
||||
to be posted (implementing as a rendez-vous point where only one message can be
|
||||
posted at a time can have a highly negative impact on performance). A message
|
||||
in a mailbox is just a pointer, nothing more.
|
||||
|
||||
Semaphores are represented by the type "sys_sem_t" which is typedef'd
|
||||
in the sys_arch.h file. Mailboxes are equivalently represented by the
|
||||
type "sys_mbox_t". Mutexes are represented by the type "sys_mutex_t".
|
||||
lwIP does not place any restrictions on how these types are represented
|
||||
internally.
|
||||
|
||||
Since lwIP 1.4.0, semaphore, mutexes and mailbox functions are prototyped in a way that
|
||||
allows both using pointers or actual OS structures to be used. This way, memory
|
||||
required for such types can be either allocated in place (globally or on the
|
||||
stack) or on the heap (allocated internally in the "*_new()" functions).
|
||||
|
||||
The following functions must be implemented by the sys_arch:
|
||||
|
||||
- void sys_init(void)
|
||||
|
||||
Is called to initialize the sys_arch layer.
|
||||
|
||||
- err_t sys_sem_new(sys_sem_t *sem, u8_t count)
|
||||
|
||||
Creates a new semaphore. The semaphore is allocated to the memory that 'sem'
|
||||
points to (which can be both a pointer or the actual OS structure).
|
||||
The "count" argument specifies the initial state of the semaphore (which is
|
||||
either 0 or 1).
|
||||
If the semaphore has been created, ERR_OK should be returned. Returning any
|
||||
other error will provide a hint what went wrong, but except for assertions,
|
||||
no real error handling is implemented.
|
||||
|
||||
- void sys_sem_free(sys_sem_t *sem)
|
||||
|
||||
Deallocates a semaphore.
|
||||
|
||||
- void sys_sem_signal(sys_sem_t *sem)
|
||||
|
||||
Signals a semaphore.
|
||||
|
||||
- u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
|
||||
|
||||
Blocks the thread while waiting for the semaphore to be
|
||||
signaled. If the "timeout" argument is non-zero, the thread should
|
||||
only be blocked for the specified time (measured in
|
||||
milliseconds). If the "timeout" argument is zero, the thread should be
|
||||
blocked until the semaphore is signalled.
|
||||
|
||||
If the timeout argument is non-zero, the return value is the number of
|
||||
milliseconds spent waiting for the semaphore to be signaled. If the
|
||||
semaphore wasn't signaled within the specified time, the return value is
|
||||
SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
|
||||
(i.e., it was already signaled), the function may return zero.
|
||||
|
||||
Notice that lwIP implements a function with a similar name,
|
||||
sys_sem_wait(), that uses the sys_arch_sem_wait() function.
|
||||
|
||||
- int sys_sem_valid(sys_sem_t *sem)
|
||||
|
||||
Returns 1 if the semaphore is valid, 0 if it is not valid.
|
||||
When using pointers, a simple way is to check the pointer for != NULL.
|
||||
When directly using OS structures, implementing this may be more complex.
|
||||
This may also be a define, in which case the function is not prototyped.
|
||||
|
||||
- void sys_sem_set_invalid(sys_sem_t *sem)
|
||||
|
||||
Invalidate a semaphore so that sys_sem_valid() returns 0.
|
||||
ATTENTION: This does NOT mean that the semaphore shall be deallocated:
|
||||
sys_sem_free() is always called before calling this function!
|
||||
This may also be a define, in which case the function is not prototyped.
|
||||
|
||||
- void sys_mutex_new(sys_mutex_t *mutex)
|
||||
|
||||
Creates a new mutex. The mutex is allocated to the memory that 'mutex'
|
||||
points to (which can be both a pointer or the actual OS structure).
|
||||
If the mutex has been created, ERR_OK should be returned. Returning any
|
||||
other error will provide a hint what went wrong, but except for assertions,
|
||||
no real error handling is implemented.
|
||||
|
||||
- void sys_mutex_free(sys_mutex_t *mutex)
|
||||
|
||||
Deallocates a mutex.
|
||||
|
||||
- void sys_mutex_lock(sys_mutex_t *mutex)
|
||||
|
||||
Blocks the thread until the mutex can be grabbed.
|
||||
|
||||
- void sys_mutex_unlock(sys_mutex_t *mutex)
|
||||
|
||||
Releases the mutex previously locked through 'sys_mutex_lock()'.
|
||||
|
||||
- void sys_mutex_valid(sys_mutex_t *mutex)
|
||||
|
||||
Returns 1 if the mutes is valid, 0 if it is not valid.
|
||||
When using pointers, a simple way is to check the pointer for != NULL.
|
||||
When directly using OS structures, implementing this may be more complex.
|
||||
This may also be a define, in which case the function is not prototyped.
|
||||
|
||||
- void sys_mutex_set_invalid(sys_mutex_t *mutex)
|
||||
|
||||
Invalidate a mutex so that sys_mutex_valid() returns 0.
|
||||
ATTENTION: This does NOT mean that the mutex shall be deallocated:
|
||||
sys_mutex_free() is always called before calling this function!
|
||||
This may also be a define, in which case the function is not prototyped.
|
||||
|
||||
- err_t sys_mbox_new(sys_mbox_t *mbox, int size)
|
||||
|
||||
Creates an empty mailbox for maximum "size" elements. Elements stored
|
||||
in mailboxes are pointers. You have to define macros "_MBOX_SIZE"
|
||||
in your lwipopts.h, or ignore this parameter in your implementation
|
||||
and use a default size.
|
||||
If the mailbox has been created, ERR_OK should be returned. Returning any
|
||||
other error will provide a hint what went wrong, but except for assertions,
|
||||
no real error handling is implemented.
|
||||
|
||||
- void sys_mbox_free(sys_mbox_t *mbox)
|
||||
|
||||
Deallocates a mailbox. If there are messages still present in the
|
||||
mailbox when the mailbox is deallocated, it is an indication of a
|
||||
programming error in lwIP and the developer should be notified.
|
||||
|
||||
- void sys_mbox_post(sys_mbox_t *mbox, void *msg)
|
||||
|
||||
Posts the "msg" to the mailbox. This function have to block until
|
||||
the "msg" is really posted.
|
||||
|
||||
- err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
|
||||
|
||||
Try to post the "msg" to the mailbox. Returns ERR_MEM if this one
|
||||
is full, else, ERR_OK if the "msg" is posted.
|
||||
|
||||
- u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
|
||||
|
||||
Blocks the thread until a message arrives in the mailbox, but does
|
||||
not block the thread longer than "timeout" milliseconds (similar to
|
||||
the sys_arch_sem_wait() function). If "timeout" is 0, the thread should
|
||||
be blocked until a message arrives. The "msg" argument is a result
|
||||
parameter that is set by the function (i.e., by doing "*msg =
|
||||
ptr"). The "msg" parameter maybe NULL to indicate that the message
|
||||
should be dropped.
|
||||
|
||||
The return values are the same as for the sys_arch_sem_wait() function:
|
||||
Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
|
||||
timeout.
|
||||
|
||||
Note that a function with a similar name, sys_mbox_fetch(), is
|
||||
implemented by lwIP.
|
||||
|
||||
- u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
|
||||
|
||||
This is similar to sys_arch_mbox_fetch, however if a message is not
|
||||
present in the mailbox, it immediately returns with the code
|
||||
SYS_MBOX_EMPTY. On success 0 is returned.
|
||||
|
||||
To allow for efficient implementations, this can be defined as a
|
||||
function-like macro in sys_arch.h instead of a normal function. For
|
||||
example, a naive implementation could be:
|
||||
#define sys_arch_mbox_tryfetch(mbox,msg) \
|
||||
sys_arch_mbox_fetch(mbox,msg,1)
|
||||
although this would introduce unnecessary delays.
|
||||
|
||||
- int sys_mbox_valid(sys_mbox_t *mbox)
|
||||
|
||||
Returns 1 if the mailbox is valid, 0 if it is not valid.
|
||||
When using pointers, a simple way is to check the pointer for != NULL.
|
||||
When directly using OS structures, implementing this may be more complex.
|
||||
This may also be a define, in which case the function is not prototyped.
|
||||
|
||||
- void sys_mbox_set_invalid(sys_mbox_t *mbox)
|
||||
|
||||
Invalidate a mailbox so that sys_mbox_valid() returns 0.
|
||||
ATTENTION: This does NOT mean that the mailbox shall be deallocated:
|
||||
sys_mbox_free() is always called before calling this function!
|
||||
This may also be a define, in which case the function is not prototyped.
|
||||
|
||||
If threads are supported by the underlying operating system and if
|
||||
such functionality is needed in lwIP, the following function will have
|
||||
to be implemented as well:
|
||||
|
||||
- sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio)
|
||||
|
||||
Starts a new thread named "name" with priority "prio" that will begin its
|
||||
execution in the function "thread()". The "arg" argument will be passed as an
|
||||
argument to the thread() function. The stack size to used for this thread is
|
||||
the "stacksize" parameter. The id of the new thread is returned. Both the id
|
||||
and the priority are system dependent.
|
||||
|
||||
When lwIP is used from more than one context (e.g. from multiple threads OR from
|
||||
main-loop and from interrupts), the SYS_LIGHTWEIGHT_PROT protection SHOULD be enabled!
|
||||
|
||||
- sys_prot_t sys_arch_protect(void)
|
||||
|
||||
This optional function does a "fast" critical region protection and returns
|
||||
the previous protection level. This function is only called during very short
|
||||
critical regions. An embedded system which supports ISR-based drivers might
|
||||
want to implement this function by disabling interrupts. Task-based systems
|
||||
might want to implement this by using a mutex or disabling tasking. This
|
||||
function should support recursive calls from the same task or interrupt. In
|
||||
other words, sys_arch_protect() could be called while already protected. In
|
||||
that case the return value indicates that it is already protected.
|
||||
|
||||
sys_arch_protect() is only required if your port is supporting an operating
|
||||
system.
|
||||
|
||||
- void sys_arch_unprotect(sys_prot_t pval)
|
||||
|
||||
This optional function does a "fast" set of critical region protection to the
|
||||
value specified by pval. See the documentation for sys_arch_protect() for
|
||||
more information. This function is only required if your port is supporting
|
||||
an operating system.
|
||||
|
||||
For some configurations, you also need:
|
||||
|
||||
- u32_t sys_now(void)
|
||||
|
||||
This optional function returns the current time in milliseconds (don't care
|
||||
for wraparound, this is only used for time diffs).
|
||||
Not implementing this function means you cannot use some modules (e.g. TCP
|
||||
timestamps, internal timeouts for NO_SYS==1).
|
||||
|
||||
|
||||
Note:
|
||||
|
||||
Be careful with using mem_malloc() in sys_arch. When malloc() refers to
|
||||
mem_malloc() you can run into a circular function call problem. In mem.c
|
||||
mem_init() tries to allcate a semaphore using mem_malloc, which of course
|
||||
can't be performed when sys_arch uses mem_malloc.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Additional files required for the "OS support" emulation layer:
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
cc.h - Architecture environment, some compiler specific, some
|
||||
environment specific (probably should move env stuff
|
||||
to sys_arch.h.)
|
||||
|
||||
Typedefs for the types used by lwip -
|
||||
u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t
|
||||
|
||||
Compiler hints for packing lwip's structures -
|
||||
PACK_STRUCT_FIELD(x)
|
||||
PACK_STRUCT_STRUCT
|
||||
PACK_STRUCT_BEGIN
|
||||
PACK_STRUCT_END
|
||||
|
||||
Platform specific diagnostic output -
|
||||
LWIP_PLATFORM_DIAG(x) - non-fatal, print a message.
|
||||
LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution.
|
||||
Portability defines for printf formatters:
|
||||
U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F
|
||||
|
||||
"lightweight" synchronization mechanisms -
|
||||
SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable.
|
||||
SYS_ARCH_PROTECT(x) - enter protection mode.
|
||||
SYS_ARCH_UNPROTECT(x) - leave protection mode.
|
||||
|
||||
If the compiler does not provide memset() this file must include a
|
||||
definition of it, or include a file which defines it.
|
||||
|
||||
This file must either include a system-local <errno.h> which defines
|
||||
the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO
|
||||
to make lwip/arch.h define the codes which are used throughout.
|
||||
|
||||
|
||||
perf.h - Architecture specific performance measurement.
|
||||
Measurement calls made throughout lwip, these can be defined to nothing.
|
||||
PERF_START - start measuring something.
|
||||
PERF_STOP(x) - stop measuring something, and record the result.
|
||||
|
||||
sys_arch.h - Tied to sys_arch.c
|
||||
|
||||
Arch dependent types for the following objects:
|
||||
sys_sem_t, sys_mbox_t, sys_thread_t,
|
||||
And, optionally:
|
||||
sys_prot_t
|
||||
|
||||
Defines to set vars of sys_mbox_t and sys_sem_t to NULL.
|
||||
SYS_MBOX_NULL NULL
|
||||
SYS_SEM_NULL NULL
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__) || defined (__GNUC__)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __CC_H__
|
||||
#define __CC_H__
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
typedef unsigned char u8_t;
|
||||
typedef signed char s8_t;
|
||||
typedef unsigned short u16_t;
|
||||
typedef signed short s16_t;
|
||||
typedef unsigned int u32_t;
|
||||
typedef signed long s32_t;
|
||||
typedef u32_t mem_ptr_t;
|
||||
typedef int sys_prot_t;
|
||||
|
||||
#define U16_F "d"
|
||||
#define S16_F "d"
|
||||
#define X16_F "x"
|
||||
#define U32_F "d"
|
||||
#define S32_F "d"
|
||||
#define X32_F "x"
|
||||
#define SZT_F "uz"
|
||||
|
||||
/* define compiler specific symbols */
|
||||
#if defined (__ICCARM__)
|
||||
#if !defined (__IARSTDLIB__) && !defined(CONFIG_PLATFORM_8195BHP)&& !defined(CONFIG_PLATFORM_8710C)
|
||||
#define _STRING
|
||||
#ifndef memcmp
|
||||
#define memcmp(dst, src, sz) _memcmp(dst, src, sz)
|
||||
#endif
|
||||
#ifndef memset
|
||||
#define memset(dst, val, sz) _memset(dst, val, sz)
|
||||
#endif
|
||||
#ifndef memcpy
|
||||
#define memcpy(dst, src, sz) _memcpy(dst, src, sz)
|
||||
#endif
|
||||
#endif // __IARSTDLIB__
|
||||
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
#define PACK_STRUCT_USE_INCLUDES
|
||||
|
||||
#elif defined (__CC_ARM)
|
||||
|
||||
#define PACK_STRUCT_BEGIN __packed
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
|
||||
#elif defined (__GNUC__)
|
||||
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
#define PACK_STRUCT_USE_INCLUDES
|
||||
|
||||
#elif defined (__TASKING__)
|
||||
|
||||
#define PACK_STRUCT_BEGIN
|
||||
#define PACK_STRUCT_STRUCT
|
||||
#define PACK_STRUCT_END
|
||||
#define PACK_STRUCT_FIELD(x) x
|
||||
|
||||
#endif
|
||||
|
||||
#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0)
|
||||
|
||||
#define LWIP_NO_STDINT_H 1
|
||||
|
||||
#if (defined (CONFIG_PLATFORM_8710C)||defined(CONFIG_PLATFORM_8721D)) && defined (__GNUC__) && (__GNUC__ >= 6)
|
||||
#define LWIP_TIMEVAL_PRIVATE 0
|
||||
#define IN_ADDR_T_DEFINED 1
|
||||
#endif
|
||||
|
||||
#endif /* __CC_H__ */
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __CPU_H__
|
||||
#define __CPU_H__
|
||||
|
||||
#if !defined(BYTE_ORDER)
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#endif /* __CPU_H__ */
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma pack()
|
||||
#elif defined (__GNUC__)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __ARCH_INIT_H__
|
||||
#define __ARCH_INIT_H__
|
||||
|
||||
#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg)
|
||||
|
||||
void tcpip_init_done(void *);
|
||||
int wait_for_tcpip_init(void);
|
||||
|
||||
#endif /* __ARCH_INIT_H__ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __LIB_H__
|
||||
#define __LIB_H__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#endif /* __LIB_H__ */
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __PERF_H__
|
||||
#define __PERF_H__
|
||||
|
||||
#define PERF_START /* null definition */
|
||||
#define PERF_STOP(x) /* null definition */
|
||||
|
||||
#endif /* __PERF_H__ */
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __SYS_RTXC_H__
|
||||
#define __SYS_RTXC_H__
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#define SYS_MBOX_NULL (xQueueHandle)0
|
||||
#define SYS_SEM_NULL (xSemaphoreHandle)0
|
||||
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
|
||||
typedef xSemaphoreHandle sys_sem_t;
|
||||
typedef xSemaphoreHandle sys_mutex_t;
|
||||
typedef xQueueHandle sys_mbox_t;
|
||||
typedef xTaskHandle sys_thread_t;
|
||||
|
||||
typedef struct _sys_arch_state_t
|
||||
{
|
||||
// Task creation data.
|
||||
char cTaskName[configMAX_TASK_NAME_LEN];
|
||||
unsigned short nStackDepth;
|
||||
unsigned short nTaskCount;
|
||||
} sys_arch_state_t;
|
||||
|
||||
|
||||
|
||||
//extern sys_arch_state_t s_sys_arch_state;
|
||||
|
||||
//void sys_set_default_state();
|
||||
//void sys_set_state(signed char *pTaskName, unsigned short nStackSize);
|
||||
|
||||
/* Message queue constants. */
|
||||
#define archMESG_QUEUE_LENGTH ( 6 )
|
||||
#endif /* __SYS_RTXC_H__ */
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef __ETHERNETIF_H__
|
||||
#define __ETHERNETIF_H__
|
||||
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/netif.h"
|
||||
|
||||
//----- ------------------------------------------------------------------
|
||||
// Ethernet Buffer
|
||||
//----- ------------------------------------------------------------------
|
||||
struct eth_drv_sg {
|
||||
unsigned int buf;
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
#define MAX_ETH_DRV_SG 32
|
||||
#define MAX_ETH_MSG 1540
|
||||
|
||||
void ethernetif_recv(struct netif *netif, int total_len);
|
||||
err_t ethernetif_init(struct netif *netif);
|
||||
err_t ethernetif_mii_init(struct netif *netif);
|
||||
void lwip_PRE_SLEEP_PROCESSING(void);
|
||||
void lwip_POST_SLEEP_PROCESSING(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __SYS_RTXC_H__
|
||||
#define __SYS_RTXC_H__
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#define SYS_MBOX_NULL (xQueueHandle)0
|
||||
#define SYS_SEM_NULL (xSemaphoreHandle)0
|
||||
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
|
||||
typedef xSemaphoreHandle sys_sem_t;
|
||||
typedef xQueueHandle sys_mbox_t;
|
||||
typedef xTaskHandle sys_thread_t;
|
||||
|
||||
typedef struct _sys_arch_state_t
|
||||
{
|
||||
// Task creation data.
|
||||
char cTaskName[configMAX_TASK_NAME_LEN];
|
||||
unsigned short nStackDepth;
|
||||
unsigned short nTaskCount;
|
||||
} sys_arch_state_t;
|
||||
|
||||
|
||||
|
||||
//extern sys_arch_state_t s_sys_arch_state;
|
||||
|
||||
//void sys_set_default_state();
|
||||
//void sys_set_state(signed char *pTaskName, unsigned short nStackSize);
|
||||
|
||||
/* Message queue constants. */
|
||||
#define archMESG_QUEUE_LENGTH ( 6 )
|
||||
#endif /* __SYS_RTXC_H__ */
|
||||
|
||||
15
sdk/component/common/network/lwip/lwip_v2.0.2/src/FILES
Normal file
15
sdk/component/common/network/lwip/lwip_v2.0.2/src/FILES
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
api/ - The code for the high-level wrapper API. Not needed if
|
||||
you use the lowel-level call-back/raw API.
|
||||
|
||||
apps/ - Higher layer applications that are specifically programmed
|
||||
with the lwIP low-level raw API.
|
||||
|
||||
core/ - The core of the TPC/IP stack; protocol implementations,
|
||||
memory and buffer management, and the low-level raw API.
|
||||
|
||||
include/ - lwIP include files.
|
||||
|
||||
netif/ - Generic network interface device drivers are kept here.
|
||||
|
||||
For more information on the various subdirectories, check the FILES
|
||||
file in each directory.
|
||||
181
sdk/component/common/network/lwip/lwip_v2.0.2/src/Filelists.mk
Normal file
181
sdk/component/common/network/lwip/lwip_v2.0.2/src/Filelists.mk
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
# SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
# OF SUCH DAMAGE.
|
||||
#
|
||||
# This file is part of the lwIP TCP/IP stack.
|
||||
#
|
||||
# Author: Adam Dunkels <adam@sics.se>
|
||||
#
|
||||
|
||||
# COREFILES, CORE4FILES: The minimum set of files needed for lwIP.
|
||||
COREFILES=$(LWIPDIR)/core/init.c \
|
||||
$(LWIPDIR)/core/def.c \
|
||||
$(LWIPDIR)/core/dns.c \
|
||||
$(LWIPDIR)/core/inet_chksum.c \
|
||||
$(LWIPDIR)/core/ip.c \
|
||||
$(LWIPDIR)/core/mem.c \
|
||||
$(LWIPDIR)/core/memp.c \
|
||||
$(LWIPDIR)/core/netif.c \
|
||||
$(LWIPDIR)/core/pbuf.c \
|
||||
$(LWIPDIR)/core/raw.c \
|
||||
$(LWIPDIR)/core/stats.c \
|
||||
$(LWIPDIR)/core/sys.c \
|
||||
$(LWIPDIR)/core/tcp.c \
|
||||
$(LWIPDIR)/core/tcp_in.c \
|
||||
$(LWIPDIR)/core/tcp_out.c \
|
||||
$(LWIPDIR)/core/timeouts.c \
|
||||
$(LWIPDIR)/core/udp.c
|
||||
|
||||
CORE4FILES=$(LWIPDIR)/core/ipv4/autoip.c \
|
||||
$(LWIPDIR)/core/ipv4/dhcp.c \
|
||||
$(LWIPDIR)/core/ipv4/etharp.c \
|
||||
$(LWIPDIR)/core/ipv4/icmp.c \
|
||||
$(LWIPDIR)/core/ipv4/igmp.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4_frag.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4_addr.c
|
||||
|
||||
CORE6FILES=$(LWIPDIR)/core/ipv6/dhcp6.c \
|
||||
$(LWIPDIR)/core/ipv6/ethip6.c \
|
||||
$(LWIPDIR)/core/ipv6/icmp6.c \
|
||||
$(LWIPDIR)/core/ipv6/inet6.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6_addr.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6_frag.c \
|
||||
$(LWIPDIR)/core/ipv6/mld6.c \
|
||||
$(LWIPDIR)/core/ipv6/nd6.c
|
||||
|
||||
# APIFILES: The files which implement the sequential and socket APIs.
|
||||
APIFILES=$(LWIPDIR)/api/api_lib.c \
|
||||
$(LWIPDIR)/api/api_msg.c \
|
||||
$(LWIPDIR)/api/err.c \
|
||||
$(LWIPDIR)/api/netbuf.c \
|
||||
$(LWIPDIR)/api/netdb.c \
|
||||
$(LWIPDIR)/api/netifapi.c \
|
||||
$(LWIPDIR)/api/sockets.c \
|
||||
$(LWIPDIR)/api/tcpip.c
|
||||
|
||||
# NETIFFILES: Files implementing various generic network interface functions
|
||||
NETIFFILES=$(LWIPDIR)/netif/ethernet.c \
|
||||
$(LWIPDIR)/netif/slipif.c
|
||||
|
||||
# SIXLOWPAN: 6LoWPAN
|
||||
SIXLOWPAN=$(LWIPDIR)/netif/lowpan6.c \
|
||||
|
||||
# PPPFILES: PPP
|
||||
PPPFILES=$(LWIPDIR)/netif/ppp/auth.c \
|
||||
$(LWIPDIR)/netif/ppp/ccp.c \
|
||||
$(LWIPDIR)/netif/ppp/chap-md5.c \
|
||||
$(LWIPDIR)/netif/ppp/chap_ms.c \
|
||||
$(LWIPDIR)/netif/ppp/chap-new.c \
|
||||
$(LWIPDIR)/netif/ppp/demand.c \
|
||||
$(LWIPDIR)/netif/ppp/eap.c \
|
||||
$(LWIPDIR)/netif/ppp/ecp.c \
|
||||
$(LWIPDIR)/netif/ppp/eui64.c \
|
||||
$(LWIPDIR)/netif/ppp/fsm.c \
|
||||
$(LWIPDIR)/netif/ppp/ipcp.c \
|
||||
$(LWIPDIR)/netif/ppp/ipv6cp.c \
|
||||
$(LWIPDIR)/netif/ppp/lcp.c \
|
||||
$(LWIPDIR)/netif/ppp/magic.c \
|
||||
$(LWIPDIR)/netif/ppp/mppe.c \
|
||||
$(LWIPDIR)/netif/ppp/multilink.c \
|
||||
$(LWIPDIR)/netif/ppp/ppp.c \
|
||||
$(LWIPDIR)/netif/ppp/pppapi.c \
|
||||
$(LWIPDIR)/netif/ppp/pppcrypt.c \
|
||||
$(LWIPDIR)/netif/ppp/pppoe.c \
|
||||
$(LWIPDIR)/netif/ppp/pppol2tp.c \
|
||||
$(LWIPDIR)/netif/ppp/pppos.c \
|
||||
$(LWIPDIR)/netif/ppp/upap.c \
|
||||
$(LWIPDIR)/netif/ppp/utils.c \
|
||||
$(LWIPDIR)/netif/ppp/vj.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/arc4.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/des.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/md4.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/md5.c \
|
||||
$(LWIPDIR)/netif/ppp/polarssl/sha1.c
|
||||
|
||||
# LWIPNOAPPSFILES: All LWIP files without apps
|
||||
LWIPNOAPPSFILES=$(COREFILES) \
|
||||
$(CORE4FILES) \
|
||||
$(CORE6FILES) \
|
||||
$(APIFILES) \
|
||||
$(NETIFFILES) \
|
||||
$(PPPFILES) \
|
||||
$(SIXLOWPAN)
|
||||
|
||||
# SNMPFILES: SNMPv2c agent
|
||||
SNMPFILES=$(LWIPDIR)/apps/snmp/snmp_asn1.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_core.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_icmp.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_interfaces.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_ip.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_snmp.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_system.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_tcp.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_mib2_udp.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_msg.c \
|
||||
$(LWIPDIR)/apps/snmp/snmpv3.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_netconn.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_pbuf_stream.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_raw.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_scalar.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_table.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_threadsync.c \
|
||||
$(LWIPDIR)/apps/snmp/snmp_traps.c \
|
||||
$(LWIPDIR)/apps/snmp/snmpv3_mbedtls.c \
|
||||
$(LWIPDIR)/apps/snmp/snmpv3_dummy.c
|
||||
|
||||
# HTTPDFILES: HTTP server
|
||||
HTTPDFILES=$(LWIPDIR)/apps/httpd/fs.c \
|
||||
$(LWIPDIR)/apps/httpd/httpd.c
|
||||
|
||||
# LWIPERFFILES: IPERF server
|
||||
LWIPERFFILES=$(LWIPDIR)/apps/lwiperf/lwiperf.c
|
||||
|
||||
# SNTPFILES: SNTP client
|
||||
SNTPFILES=$(LWIPDIR)/apps/sntp/sntp.c
|
||||
|
||||
# MDNSFILES: MDNS responder
|
||||
MDNSFILES=$(LWIPDIR)/apps/mdns/mdns.c
|
||||
|
||||
# NETBIOSNSFILES: NetBIOS name server
|
||||
NETBIOSNSFILES=$(LWIPDIR)/apps/netbiosns/netbiosns.c
|
||||
|
||||
# TFTPFILES: TFTP server files
|
||||
TFTPFILES=$(LWIPDIR)/apps/tftp/tftp_server.c
|
||||
|
||||
# MQTTFILES: MQTT client files
|
||||
MQTTFILES=$(LWIPDIR)/apps/mqtt/mqtt.c
|
||||
|
||||
# LWIPAPPFILES: All LWIP APPs
|
||||
LWIPAPPFILES=$(SNMPFILES) \
|
||||
$(HTTPDFILES) \
|
||||
$(LWIPERFFILES) \
|
||||
$(SNTPFILES) \
|
||||
$(MDNSFILES) \
|
||||
$(NETBIOSNSFILES) \
|
||||
$(TFTPFILES) \
|
||||
$(MQTTFILES)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<html>
|
||||
<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
|
||||
<body bgcolor="white" text="black">
|
||||
|
||||
<table width="100%">
|
||||
<tr valign="top"><td width="80">
|
||||
<a href="http://www.sics.se/"><img src="/img/sics.gif"
|
||||
border="0" alt="SICS logo" title="SICS logo"></a>
|
||||
</td><td width="500">
|
||||
<h1>lwIP - A Lightweight TCP/IP Stack</h1>
|
||||
<h2>404 - Page not found</h2>
|
||||
<p>
|
||||
Sorry, the page you are requesting was not found on this
|
||||
server.
|
||||
</p>
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 724 B |
|
|
@ -0,0 +1,47 @@
|
|||
<html>
|
||||
<head><title>lwIP - A Lightweight TCP/IP Stack</title></head>
|
||||
<body bgcolor="white" text="black">
|
||||
|
||||
<table width="100%">
|
||||
<tr valign="top"><td width="80">
|
||||
<a href="http://www.sics.se/"><img src="/img/sics.gif"
|
||||
border="0" alt="SICS logo" title="SICS logo"></a>
|
||||
</td><td width="500">
|
||||
<h1>lwIP - A Lightweight TCP/IP Stack</h1>
|
||||
<p>
|
||||
The web page you are watching was served by a simple web
|
||||
server running on top of the lightweight TCP/IP stack <a
|
||||
href="http://www.sics.se/~adam/lwip/">lwIP</a>.
|
||||
</p>
|
||||
<p>
|
||||
lwIP is an open source implementation of the TCP/IP
|
||||
protocol suite that was originally written by <a
|
||||
href="http://www.sics.se/~adam/lwip/">Adam Dunkels
|
||||
of the Swedish Institute of Computer Science</a> but now is
|
||||
being actively developed by a team of developers
|
||||
distributed world-wide. Since it's release, lwIP has
|
||||
spurred a lot of interest and has been ported to several
|
||||
platforms and operating systems. lwIP can be used either
|
||||
with or without an underlying OS.
|
||||
</p>
|
||||
<p>
|
||||
The focus of the lwIP TCP/IP implementation is to reduce
|
||||
the RAM usage while still having a full scale TCP. This
|
||||
makes lwIP suitable for use in embedded systems with tens
|
||||
of kilobytes of free RAM and room for around 40 kilobytes
|
||||
of code ROM.
|
||||
</p>
|
||||
<p>
|
||||
More information about lwIP can be found at the lwIP
|
||||
homepage at <a
|
||||
href="http://savannah.nongnu.org/projects/lwip/">http://savannah.nongnu.org/projects/lwip/</a>
|
||||
or at the lwIP wiki at <a
|
||||
href="http://lwip.wikia.com/">http://lwip.wikia.com/</a>.
|
||||
</p>
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_FSDATA_H
|
||||
#define LWIP_FSDATA_H
|
||||
|
||||
#include "lwip/apps/httpd_opts.h"
|
||||
#include "lwip/apps/fs.h"
|
||||
|
||||
struct fsdata_file {
|
||||
const struct fsdata_file *next;
|
||||
const unsigned char *name;
|
||||
const unsigned char *data;
|
||||
int len;
|
||||
u8_t flags;
|
||||
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||
u16_t chksum_count;
|
||||
const struct fsdata_chksum *chksum;
|
||||
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||
};
|
||||
|
||||
#endif /* LWIP_FSDATA_H */
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
#ifndef LWIP_HTTPD_STRUCTS_H
|
||||
#define LWIP_HTTPD_STRUCTS_H
|
||||
|
||||
#include "lwip/apps/httpd.h"
|
||||
|
||||
#if LWIP_HTTPD_DYNAMIC_HEADERS
|
||||
/** This struct is used for a list of HTTP header strings for various
|
||||
* filename extensions. */
|
||||
typedef struct
|
||||
{
|
||||
const char *extension;
|
||||
const char *content_type;
|
||||
} tHTTPHeader;
|
||||
|
||||
/** A list of strings used in HTTP headers (see RFC 1945 HTTP/1.0 and
|
||||
* RFC 2616 HTTP/1.1 for header field definitions) */
|
||||
static const char * const g_psHTTPHeaderStrings[] =
|
||||
{
|
||||
"HTTP/1.0 200 OK\r\n",
|
||||
"HTTP/1.0 404 File not found\r\n",
|
||||
"HTTP/1.0 400 Bad Request\r\n",
|
||||
"HTTP/1.0 501 Not Implemented\r\n",
|
||||
"HTTP/1.1 200 OK\r\n",
|
||||
"HTTP/1.1 404 File not found\r\n",
|
||||
"HTTP/1.1 400 Bad Request\r\n",
|
||||
"HTTP/1.1 501 Not Implemented\r\n",
|
||||
"Content-Length: ",
|
||||
"Connection: Close\r\n",
|
||||
"Connection: keep-alive\r\n",
|
||||
"Connection: keep-alive\r\nContent-Length: ",
|
||||
"Server: "HTTPD_SERVER_AGENT"\r\n",
|
||||
"\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
|
||||
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||
,"Connection: keep-alive\r\nContent-Length: 77\r\n\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Indexes into the g_psHTTPHeaderStrings array */
|
||||
#define HTTP_HDR_OK 0 /* 200 OK */
|
||||
#define HTTP_HDR_NOT_FOUND 1 /* 404 File not found */
|
||||
#define HTTP_HDR_BAD_REQUEST 2 /* 400 Bad request */
|
||||
#define HTTP_HDR_NOT_IMPL 3 /* 501 Not Implemented */
|
||||
#define HTTP_HDR_OK_11 4 /* 200 OK */
|
||||
#define HTTP_HDR_NOT_FOUND_11 5 /* 404 File not found */
|
||||
#define HTTP_HDR_BAD_REQUEST_11 6 /* 400 Bad request */
|
||||
#define HTTP_HDR_NOT_IMPL_11 7 /* 501 Not Implemented */
|
||||
#define HTTP_HDR_CONTENT_LENGTH 8 /* Content-Length: (HTTP 1.0)*/
|
||||
#define HTTP_HDR_CONN_CLOSE 9 /* Connection: Close (HTTP 1.1) */
|
||||
#define HTTP_HDR_CONN_KEEPALIVE 10 /* Connection: keep-alive (HTTP 1.1) */
|
||||
#define HTTP_HDR_KEEPALIVE_LEN 11 /* Connection: keep-alive + Content-Length: (HTTP 1.1)*/
|
||||
#define HTTP_HDR_SERVER 12 /* Server: HTTPD_SERVER_AGENT */
|
||||
#define DEFAULT_404_HTML 13 /* default 404 body */
|
||||
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||
#define DEFAULT_404_HTML_PERSISTENT 14 /* default 404 body, but including Connection: keep-alive */
|
||||
#endif
|
||||
|
||||
|
||||
#define HTTP_HDR_HTML "Content-type: text/html\r\n\r\n"
|
||||
#define HTTP_HDR_SSI "Content-type: text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n"
|
||||
#define HTTP_HDR_GIF "Content-type: image/gif\r\n\r\n"
|
||||
#define HTTP_HDR_PNG "Content-type: image/png\r\n\r\n"
|
||||
#define HTTP_HDR_JPG "Content-type: image/jpeg\r\n\r\n"
|
||||
#define HTTP_HDR_BMP "Content-type: image/bmp\r\n\r\n"
|
||||
#define HTTP_HDR_ICO "Content-type: image/x-icon\r\n\r\n"
|
||||
#define HTTP_HDR_APP "Content-type: application/octet-stream\r\n\r\n"
|
||||
#define HTTP_HDR_JS "Content-type: application/javascript\r\n\r\n"
|
||||
#define HTTP_HDR_RA "Content-type: application/javascript\r\n\r\n"
|
||||
#define HTTP_HDR_CSS "Content-type: text/css\r\n\r\n"
|
||||
#define HTTP_HDR_SWF "Content-type: application/x-shockwave-flash\r\n\r\n"
|
||||
#define HTTP_HDR_XML "Content-type: text/xml\r\n\r\n"
|
||||
#define HTTP_HDR_PDF "Content-type: application/pdf\r\n\r\n"
|
||||
#define HTTP_HDR_JSON "Content-type: application/json\r\n\r\n"
|
||||
|
||||
#define HTTP_HDR_DEFAULT_TYPE "Content-type: text/plain\r\n\r\n"
|
||||
|
||||
/** A list of extension-to-HTTP header strings (see outdated RFC 1700 MEDIA TYPES
|
||||
* and http://www.iana.org/assignments/media-types for registered content types
|
||||
* and subtypes) */
|
||||
static const tHTTPHeader g_psHTTPHeaders[] =
|
||||
{
|
||||
{ "html", HTTP_HDR_HTML},
|
||||
{ "htm", HTTP_HDR_HTML},
|
||||
{ "shtml",HTTP_HDR_SSI},
|
||||
{ "shtm", HTTP_HDR_SSI},
|
||||
{ "ssi", HTTP_HDR_SSI},
|
||||
{ "gif", HTTP_HDR_GIF},
|
||||
{ "png", HTTP_HDR_PNG},
|
||||
{ "jpg", HTTP_HDR_JPG},
|
||||
{ "bmp", HTTP_HDR_BMP},
|
||||
{ "ico", HTTP_HDR_ICO},
|
||||
{ "class",HTTP_HDR_APP},
|
||||
{ "cls", HTTP_HDR_APP},
|
||||
{ "js", HTTP_HDR_JS},
|
||||
{ "ram", HTTP_HDR_RA},
|
||||
{ "css", HTTP_HDR_CSS},
|
||||
{ "swf", HTTP_HDR_SWF},
|
||||
{ "xml", HTTP_HDR_XML},
|
||||
{ "xsl", HTTP_HDR_XML},
|
||||
{ "pdf", HTTP_HDR_PDF},
|
||||
{ "json", HTTP_HDR_JSON}
|
||||
};
|
||||
|
||||
#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader))
|
||||
|
||||
#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
|
||||
|
||||
#if LWIP_HTTPD_SSI
|
||||
static const char * const g_pcSSIExtensions[] = {
|
||||
".shtml", ".shtm", ".ssi", ".xml"
|
||||
};
|
||||
#define NUM_SHTML_EXTENSIONS (sizeof(g_pcSSIExtensions) / sizeof(const char *))
|
||||
#endif /* LWIP_HTTPD_SSI */
|
||||
|
||||
#endif /* LWIP_HTTPD_STRUCTS_H */
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
open(OUTPUT, "> fsdata.c");
|
||||
|
||||
chdir("fs");
|
||||
open(FILES, "find . -type f |");
|
||||
|
||||
while($file = <FILES>) {
|
||||
|
||||
# Do not include files in CVS directories nor backup files.
|
||||
if($file =~ /(CVS|~)/) {
|
||||
next;
|
||||
}
|
||||
|
||||
chop($file);
|
||||
|
||||
open(HEADER, "> /tmp/header") || die $!;
|
||||
if($file =~ /404/) {
|
||||
print(HEADER "HTTP/1.0 404 File not found\r\n");
|
||||
} else {
|
||||
print(HEADER "HTTP/1.0 200 OK\r\n");
|
||||
}
|
||||
print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
|
||||
if($file =~ /\.html$/) {
|
||||
print(HEADER "Content-type: text/html\r\n");
|
||||
} elsif($file =~ /\.gif$/) {
|
||||
print(HEADER "Content-type: image/gif\r\n");
|
||||
} elsif($file =~ /\.png$/) {
|
||||
print(HEADER "Content-type: image/png\r\n");
|
||||
} elsif($file =~ /\.jpg$/) {
|
||||
print(HEADER "Content-type: image/jpeg\r\n");
|
||||
} elsif($file =~ /\.class$/) {
|
||||
print(HEADER "Content-type: application/octet-stream\r\n");
|
||||
} elsif($file =~ /\.ram$/) {
|
||||
print(HEADER "Content-type: audio/x-pn-realaudio\r\n");
|
||||
} else {
|
||||
print(HEADER "Content-type: text/plain\r\n");
|
||||
}
|
||||
print(HEADER "\r\n");
|
||||
close(HEADER);
|
||||
|
||||
unless($file =~ /\.plain$/ || $file =~ /cgi/) {
|
||||
system("cat /tmp/header $file > /tmp/file");
|
||||
} else {
|
||||
system("cp $file /tmp/file");
|
||||
}
|
||||
|
||||
open(FILE, "/tmp/file");
|
||||
unlink("/tmp/file");
|
||||
unlink("/tmp/header");
|
||||
|
||||
$file =~ s/\.//;
|
||||
$fvar = $file;
|
||||
$fvar =~ s-/-_-g;
|
||||
$fvar =~ s-\.-_-g;
|
||||
print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
|
||||
print(OUTPUT "\t/* $file */\n\t");
|
||||
for($j = 0; $j < length($file); $j++) {
|
||||
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
|
||||
}
|
||||
printf(OUTPUT "0,\n");
|
||||
|
||||
|
||||
$i = 0;
|
||||
while(read(FILE, $data, 1)) {
|
||||
if($i == 0) {
|
||||
print(OUTPUT "\t");
|
||||
}
|
||||
printf(OUTPUT "%#02x, ", unpack("C", $data));
|
||||
$i++;
|
||||
if($i == 10) {
|
||||
print(OUTPUT "\n");
|
||||
$i = 0;
|
||||
}
|
||||
}
|
||||
print(OUTPUT "};\n\n");
|
||||
close(FILE);
|
||||
push(@fvars, $fvar);
|
||||
push(@files, $file);
|
||||
}
|
||||
|
||||
for($i = 0; $i < @fvars; $i++) {
|
||||
$file = $files[$i];
|
||||
$fvar = $fvars[$i];
|
||||
|
||||
if($i == 0) {
|
||||
$prevfile = "NULL";
|
||||
} else {
|
||||
$prevfile = "file" . $fvars[$i - 1];
|
||||
}
|
||||
print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
|
||||
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
|
||||
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
|
||||
}
|
||||
|
||||
print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
|
||||
print(OUTPUT "#define FS_NUMFILES $i\n");
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
This directory contains a script ('makefsdata') to create C code suitable for
|
||||
httpd for given html pages (or other files) in a directory.
|
||||
|
||||
There is also a plain C console application doing the same and extended a bit.
|
||||
|
||||
Usage: htmlgen [targetdir] [-s] [-i]s
|
||||
targetdir: relative or absolute path to files to convert
|
||||
switch -s: toggle processing of subdirectories (default is on)
|
||||
switch -e: exclude HTTP header from file (header is created at runtime, default is on)
|
||||
switch -11: include HTTP 1.1 header (1.0 is default)
|
||||
|
||||
if targetdir not specified, makefsdata will attempt to
|
||||
process files in subdirectory 'fs'.
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue