Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Reorganize directory structure #31

Closed
splasky opened this issue Feb 27, 2020 · 4 comments
Closed

Reorganize directory structure #31

splasky opened this issue Feb 27, 2020 · 4 comments
Assignees
Labels
A-refactor Some improvement P-low Priority - Low

Comments

@splasky
Copy link
Contributor

splasky commented Feb 27, 2020

There are three directory at the root directory. Why don't we put source code into same src directory and put headers file into same include directory?

@jserv
Copy link
Member

jserv commented Feb 27, 2020

It is not "folder" but "directory."
Show the tree view rather than words while you are proposing something.

@howjmay howjmay added A-refactor Some improvement P-low Priority - Low labels Mar 6, 2020
@howjmay howjmay changed the title Make directory structure more clearly Redesign directory structure Mar 6, 2020
@howjmay howjmay pinned this issue Mar 14, 2020
@howjmay
Copy link
Contributor

howjmay commented Mar 17, 2020

@splasky Provide the structure you designed here.

@DLTcollab DLTcollab deleted a comment from howjmay Mar 17, 2020
@jserv jserv changed the title Redesign directory structure Reorganize directory structure Mar 17, 2020
@splasky splasky self-assigned this Mar 19, 2020
@splasky
Copy link
Contributor Author

splasky commented Mar 20, 2020

How to porting TA-endpoint on your device

tags: TA-endpoint

Written by HY Chang<[email protected]>

Directory Overview

  • connectivity: Connect to Tangle-accelerator functions.
  • devices: The real directory to implement devices.
  • hal: Hardware abstraction layer.
  • hooks: Git hook functions.
  • tests: Unit-tests.
  • third_party: Third party directory.
  • utils: Utility functions for TA-endpoint.

How to implement your device

Create your device folder into devices.

mkdir devices/<my_device>
  • Create your impl.c Makefile under your device folder.
  • Include device.h into your header files.

Implement your device operations, which are included from hal/device.h

device.h:

... 

#define DECLARE_DEVICE(name)                                  \
  void init_##name##_init(void) __attribute__((constructor)); \
  void init_##name##_init(void) { name##_device_type.op->init(); }

typedef struct device_type device_t;
enum { DEVICE_OK, DEVICE_ERROR };

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

struct logging_operations {
  void (*write_log)(char *path, char *msg, size_t msg_len);
}; // Will be removed

struct uart_operations {
  retcode_t (*init)(const char *device);
  void (*write)(const int fd, const char *cmd);
  char *(*read)(const int fd);
  void (*clean)(const int fd);
};

struct secure_store_operations {
  retcode_t (*init)(void); /**< init secure storage */
  retcode_t (*write)(const char *name, const uint8_t *bufPtr, size_t bufSize);
  retcode_t (*read)(const char *name, uint8_t *bufPtr, size_t *bufSizePtr);
  retcode_t (*delete)(const char *name);
};

struct device_type {
  const char *name;
  int uart_fd;
  const struct device_operations *op;
  const struct uart_operations *uart;
  const struct secure_store_operations *sec_ops;
  device_t *next;
};

device_t *get_device(const char *);
retcode_t register_device(struct device_type *dv);
retcode_t unregister_device(struct device_type *dv);
...

add your device into hal/Makefile:

  • Add device object after DEVICES_OBJ
  • Add your device build target
DEVICES_OBJ = wp7702.o emulator.o device.o mydevice.o
INCLUDES += -I/$(CURDIR)
export DEVICES_OBJ

all: $(DEVICES_OBJ)
... 
mydevice.o: device.o
    $(MAKE) -C ../devices/mydevice
...
    

implement device:
must include

  1. impl.c
  2. Makefile

edit Makefile, example device name as mydevice:

all: mydevice.o
mydevice.o: impl.c
        $(CC) $(CFLAGS) $(INCLUDES) -c $^ -o $@

$(CC),$(CFLAGS),$(INCLUDES) is provide by TA-endpoint. Don't define same flags inside your Makefile.

impl.c

#include "impl.h"
...

static inline void register_emulator(void);
static inline void unregister_emulator(void);
...

static struct device_operations emulator_ops = {.init = &emulator_init,
                                                .fini = &emulator_release,
                                                .get_key = &emulator_get_key,
                                                .get_device_id = &emulator_get_device_id};

static struct logging_operations emulator_logger = {.write_log = &write_log}; // Will be removed

static struct uart_operations emulator_uart = {
    .init = &uart_init, .write = &uart_write, .read = &uart_read, .clean = &uart_clean};

static struct device_type emulator_device_type = {
    .name = "emulator", .op = &emulator_ops, .uart = &emulator_uart, .logger = &emulator_logger};

static inline void register_emulator(void) {
  int err = register_device(&emulator_device_type);
  if (err) LOG_ERROR("register emulator device error:%d", err);
}

static inline void unregister_emulator(void) {
  int err = unregister_device(&emulator_device_type);
  if (err) LOG_ERROR("unregister device emulator error:%d", err);
}

static int emulator_init(void) {
  register_emulator();
  return DEVICE_OK;
}

static void emulator_release(void) { unregister_emulator(); }

...

// must be declared at the end of impl.c
DECLARE_DEVICE(emulator);

UML:

classDiagram
    class device_operations{
        +init(void) int
        +get_key(uint8_t*) retcode_t
        +get_device_id(char*) retcode_t
        +fini(void) void
    }
   
    class uart_operations{
        +init(const char*) int
        +read(const int) char*
        +write(const int, const char*) void
        +clean(const int) void
    }
    
    class secure_store_operations{
         +init(void) retcode_t
         +write(const char *name, const uint8_t *bufPtr, size_t bufSize) retcode_t
         +read(const char *name, uint8_t *bufPtr, size_t *bufSizePtr) retcode_t
         +delete(const char *name) retcode_t
    }

    class device_t{
        const char* name
        int uart_fd
        device_operation* op
        uart_operation* uart
        device_t* next
    }
    uart_operations <|-- device_t
    device_operations <|-- device_t
    secure_store_operations <|-- device_t
    class wp7702{
        +DECLARE_DEVICE("wp7702")
    }
    
    class emulator{
        +DECLARE_DEVICE("emulator")
    }
    
     device_t <|.. emulator
    device_t <|.. wp7702
    
Loading

template inc:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "conn_http.h"
#include "crypto_utils.h"
#include "device.h"
#include "logger.h"
#include "serializer.h"
#include "tryte_byte_conv.h"
#include "tryte_msg.h"
#include "url.h"

#define SSL_SEED "nonce"
#define ADDRESS                                                                \
  "POWEREDBYTANGLEACCELERATOR999999999999999999999999999999999999999999999999" \
  "999999A"
#define ADDR_LEN 81

int runner(const char* host, const char* port, const char* api)
{
    uint8_t addr[ADDR_LEN] = ADDRESS, next_addr[ADDR_LEN] = {0}, iv[16] = {0};
    char raw_msg[1000] = {0}, ciphertext[1024] = {0};
    char tryte_msg[1024] = {0}, msg[1024] = {0};
    uint32_t raw_msg_len = 1 + ADDR_LEN + 20, msg_len = 0;
    srand(time(NULL));

    device_t *dv = get_device("{% device_name %}");
    int fd = dv->uart->init("{% uart_port %}");
    if (fd < 0) {
      LOG_ERROR("Error in initializing UART\n");
      return -1;
    }

    char* log_msg = malloc(sizeof(char)*ADDR_LEN + 3);
    memset(log_msg, '0', ADDR_LEN + 3);
    snprintf(log_msg, strlen(next_addr), "\n%s", next_addr);
    dv->logger->write_log("{% log_path %}", next_addr, strlen(next_addr));
    free(log_msg);

    char *response = NULL;
    time_t timer;
    char time_str[26];
    struct tm *tm_info;

    fd_set rset;
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 500;
    while (true) {
      FD_ZERO(&rset);
      FD_SET(fd, &rset);
      select(fd + 1, &rset, NULL, NULL, &tv);

      if (FD_ISSET(fd, &rset)) {
        time(&timer);
        tm_info = localtime(&timer);
        strftime(time_str, 26, "%Y-%m-%d %H:%M:%S", tm_info);
        LOG_DEBUG("%s\n", time_str);
        gen_rand_trytes(ADDR_LEN, next_addr);

        response = dv->uart->read(fd);
        snprintf(raw_msg, raw_msg_len, "%s:%s", next_addr, response);

        LOG_DEBUG("Raw Message: %s\n", raw_msg);
        uint8_t private_key[AES_BLOCK_SIZE] = {0};
        uint8_t id[IMSI_LEN] = {0};

        if (dv->op->get_key(private_key) != 0) {
          LOG_ERROR("%s\n", "get aes key error");
          return -1;
        }

        // fetch Device_ID (IMSI, len <= 16)
        if (dv->op->get_device_id(id) != 0) {
          LOG_ERROR("%s\n", "get device id error");
          return -1;
        }
        int ciphertext_len = encrypt(raw_msg, strlen(raw_msg), ciphertext, 1024, iv, private_key, id);
        if (ciphertext_len == 0) {
          LOG_ERROR("encrypt msg error");
          return -1;
        }
        serialize_msg(iv, ciphertext_len, ciphertext, msg, &msg_len);
        bytes_to_trytes((const unsigned char *)msg, msg_len, tryte_msg);

        // Init http session. verify: check the server CA cert.
        char msg_body[1024];
        gen_tryte_msg(tryte_msg, addr, msg_body);
        if (send_https_msg(host, port, api, msg_body, 1024, SSL_SEED) != HTTP_OK) {
          LOG_ERROR("Response from ta server failed");
        }

        memcpy(addr, next_addr, ADDR_LEN);
        free(response);
        response = NULL;
        LOG_INFO("Finish transaction");
      }
      dv->uart->clean(fd);
    }
}

device will be used:

    device_t *dv = get_device("{% device_name %}");
    int fd = dv->uart->init("{% uart_port %}");

test_driver.c:

#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)

const char *HOST = STRINGIZE_VALUE_OF(TA_HOST);
const char *PORT = STRINGIZE_VALUE_OF(TA_PORT);
const char *API = STRINGIZE_VALUE_OF(TA_API);

#include "use_models.h"

int main(void) { return runner(HOST, PORT, API); }

build process:

splasky added a commit to splasky/TA-endpoint that referenced this issue Mar 26, 2020
Add hardware abstraction layer for create unify device operators.

Closes DLTcollab#31
splasky added a commit to splasky/TA-endpoint that referenced this issue Mar 27, 2020
Add hardware abstraction layer for create unify device operators.

Closes DLTcollab#31
@splasky
Copy link
Contributor Author

splasky commented Apr 20, 2020

The TA-endpoint is migrated into tangle-accelerator so I close this issue.

@splasky splasky closed this as completed Apr 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A-refactor Some improvement P-low Priority - Low
Projects
None yet
Development

No branches or pull requests

4 participants