Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

src/d7a.cpp

Committer:
Jeej
Date:
2016-10-26
Revision:
67:9ac9d109b80a
Parent:
66:492b1d7ba370
Child:
68:d2778c6abf1a

File content as of revision 67:9ac9d109b80a:

#include "mbed.h"
#include "rtos.h"
#include "dbg.h"
#include "d7a.h"
#include "d7a_com.h"
#include "d7a_common.h"
#include "d7a_fs.h"
#include "d7a_modem.h"
#include "d7a_sys.h"
#include "d7a_alp.h"

#define FIRST_IFT_FILE      (108)

bool g_open = false;
bool g_started = false;
bool g_local_fs = false;

d7a_errors_t d7a_open(const d7a_com_config_t* com_config, PinName reset_pin, const d7a_callbacks_t* callbacks)
{
    FPRINT("\r\n");
    
    d7a_errors_t err = D7A_ERR_STATE;
    
    if (g_open)
    {
        WARNING(false, "D7A Already open\r\n");
        return D7A_ERR_NONE;
    }
    
    do
    {
        
        err = d7a_com_open(com_config);
        if (err < D7A_ERR_NONE) break;
        
        err = d7a_sys_open();
        if (err < D7A_ERR_NONE) break;
        
        err = d7a_fs_open(callbacks->write_file, callbacks->read_file);
        if (err < D7A_ERR_NONE) break;
        
        err = d7a_alp_open(callbacks->unsolicited_msg);
        if (err < D7A_ERR_NONE) break;
        
        err = d7a_modem_open(reset_pin, callbacks->notif_done);
        if (err < D7A_ERR_NONE) break;
        
        if (callbacks->write_file != NULL && callbacks->read_file != NULL)
        {
            g_local_fs = true;
        }
        
        g_open = true;
        g_started = true;
        
    } while (0);
    
    WARNING(err == D7A_ERR_NONE, "%s err %d\r\n", __FUNCTION__, err);
    
    return err;
}


d7a_errors_t d7a_close(void)
{
    FPRINT("\r\n");
    
    d7a_errors_t err = D7A_ERR_STATE;
    
    do
    {
        err = d7a_com_close();
        if (err < D7A_ERR_NONE) break;
        
        err = d7a_modem_close();
        if (err < D7A_ERR_NONE) break;
        
        err = d7a_fs_close();
        if (err < D7A_ERR_NONE) break;
        
        err = d7a_sys_close();
    } while (0);
    
    WARNING(err == D7A_ERR_NONE, "%s err %d\r\n", __FUNCTION__, err);
    
    return err;
}


d7a_errors_t d7a_start(void)
{
    FPRINT("\r\n");
    
    d7a_errors_t err = D7A_ERR_STATE;
    
    if (!g_started)
    {
        err = d7a_modem_start();
        if (err == D7A_ERR_NONE)
        {
            g_started = true;
        }
    }
    
    WARNING(err == D7A_ERR_NONE, "%s err %d\r\n", __FUNCTION__, err);
    
    return err;
}


d7a_errors_t d7a_stop(void)
{
    FPRINT("\r\n");
    
    d7a_errors_t err = D7A_ERR_STATE;
    
    if (g_started)
    {
        err = d7a_modem_stop();
        if (err == D7A_ERR_NONE)
        {
            g_started = false;
        }
    }
    
    WARNING(err == D7A_ERR_NONE, "%s err %d\r\n", __FUNCTION__, err);
    
    return err;
}


d7a_errors_t d7a_create(const uint8_t file_id, d7a_fs_storage_t prop, d7a_fs_perm_t perm, uint32_t size, uint32_t alloc, d7a_action_t action, alp_rpol_t retry)
{
    FPRINT("\r\n");
    
    d7a_errors_t err = D7A_ERR_STATE;
    
    DPRINT("Create %d.\r\n", file_id);
    
    if (g_started)
    {
        register_file_param_t file_infos = {
            .fid = file_id,
            .type = RAM,
            .afid = action,
            .ifid = FIRST_IFT_FILE + retry, // The interface files match the retry policies
            .prop = (uint8_t)prop | ((action)? FS_ACT_EN : 0),
            .perm = (uint8_t)perm,
            .size = size,
            .alloc = alloc,
        };
        
        err = d7a_modem_register(&file_infos);
    }
    
    DPRINT("Create %d Done. err %d\r\n", file_id, err);
    
    WARNING(err == D7A_ERR_NONE, "%s FID %d err %d\r\n", __FUNCTION__, file_id, err);
    
    return err;
}


d7a_errors_t d7a_declare(const uint8_t file_id, d7a_fs_storage_t prop, d7a_fs_perm_t perm, uint32_t length, uint32_t alloc, d7a_action_t action, alp_rpol_t retry)
{
    FPRINT("\r\n");
        
    d7a_errors_t err = D7A_ERR_STATE;
    
    DPRINT("Declare %d.\r\n", file_id);
    
    ASSERT(g_local_fs, "You cannot delare a file if the write_file/read_file callbacks are not specified\r\n");
    
    if (g_started)
    {
        register_file_param_t file_infos = {
            .fid = file_id,
            .type = HOST+RAM,
            .afid = action,
            .ifid = FIRST_IFT_FILE + retry, // The interface files match the retry policies
            .prop = (uint8_t)prop | ((action)? FS_ACT_EN : 0),
            .perm = (uint8_t)perm,
            .size = length,
            .alloc = alloc,
        };
        
        err = d7a_modem_register(&file_infos);
    }
    
    DPRINT("Declare %d Done\r\n", file_id);
    
    WARNING(err == D7A_ERR_NONE, "%s FID %d err %d\r\n", __FUNCTION__, file_id, err);
    
    return err;
}


d7a_msg_t** d7a_read(const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* root_key, d7a_addressee_t* addressee, alp_rpol_t retry)
{
    FPRINT("\r\n");
    
    d7a_msg_t** ret = NULL;
    
    DPRINT("Read %d @%d %d bytes.\r\n", file_id, offset, size);
    
    if (g_started)
    {
        ret = d7a_alp_read_file(file_id, offset, size, root_key, addressee, retry);
    }
    
    DPRINT("Read %d Done.\r\n", file_id);
    
    WARNING(ret[0]->err == D7A_ERR_NONE, "%s FID: %d OFF: %d LEN: %d err %d\r\n", __FUNCTION__, file_id, offset, size, ret[0]->err);
    
    return ret;
}


d7a_msg_t** d7a_write(const uint8_t file_id, const uint32_t offset, const uint32_t size, const uint8_t* const buf, const uint8_t* root_key, d7a_addressee_t* addressee, alp_rpol_t retry, bool resp)
{
    FPRINT("\r\n");
    
    d7a_msg_t** ret = NULL;
    
    DPRINT("Write %d @%d %d bytes.\r\n", file_id, offset, size);
    
    if (g_started)
    {
        ret = d7a_alp_write_file(file_id, offset, size, buf, root_key, addressee, retry, resp);
    }
    
    DPRINT("Write %d Done.\r\n", file_id);
    
    WARNING(ret[0]->err == D7A_ERR_NONE, "%s FID: %d OFF: %d LEN: %d err %d\r\n", __FUNCTION__, file_id, offset, size, ret[0]->err);
    
    return ret;
}

d7a_msg_t** d7a_flush(const uint8_t file_id, const uint8_t* root_key, d7a_addressee_t* addressee, alp_rpol_t retry, bool resp)
{
    FPRINT("\r\n");
    
    d7a_msg_t** ret = NULL;
    
    DPRINT("Flush %d.\r\n", file_id);
    
    if (g_started)
    {
        ret = d7a_alp_flush_file(file_id, root_key, addressee, retry, resp);
    }
    
    DPRINT("Flush %d Done.\r\n", file_id);
    
    WARNING(ret[0]->err == D7A_ERR_NONE, "%s FID: %d err %d\r\n", __FUNCTION__, file_id, ret[0]->err);
    
    return ret;
}

d7a_errors_t d7a_notify(const uint8_t file_id, const uint32_t offset, const uint32_t size)
{
    FPRINT("\r\n");
    
    d7a_errors_t err = D7A_ERR_STATE;
    
    DPRINT("Notify %d @%d %d bytes.\r\n", file_id, offset, size);
    
    if (g_started)
    {
        notify_file_param_t notif = {
            .bf.fid = file_id,
            .bf.offset = offset,
            .bf.size = size
        };
        
        err = d7a_modem_notify(&notif);
    }
    
    DPRINT("Notify %d Done. err %d\r\n", file_id, err);
    
    WARNING(err == D7A_ERR_NONE, "%s FID: %d OFF: %d LEN: %d err %d\r\n", __FUNCTION__, file_id, offset, size, err);
    
    return err;
}


void d7a_free_msg(d7a_msg_t** msg)
{
    int i = 0;
    while (msg[i] != NULL)
    {
        d7a_alp_free_msg(msg[i]);
        i++;
    }
    
    FREE(msg);
}

void d7a_print_msg(d7a_msg_t** msg)
{
    uint8_t i = 0;
    while (msg[i] != NULL)
    {
        PRINT("MSG %2d ERR:%4d", i, msg[i]->err);
        if (msg[i]->lb)
        {
            PRINT_DATA(" UID:", "%02X", msg[i]->id, 8, " ");
            PRINT("LB:%3d", msg[i]->lb);
        }
        if (msg[i]->data)
        {
            PRINT(" FID: %3d OFF: %3d LEN: %3d", msg[i]->data->fid, msg[i]->data->offset, msg[i]->data->length);
            PRINT_DATA(" DATA:", " %02X", msg[i]->data->buf, msg[i]->data->length, "");
        }
        PRINT("\r\n");
        i++;
    }
}

void d7a_modem_print_infos(void)
{
    uint8_t uid[8];
    d7a_revision_t rev;
    
    d7a_msg_t** msg;
    
    msg = d7a_read(0, 0, D7A_UID_LEN);
    ASSERT(msg[0]->err >= D7A_ERR_NONE, "Failed to read UID file. err %d\r\n", msg[0]->err);
    ASSERT(msg[0]->data, "No data in response\r\n");
    memcpy(uid, msg[0]->data->buf, D7A_UID_LEN);
    d7a_free_msg(msg);
    
    msg = d7a_read(2, 0, sizeof(d7a_revision_t));
    ASSERT(msg[0]->err >= D7A_ERR_NONE, "Failed to read Revision file. err %d\r\n", msg[0]->err);
    ASSERT(msg[0]->data, "No data in response\r\n");
    memcpy(&rev, msg[0]->data->buf, sizeof(d7a_revision_t));
    d7a_free_msg(msg);
    
    PRINT("------------ D7A Modem infos ------------\r\n");
    PRINT_DATA("| UID:              ", "%02X", uid, 8, "    |\r\n");
    PRINT("| Manufacturer ID:  %08X            |\r\n", rev.manufacturer_id);
    PRINT("| Device ID:        %08X            |\r\n", rev.device_id);
    PRINT("| Hardware version: %08X            |\r\n", rev.hw_version);
    PRINT("| Firmware version: (%02X) v%d.%d.%d-%08x \t|\r\n", rev.fw_version.id, rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, rev.fw_version.hash);
    PRINT("| File system CRC:  0x%08x          |\r\n", rev.fs_crc);
    PRINT("-----------------------------------------\r\n");
    
}