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

Commit 7947daa

Browse files
howjmayHYChang
authored andcommitted
feat(endpoint): Consolidate by merging Endpoint subproject
Endpoint aims for solving issues on low level endpoint devices. Low level devices can request trustable blockchain services with `endpoint` of tangle-accelerator. For more information, README under `docs/endpoint.md` would provide more detailed information. The mbedtls and http-parser submodule are added into third_party/. Add "//third_party:mbedtls" and "//third_party/http-parser" after `deps` if you need to use them. The PEM directory contains the private key and certificate for building system. See pem/README.md to change the certificate.
1 parent 1bf3732 commit 7947daa

37 files changed

+1874
-3
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,6 @@ docs/html/
9292

9393
# Python
9494
__pycache__/
95+
96+
# Certificate for build system
97+
pem/*.inc

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@
77
[submodule "third_party/mosquitto"]
88
path = third_party/mosquitto
99
url = https://github.com/eclipse/mosquitto.git
10+
[submodule "third_party/http-parser"]
11+
path = third_party/http-parser
12+
url = https://github.com/nodejs/http-parser.git
13+
[submodule "third_party/mbedtls"]
14+
path = third_party/mbedtls
15+
url = https://github.com/ARMmbed/mbedtls.git

Makefile

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@ DCURL_DIR := third_party/dcurl
22
DCURL_LIB := $(DCURL_DIR)/build/libdcurl.so
33
MOSQUITTO_DIR := third_party/mosquitto
44
MOSQUITTO_LIB := $(MOSQUITTO_DIR)/lib/libmosquitto.so.1
5-
DEPS += $(DCURL_LIB)
5+
MBEDTLS_DIR := third_party/mbedtls
6+
MBEDTLS_LIB := $(MBEDTLS_PATH)/library/libmbedx509.so $(MBEDTLS_PATH)/library/libmbedtls.so $(MBEDTLS_PATH)/library/libmbedcrypto.so
7+
HTTPPARSER_DIR := third_party/http-parser
8+
HTTPPARSER_LIB := $(HTTPPARSER_DIR)/libhttp_parser.so
9+
PEM_DIR = pem
10+
DEPS += $(DCURL_LIB) $(HTTPPARSER_LIB) $(MBEDTLS_LIB)
11+
PEM := $(PEM_DIR)/cert.pem
612

7-
all: $(DEPS)
13+
all: $(DEPS) cert
814

9-
.PHONY: $(DCURL_LIB) $(MOSQUITTO_LIB)
15+
.PHONY: $(DCURL_LIB) $(MOSQUITTO_LIB) cert check_pem
1016

1117
$(DCURL_LIB): $(DCURL_DIR)
1218
git submodule update --init $^
@@ -21,9 +27,34 @@ $(MOSQUITTO_LIB): $(MOSQUITTO_DIR)
2127
@echo
2228
$(MAKE) -C $^ WITH_DOCS=no
2329

30+
$(HTTPPARSER_LIB): $(HTTPPARSER_DIR)
31+
git submodule update --init $^
32+
$(MAKE) -C $^ library
33+
34+
$(MBEDTLS_LIB): $(MBEDTLS_DIR)
35+
git submodule update --init $^
36+
$(MAKE) -C $^ SHARED=1 lib
37+
38+
cert: check_pem
39+
@xxd -i $(PEM) > $(PEM_DIR)/ca_crt.inc
40+
@sed -E \
41+
-e 's/(unsigned char)(.*)(\[\])(.*)/echo "\1 ca_crt_pem\3\4"/ge' \
42+
-e 's/(unsigned int)(.*)(=)(.*)/echo "\1 ca_crt_pem_len \3\4"/ge' \
43+
-e 's/^unsigned/static &/' \
44+
-e 's/(.*)(pem_len = )([0-9]+)(.*)/echo "\1\2$$((\3+1))\4"/ge' \
45+
-e 's/(0[xX][[[:xdigit:]]+)$$/\1, 0x0/g' \
46+
-i $(PEM_DIR)/ca_crt.inc
47+
check_pem:
48+
ifndef PEM
49+
$(error PEM is not set)
50+
endif
51+
2452
clean:
2553
$(MAKE) -C $(DCURL_DIR) clean
2654
$(MAKE) -C $(MOSQUITTO_DIR) clean
55+
$(MAKE) -C $(HTTPPARSER_DIR) clean
56+
$(MAKE) -C $(MBEDTLS_DIR) clean
57+
2758

2859
distclean: clean
2960
$(RM) -r $(DCURL_DIR)

common/BUILD

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ cc_library(
4545
"@entangled//common/model:transaction",
4646
],
4747
)
48+
49+
cc_library(
50+
name = "defined_error",
51+
hdrs = ["defined_error.h"],
52+
)

common/defined_error.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (C) 2019-2020 BiiLabs Co., Ltd. and Contributors
3+
* All Rights Reserved.
4+
* This is free software; you can redistribute it and/or modify it under the
5+
* terms of the MIT license. A copy of the license can be found in the file
6+
* "LICENSE" at the root of this distribution.
7+
*/
8+
9+
#ifndef COMMON_DEFINED_ERROR_H
10+
#define COMMON_DEFINED_ERROR_H
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
#define HTTP_OK 200 /**< HTTP status codes */
17+
18+
/* FIXME:The status should be integrated into common/ta_error.h */
19+
/* status code */
20+
typedef enum {
21+
RET_OK, /**< success */
22+
RET_WRITE_ERROR, /**< write error */
23+
RET_OOM, /**< out of memory */
24+
RET_HTTP_INIT, /**< failed on HTTP init */
25+
RET_HTTP_CERT, /**< failed on x509 cert parse */
26+
RET_HTTP_CONNECT, /**< failed on HTTP initial connection */
27+
RET_HTTP_SSL, /**< failed on setting ssl config */
28+
RET_DEVICE_INIT, /**< initialize device error */
29+
RET_DEVICE_FINI, /**< finalize device error */
30+
RET_UART_INIT, /**< initialize uart error */
31+
RET_OVERFLOW, /**< overflow error */
32+
RET_NOT_FOUND, /**< item not found error */
33+
RET_UNAVAILABLE, /**< item not available */
34+
RET_FAULT /**< some other fault */
35+
} endpoint_retcode_t;
36+
37+
#ifdef __cplusplus
38+
}
39+
#endif
40+
41+
#endif // COMMON_DEFINED_ERROR_H

docs/endpoint-hal.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Hardware Abstract Layer(HAL) for Endpoint
2+
3+
Hardware Abstract Layer(HAL) defines a standard interface for hardware vendors to implement new device, which enables Tangle-accelerator to be aware of lower-level driver implementations. HAL provides operators such as UART, GPIO, secure storage and other low-level operators. The endpoint is a daemon, offering monitor for the device and being able to send message to Tangle-Accelerator. HAL layer lets the user only need to implement their device operators from abstract interface which is defined inside `device.h` but not need to know how endpoint works.
4+
5+
## How to implement new device
6+
7+
Create a directory for the new device under `devices`.
8+
```
9+
$mkdir -p devices/mydevice
10+
```
11+
* Create `impl.c` and `Makefile` under the new device directory.
12+
* Include `device.h` into the new device header or the new device source file.
13+
14+
Here are some operations needed to be implemented for new device:
15+
* device_operations
16+
* init : initialize device
17+
* fini : finalize device
18+
* get_key : get device key
19+
* get_device_id : get device id(IMEI or other identifier)
20+
* uart_operations
21+
* init : initialize uart
22+
* write : write command to uart device
23+
* read : read from uart device
24+
* clean : flush buffer
25+
* secure_store_operations
26+
* init : initialize secure storage
27+
* write : write item to secure storage
28+
* read : read item from secure storage
29+
* delete : delete item inside secure storage
30+
31+
Here are the functions needed to be registered/unregistered inside `impl.c`:
32+
* register_device : register device on startup
33+
* unregister_device : unregister device
34+
* DECLARE_DEVICE : this must be declared inside `impl.c`
35+
36+
Add the new device into `hal/Makefile`:
37+
38+
* Append the device object to DEVICE_OBJS
39+
* Add the new device build target(mydevice.o)
40+
```
41+
DEVICE_OBJS = wp7702.o emulator.o device.o mydevice.o
42+
export DEVICE_OBJS
43+
44+
all: $(DEVICE_OBJS)
45+
46+
mydevice.o: device.o
47+
$(MAKE) -C ../devices/mydevice
48+
```
49+
50+
Implement a new device which is created under `devices` directory, and edit the Makefile. The example device is named as `mydevice`:
51+
```
52+
all: mydevice.o
53+
mydevice.o: impl.c
54+
$(CC) $(CFLAGS) $(INCLUDES) -c $^ -o $@
55+
```
56+
`$(CC)`,`$(CFLAGS)` and `$(INCLUDES)` are specified by build system. `CC` sets the default compiler for the project. `CFLAGS` are the default flags that would be passed to default compiler during compiling time. `INCLUDES` flag includes headers inside sub-projects and third-party libraries. You can also modify these flags inside your device's Makefile.
57+
58+
impl.c
59+
```c
60+
#include "device.h"
61+
62+
static inline void register_emulator(void);
63+
static inline void unregister_emulator(void);
64+
65+
static struct device_operations emulator_ops = {.init = &emulator_init,
66+
.fini = &emulator_release,
67+
.get_key = &emulator_get_key,
68+
.get_device_id = &emulator_get_device_id};
69+
70+
static struct uart_operations emulator_uart = {
71+
.init = &uart_init, .write = &uart_write, .read = &uart_read, .clean = &uart_clean};
72+
73+
static struct device_type emulator_device_type = {
74+
.name = "emulator", .op = &emulator_ops, .uart = &emulator_uart, .sec_ops = &emulator_sec_ops};
75+
76+
static inline void register_emulator(void) {
77+
int err = register_device(&emulator_device_type);
78+
if (err) LOG_ERROR("register emulator device error:%d", err);
79+
}
80+
81+
static inline void unregister_emulator(void) {
82+
int err = unregister_device(&emulator_device_type);
83+
if (err) LOG_ERROR("unregister device emulator error:%d", err);
84+
}
85+
86+
static int emulator_init(void) {
87+
register_emulator();
88+
return DEVICE_OK;
89+
}
90+
91+
static void emulator_release(void) { unregister_emulator(); }
92+
93+
// must be declared at the end of impl.c
94+
DECLARE_DEVICE(emulator);
95+
```

docs/endpoint.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Endpoint
2+
The endpoint is one of the components provided by Tangle-accelerator, running on a resource-constrained network connectivity module. The embedded devices can send messages to blockchain network (Tangle) with a connectivity module loaded endpoint. The message would be transmitted to connectivity module through UART. Message would be encrypted and send to tangle.
3+
4+
# Streaming Message Channel Implementation
5+
The encrypted message would be sent to Tangle with a streaming message channel API. The streaming message channel API would ensure the order of messages in the channel. The user who wants to fetch/send message to Tangle needs to provide `data_id`, `key` and `protocol` to identify a specific message.
6+
A message sent by endpoint needs to be encrypted locally, which avoids message being peeked and modified.
7+
8+
# How to use
9+
```
10+
$ bazel build //endpoint:wp7702
11+
$ bazel build //endpoint:sim
12+
```

endpoint/BUILD

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
cc_library(
2+
name = "endpoint",
3+
srcs = ["endpoint.c"],
4+
hdrs = ["endpoint.h"],
5+
defines = [
6+
"TA_HOST=\"tangle-accel.biilabs.io\"",
7+
"TA_PORT=\"443\"",
8+
"TA_SSL_SEED=\"nonce\"",
9+
],
10+
visibility = ["//visibility:public"],
11+
deps = [
12+
"//common:defined_error",
13+
"//utils:cipher",
14+
"//utils:https",
15+
"//utils:text_serializer",
16+
"//utils:tryte_byte_conv",
17+
],
18+
)
19+
20+
cc_test(
21+
name = "test_endpoint",
22+
srcs = [
23+
"test_endpoint.c",
24+
],
25+
deps = [
26+
":endpoint",
27+
"//common",
28+
"//tests:test_define",
29+
],
30+
)

endpoint/endpoint.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (C) 2019-2020 BiiLabs Co., Ltd. and Contributors
3+
* All Rights Reserved.
4+
* This is free software; you can redistribute it and/or modify it under the
5+
* terms of the MIT license. A copy of the license can be found in the file
6+
* "LICENSE" at the root of this distribution.
7+
*/
8+
9+
#include "endpoint.h"
10+
#include <stdio.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
#include "http_parser.h"
14+
#include "utils/cipher.h"
15+
#include "utils/connectivity/conn_http.h"
16+
#include "utils/https.h"
17+
#include "utils/text_serializer.h"
18+
#include "utils/tryte_byte_conv.h"
19+
20+
#define STRINGIZE(x) #x
21+
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
22+
23+
const char* HOST = STRINGIZE_VALUE_OF(TA_HOST);
24+
const char* PORT = STRINGIZE_VALUE_OF(TA_PORT);
25+
const char* SSL_SEED = STRINGIZE_VALUE_OF(TA_SSL_SEED);
26+
27+
#define REQ_BODY \
28+
"{\"value\": %d, \"message\": \"%s\", \"message_format\": \"%s\", \"tag\": \"%s\", \"address\": \"%s\"}\r\n\r\n"
29+
30+
#define SEND_TRANSACTION_API "transaction/"
31+
32+
endpoint_retcode_t send_transaction_information(int value, const char* message, const char* message_fmt,
33+
const char* tag, const char* address, const char* next_address,
34+
const uint8_t* private_key, const char* device_id, uint8_t* iv) {
35+
char tryte_msg[MAX_MSG_LEN] = {0};
36+
char msg[MAX_MSG_LEN] = {0};
37+
char ciphertext[MAX_MSG_LEN] = {0};
38+
char req_body[MAX_MSG_LEN] = {0};
39+
char raw_msg[MAX_MSG_LEN] = {0};
40+
41+
int ret = snprintf(raw_msg, MAX_MSG_LEN, "%s:%s", address, message);
42+
if (ret < 0) {
43+
// FIXME: Replace to default logger
44+
fprintf(stderr, "message is to long");
45+
return RET_FAULT;
46+
}
47+
48+
size_t msg_len = 0;
49+
ta_cipher_ctx encrypt_ctx = {.plaintext = raw_msg,
50+
.plaintext_len = ret,
51+
.ciphertext = ciphertext,
52+
.ciphertext_len = MAX_MSG_LEN,
53+
.device_id = device_id,
54+
.iv = {0},
55+
.key = private_key,
56+
.keybits = TA_AES_KEY_BITS};
57+
memcpy(encrypt_ctx.iv, iv, AES_IV_SIZE);
58+
ret = aes_encrypt(&encrypt_ctx);
59+
memcpy(iv, encrypt_ctx.iv, AES_IV_SIZE);
60+
61+
// FIXME: Replace to default logger
62+
if (ret != RET_OK) {
63+
fprintf(stderr, "%s\n", "encrypt msg error");
64+
return ret;
65+
}
66+
serialize_msg(iv, encrypt_ctx.ciphertext_len, encrypt_ctx.ciphertext, msg, &msg_len);
67+
bytes_to_trytes((const unsigned char*)msg, msg_len, tryte_msg);
68+
69+
memset(req_body, 0, sizeof(char) * MAX_MSG_LEN);
70+
71+
ret = snprintf(req_body, MAX_MSG_LEN, REQ_BODY, value, tryte_msg, message_fmt, tag, address);
72+
if (ret < 0) {
73+
// FIXME: Replace to default logger
74+
fprintf(stderr, "message is to long");
75+
return RET_FAULT;
76+
}
77+
78+
if (send_https_msg(HOST, PORT, SEND_TRANSACTION_API, req_body, MAX_MSG_LEN, SSL_SEED) != RET_OK) {
79+
// FIXME: Replace to default logger
80+
fprintf(stderr, "%s\n", "send http message error");
81+
return RET_FAULT;
82+
}
83+
84+
return RET_OK;
85+
}

endpoint/endpoint.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (C) 2019-2020 BiiLabs Co., Ltd. and Contributors
3+
* All Rights Reserved.
4+
* This is free software; you can redistribute it and/or modify it under the
5+
* terms of the MIT license. A copy of the license can be found in the file
6+
* "LICENSE" at the root of this distribution.
7+
*/
8+
9+
#ifndef ENDPOINT_H
10+
#define ENDPOINT_H
11+
12+
#define ADDR_LEN 81
13+
#define MAX_MSG_LEN 1024
14+
15+
#include <stdint.h>
16+
#include "common/defined_error.h"
17+
18+
/**
19+
* @brief Send transaction information to tangle accelerator
20+
*
21+
* @param[in] value Amount of the IOTA currency will be sent
22+
* @param[in] message Message of the transaction in Trytes format
23+
* @param[in] message_fmt Treating message field as specified format. Can be one of `ascii` or `trytes`. Default:
24+
* `ascii`
25+
* @param[in] tag Tag of transactions into several classifications. Tag is 27-trytes characters, e.g.
26+
* POWEREDBYTANGLEACCELERATOR9
27+
* @param[in] address Address of the receiver where IOTA currency will be sent to
28+
* @param[in] next_address Next address to be sent inside message
29+
* @param[in] private_key Private key from device
30+
* @param[in] device_id Device id from device
31+
* @param[in/out] iv Initialization vector, must be read/write. The length of iv must be AES_IV_SIZE @see #ta_cipher_ctx
32+
*
33+
* @return #endpoint_retcode_t
34+
*/
35+
endpoint_retcode_t send_transaction_information(const int value, const char* message, const char* message_fmt,
36+
const char* tag, const char* address, const char* next_address,
37+
const uint8_t* private_key, const char* device_id, uint8_t* iv);
38+
39+
#endif // ENDPOINT_H

0 commit comments

Comments
 (0)