Skip to content

Commit

Permalink
feat: Add HAL support
Browse files Browse the repository at this point in the history
Add hardware abstraction layer for create unify device operators.

Closes DLTcollab#31
  • Loading branch information
splasky committed Mar 27, 2020
1 parent e6173c1 commit f1f0f59
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 90 deletions.
23 changes: 13 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ UNITY_PATH = $(THIRD_PARTY_PATH)/Unity
TEST_PATH = $(ROOT_DIR)/tests
UTILS_PATH = $(ROOT_DIR)/utils
CONNECTIVITY_PATH = $(ROOT_DIR)/connectivity
export THIRD_PARTY_PATH ROOT_DIR UTILS_PATH MBEDTLS_PATH UNITY_PATH
HAL_PATH = $(ROOT_DIR)/hal
export THIRD_PARTY_PATH ROOT_DIR UTILS_PATH MBEDTLS_PATH UNITY_PATH HAL_PATH

ifeq ($(DEBUG), n)
CFLAGS = -Wall -Werror -fPIC -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -O2
Expand All @@ -26,7 +27,7 @@ CFLAGS = -Wall -fPIC -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -g3 -DDEBUG
endif
export CFLAGS

INCLUDES = -I$(THIRD_PARTY_PATH)/http-parser -I$(MBEDTLS_PATH)/include -I$(ROOT_DIR)/connectivity -I$(ROOT_DIR)/utils
INCLUDES = -I$(THIRD_PARTY_PATH)/http-parser -I$(MBEDTLS_PATH)/include -I$(ROOT_DIR)/connectivity -I$(ROOT_DIR)/utils -I$(HAL_PATH)
LIBS = $(MBEDTLS_PATH)/library/libmbedx509.a $(MBEDTLS_PATH)/library/libmbedtls.a $(MBEDTLS_PATH)/library/libmbedcrypto.a
export INCLUDES

Expand All @@ -38,13 +39,9 @@ CONNECTIVITY_OBJS = conn_http.o
OBJS = main.o $(HTTP_PARSER_PATH)/http_parser.o $(UTILS_OBJS) $(CONNECTIVITY_OBJS)

.SUFFIXES:.c .o
.PHONY: all clean test pre-build
.PHONY: all clean test pre-build hal

all: pre-build ta_client mbedtls_make

ta_client: mbedtls_make $(OBJS)
@echo Linking: $@ ....
$(CC) -o $@ $(OBJS) $(LIBS)
all: pre-build mbedtls_make hal

mbedtls_make:
@for dir in $(MBEDTLS_PATH); do \
Expand All @@ -64,15 +61,21 @@ $(UTILS_OBJS):
test: $(TEST_PATH) $(UTILS_OBJS)
$(MAKE) -C $(TEST_PATH)

clean: clean_client clean_third_party clean_test
hal:
$(MAKE) -C $(HAL_PATH)

clean: clean_client clean_third_party clean_test clean_devices

clean_test:
$(MAKE) -C $(TEST_PATH) clean

clean_client:
$(MAKE) -C $(UTILS_PATH) clean
$(MAKE) -C $(CONNECTIVITY_PATH) clean
rm -f ta_client *.o *.c.d
rm -f *.o *.c.d

clean_devices:
$(MAKE) -C $(HAL_PATH) clean

clean_third_party: clean_mbedtls clean_http_parser

Expand Down
12 changes: 12 additions & 0 deletions hal/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
DEVICES_OBJ = device.o
INCLUDES += -I/$(CURDIR)
export DEVICES_OBJ

all: $(DEVICES_OBJ)

device.o: device.c
$(CC) $(CFLAGS) $(INCLUDES) -c $^

clean:
find $(DEVICES_PATH) -name "*.o" -exec rm -f {} \;
rm *.o
49 changes: 49 additions & 0 deletions hal/device.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "device.h"

static struct device_type *devices;

static struct device_type **find_device(const char *name, unsigned len) {
struct device_type **p;
for (p = &devices; *p; p = &(*p)->next)
if (strlen((*p)->name) == len && strncmp((*p)->name, name, len) == 0) break;
return p;
}

device_t *device(const char *type) {
struct device_type **p;
if (devices->next) {
fprintf(stderr, "No device type registered!");
return NULL;
}
p = find_device(type, strlen(type));
if (*p) {
fprintf(stderr, "Device type %s not found", type);
}
return *p;
}

retcode_t register_device(struct device_type *dv) {
retcode_t res = RET_OK;
struct device_type **p;
if (dv->next) {
return -DEVICE_REG;
}
p = find_device(dv->name, strlen(dv->name));
if (*p) {
res = -DEVICE_REG;
} else {
*p = dv;
}
return res;
}

retcode_t unregister_device(struct device_type *dv) {
for (struct device_type **tmp = &devices; *tmp != NULL; tmp = &(*tmp)->next) {
if (dv == *tmp) {
*tmp = dv->next;
dv->next = NULL;
return RET_OK;
}
}
return -DEVICE_UNREG;
}
135 changes: 135 additions & 0 deletions hal/device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright (C) 2019-2020 BiiLabs Co., Ltd. and Contributors
* All Rights Reserved.
* This is free software; you can redistribute it and/or modify it under the
* terms of the MIT license. A copy of the license can be found in the file
* "LICENSE" at the root of this distribution.
*/

#ifndef HAL_DEVICE_H
#define HAL_DEVICE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defined_error.h"

/*! device initialization entry point */
#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;

struct device_operations {
retcode_t (*init)(void); /**< initialize 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 uart_operations {
retcode_t (*init)(const char *device); /**< init 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 */
};

struct secure_store_operations {
retcode_t (*init)(void); /**< init secure storage */
/**
* @brief Write an item to secure storage
*
* @param[in] name Name of item
* @param[in] bufPtr Pointer to data
* @param[in] bufSize Length of data
*
* @return
* - #RET_OK on success
* - #NO_MEMORY on no memory error
* - #UNAVAILABLE on secure storage is currently unavailable
* - #FAULT on some other error
*/
retcode_t (*write)(const char *name, const uint8_t *bufPtr, size_t bufSize);
/**
* @brief Read an item from secure storage
*
* @param[in] name Name of item
* @param[out] bufPtr Buffer to store the data in
* @param[out] bufSizePtr Pointer to length of data
*
* @return
* - #RET_OK on success
* - #OVERFLOW error on the buffer is too small
* - #NOT_FOUND error on the item not found inside secure storage
* - #UNAVAILABLE error if the storage is currently unavailable
* - #FAULT if there was some other error
*/
retcode_t (*read)(const char *name, uint8_t *bufPtr, size_t *bufSizePtr);
/**
* @brief Delete item in secure storage
*
* @param[in] name Name of item
*
* @return
* - #RET_OK on success
* - #NOT_FOUND error on the item not found inside secure storage
* - #UNAVAILABLE error if the storage is currently unavailable
* - #FAULT if there was some other error
*/
retcode_t (*delete)(const char *name);
};

struct device_type {
const char *name; /**< device type, a string */
int uart_fd; /**< uart file descriptor */
const struct device_operations *op; /**< device operations handler */
const struct uart_operations *uart; /**< uart operations handler */
const struct secure_store_operations *sec_ops; /**< secure storage operations handler */
device_t *next; /**< Pointer to next device type, don't use this directly */
};

/**
* @brief Obtain specific device handler
*
* @param[in] device Device type
*
* @return
* - device handler on success
* - NULL on failed
* @see #device_type
*/
device_t *device(const char *device);

/**
* @brief Register device
*
* @param[in] dv Device to register
*
* @return
* - #RET_OK on success
* - #DEVICE_REG on failed
*/
retcode_t register_device(struct device_type *dv);

/**
* @brief Unregister device
*
* @param[in] dv Device to unregister
*
* @return
* - #RET_OK on success
* - #DEVICE_UNREG on failed
*/
retcode_t unregister_device(struct device_type *dv);

#ifdef __cplusplus
}
#endif

#endif // HAL_DEVICE_H
58 changes: 0 additions & 58 deletions utils/crypto_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,64 +16,6 @@

#define MAX_TIMESTAMP_LEN 20

// The device ID we are used here is IMSI. We could use other physical ID in the
// future.
int get_device_id(const char *device_id) {
// TODO: replace cm command
char result_buf[MAXLINE], *imsi;
char cmd[] = "cm sim info";
FILE *fp;

fp = popen(cmd, "r");
if (NULL == fp) {
perror("popen open error");
return -1;
}

while (fgets(result_buf, sizeof(result_buf), fp) != NULL) {
if (strstr(result_buf, "IMSI")) {
result_buf[strlen(result_buf) - 1] = '\0';
imsi = strtok(result_buf + 5, " ");
}
}

strncpy((char *)device_id, imsi, IMSI_LEN);

if (pclose(fp) == -1) {
perror("close FILE pointer");
return -1;
}
return 0;
}

// Get AES key with hashchain in legato originated app form.
int get_aes_key(const uint8_t *key) {
// TODO: replace cm command
char hash_chain_res[MAXLINE];
char cmd[] = "cm sim info";
FILE *fp;

fp = popen(cmd, "r");

if (NULL == fp) {
perror("popen open error");
return -1;
}

if (fgets(hash_chain_res, sizeof(hash_chain_res), fp) != NULL) {
hash_chain_res[strlen(hash_chain_res) - 2] = '\0';
}

strncpy((char *)key, hash_chain_res, AES_BLOCK_SIZE);

if (pclose(fp) == -1) {
perror("close FILE pointer");
return -1;
}

return 0;
}

int aes_encrypt(const char *plaintext, int plaintext_len, const unsigned char *key, unsigned int keybits,
unsigned char iv[AES_BLOCK_SIZE], char *ciphertext, int ciphertext_len) {
mbedtls_aes_context ctx;
Expand Down
22 changes: 0 additions & 22 deletions utils/crypto_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,6 @@ extern "C" {
#define MAXLINE 1024
#define IMSI_LEN 15

/**
* @brief Obtain device IMSI or physical ID
*
* @param[out] device_id Device id output
*
* @return
* - 0 on success
* - -1 on failed
*/
int get_device_id(const char *device_id);

/**
* @brief Obtain aes key from hashchain
*
* @param[out] key Device key output
*
* @return
* - 0 on success
* - -1 on failed
*/
int get_aes_key(const uint8_t *key);

/**
* @brief Encrypt plaintext
*
Expand Down
8 changes: 8 additions & 0 deletions utils/defined_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ typedef enum {
RET_HTTP_CERT, /**< failed on x509 cert parse */
RET_HTTP_CONNECT, /**< failed on HTTP initial connection */
RET_HTTP_SSL, /**< failed on setting ssl config */
DEVICE_REG, /**< register device error */
DEVICE_UNREG, /**< unregister device error */
UART_INIT, /**< initialize uart error */
NO_MEMORY, /**< no enough memory error */
OVERFLOW, /**< overflow error */
NOT_FOUND, /**< item not found error */
UNAVAILABLE, /**< item not available */
FAULT /** some other fault */
} retcode_t;

#ifdef __cplusplus
Expand Down

0 comments on commit f1f0f59

Please sign in to comment.