Skip to content
This repository has been archived by the owner on Dec 26, 2022. It is now read-only.

Commit

Permalink
feat(endpoint): Implement wp77xx platform
Browse files Browse the repository at this point in the history
This commit Implements the wp77xx platform for endpoint.
The AirPrime WP7702 LPWA module is the first verified device.

See https://www.sierrawireless.com/products-and-solutions/embedded-solutions/products/wp7702/
for more information.

The resolv.conf is removed. Change to use the system's default /etc/resolv.conf.

Close #679
  • Loading branch information
splasky committed Jun 29, 2020
1 parent 5b3fe83 commit 3f83bd2
Show file tree
Hide file tree
Showing 14 changed files with 386 additions and 48 deletions.
31 changes: 18 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ MOSQUITTO_LIB := $(MOSQUITTO_DIR)/lib/libmosquitto.so.1
PEM_DIR = pem
# Default pem file. See pem/README.md for more information
PEM := $(PEM_DIR)/cert.pem
NAMESERVER := 8.8.8.8
RESOLV_CONF_DIR := endpoint/endpointComp
OUTPUT_BASE_DIR := output_base
# Endpoint build target. The default intends to the platform of your development system.
TARGET := simulator
Expand All @@ -16,32 +14,41 @@ TESTS := false
# The endpoint uses HTTP connection to transmit encrypted data by default.
# See "HTTPS Connection Support" in docs/endpoint.md for more information.
ENFORCE_EP_HTTPS := false
# The CFLAGS to pass during endpoint app build
ENDPOINT_CFLAGS :=
# The flags that will be preprocessed by mkapp program, part of Legato Application Framework.
# Eventually, the processed flags are passed as compiler-time options.
LEGATO_FLAGS :=
DEPS += $(DCURL_LIB)

# Determine to enable HTTPS connection
ifeq ($(ENFORCE_EP_HTTPS), true)
ENDPOINT_CFLAGS += -C -DENDPOINT_HTTPS
LEGATO_FLAGS += -DENDPOINT_HTTPS
endif

# Determine to build test suite
ifeq ($(TESTS), true)
ENDPOINT_CFLAGS += -C -DENABLE_ENDPOINT_TEST
LEGATO_FLAGS += -DENABLE_ENDPOINT_TEST
endif

# The tangle-acclerator host for endpoint to connect
ifdef EP_TA_HOST
ENDPOINT_CFLAGS += -C -DEP_TA_HOST=${EP_TA_HOST}
LEGATO_FLAGS += -DEP_TA_HOST=${EP_TA_HOST}
endif

# The tangle-acclerator port for endpoint to connect
ifdef EP_TA_PORT
ENDPOINT_CFLAGS += -C -DEP_TA_PORT=${EP_TA_PORT}
LEGATO_FLAGS += -DEP_TA_PORT=${EP_TA_PORT}
endif

# The ssl seed for endpoint (optional)
ifdef EP_SSL_SEED
ENDPOINT_CFLAGS += -C -DEP_SSL_SEED=${EP_SSL_SEED}
LEGATO_FLAGS += -DEP_SSL_SEED=${EP_SSL_SEED}
endif

# Pass target into endpoint build process
LEGATO_FLAGS += -DTARGET=$(TARGET)

# Prepend the "-C" flag at the beginging for passing cflags into mkapp
LEGATO_FLAGS := $(foreach flags, $(LEGATO_FLAGS), -C $(flags))

# Include the build command from the specific target
include endpoint/platform/$(TARGET)/build.mk

all: $(DEPS) cert
Expand All @@ -63,8 +70,6 @@ $(MOSQUITTO_LIB): $(MOSQUITTO_DIR)

# Build endpoint Legato app
legato: cert
# Generate resolv.conf
echo "nameserver $(NAMESERVER)" > $(RESOLV_CONF_DIR)/resolv.conf
# Fetch the required external source code
# FIXME: Use 'fetch' instead of 'build' to avoid extra building actions.
# The 'build' option is for getting the header file like 'mam/mam/mam_endpoint_t_set.h',
Expand Down
10 changes: 9 additions & 1 deletion common/ta_errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,22 @@ const char* ta_error_to_string(status_t err) {
return "Failed to finalize the device";
case SC_ENDPOINT_UART:
return "UART error occurred in device component";
case SC_ENDPOINT_UART_SET_ATTR:
return "UART error occurred when setting UART attribute";
case SC_ENDPOINT_SEC_FAULT:
return "Error occurred inside secure storage";
case SC_ENDPOINT_SEC_ITEM_NOT_FOUND:
return "Item not found inside secure storage";
case SC_ENDPOINT_SEC_UNAVAILABLE:
return "Secure storage service is unavailable";
case SC_ENDPOINT_SEND_TRANSFER:
return "Error occurred when the sending transfer message";
return "Error occurred when sending the transfer message";
case SC_ENDPOINT_GET_KEY_ERROR:
return "Error occurred when get private key from endpoint device";
case SC_ENDPOINT_GET_DEVICE_ID_ERROR:
return "Error occurred when get device id from endpoint device";
case SC_ENDPOINT_DNS_RESOLVE_ERROR:
return "Error occurred when resolving the domain name";

default:
return "Unknown error.";
Expand Down
18 changes: 13 additions & 5 deletions common/ta_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,22 @@ typedef enum {
/**< Failed to finalize the device */
SC_ENDPOINT_UART = 0x03 | SC_MODULE_ENDPOINT | SC_SEVERITY_FATAL,
/**< UART error occurred in device component */
SC_ENDPOINT_SEC_FAULT = 0x04 | SC_MODULE_ENDPOINT | SC_SEVERITY_MINOR,
SC_ENDPOINT_UART_SET_ATTR = 0x04 | SC_MODULE_ENDPOINT | SC_SEVERITY_FATAL,
/**< Error occurred when setting UART attribute */
SC_ENDPOINT_SEC_FAULT = 0x05 | SC_MODULE_ENDPOINT | SC_SEVERITY_MINOR,
/**< Error occurred inside secure storage */
SC_ENDPOINT_SEC_ITEM_NOT_FOUND = 0x05 | SC_MODULE_ENDPOINT | SC_SEVERITY_MINOR,
SC_ENDPOINT_SEC_ITEM_NOT_FOUND = 0x06 | SC_MODULE_ENDPOINT | SC_SEVERITY_MINOR,
/**< Item not found inside secure storage */
SC_ENDPOINT_SEC_UNAVAILABLE = 0x06 | SC_MODULE_ENDPOINT | SC_SEVERITY_MINOR,
SC_ENDPOINT_SEC_UNAVAILABLE = 0x07 | SC_MODULE_ENDPOINT | SC_SEVERITY_MINOR,
/**< Secure storage service is unavailable */
SC_ENDPOINT_SEND_TRANSFER = 0x07 | SC_MODULE_ENDPOINT | SC_SEVERITY_FATAL,
/**< Error occurred when the sending transfer message */
SC_ENDPOINT_SEND_TRANSFER = 0x08 | SC_MODULE_ENDPOINT | SC_SEVERITY_FATAL,
/**< Error occurred when sending transfer message */
SC_ENDPOINT_GET_KEY_ERROR = 0x09 | SC_MODULE_ENDPOINT | SC_SEVERITY_FATAL,
/**< Failed to get the private key */
SC_ENDPOINT_GET_DEVICE_ID_ERROR = 0x0A | SC_MODULE_ENDPOINT | SC_SEVERITY_FATAL,
/**< Failed to get the device id */
SC_ENDPOINT_DNS_RESOLVE_ERROR = 0x0B | SC_MODULE_ENDPOINT | SC_SEVERITY_FATAL,
/**< Failed to resolve the domain name address */

} status_t;

Expand Down
8 changes: 6 additions & 2 deletions docs/endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,15 @@ $ leaf setup legato-stable -p swi-wp77_3.0.0

Finally, make the wp77xx endpoint target. Be careful with the directory of tangle-accelerator. It should be located within the workspace directory.

The host-port pair and SSL seed can be set at build-time and run-time. The run-time command line option '--host', '--port' and '--ssl-seed" are added.

For setting `host`, `port` and `ssl seed` during compile-time. Add `EP_TA_HOST=xxx.xxxx.xxx`, `EP_TA_HOST=xxxx` and `EP_SSL_SEED=xxxxxxxxx` option. If you doesn't change the host and port, the default host will be set to `localhost` and default port will be set to `8000`.

```shell
$ git clone https://github.com/DLTcollab/tangle-accelerator.git
$ cd tangle-accelerator
$ make TARGET=wp77xx legato # build endpoint as wp77xx target
$ make TESTS=true TARGET=wp77xx legato # build endpoint as wp77xx target in test mode
$ make TARGET=wp77xx EP_TA_HOST=node.deviceproof.org EP_TA_PORT=5566 legato # build endpoint as wp77xx target, and set the connected host to "node.deviceproof.org" with port 5566
$ make TESTS=true TARGET=wp77xx EP_TA_HOST=node.deviceproof.org EP_TA_PORT=5566 legato # build endpoint as wp77xx target in test mode
```

### How to build endpoint application for native target
Expand Down
6 changes: 6 additions & 0 deletions endpoint/endpoint.adef
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ processes:
}
}

bindings:
{
endpoint.endpointComp.le_secStore -> secStore.le_secStore
endpoint.endpointComp.le_sim -> modemService.le_sim
}

start: manual
17 changes: 8 additions & 9 deletions endpoint/endpointComp/Component.cdef
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
sources:
{
${CURDIR}/../endpoint_core.c
${CURDIR}/../hal/device.c
${CURDIR}/../platform/wp77xx/impl.c

${CURDIR}/../../output_base/external/org_iota_common/utils/logger_helper.c

Expand Down Expand Up @@ -85,19 +87,16 @@ cflags:
-I${CURDIR}/../../output_base/external/mbedtls_2_16_6/include
}

bundles:
{
// List of files copied from the build host into the App for runtime usage
file:
{
resolv.conf /etc/
}
}

requires:
{
device:
{
[rw] /dev/ttyHS0 /dev/ttyHS0
}

api:
{
le_secStore.api
modemServices/le_sim.api
}
}
24 changes: 15 additions & 9 deletions endpoint/endpointComp/endpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
*/

#include "endpoint.h"
#include "hal/device.h"

#include "common/ta_errors.h"
#include "endpoint/endpoint_core.h"
#include "le_test.h"
#include "legato.h"
#include "utils/cipher.h"

#include "le_log.h"

#define TEST_VALUE 0
#define TEST_MESSAGE "THISISMSG9THISISMSG9THISISMSG"
#define TEST_MESSAGE_FMT "ascii"
Expand All @@ -24,11 +27,7 @@
#define TEST_NEXT_ADDRESS \
"POWEREDBYTANGLEACCELERATOR999999999999999999999999999999999999999999999999" \
"999999B"
#define TEST_DEVICE_ID "470010171566423"

const uint8_t test_private_key[AES_CBC_KEY_SIZE] = {82, 142, 184, 64, 74, 105, 126, 65, 154, 116, 14,
193, 208, 41, 8, 115, 158, 252, 228, 160, 79, 5,
167, 185, 13, 159, 135, 113, 49, 209, 58, 68};
const uint8_t test_iv[AES_IV_SIZE] = {164, 3, 98, 193, 52, 162, 107, 252, 184, 42, 74, 225, 157, 26, 88, 72};

static void print_help(void) {
Expand Down Expand Up @@ -104,7 +103,10 @@ COMPONENT_INIT {
const char* tag = TEST_TAG;
const char* address = TEST_ADDRESS;
const char* next_address = TEST_NEXT_ADDRESS;
const char* device_id = TEST_DEVICE_ID;

char device_id[16] = {0};
const char* device_id_ptr = device_id;

uint8_t private_key[AES_CBC_KEY_SIZE] = {0};
uint8_t iv[AES_IV_SIZE] = {0};

Expand All @@ -120,20 +122,24 @@ COMPONENT_INIT {
le_arg_SetFlagCallback(print_help, "h", "help");
le_arg_Scan();

memcpy(private_key, test_private_key, AES_CBC_KEY_SIZE);
memcpy(iv, test_iv, AES_IV_SIZE);
srand(time(NULL));

device_t* device = ta_device(STRINGIZE(TARGET));
device->op->get_key(private_key);
device->op->get_device_id(device_id);

#ifdef ENABLE_ENDPOINT_TEST
LE_TEST_INIT;
LE_TEST_INFO("=== ENDPOINT TEST BEGIN ===");
LE_TEST(SC_OK == send_transaction_information(host, port, ssl_seed, value, message, message_fmt, tag, address,
next_address, private_key, device_id, iv));
next_address, private_key, device_id_ptr, iv));
LE_TEST_EXIT;
#else
while (true) {
send_transaction_information(host, port, ssl_seed, value, message, message_fmt, tag, address, next_address,
private_key, device_id, iv);
status_t ret = send_transaction_information(host, port, ssl_seed, value, message, message_fmt, tag, address,
next_address, private_key, device_id_ptr, iv);
LE_INFO("Send transaction information return: %d", ret);
sleep(10);
}
#endif
Expand Down
48 changes: 47 additions & 1 deletion endpoint/endpoint_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include "utils/text_serializer.h"
#include "utils/tryte_byte_conv.h"

#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>

// FIXME: Same as STR() inside tests/test_defined.h
#define STR_HELPER(num) #num
#define STR(num) STR_HELPER(num)
Expand Down Expand Up @@ -69,8 +73,14 @@ status_t send_transaction_information(const char* host, const char* port, const
char req_body[MAX_MSG_LEN] = {0};
uint8_t ciphertext[MAX_MSG_LEN] = {0};
uint8_t raw_msg[MAX_MSG_LEN] = {0};

const char* ta_host = host ? host : STR(EP_TA_HOST);
const char* ta_port = port ? port : STR(EP_TA_PORT);
char ipv4[16];
if (resolve_ip_address(ta_host, ipv4) != SC_OK) {
return SC_ENDPOINT_DNS_RESOLVE_ERROR;
}

const char* seed = ssl_seed ? ssl_seed : STR(EP_SSL_SEED);

int ret = snprintf((char*)raw_msg, MAX_MSG_LEN, "%s:%s", next_address, message);
Expand Down Expand Up @@ -112,10 +122,46 @@ status_t send_transaction_information(const char* host, const char* port, const
return SC_ENDPOINT_SEND_TRANSFER;
}

if (send_https_msg(ta_host, ta_port, SEND_TRANSACTION_API, req_body, seed) != SC_OK) {
if (send_https_msg(ipv4, ta_port, SEND_TRANSACTION_API, req_body, seed) != SC_OK) {
ta_log_error("http message sending error.\n");
return SC_ENDPOINT_SEND_TRANSFER;
}

return SC_OK;
}

status_t resolve_ip_address(const char* host, char result[16]) {
struct addrinfo hints;
struct addrinfo* res;

/* Obtain address(es) matching host */
memset(result, 0, 16);
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; /* Allow IPV4 format */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */

int ret = getaddrinfo(host, NULL, &hints, &res);
if (ret != 0) {
ta_log_error("Getaddrinfo returned: %s\n", gai_strerror(ret));
return SC_ENDPOINT_DNS_RESOLVE_ERROR;
}

if (res == NULL) { /* No address succeeded */
ta_log_error("Could not resolve host: %s\n", host);
return SC_ENDPOINT_DNS_RESOLVE_ERROR;
}

for (struct addrinfo* re = res; res != NULL; re = re->ai_next) {
char host_buf[1024];
int ret = getnameinfo(re->ai_addr, re->ai_addrlen, host_buf, sizeof(host_buf), NULL, 0, NI_NUMERICHOST);
if (ret == 0) {
snprintf(result, 16, "%s", host_buf);
break;
} else {
ta_log_error("Getnameinfo returned: %s\n", gai_strerror(ret));
}
}
freeaddrinfo(res); /* No longer needed */

return SC_OK;
}
8 changes: 8 additions & 0 deletions endpoint/endpoint_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,13 @@ status_t send_transaction_information(const char* host, const char* port, const
const char* message, const char* message_fmt, const char* tag,
const char* address, const char* next_address, const uint8_t* private_key,
const char* device_id, uint8_t* iv);
/**
* @brief Resolve the server address name
*
* @param[in] host The domain name of the host
* @param[out] result The buffer to store the IPV4 address output
* @return #status_t
*/
status_t resolve_ip_address(const char* host, char result[16]);

#endif // ENDPOINT_CORE_H
11 changes: 5 additions & 6 deletions endpoint/hal/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ extern "C" {
typedef struct device_type device_t;

struct device_operations {
status_t (*init)(void); /**< initialize device */
void (*fini)(void); /**< destructor of device */
status_t (*get_key)(uint8_t *); /**< get device private key */
status_t (*get_device_id)(uint8_t *); /**< get device id */
status_t (*init)(void); /**< initialize device */
void (*fini)(void); /**< destructor of device */
status_t (*get_key)(uint8_t *); /**< get device private key */
status_t (*get_device_id)(char *); /**< get device id */
};

struct uart_operations {
status_t (*init)(const uint8_t *device); /**< initialize uart */
status_t (*init)(const char *device); /**< initialize uart */
void (*write)(const int fd, const char *cmd); /**< write command to uart */
char *(*read)(const int fd); /**< read from uart */
void (*clean)(const int fd); /**< flush uart buffer */
Expand All @@ -51,7 +51,6 @@ struct secure_store_operations {
*
* @return
* - #SC_OK on success
* - #RET_NO_MEMORY on no memory error
* - #SC_ENDPOINT_SEC_UNAVAILABLE on unavailable secure storage
* - #SC_ENDPOINT_SEC_FAULT on some other error
*/
Expand Down
2 changes: 1 addition & 1 deletion endpoint/platform/simulator/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# "LICENSE" at the root of this distribution.

platform-build-command = \
cd endpoint && mkapp -v -t localhost -C -DENABLE_ENDPOINT_TEST $(ENDPOINT_CFLAGS) endpoint.adef;
cd endpoint && mkapp -v -t localhost -C -DENABLE_ENDPOINT_TEST $(LEGATO_FLAGS) endpoint.adef;
9 changes: 9 additions & 0 deletions endpoint/platform/wp77xx/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package(default_visibility = ["//visibility:public"])

cc_library(
name = "wp77xx",
srcs = ["wp77xx.c"],
deps = [
"//endpoint/hal",
],
)
2 changes: 1 addition & 1 deletion endpoint/platform/wp77xx/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
# "LICENSE" at the root of this distribution.

platform-build-command = \
cd endpoint && leaf shell -c "mkapp -v -t wp77xx $(ENDPOINT_CFLAGS) endpoint.adef"
cd endpoint && leaf shell -c "mkapp -v -t wp77xx $(LEGATO_FLAGS) endpoint.adef"
Loading

0 comments on commit 3f83bd2

Please sign in to comment.