Import app manager, samples and test-tools

This commit is contained in:
wenyongh
2019-05-17 17:15:25 +08:00
parent b6e29e2153
commit dd5b133fa5
164 changed files with 21123 additions and 496 deletions

View File

@ -0,0 +1,38 @@
Contiki is licensed under the 3-clause BSD license. This license gives
everyone the right to use and distribute the code, either in binary or
source code format, as long as the copyright license is retained in
the source code.
The copyright for different parts of the code is held by different
people and organizations, but the code is licensed under the same type
of license. The license text is:
* Copyright (c) (Year), (Name of copyright holder)
* 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 copyright holder 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 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 HOLDER 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.

View File

@ -0,0 +1,19 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# 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.
COAP_ROOT=${ZEPHYR_BASE}/subsys/aee/Beihai/runtime/utils/coap
subdir-ccflags-y += -I${COAP_ROOT}/er-coap -I${COAP_ROOT}/extension
obj-y += er-coap/
obj-y += extension/

View File

@ -0,0 +1,15 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# 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.
obj-y += er-coap.o

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* 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.
*/
/**
* \file
* Collection of default configuration values.
* \author
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
*/
#ifndef ER_COAP_CONF_H_
#define ER_COAP_CONF_H_
/* Features that can be disabled to achieve smaller memory footprint */
#define COAP_LINK_FORMAT_FILTERING 0
#define COAP_PROXY_OPTION_PROCESSING 0
/* Listening port for the CoAP REST Engine */
#ifndef COAP_SERVER_PORT
#define COAP_SERVER_PORT COAP_DEFAULT_PORT
#endif
/* The number of concurrent messages that can be stored for retransmission in the transaction layer. */
#ifndef COAP_MAX_OPEN_TRANSACTIONS
#define COAP_MAX_OPEN_TRANSACTIONS 4
#endif /* COAP_MAX_OPEN_TRANSACTIONS */
/* Maximum number of failed request attempts before action */
#ifndef COAP_MAX_ATTEMPTS
#define COAP_MAX_ATTEMPTS 4
#endif /* COAP_MAX_ATTEMPTS */
/* Conservative size limit, as not all options have to be set at the same time. Check when Proxy-Uri option is used */
#ifndef COAP_MAX_HEADER_SIZE /* Hdr CoF If-Match Obs Blo strings */
#define COAP_MAX_HEADER_SIZE 512
//(4 + COAP_TOKEN_LEN + 3 + 1 + COAP_ETAG_LEN + 4 + 4 + 30) /* 65 */
#endif /* COAP_MAX_HEADER_SIZE */
/* Number of observer slots (each takes abot xxx bytes) */
#ifndef COAP_MAX_OBSERVERS
#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS - 1
#endif /* COAP_MAX_OBSERVERS */
/* Interval in notifies in which NON notifies are changed to CON notifies to check client. */
#define COAP_OBSERVE_REFRESH_INTERVAL 20
#endif /* ER_COAP_CONF_H_ */

View File

@ -0,0 +1,161 @@
/*
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* 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.
*/
/**
* \file
* Collection of constants specified in the CoAP standard.
* \author
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
*/
#ifndef ER_COAP_CONSTANTS_H_
#define ER_COAP_CONSTANTS_H_
#define COAP_DEFAULT_PORT 5683
#define COAP_DEFAULT_MAX_AGE 60
#define COAP_RESPONSE_TIMEOUT 3
#define COAP_RESPONSE_RANDOM_FACTOR 1.5
#define COAP_MAX_RETRANSMIT 4
#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */
#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */
#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */
#define COAP_HEADER_VERSION_MASK 0xC0
#define COAP_HEADER_VERSION_POSITION 6
#define COAP_HEADER_TYPE_MASK 0x30
#define COAP_HEADER_TYPE_POSITION 4
#define COAP_HEADER_TOKEN_LEN_MASK 0x0F
#define COAP_HEADER_TOKEN_LEN_POSITION 0
#define COAP_HEADER_OPTION_DELTA_MASK 0xF0
#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F
/* CoAP message types */
typedef enum {
COAP_TYPE_CON, /* confirmables */
COAP_TYPE_NON, /* non-confirmables */
COAP_TYPE_ACK, /* acknowledgements */
COAP_TYPE_RST /* reset */
} coap_message_type_t;
/* CoAP request method codes */
typedef enum {
COAP_GET = 1, COAP_POST, COAP_PUT, COAP_DELETE
} coap_method_t;
/* CoAP response codes */
typedef enum {
NO_ERROR = 0,
CREATED_2_01 = 65, /* CREATED */
DELETED_2_02 = 66, /* DELETED */
VALID_2_03 = 67, /* NOT_MODIFIED */
CHANGED_2_04 = 68, /* CHANGED */
CONTENT_2_05 = 69, /* OK */
CONTINUE_2_31 = 95, /* CONTINUE */
BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */
UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */
BAD_OPTION_4_02 = 130, /* BAD_OPTION */
FORBIDDEN_4_03 = 131, /* FORBIDDEN */
NOT_FOUND_4_04 = 132, /* NOT_FOUND */
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */
INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */
NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */
BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */
SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */
GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */
PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
/* Erbium errors */
MEMORY_ALLOCATION_ERROR = 192, PACKET_SERIALIZATION_ERROR,
/* Erbium hooks */
MANUAL_RESPONSE, PING_RESPONSE
} coap_status_t;
/* CoAP header option numbers */
typedef enum {
COAP_OPTION_IF_MATCH = 1, /* 0-8 B */
COAP_OPTION_URI_HOST = 3, /* 1-255 B */
COAP_OPTION_ETAG = 4, /* 1-8 B */
COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */
COAP_OPTION_OBSERVE = 6, /* 0-3 B */
COAP_OPTION_URI_PORT = 7, /* 0-2 B */
COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */
COAP_OPTION_URI_PATH = 11, /* 0-255 B */
COAP_OPTION_CONTENT_FORMAT = 12, /* 0-2 B */
COAP_OPTION_MAX_AGE = 14, /* 0-4 B */
COAP_OPTION_URI_QUERY = 15, /* 0-255 B */
COAP_OPTION_ACCEPT = 17, /* 0-2 B */
COAP_OPTION_LOCATION_QUERY = 20, /* 0-255 B */
COAP_OPTION_BLOCK2 = 23, /* 1-3 B */
COAP_OPTION_BLOCK1 = 27, /* 1-3 B */
COAP_OPTION_SIZE2 = 28, /* 0-4 B */
COAP_OPTION_PROXY_URI = 35, /* 1-1034 B */
COAP_OPTION_PROXY_SCHEME = 39, /* 1-255 B */
COAP_OPTION_SIZE1 = 60, /* 0-4 B */
} coap_option_t;
/* CoAP Content-Formats */
typedef enum {
TEXT_PLAIN = 0,
TEXT_XML = 1,
TEXT_CSV = 2,
TEXT_HTML = 3,
IMAGE_GIF = 21,
IMAGE_JPEG = 22,
IMAGE_PNG = 23,
IMAGE_TIFF = 24,
AUDIO_RAW = 25,
VIDEO_RAW = 26,
APPLICATION_LINK_FORMAT = 40,
APPLICATION_XML = 41,
APPLICATION_OCTET_STREAM = 42,
APPLICATION_RDF_XML = 43,
APPLICATION_SOAP_XML = 44,
APPLICATION_ATOM_XML = 45,
APPLICATION_XMPP_XML = 46,
APPLICATION_EXI = 47,
APPLICATION_FASTINFOSET = 48,
APPLICATION_SOAP_FASTINFOSET = 49,
APPLICATION_JSON = 50,
APPLICATION_X_OBIX_BINARY = 51
} coap_content_format_t;
#endif /* ER_COAP_CONSTANTS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,370 @@
/*
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* 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.
*/
/**
* \file
* An implementation of the Constrained Application Protocol (RFC).
* \author
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
*/
#ifndef ER_COAP_H_
#define ER_COAP_H_
#include "../extension/coap_platforms.h"
#include <stddef.h> /* for size_t */
#include <stdint.h>
//#include "contiki-net.h"
#include "er-coap-constants.h"
#include "er-coap-conf.h"
#ifdef __cplusplus
extern "C" {
#endif
/* sanity check for configured values */
#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE)
/*#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN)
#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE"
#endif
*/
/* ------------------------------------------------------ */
/* ------ section added by the coap request --------- */
/* ------------------------------------------------------ */
//typedef int (*restful_response_handler)(void *response,void *data);
#define RX_TIMEOUT (-1)
typedef int (*Tx_Data)(void * coap_ctx, const uip_ipaddr_t *dst_addr, void *buf, int len);
typedef int (*Rx_Data) (void * coap_ctx, void *buf, int len, int timeout);
typedef int (*Request_Handler) (void * coap_ctx, void *);
typedef int (*CoAP_Res_Handler) (void * request, void * response, char **out_payload, int * payload_len);
typedef struct _coap_resource_handler
{
struct _coap_resource_handler * next;
char * url;
CoAP_Res_Handler get_handler;
CoAP_Res_Handler put_handler;
CoAP_Res_Handler post_handler;
CoAP_Res_Handler other_handler; // create | delete
}coap_resource_handler_t;
typedef struct res_block_state
{
struct res_block_state * next;
char * url;
void * buffer;
int buffer_size;
uint32_t block_num;
uint16_t block_size;
uint16_t content_fmt;
uint32_t last_access;
uint8_t is_get;
} res_block_state_t;
typedef struct peer_block_state
{
struct peer_block_state * next;
struct net_addr_coap peer_addr;
res_block_state_t * list;
}peer_block_state_t;
typedef struct coap_context {
uint8_t * buf;
uint32_t buf_len; // the data length
uint32_t buf_size; // the malloced buffer size
struct net_addr_coap my_addr;
// the address associated with current buffer
struct net_addr_coap src_addr;
uint8_t status;
uint8_t is_used;
uint8_t response_on_not_found;
uint16_t default_retrans_cnt;
uint32_t default_retrans_ms;
Tx_Data tx_data;
Rx_Data rx_data;
int socket;
char * user_data;
peer_block_state_t * blockwise_list;
coap_resource_handler_t * resource_handlers;
void * transactions;
void * transaction_lock;
uint32_t last_checktime;
void * request_handler;
#ifdef WITH_DTLS
struct dtls_context_t *dtls_context;
dtls_handler_t dtls_handler;
struct process *process;
#endif /* WITH_DTLS */
} coap_context_t;
int add_resource_handler(coap_context_t * coap_ctx, coap_resource_handler_t * handler);
// coap_context_t * coap_context_new(uip_ipaddr_t *my_addr, uint16_t my_port); //CANNOTBUILD
void coap_context_close(coap_context_t *coap_ctx);
void coap_ctx_send(coap_context_t *coap_ctx, uint8_t *data,
uint16_t length);
/* ---------------- end of section ------------------ */
/* use Erbium CoAP for the REST Engine. Must come before include of rest-engine.h. */
//#define REST coap_rest_implementation
//#include "rest-engine.h"
/* REST_MAX_CHUNK_SIZE can be different from 2^x so we need to get next lower 2^x for COAP_MAX_BLOCK_SIZE */
#ifndef COAP_MAX_BLOCK_SIZE
#define COAP_MAX_BLOCK_SIZE (REST_MAX_CHUNK_SIZE < 32 ? 16 : \
(REST_MAX_CHUNK_SIZE < 64 ? 32 : \
(REST_MAX_CHUNK_SIZE < 128 ? 64 : \
(REST_MAX_CHUNK_SIZE < 256 ? 128 : \
(REST_MAX_CHUNK_SIZE < 512 ? 256 : \
(REST_MAX_CHUNK_SIZE < 1024 ? 512 : \
(REST_MAX_CHUNK_SIZE < 2048 ? 1024 : 2048)))))))
#endif /* COAP_MAX_BLOCK_SIZE */
/* direct access into the buffer */
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#ifdef NETSTACK_CONF_WITH_IPV6
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
#else
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
#endif
/* bitmap for set options */
enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };
#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE))
#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE)))
/* parsed message struct */
typedef struct {
uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */
uint8_t version;
coap_message_type_t type;
uint8_t code;
uint16_t mid;
uint8_t token_len;
uint8_t token[COAP_TOKEN_LEN];
uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1]; /* bitmap to check if option is set */
coap_content_format_t content_format; /* parse options once and store; allows setting options in random order */
uint32_t max_age;
uint8_t etag_len;
uint8_t etag[COAP_ETAG_LEN];
size_t proxy_uri_len;
const char *proxy_uri;
size_t proxy_scheme_len;
const char *proxy_scheme;
size_t uri_host_len;
const char *uri_host;
size_t location_path_len;
const char *location_path;
uint16_t uri_port;
size_t location_query_len;
const char *location_query;
size_t uri_path_len;
const char *uri_path;
int32_t observe;
coap_content_format_t accept;
uint8_t if_match_len;
uint8_t if_match[COAP_ETAG_LEN];
uint32_t block2_num;
uint8_t block2_more;
uint32_t block2_size;
uint32_t block2_offset;
uint32_t block1_num;
uint8_t block1_more;
uint32_t block1_size;
uint32_t block1_offset;
uint32_t size2;
uint32_t size1;
size_t uri_query_len;
const char *uri_query;
uint8_t if_none_match;
uint32_t payload_len;
uint8_t *payload;
} coap_packet_t;
/* option format serialization */
#define COAP_SERIALIZE_INT_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " [%u]\n", coap_pkt->field); \
option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \
current_number = number; \
}
#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \
coap_pkt->field[0], \
coap_pkt->field[1], \
coap_pkt->field[2], \
coap_pkt->field[3], \
coap_pkt->field[4], \
coap_pkt->field[5], \
coap_pkt->field[6], \
coap_pkt->field[7] \
); /* FIXME always prints 8 bytes */ \
option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \
current_number = number; \
}
#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \
if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \
option += coap_serialize_array_option(number, current_number, option, (uint8_t *)coap_pkt->field, coap_pkt->field##_len, splitter); \
current_number = number; \
}
#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) \
{ \
PRINTF(text " [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
uint32_t block = coap_pkt->field##_num << 4; \
if(coap_pkt->field##_more) { block |= 0x8; } \
block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \
PRINTF(text " encoded: 0x%lX\n", block); \
option += coap_serialize_int_option(number, current_number, option, block); \
current_number = number; \
}
/* to store error code and human-readable payload */
extern coap_status_t erbium_status_code;
extern char *coap_error_message;
void coap_init_connection(uint16_t port);
uint16_t coap_get_mid(void);
void coap_init_message(void *packet, coap_message_type_t type, uint8_t code,
uint16_t mid);
size_t coap_serialize_message(void *packet, uint8_t *buffer);
void coap_send_message(coap_context_t*, uip_ipaddr_t *addr, uint16_t port, uint8_t *data,
uint16_t length);
coap_status_t coap_parse_message(void *request, uint8_t *data,
uint16_t data_len);
int coap_get_query_variable(void *packet, const char *name,
const char **output);
int coap_get_post_variable(void *packet, const char *name,
const char **output);
/*---------------------------------------------------------------------------*/
int coap_set_status_code(void *packet, unsigned int code);
int coap_set_token(void *packet, const uint8_t *token, size_t token_len);
int coap_get_header_content_format(void *packet, unsigned int *format);
int coap_set_header_content_format(void *packet, unsigned int format);
int coap_get_header_accept(void *packet, unsigned int *accept);
int coap_set_header_accept(void *packet, unsigned int accept);
int coap_get_header_max_age(void *packet, uint32_t *age);
int coap_set_header_max_age(void *packet, uint32_t age);
int coap_get_header_etag(void *packet, const uint8_t **etag);
int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len);
int coap_get_header_if_match(void *packet, const uint8_t **etag);
int coap_set_header_if_match(void *packet, const uint8_t *etag,
size_t etag_len);
int coap_get_header_if_none_match(void *packet);
int coap_set_header_if_none_match(void *packet);
int coap_get_header_proxy_uri(void *packet, const char **uri); /* in-place string might not be 0-terminated. */
int coap_set_header_proxy_uri(void *packet, const char *uri);
int coap_get_header_proxy_scheme(void *packet, const char **scheme); /* in-place string might not be 0-terminated. */
int coap_set_header_proxy_scheme(void *packet, const char *scheme);
int coap_get_header_uri_host(void *packet, const char **host); /* in-place string might not be 0-terminated. */
int coap_set_header_uri_host(void *packet, const char *host);
int coap_get_header_uri_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */
int coap_set_header_uri_path(void *packet, const char *path);
int coap_get_header_uri_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */
int coap_set_header_uri_query(void *packet, const char *query);
int coap_get_header_location_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */
int coap_set_header_location_path(void *packet, const char *path); /* also splits optional query into Location-Query option. */
int coap_get_header_location_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */
int coap_set_header_location_query(void *packet, const char *query);
int coap_get_header_observe(void *packet, uint32_t *observe);
int coap_set_header_observe(void *packet, uint32_t observe);
int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more,
uint32_t *size, uint32_t *offset);
int coap_set_header_block2(void *packet, uint32_t num, uint8_t more,
uint32_t size);
int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more,
uint16_t *size, uint32_t *offset);
int coap_set_header_block1(void *packet, uint32_t num, uint8_t more,
uint16_t size);
int coap_get_header_size2(void *packet, uint32_t *size);
int coap_set_header_size2(void *packet, uint32_t size);
int coap_get_header_size1(void *packet, uint32_t *size);
int coap_set_header_size1(void *packet, uint32_t size);
int coap_get_payload(void *packet, const uint8_t **payload);
int coap_set_payload(void *packet, const void *payload, size_t length);
#ifdef __cplusplus
}
#endif
#endif /* ER_COAP_H_ */

View File

@ -0,0 +1,15 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# 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.
obj-y += coap_over_tcp.o

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* 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.
*/
#include "coap_ext.h"
char * coap_get_full_url_alloc(coap_packet_t * request)
{
const char *url = NULL;
const char * query = NULL;
int url_len = coap_get_header_uri_path(request, &url);
int query_len = coap_get_header_uri_query(request, &query);
if (url_len == 0)
return NULL;
char * url_alloc = (char*) bh_malloc(url_len + 1 + query_len + 1);
memcpy(url_alloc, url, url_len);
url_alloc[url_len] = 0;
// make the url looks like /abc?e=f
if (query_len != 0) {
strcat(url_alloc, "&");
memcpy(url_alloc + strlen(url_alloc), query, query_len);
url_alloc[url_len + 1 + query_len] = 0;
}
return url_alloc;
}
void convert_request_to_coap_packet(request_t * req, coap_packet_t * packet)
{
coap_init_message(packet, COAP_TYPE_NON, req->action, req->mid);
coap_set_token(packet, (uint8_t *) &req->mid, sizeof(req->mid));
coap_set_header_content_format(packet, req->fmt);
coap_set_header_uri_path(packet, req->url);
coap_set_payload(packet, req->payload, req->payload_len);
packet->mid = req->mid;
}
void convert_response_to_coap_packet(response_t * response,
coap_packet_t * packet)
{
coap_init_message(packet, COAP_TYPE_NON, response->status, response->mid);
coap_set_token(packet, (uint8_t *) &response->mid, sizeof(response->mid));
coap_set_header_content_format(packet, response->fmt);
coap_set_payload(packet, response->payload, response->payload_len);
packet->mid = response->mid;
}
// return: the length of url.
// note: the url is probably not end with 0 due to coap packing design.
int convert_coap_packet_to_request(coap_packet_t *packet, request_t *request)
{
const char *url = NULL;
int url_len = coap_get_header_uri_path(packet, &url);
memset(request, 0, sizeof(*request));
request->action = packet->code;
request->fmt = packet->content_format;
if (packet->token_len == 4) {
request->mid = *((unsigned long *) packet->token);
} else {
request->mid = packet->mid;
}
request->payload = packet->payload;
request->payload_len = packet->payload_len;
request->url = (char *)url;
return url_len;
}
void convert_coap_packet_to_response(coap_packet_t *packet,
response_t *response)
{
memset(response, 0, sizeof(*response));
response->status = packet->code;
response->fmt = packet->content_format;
if (packet->token_len == 4) {
response->mid = *((unsigned long *) packet->token);
} else {
response->mid = packet->mid;
}
response->payload = packet->payload;
response->payload_len = packet->payload_len;
return;
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* 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 COAP_EXTENSION_COAP_EXT_H_
#define COAP_EXTENSION_COAP_EXT_H_
#include "er-coap.h"
#include "shared_utils.h"
#ifdef __cplusplus
extern "C" {
#endif
#define COAP_EVENT (COAP_DELETE + 2)
char * coap_get_full_url_alloc(coap_packet_t * request);
coap_status_t coap_parse_message_tcp(void *packet, uint8_t *data,
uint32_t data_len);
int coap_serialize_message_tcp(void *packet, uint8_t ** buffer_out);
int coap_set_payload_tcp(void *packet, const void *payload, size_t length);
uint8_t coap_is_request(coap_packet_t * coap_message);
uint16_t coap_find_mid(uint8_t *buffer);
uint8_t coap_find_code(uint8_t *buffer);
void coap_change_mid(uint8_t *buffer, uint16_t id);
int add_resource_handler(coap_context_t * coap_ctx,
coap_resource_handler_t * handler);
uint32_t check_blockwise_timeout_ms(coap_context_t * coap_ctx, int timeout_sec);
int convert_coap_packet_to_request(coap_packet_t *packet, request_t *request);
void convert_coap_packet_to_response(coap_packet_t *packet,
response_t *response);
void convert_response_to_coap_packet(response_t * response,
coap_packet_t * packet);
void convert_request_to_coap_packet(request_t * req, coap_packet_t * packet);
#ifdef __cplusplus
}
#endif
#endif /* COAP_EXTENSION_COAP_EXT_H_ */

View File

@ -0,0 +1,481 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* 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.
*/
#include <string.h>
#include <stdio.h>
#include "bh_common.h"
#include "er-coap.h"
#include "coap_ext.h"
#include "er-coap-constants.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
#else
#define PRINTF(...)
#define PRINT6ADDR(addr)
#define PRINTLLADDR(addr)
#endif
extern size_t
coap_serialize_array_option(unsigned int number, unsigned int current_number,
uint8_t *buffer, uint8_t *array, size_t length, char split_char);
extern size_t
coap_serialize_int_option(unsigned int number, unsigned int current_number,
uint8_t *buffer, uint32_t value);
extern uint16_t coap_log_2(uint16_t value);
extern uint32_t coap_parse_int_option(uint8_t *bytes, size_t length);
extern void
coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option,
size_t option_len, char separator);
/*
*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Len=15 | TKL | Extended Length (32 bits)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | Code | Token (if any, TKL bytes) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| Payload (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
int coap_set_payload_tcp(void *packet, const void *payload, size_t length)
{
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
coap_pkt->payload = (uint8_t *) payload;
coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length);
return coap_pkt->payload_len;
}
#if 0
static size_t coap_calc_ext_len_field(int len)
{
if(len < 13)
return 0;
else if(len <= (0xFF+13))
return 1;
else if(len <= (0xFFFF+269))
return 2;
else if(len < (0xFFFFFFFF+65805))
return 4;
else
return 0;
}
#endif
static size_t coap_max_options_offset(void *packet)
{
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
return 6 + coap_pkt->token_len;
}
int coap_serialize_message_tcp(void *packet, uint8_t ** buffer_out)
{
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
uint8_t buffer[128];
uint8_t *option = buffer;
unsigned int current_number = 0;
if (coap_pkt->uri_path_len > 100) {
*buffer_out = 0;
return -1;
}
/* Serialize options */
current_number = 0;
if (0 == coap_pkt->token_len) {
bh_memcpy_s(coap_pkt->token, COAP_TOKEN_LEN, &coap_pkt->mid,
sizeof(coap_pkt->mid));
coap_pkt->token_len = sizeof(coap_pkt->mid);
}PRINTF("-Serializing options at %p-\n", option);
/* The options must be serialized in the order of their number */
COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match, "If-Match");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host, '\0',
"Uri-Host");
COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag, "ETag");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
content_format - coap_pkt-> content_format /* hack to get a zero field */,
"If-None-Match");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe, "Observe");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port, "Uri-Port");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path, '/',
"Location-Path");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, 0, //'/',
"Uri-Path");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
"Content-Format");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query, '&',
"Uri-Query");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT, accept, "Accept");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query,
'&', "Location-Query");
COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2, "Block2");
COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1, "Block1");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2, "Size2");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri, '\0',
"Proxy-Uri");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme, '\0',
"Proxy-Scheme");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1, "Size1");
/* Pack payload */
if (coap_pkt->payload_len) {
*option = 0xFF;
++option;
}
uint32_t option_len = option - &buffer[0];
uint8_t * p = (uint8_t *) os_malloc(
coap_max_options_offset(packet) + option_len
+ coap_pkt->payload_len);
if (p == NULL)
return 0;
*buffer_out = p;
uint8_t first_4bits;
*p = (coap_pkt->token_len & 0xF);
uint32_t len = option_len + coap_pkt->payload_len;
if (len < 13) {
first_4bits = len;
*p++ |= first_4bits << 4;
} else if (len <= (0xFF + 13)) {
first_4bits = 13;
*p++ |= first_4bits << 4;
*p++ = len - 13;
} else if (len <= (0xFFFF + 269)) {
first_4bits = 14;
*p++ |= first_4bits << 4;
len -= 269;
*p = (uint8_t)(len >> 8);
p++;
*p = (uint8_t)(len & 0xFF);
p++;
} else {
first_4bits = 15;
*p++ |= first_4bits << 4;
len -= 65805;
*p++ = (uint8_t)(len >> 24);
*p++ = (uint8_t)(len >> 16);
*p++ = (uint8_t)(len >> 8);
*p++ = (uint8_t)(len & 0xFF);
}
*p = coap_pkt->code;
p++;
if (coap_pkt->token_len)
bh_memcpy_s(p, coap_pkt->token_len, coap_pkt->token,
coap_pkt->token_len);
p += coap_pkt->token_len;
bh_memcpy_s(p, option_len, buffer, option_len);
p += option_len;
bh_memcpy_s(p, coap_pkt->payload_len, coap_pkt->payload,
coap_pkt->payload_len);
p += coap_pkt->payload_len;
return (p - *buffer_out); /* packet length */
}
coap_status_t coap_parse_message_tcp(void *packet, uint8_t *data,
uint32_t data_len)
{
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
/* initialize packet */
memset(coap_pkt, 0, sizeof(coap_packet_t));
/* pointer to packet bytes */
coap_pkt->buffer = data;
/* parse header fields */
coap_pkt->version = 1;
coap_pkt->type = COAP_TYPE_NON;
coap_pkt->token_len = MIN(COAP_TOKEN_LEN, data[0] & 0xF);
coap_pkt->mid = 0;
uint8_t *p = data;
uint8_t first_4bits = data[0] >> 4;
uint32_t options_payload_size;
uint8_t ext_len_field = 0;
if (first_4bits < 13) {
options_payload_size = first_4bits;
p++;
} else if (first_4bits == 13) {
ext_len_field = 1;
options_payload_size = data[1] + 13;
p += 2;
} else if (first_4bits == 14) {
ext_len_field = 2;
options_payload_size = (uint16_t)(data[1] << 8) + data[2] + 269;
p += 3;
} else if (first_4bits == 15) {
ext_len_field = 4;
options_payload_size = (data[1] << 24) + (data[2] << 16)
+ (data[3] << 8) + data[4] + 65805;
p += 5;
}
// check the data size is smaller than the size indicated by the packet
if (ext_len_field + coap_pkt->token_len + 2 + options_payload_size
> data_len)
return BAD_REQUEST_4_00;
coap_pkt->code = *p++;
if (coap_pkt->token_len)
bh_memcpy_s(coap_pkt->token, COAP_TOKEN_LEN, p, coap_pkt->token_len);
if (coap_pkt->token_len >= 2) {
union {
uint16_t *mid;
uint8_t *token;
} mid_token_union;
mid_token_union.token = coap_pkt->token;
coap_pkt->mid = *(mid_token_union.mid);
}
p += coap_pkt->token_len;
uint8_t *current_option = p;
uint8_t * option_start = p;
/* parse options */
memset(coap_pkt->options, 0, sizeof(coap_pkt->options));
unsigned int option_number = 0;
unsigned int option_delta = 0;
size_t option_length = 0;
while (current_option < data + data_len) {
/* payload marker 0xFF, currently only checking for 0xF* because rest is reserved */
if ((current_option[0] & 0xF0) == 0xF0) {
coap_pkt->payload = ++current_option;
coap_pkt->payload_len = options_payload_size
- (coap_pkt->payload - option_start);
//coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
break;
}
option_delta = current_option[0] >> 4;
option_length = current_option[0] & 0x0F;
++current_option;
/* avoids code duplication without function overhead */
unsigned int *x = &option_delta;
do {
if (*x == 13) {
*x += current_option[0];
++current_option;
} else if (*x == 14) {
*x += 255;
*x += current_option[0] << 8;
++current_option;
*x += current_option[0];
++current_option;
}
} while (x != (unsigned int*) &option_length && (x =
(unsigned int*) &option_length));
option_length = *x;
option_number += option_delta;
PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta,
option_length);
SET_OPTION(coap_pkt, option_number);
switch (option_number) {
case COAP_OPTION_CONTENT_FORMAT:
coap_pkt->content_format = coap_parse_int_option(current_option,
option_length);
PRINTF("Content-Format [%u]\n", coap_pkt->content_format);
break;
case COAP_OPTION_MAX_AGE:
coap_pkt->max_age = coap_parse_int_option(current_option,
option_length);
PRINTF("Max-Age [%lu]\n", coap_pkt->max_age);
break;
case COAP_OPTION_ETAG:
coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
bh_memcpy_s(coap_pkt->etag, COAP_ETAG_LEN, current_option,
coap_pkt->etag_len);
PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
); /*FIXME always prints 8 bytes */
break;
case COAP_OPTION_ACCEPT:
coap_pkt->accept = coap_parse_int_option(current_option,
option_length);
PRINTF("Accept [%u]\n", coap_pkt->accept);
break;
case COAP_OPTION_IF_MATCH:
/* TODO support multiple ETags */
coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length);
bh_memcpy_s(coap_pkt->if_match, COAP_ETAG_LEN, current_option,
coap_pkt->if_match_len);
PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
coap_pkt->if_match_len, coap_pkt->if_match[0],
coap_pkt->if_match[1], coap_pkt->if_match[2],
coap_pkt->if_match[3], coap_pkt->if_match[4],
coap_pkt->if_match[5], coap_pkt->if_match[6],
coap_pkt->if_match[7]
); /* FIXME always prints 8 bytes */
break;
case COAP_OPTION_IF_NONE_MATCH:
coap_pkt->if_none_match = 1;
PRINTF("If-None-Match\n");
break;
case COAP_OPTION_PROXY_URI:
#if COAP_PROXY_OPTION_PROCESSING
coap_pkt->proxy_uri = (char *)current_option;
coap_pkt->proxy_uri_len = option_length;
#endif
PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len,
coap_pkt->proxy_uri);
coap_error_message = "This is a constrained server (Contiki)";
return PROXYING_NOT_SUPPORTED_5_05;
break;
case COAP_OPTION_PROXY_SCHEME:
#if COAP_PROXY_OPTION_PROCESSING
coap_pkt->proxy_scheme = (char *)current_option;
coap_pkt->proxy_scheme_len = option_length;
#endif
PRINTF("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n",
coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme);
coap_error_message = "This is a constrained server (Contiki)";
return PROXYING_NOT_SUPPORTED_5_05;
break;
case COAP_OPTION_URI_HOST:
coap_pkt->uri_host = (char *) current_option;
coap_pkt->uri_host_len = option_length;
PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host);
break;
case COAP_OPTION_URI_PORT:
coap_pkt->uri_port = coap_parse_int_option(current_option,
option_length);
PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port);
break;
case COAP_OPTION_URI_PATH:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **) &(coap_pkt->uri_path),
&(coap_pkt->uri_path_len), current_option, option_length,
'/');
PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path);
break;
case COAP_OPTION_URI_QUERY:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **) &(coap_pkt->uri_query),
&(coap_pkt->uri_query_len), current_option, option_length,
'&');
PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len,
coap_pkt->uri_query);
break;
case COAP_OPTION_LOCATION_PATH:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **) &(coap_pkt->location_path),
&(coap_pkt->location_path_len), current_option,
option_length, '/');
PRINTF("Location-Path [%.*s]\n", coap_pkt->location_path_len,
coap_pkt->location_path);
break;
case COAP_OPTION_LOCATION_QUERY:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **) &(coap_pkt->location_query),
&(coap_pkt->location_query_len), current_option,
option_length, '&');
PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len,
coap_pkt->location_query);
break;
case COAP_OPTION_OBSERVE:
coap_pkt->observe = coap_parse_int_option(current_option,
option_length);
PRINTF("Observe [%lu]\n", coap_pkt->observe);
break;
case COAP_OPTION_BLOCK2:
coap_pkt->block2_num = coap_parse_int_option(current_option,
option_length);
coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3;
coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
<< (coap_pkt->block2_num & 0x07);
coap_pkt->block2_num >>= 4;
PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num,
coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size);
break;
case COAP_OPTION_BLOCK1:
coap_pkt->block1_num = coap_parse_int_option(current_option,
option_length);
coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3;
coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
<< (coap_pkt->block1_num & 0x07);
coap_pkt->block1_num >>= 4;
PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num,
coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size);
break;
case COAP_OPTION_SIZE2:
coap_pkt->size2 = coap_parse_int_option(current_option,
option_length);
PRINTF("Size2 [%lu]\n", coap_pkt->size2);
break;
case COAP_OPTION_SIZE1:
coap_pkt->size1 = coap_parse_int_option(current_option,
option_length);
PRINTF("Size1 [%lu]\n", coap_pkt->size1);
break;
default:
PRINTF("unknown (%u)\n", option_number);
/* check if critical (odd) */
if (option_number & 1) {
coap_error_message = "Unsupported critical option";
return BAD_OPTION_4_02;
}
}
current_option += option_length;
} /* for */
PRINTF("-Done parsing-------\n");
return NO_ERROR;
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* 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 COAP_PLATFORMS_H_
#define COAP_PLATFORMS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_platform.h"
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
/*#include "list_coap.h"*/
#include <stdbool.h>
#define COAP_TRANS_LOCK(ctx) coap_lock(ctx->transaction_lock)
#define COAP_TRANS_UNLOCK(ctx ) coap_unlock(ctx->transaction_lock)
/* REST_MAX_CHUNK_SIZE is the max size of payload.
* The maximum buffer size that is provided for resource responses and must be respected due to the limited IP buffer.
* Larger data must be handled by the resource and will be sent chunk-wise through a TCP stream or CoAP blocks.
*/
#ifndef REST_MAX_CHUNK_SIZE
#define REST_MAX_CHUNK_SIZE (1024*1024)
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif /* MIN */
#define CLOCK_SECOND 1000
typedef enum {
A_Raw, A_Sock_Addr, A_IP_Addr, A_Custom
} Net_Addr_Type;
#define NET_ADDR_RAW_SIZE 32
typedef struct net_addr_coap {
Net_Addr_Type addr_type;
union {
char raw[NET_ADDR_RAW_SIZE];
struct sockaddr_in sock_addr;
} u;
uint16_t port;
uint16_t addr_len;
} net_addr_t;
#define uip_ipaddr_t struct net_addr_coap
#define memb_free(x, y) free(x)
void set_addr_ip(uip_ipaddr_t *, char * ip, int port);
uip_ipaddr_t * new_net_addr(Net_Addr_Type type);
void copy_net_addr(uip_ipaddr_t * dest, uip_ipaddr_t * src);
bool compare_net_addr(uip_ipaddr_t * dest, uip_ipaddr_t * src);
uint32_t get_elpased_ms(uint32_t * last_system_clock);
uint32_t get_platform_time();
uint32_t get_platform_time_sec();
void coap_sleep_ms(uint32_t ms);
void coap_lock(void *);
void coap_unlock(void *);
void * coap_create_lock();
void coap_free_lock(void *);
void *xalloc(uint32_t size);
#define os_malloc bh_malloc
#define os_free bh_free
#ifdef __cplusplus
}
#endif
#endif /* COAP_PLATFORMS_H_ */

View File

@ -0,0 +1,23 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# 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.
set (LIB_COAP_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${LIB_COAP_DIR}/er-coap)
include_directories(${LIB_COAP_DIR}/extension)
file (GLOB_RECURSE source_all ${LIB_COAP_DIR}/*.c)
set (LIB_COAP_SOURCE ${source_all})

View File

@ -0,0 +1,236 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* 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 bni.h
* @date Mon Jul 2 16:54:58 2012
*
* @brief Beihai native interface.
*/
#ifndef BNI_H
#define BNI_H
#include "bh_types.h"
/* Primitive types */
typedef uint8 jboolean;
typedef int8 jbyte;
typedef uint16 jchar;
typedef int16 jshort;
typedef int32 jint;
typedef int64 jlong;
typedef float jfloat;
typedef double jdouble;
typedef jint jsize;
/* Predefined Java class types. */
struct _jobject;
typedef struct _jobject *jobject;
struct _jclass;
typedef struct _jclass *jclass;
struct _jstring;
typedef struct _jstring *jstring;
/* Values of jboolean: */
#define BNI_FALSE 0
#define BNI_TRUE 1
/**
* Return the length of the array object.
*
* @param array Java array object
*
* @return the length of the Java array
*/
#define bni_array_length(array) ((jsize)((uint32)(array)->__length >> 2))
/**
* Return the address of the first element of array object.
*
* @param array Java array object
*
* @return the address of the first element of array object
*/
#define bni_array_elem(array) ((array)->__elem)
/**
* Find the Java class with given class name.
*
* @param name Java class name
*
* @return class object of the Java class if found, NULL otherwise
*
* @throws OutOfMemoryError if VM runs out of memory.
*/
jclass
bni_find_class(const char *name);
/**
* Throw an exception of given class with message.
*
* @param clazz class object of a subclass of java.lang.Throwable
* @param msg message for the exception or NULL if no message
*
* @return 0 if succeeds, nonzero otherwise
*/
jint
bni_throw_new(jclass clazz, const char *msg);
/**
* Throw a NullPointerException.
*
* @throws NullPointerException
*/
void
bni_throw_npe(void);
/**
* Throw an ArrayIndexOutOfBoundsException
*
* @param index the index used to access the array
*
* @throws ArrayIndexOutOfBoundsException
*/
void
bni_throw_aioobe(int index);
/**
* Determine whether an exception is being thrown.
*
* @return exception object if exception is thrown, NULL otherwise
*/
jobject
bni_exception_occurred(void);
/**
* Print the current exception to error-reporting channel.
*/
void
bni_exception_describe(void);
/**
* Clear the currently thrown exception.
*/
void
bni_exception_clear(void);
/**
* Return the Unicode character number of a string.
*
* @param str Java string object
*
* @return the Unicode character number of the string
*/
jsize
bni_string_length(jstring str);
/**
* Return the length in bytes of the modified UTF-8 representation of
* a string.
*
* @param str Java string object
* @param start start offset in the string
* @param len number of Unicode characters
*
* @return the UTF-8 length of the string
*
* @throws StringIndexOutOfBoundsException on index overflow.
*/
jsize
bni_string_utf_length(jstring str, jsize start, jsize len);
/**
* Copies len number of Unicode characters beginning at offset start
* to the given buffer buf.
*
* @param str Java string object
* @param start start offset in the string
* @param len number of Unicode characters to copy
* @param buf buffer for storing the result
*/
void
bni_string_region(jstring str, jsize start, jsize len, jchar *buf);
/**
* Translates len number of Unicode characters beginning at offset
* start into modified UTF-8 encoding and place the result in the
* given buffer buf.
*
* @param str Java string object
* @param start start offset in the string
* @param len number of Unicode characters to copy
* @param buf buffer for storing the result
*
* @throws StringIndexOutOfBoundsException on index overflow.
*/
void
bni_string_utf_region(jstring str, jsize start, jsize len, char *buf);
/**
* Translate Unicode characters into modified UTF-8 encoding and return
* the result.
*
* @param str Java string object
*
* @return the UTF-8 encoding string if succeeds, NULL otherwise
*/
char *
bni_string_get_utf_chars(jstring str);
/**
* Get the given Java object's class index.
*
* @param obj Java object
*
* @return -1 if obj is an array, class index of the object otherwise
*/
jint
bni_object_class_index(jobject obj);
/**
* Allocate memory from the current instance's private heap.
*
* @param size bytes to allocate
*
* @return pointer to the allocated memory
*
* @throws OutOfMemoryError if VM runs out of memory.
*/
void*
bni_malloc(unsigned size);
/**
* Allocate memory from the current instance's private heap and clear
* to zero.
*
* @param size bytes to allocate
*
* @return pointer to the allocated memory
*
* @throws OutOfMemoryError if VM runs out of memory.
*/
void*
bni_calloc(unsigned size);
/**
* Free the memory allocated from the current instance's private heap.
*
* @param ptr pointer to the memory in current instance's private heap
*/
void
bni_free(void *ptr);
#endif

View File

@ -0,0 +1,615 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* 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 jeff-export.h
* @date Wed Aug 3 18:17:30 2011
*
* @brief Exported interface for operating or executing JEFF files.
* All interface names start with "jeff_", which is the namespace name
* of this module.
*/
#ifndef JEFF_EXPORT_H
#define JEFF_EXPORT_H
#include "bni.h"
#include "korp_types.h"
/********************************************************************
* Exported internal types
********************************************************************/
/**
* JEFF file handle type
*/
struct JeffFileHeaderLinked;
typedef struct JeffFileHeaderLinked *jeff_file_t;
/**
* JEFF class type
*/
struct JeffClassHeaderLinked;
typedef struct JeffClassHeaderLinked *jeff_class_t;
/**
* VM instance handle type
*/
struct JeffInstanceLocalRoot;
typedef struct JeffInstanceLocalRoot *jeff_instance_t;
/**
* Record of one native method's definition.
*/
struct JeffNativeMethodDef {
/* Mangled name of the native method. NULL for initialization
functions. */
const char *mangled_name;
/* Points to the native C function. */
void (*func_ptr)(uint32 *);
/* Return size type of the native function. */
uint32 return_size_type;
};
/********************************************************************
* Interface for operating global environment of the JEFF VM
********************************************************************/
/**
* Load the core library from the given file buffer and initialize the
* runtime environment (global objects etc.) of the VM. The thread
* calls this function becomes the supervisor thread, which belongs to
* a unique supervisor instance. Currently, if this init failed,
* partially initialized states of the VM runtime environment won't be
* cleaned up, so the VM must be shutdown and restarted. method_defs
* points to an array of native method definition records.
* Initialization functions must be in the front of the array and
* following native method definitions must be sorted by their mangled
* names.
*
* @param file the JEFF file of the core library
* @param file_size the size of the JEFF file of the core library
* @param method_defs native method definition records
* @param method_defs_num number of native method records
* @param heap the heap for the current (supervisor) instance
*
* @return true if succeeds, otherwise the error cannot be recovered
*/
bool
jeff_runtime_init(jeff_file_t file, unsigned file_size,
struct JeffNativeMethodDef *method_defs, unsigned method_defs_num,
void *heap);
/**
* Load a JEFF file into the VM from the given file buffer. It can be
* called from any VM thread.
*
* @param file the JEFF file to be loaded
* @param size the size of the JEFF file
* @param is_library whether the JEFF file is a library
* @param allow_to_load a function that returns true if classes in the
* given package is allowed to be loaded. The NULL function pointer
* allows all packages.
* @param allow_to_link a function that returns true if classes in the
* given package is allowed to be linked to. The NULL function
* pointer allows all packages.
*
* @return true if succeeds, otherwise detailed error information is
* passed to vmci_diagnostic_print. The caller can catch it by
* implementing that function.
*/
bool
jeff_runtime_load(jeff_file_t file, unsigned size, bool is_library,
bool (*allow_to_load)(const uint8 *pname, unsigned len),
bool (*allow_to_link)(const uint8 *pname, unsigned plen,
const uint8 *cname, unsigned clen));
/**
* Unload a JEFF file from the VM. All resources related to the JEFF
* file except the JEFF file itself are released. It can be called
* from any VM thread.
*
* @param file the JEFF file to be unloaded
*
* @return true if succeeds, otherwise detailed error information is
* passed to vmci_diagnostic_print. The caller can catch it by
* implementing that function.
*/
bool
jeff_runtime_unload(jeff_file_t file);
/**
* Return the JEFF file with the given file uid.
*
* @param fuid the unique id of a loaded JEFF file
*
* @return the JEFF file is exists, otherwise NULL
*/
jeff_file_t
jeff_runtime_fuid_to_file(unsigned fuid);
/**
* Return the file uid of the given JEFF file.
*
* @param file a loaded JEFF file
*
* @return the unique id of the given JEFF file
*/
unsigned
jeff_runtime_file_to_fuid(jeff_file_t file);
/**
* Create a supervisor thread belonging to the supervisor instance.
* Threads that may interact with VM core must be either the main
* thread of supervisor instance (which calls jeff_runtime_init) or
* created by this function so that VM core required data structures
* can be set up correctly.
*
* @param start_routine the start routine of the new thread
* @param arg argument to the start routine
*
* @return true if succeeds, false otherwise
*/
bool
jeff_runtime_create_supervisor_thread(void* (*start_routine)(void *),
void *arg);
/**
* Create a supervisor thread belonging to the supervisor instance.
* Threads that may interact with VM core must be either the main
* thread of supervisor instance (which calls jeff_runtime_init) or
* created by this function so that VM core required data structures
* can be set up correctly.
*
* @param start_routine the start routine of the new thread
* @param arg argument to the start routine
* @param prio thread priority
*
* @return true if succeeds, false otherwise
*/
bool
jeff_runtime_create_supervisor_thread_with_prio(void* (*start_routine)(void *),
void *arg, int prio);
/********************************************************************
* Interface for operating instance local environment
********************************************************************/
/**
* Create a VM instance with the given JEFF file as its main file,
* (i.e. the file containing the main class of the VM instance). This
* function can be called from any VM thread, but it must be isolated
* from JEFF file's unloading operation so that the main file won't be
* unloaded before it's locked by the new instance. All instance
* local memory except stacks of threads are allocated from the given
* heap. If succeeds, it increases reference count of the main_file
* and returns the handle of the new VM instance. The new instance's
* main thread will run the start_routine with argument arg. If the
* cleanup_routine is not NULL, it will be called after start_routine
* returns and just before the main thread exits. It will also be
* called after the instance is destroied. It is guaranteed to be
* called exactly once no matter how the instance terminates.
*
* @param main_file the main JEFF file of the new instance
* @param heap the private heap of the new instance
* @param stack_depth the maximal nesting levels of Java methods of
* the new instance. It must be <= 16 * 1024. Otherwise the instance
* creation will fail.
* @param start_routine start routine of the main thread. Don't
* destroy the heap or inform other thread to do this at the end of
* this routine since after it returns, VM core will call destroy
* functions on objects allocated in this heap (e.g. locks and
* condition variables). Do the destroying or informing of destroying
* in the cleanup_routine.
* @param arg the instance argument that will be passed to the start
* routine. It can be get or set by jeff_runtime_get_instance_arg and
* jeff_runtime_set_instance arg from threads of the instance. The
* caller can use it to store instance local data.
* @param cleanup_routine the optional cleanup routine for the
* instance, which may be NULL. It may be executed in the end of the
* main thread of the created instance by this function if this
* instance exits normally, or it may be executed in a thread of other
* instance in case this instance is being killed by that instance.
* In both cases, this routine regards it is executed in a thread of
* this instance (the instance created by this function) because
* jeff_runtime_get_instance_arg will always return the argument of
* this instance.
*
* @return the VM instance handle if succeeds, NULL otherwise
*/
jeff_instance_t
jeff_runtime_create_instance(jeff_file_t main_file, void *heap,
unsigned stack_depth, void* (*start_routine)(void *), void *arg,
void (*cleanup_routine)(void));
/**
* Destroy the given VM instance and decrease the reference count of
* its main file and all explicitly used JEFF files. It can be called
* from any VM thread. If there are alive threads of the instance,
* they will be terminated mandatorily and then the cleanup routine is
* called if it's not NULL.
*
* @param handle the handle of the instance to be destroyed
*/
void
jeff_runtime_destroy_instance(jeff_instance_t handle);
/**
* Retrieve the current instance's argument.
*
* @return the current instance's argument
*/
void*
jeff_runtime_get_instance_arg(void);
/**
* Set the current instance's argument.
*
* @return the new argument for the current instance
*/
void
jeff_runtime_set_instance_arg(void *arg);
/**
* Retrieve the current instance's heap.
*
* @return the current instance's heap
*/
void*
jeff_runtime_get_instance_heap(void);
/**
* Suspend all threads of the given VM instance. This function can
* only be called from thread that is not of the given VM instance.
*
* @param handle the handle of the instance to be suspended
*/
void
jeff_runtime_suspend_instance(jeff_instance_t handle);
/**
* Resume all threads of the given VM instance. This function can
* only be called from thread that is not of the given VM instance.
*
* @param handle the handle of the instance to be resumed
*/
void
jeff_runtime_resume_instance(jeff_instance_t handle);
/**
* Interrupt all threads of the given VM instance. This function can
* only be called from thread that is not of the given VM instance.
*
* @param handle the handle of the instance to be interrupted
* @param by_force whether the interruption is by force
*/
void
jeff_runtime_interrupt_instance(jeff_instance_t handle, bool by_force);
/**
* Wait for the given VM instance to terminate.
*
* @param ilr the VM instance to be waited for
* @param mills wait millseconds to return
*/
void
jeff_runtime_wait_for_instance(jeff_instance_t ilr, int mills);
/********************************************************************
* Interface for operating thread local environment
********************************************************************/
/**
* Return true if there is an uncaught exception (thrown during
* running an application or applet command).
*
* @return true if there is an uncaught exception
*/
bool
jeff_runtime_check_uncaught_exception(void);
/**
* Print qualified name of the uncaught exception (and stack trace if
* enabled) by calling vmci_diagnostic_print.
*/
void
jeff_runtime_print_uncaught_exception(void);
/**
* Clear the uncaught exception.
*/
void
jeff_runtime_reset_uncaught_exception(void);
/**
* Change current thread to a safe state (VMWAIT). After calling this
* and before calling jeff_runtime_exit_safe_state, all operations
* must be safe, i.e. no GC or system level resource operations are
* allowed because in a safe state, the VM instance is assumed to be
* able to perform GC, JDWP or termination at any time. Usually, this
* function is called just before the native code is going to wait for
* something and the exiting safe state function is called just after
* the waiting returns.
*/
void
jeff_runtime_enter_safe_state(void);
/**
* Change current thread to an unsafe state (RUNNING) so that unsafe
* operations can also be done.
*/
void
jeff_runtime_exit_safe_state(void);
/**
* Set thread local error code for the current thread.
*
* @param code the error code to be set
*/
void
jeff_runtime_set_error(unsigned code);
/**
* Get the last error code of current thread.
*
* @return the last error code of current thread
*/
unsigned
jeff_runtime_get_error(void);
/********************************************************************
* Interface for GC support
********************************************************************/
/**
* Traverse all objects of the given heap that are global or locate in
* threads' frames and return them by calling vmci_gc_rootset_elem.
* This function will suspend all threads except the current one of
* the VM instance owning the given heap before traversing. It
* traverses either all or none of the rootset objects, and returns
* true and false respectively. If it returns false, the GC process
* shouldn't proceed and is not necessary to unmark anything because
* no objects are marked. The function jeff_runtime_gc_finished must
* be called if and only if this function returns true so as to resume
* threads that are suspended during GC process.
*
* @param heap the heap for which rootset objects are looked up
*
* @return true if succeeds, false otherwise
*/
bool
jeff_runtime_traverse_gc_rootset(void *heap);
/**
* Get the reference offset table of the given object. If the
* returned value R >= 0, *ret points to the reference offset table of
* the object and R is the number of offsets in the table. Otherwise,
* if the returned value R < 0, all reference fields of the object
* must be in a continuous region (usually the object is an array),
* then *ret is the offset to the first field in the region and R is
* the number of such fields in the region.
*
* @param obj pointer to the Java object
* @param ret points to a pointer for storing the reference offset
* table if return value >= 0, or for storing the offset to the first
* object reference in the Java object if return value < 0
*
* @return number of offsets in the reference_offset table if >= 0, or
* number of object references in the object if < 0
*/
int
jeff_object_get_reference_offsets(const jobject obj, uint16 **ret);
/**
* Inform the containing VM instance that GC has finished and all
* suspended threads can be resumed. This function must be called if
* and only if jeff_runtime_traverse_gc_rootset returns true.
*/
void
jeff_runtime_gc_finished(void);
/********************************************************************
* Interface for tooling support
********************************************************************/
/**
* This function is used to suspend the main thread of VM instance so
* that debugger can have chance to connect to the VM instance, set
* breakpoints and do any other debug settings. It must be called
* from the main thread of VM instance at the point just after VM
* instance initialization finishes and just before application code
* is to be executed.
*/
void
jeff_tool_suspend_self(void);
/**
* Start up tool agent thread for the given VM instance. It can be
* called from any VM thread.
*
* @param handle the VM instance for which tool agent is started up
* @param queue queue of the tool agent
* @return true if succeeds, false otherwise
*/
bool
jeff_tool_start_agent(jeff_instance_t handle, void *queue);
/********************************************************************
* Interface for toolkit support
********************************************************************/
/**
* Return the JEFF class pointer of the given class name.
*
* @param class_name the qualified class name
*
* @return the JEFF class pointer
*/
jeff_class_t
jeff_tool_get_jeff_class(const char *class_name);
/**
* Get the mangled class name of the given class.
*
* @param clz the JEFF class
* @param buf buffer for returning the mangled name
* @param buf_size size of the buffer
*
* @return actual size of the mangled class name including the
* terminating null byte
*/
unsigned
jeff_tool_get_mangled_class_name(jeff_class_t clz, char *buf,
unsigned buf_size);
/**
* Get class index of given class in its containing JEFF file.
*
* @param clz the JEFF class
*
* @return class index in the containing JEFF file
*/
int
jeff_tool_get_class_index(jeff_class_t clz);
/**
* Callback handler prototype for traversing fields of class.
*
* @param arg argument passed to the handler from caller
* @param access_flag access flag of the method
* @param name the field name
* @param descriptor mangled field type descriptor
* @param offset the offset of the field in the class
* @param size size of the field
*/
typedef void
(*JeffToolFieldHandler)(void *arg, unsigned access_flag, const char *name,
const char *descriptor, unsigned offset, unsigned size);
/**
* Traverse all fields of the given class, including those inherited
* from super classes. The fields are traversed in the same order as
* the field layout of the class.
*
* @param arg argument to be passed to the handler
* @param clz the JEFF class
* @param instance instance fields or static fielts
* @param handler the callback handler for each field
*/
void
jeff_tool_foreach_field(void *arg, jeff_class_t clz, bool instance,
JeffToolFieldHandler handler);
/**
* Callback handler prototype for traversing methods of class.
*
* @param arg argument passed to the handler from caller
* @param access_flag access flag of the method
* @param name mangled name of the method
* @param descriptor mangled method arguments descriptor
* @param retune_type mangled descriptor of method's return type
*/
typedef void
(*JeffToolMethodHandler)(void *arg, unsigned access_flag, const char *name,
const char *descriptor, const char *return_type);
/**
* Traverse all methods of the given class.
*
* @param arg argument to be passed to the handler
* @param clz the JEFF class
* @param handler the callback handler for each method
*/
void
jeff_tool_foreach_method(void *arg, jeff_class_t clz,
JeffToolMethodHandler handler);
/**
* Callback handler prototype for traversing classes of main file.
*
* @param arg argument passed to the handler from caller
* @param clz pointer to one class in the main file
*/
typedef void
(*JeffToolClassHandler)(void *arg, jeff_class_t clz);
/**
* Traverse all classes of the main file.
*
* @param arg argument to be passed to the handler
* @param handler the callback handler for each class
*/
void
jeff_tool_foreach_class(void *arg, JeffToolClassHandler handler);
/********************************************************************
* Interface for executing applications
********************************************************************/
/**
* Initialize global environment for executing Java applications.
*
* @return true if succeeds, false otherwise
*/
bool
jeff_application_env_init(void);
/**
* Find the unique class containing a public static "main
* ([Ljava.lang.String;)V" method from the main JEFF file of the
* current instance and execute that method.
*
* @param argc the number of arguments
* @param argv the arguments array
*
* @return true if the main method is called, false otherwise (e.g. an
* exception occurs when preparing the arguments Java string array)
*/
bool
jeff_application_execute(int argc, char *argv[]);
/********************************************************************
* Interface for executing applets
********************************************************************/
/**
* Initialize global environment for executing applets.
*
* @return true if succeeds, false otherwise
*/
bool
jeff_applet_env_init(void);
/**
* Start to run from com.intel.runtime.core.RuntimeContext.main with a
* default message queue size and a default service class object. If
* the main JEFF file of the current VM instance contains exactly one
* class that is derived from com.intel.util.IntelApplet, then use it
* as the default service class.
*
* @param queue_size the default main message queue size
* @param default_service_class qualified class name of the default
* service class (entry point class), which must be in the main JEFF
* file. If NULL, find the default main class with rules described
* above.
*
* @return true if succeeds, false otherwise
*/
bool
jeff_applet_start(int queue_size, const char *default_service_class);
#endif

View File

@ -152,7 +152,7 @@ void gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
bh_assert(
hmu && (gc_uint8*) hmu >= heap->base_addr
&& (gc_uint8*) hmu < heap->base_addr + heap->current_size);
bh_assert(((gc_uint32)(uintptr_t)hmu_to_obj(hmu) & 7) == 0);
bh_assert(((gc_uint32) hmu_to_obj(hmu) & 7) == 0);
bh_assert(
size > 0
&& ((gc_uint8*) hmu) + size
@ -242,7 +242,7 @@ BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
p = node->next;
node->next = p->next;
bh_assert(((gc_int32)(intptr_t)hmu_to_obj(p) & 7) == 0);
bh_assert(((gc_int32) hmu_to_obj(p) & 7) == 0);
if ((gc_size_t) node_idx
!= init_node_idx&& ((gc_size_t)node_idx << 3) >= size + GC_SMALLEST_SIZE) { /* with bigger size*/

View File

@ -75,7 +75,7 @@ static void *vm_thread_wrapper(void *arg)
{
thread_wrapper_arg * targ = arg;
LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ);
targ->stack = (void *) ((uintptr_t)(&arg) & ~0xfff);
targ->stack = (void *) ((unsigned int) (&arg) & ~0xfff);
_vm_tls_put(1, targ);
targ->start(targ->arg);
bh_free(targ);

View File

@ -417,7 +417,6 @@ int check_app_timers(timer_ctx_t ctx)
vm_mutex_lock(&ctx->mutex);
app_timer_t * t = ctx->g_app_timers;
app_timer_t * prev = NULL;
app_timer_t * expired = NULL;
uint64 now = bh_get_tick_ms();
@ -443,8 +442,6 @@ int check_app_timers(timer_ctx_t ctx)
void cleanup_app_timers(timer_ctx_t ctx)
{
app_timer_t *t;
vm_mutex_lock(&ctx->mutex);
release_timer_list(&ctx->g_app_timers);