afLib 1.3 which is supporting both SPI and UART

Dependencies:   vt100 mbed afLib_1_3

af_utils/af_attriburtes.cpp

Committer:
Rhyme
Date:
2018-04-23
Revision:
0:87662653a3c6

File content as of revision 0:87662653a3c6:

#include "mbed.h"
#include <ctype.h>
#include "af_attributes.h"
#include "af_mgr.h"
#include "edge_time.h"
#include "edge_mgr.h"
#include "edge_reset_mgr.h"


static const af_attribute_type af_attr[] = {
#if 1
/*     ID,                     Description,                Type,                Size */     
/* Software Reset Request */    
    {  ATTR_SOFTWARE_RESET,   "Software Reset",            ATTRIBUTE_TYPE_BOOLEAN, 1 },
    {  ATTR_MCU_RESET_REASON, "MCU Reset Reason",          ATTRIBUTE_TYPE_UTF8S,  64 },
    
    { ATTR_LED,               "LED",                       ATTRIBUTE_TYPE_SINT16,  2 },
    { ATTR_IO0,               "I/O 0",                     ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_IO1,               "I/O 1",                     ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_IO2,               "I/O 2",                     ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_BUTTON,            "BUTTON",                    ATTRIBUTE_TYPE_BOOLEAN, 2 },
    { ATTR_IO3,               "I/O 3",                     ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_BOOT_LOADER_VER,   "Bootloader Version",        ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_BLE_STACK_VER,     "BLE Stack Version",         ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_FW_APP_VER,        "FW Application Version",    ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_DEVICE_DESC,       "Device Description",        ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_WIFI_VER,          "Wi-Fi chip",                ATTRIBUTE_TYPE_SINT64,  8 },
    { ATTR_OFFLINE_SCHED,     "Offline Schedules enable",  ATTRIBUTE_TYPE_SINT16,  2 }, 
    { ATTR_SECURITY_ENABLED,  "Security Enabled",          ATTRIBUTE_TYPE_SINT8,   1 }, /* ? */
    { ATTR_UTC_OFFSET,        "UTC offset data",           ATTRIBUTE_TYPE_BYTES,   8 },
    { ATTR_CONFIGURES_SSID,   "Configured SSID",           ATTRIBUTE_TYPE_UTF8S,  10 }, /* ? */
    { ATTR_WIFI_BARS,         "Wi-Fi Bars",                ATTRIBUTE_TYPE_SINT8,   1 },
    { ATTR_WIFI_STDY_STATE,   "Wi-Fi Steady State",        ATTRIBUTE_TYPE_SINT8,   1 },
    { ATTR_COMMAND,           "Command",                   ATTRIBUTE_TYPE_BYTES,   8 }, /* ? */   
    { ATTR_ASR_STATE,         "ASR State",                 ATTRIBUTE_TYPE_SINT8,   1 },
    { ATTR_LOW_BATTERY,       "Low Battery Warning",       ATTRIBUTE_TYPE_SINT8,   1 },
    { ATTR_LINKED_TIMESTAMP,  "Linked Timestamp",          ATTRIBUTE_TYPE_SINT32,  4 },
    { ATTR_ATTR_ACK,          "Attribute ACK",             ATTRIBUTE_TYPE_SINT16,  8 },
    { ATTR_REBOOT_REASON,     "Reboot Reason",             ATTRIBUTE_TYPE_UTF8S, 100 },
    { ATTR_BLE_COMMS,         "BLE Comms",                 ATTRIBUTE_TYPE_BYTES,  12 },
    { ATTR_MCU_INTERFACE,     "MCU Interface",             ATTRIBUTE_TYPE_SINT8,   1 },
    { 0,                      0,                           0,                      0 }
} ;
#endif

int get_af_attr(uint16_t id) 
{
    int i ;
    for (i = 0 ; af_attr[i].id != 0 ; i++ ) {
        if (id == af_attr[i].id) {
            break ;
        }
    }
    return (i) ;
}

void print_af_error(int resultCode) 
{
    switch(resultCode) {
    case afSUCCESS:
        tty->printf("Operation completed successfully\n") ;
        break ;
    case afERROR_NO_SUCH_ATTRIBUTE:
        tty->printf("Request was made for unknown attribute id\n") ;
        break ;
    case afERROR_BUSY:
        tty->printf("Request already in progress, try again\n") ;
        break ;
    case afERROR_INVALID_COMMAND:
        tty->printf("Command could not be parsed\n") ;
        break ;
    case afERROR_QUEUE_OVERFLOW:
        tty->printf("Queue is full\n") ;
        break ;
    case afERROR_QUEUE_UNDERFLOW:
        tty->printf("Queue is empty\n") ;
        break ;
    case afERROR_INVALID_PARAM:
        tty->printf("Bad input parameter\n") ;
        break ;
    default:
        tty->printf("Unknown error code %d\n", resultCode) ;
        break ;
    }
}

void af_print_values(
    const uint8_t   requestId, 
    const uint16_t  attributeId,
    const uint16_t  valueLen,
    const uint8_t   *value
) 
{
    int i, id ;

    id = get_af_attr(attributeId) ;

    if (af_attr[id].id  != 0) {
        tty->printf(af_attr[id].description) ;
        tty->printf(" : ") ;
        switch(af_attr[id].attribute_type) {
        case ATTRIBUTE_TYPE_BOOLEAN:
        case ATTRIBUTE_TYPE_SINT8: 
            if (valueLen >= 1) {
                tty->printf("%02X\n", value[0]) ;
            }
            break ;
        case ATTRIBUTE_TYPE_SINT16:
            if (valueLen >= 2) {
                tty->printf("%02X%02X\n", value[1], value[0]) ;
            }
            break ; 
        case ATTRIBUTE_TYPE_SINT32:
            if (valueLen >= 4) {
                tty->printf("%02X%02X%02X%02X\n",
                    value[3],value[2],value[1],value[0]) ;
            }
            break ;
        case ATTRIBUTE_TYPE_SINT64:
            if (valueLen >= 8) {
                tty->printf("%02X%02X %02X%02X %02X%02X %02X%02X\n",
                    value[7], value[6], value[5], value[4],
                    value[3], value[2], value[1], value[0]) ;
            }
            break ;
        case ATTRIBUTE_TYPE_UTF8S: 
            if (valueLen > 0) {
                for (i = 0 ; i < valueLen ; i++) {
                    if (isprint(value[i])) {
                        tty->printf("%c", value[i]) ;
                    } else if (value[i] == 0) { /* string terminator NULL */
                        break ;
                    } else {
                        tty->printf("\'%02X\'",value[i]) ;
                    }
                }
                tty->printf("\n") ;
            }
            break ;
        case ATTRIBUTE_TYPE_BYTES:
        default:
            if (valueLen > 0) {
                for (i = 0 ; i < valueLen ; i++ ) {
                    tty->printf("%02X ", value[i]) ;
                }
                tty->printf("\n") ;
            }
            break ;
        }
    } else {
        if (valueLen > 0) {
            for (i = 0 ; i < valueLen ; i++ ) {
                tty->printf("%02X ", value[i]) ;
            }
            tty->printf("\n") ;
        }
    }
//    tty->printf("\n") ;
}

bool assignAttribute(
    const uint8_t   requestId, 
    const uint16_t  attributeId,
    const uint16_t  valueLen,
    const uint8_t   *value,
    bool fromRequest
) 
{
    bool result = true ;
    switch(attributeId) {
    case ATTR_LINKED_TIMESTAMP: /* timestamp */  
        set_time(valueLen, value) ; /* 68 us */
//        if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ;
        tty->printf("timestamp = ") ;
        print_date_wd(&current_time) ;
//        print_time(&current_time) ;
        tty->printf("\n") ;
        break ;  
    case ATTR_SOFTWARE_RESET: /* software reset requested! */
        if (value[0]) {
            printf("Software Reset Requested!\n") ;
            reset_watch_dog() ;
//            if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ;
            wait(0.5) ;
            reboot_edge() ;
        }
        break ;          
    default:
        break ;    
    }
    return result ;
}

/*
 * Callback that allows ASR to request an MCU attribute be changed. 
 * You should define this function in your MCU firmware to perform application-specific actions 
 * your code must take (e.g., updating the state of the hardware), 
 * in light of the attribute value change.
*/
bool attributeChangeRequest(
    const uint8_t   requestId, 
    const uint16_t  attributeId,
    const uint16_t  valueLen,
    const uint8_t   *value
) 
{ 
    int result ;
    uint32_t timestamp = edge_time ;

    ts2time(timestamp, &current_time) ; /* 12 us */
//    if (verbos) {
        print_time(&current_time) ;
        tty->printf(" %5d ASR requested [%d] : ", attributeId, requestId) ;
        af_print_values(requestId, attributeId, valueLen, value) ;
//    }

    result = assignAttribute(requestId, attributeId, valueLen, value, true) ;

//    af_print_values(requestId, attributeId, valueLen, value) ;
    return(result == afSUCCESS) ;
}

/*
 * Application callback that allows afLib to notify that an attribute has changed. 
 * This method will be called in response to a getAttribute call from the application 
 * and whenever a ASR module attribute changes.
 */
void attributeUpdatedReport(
    const uint8_t   requestId,
    const uint16_t  attributeId,
    const uint16_t  valueLen,
    const uint8_t   *value
) 
{
    uint32_t timestamp = edge_time ;
    int result ;

    ts2time(timestamp, &current_time) ; /* 12us */
//    if (verbos) {
        print_time(&current_time) ;
        tty->printf(" %5d ASR reported [%d]: ", attributeId, requestId) ;
        af_print_values(requestId, attributeId, valueLen, value) ;
//    }

    switch(attributeId) {
    case ATTR_LED:
        tty->printf("LED : ") ;
        if (value[0]) {
            tty->printf("ON\n") ;
        } else {
            tty->printf("OFF\n") ;
        }
        break ;
    case ATTR_LINKED_TIMESTAMP:
        set_time(valueLen, value) ; /* 68 us */
        tty->printf("timestamp = ") ;
        print_date_wd(&current_time) ;
//        print_time(&current_time) ;
        tty->printf("\n") ;
        break ;         
    case ATTR_WIFI_STDY_STATE:
        gConnected = false ;
        tty->printf("WiFi Steady State: ") ;
        switch(value[0]) {
        case 0: tty->printf("Not Connected\n")      ; break ;
        case 1: tty->printf("Pending\n") ;            break ;
        case 2: 
            tty->printf("Connected\n") ;       
            gConnected = true ; // the only case Connected state is OK   
            break ;
        case 3: tty->printf("Unknown Failure\n") ;    break ;
        case 4: tty->printf("Association Failed\n") ; break ;
        case 5: tty->printf("Handshake Failed\n") ;   break ;
        case 6: tty->printf("Echo Failed\n") ;        break ;
        case 7: tty->printf("SSID Not Found\n") ;     break ;
        case 8: tty->printf("NTP Failed\n") ;         break ;
        default: tty->printf("Unknown [%d]\n", value[0]) ; break ;
        }
        break ;
    case ATTR_REBOOT_REASON:
        tty->printf("Reboot Reason: ") ;
        switch(value[0]) {
        case 1: tty->printf("Reset pin asserted\n") ; break ;
        case 2: tty->printf("Watchdog reset\n") ;     break ;
        case 4: tty->printf("Software reset\n") ;     break ;
        case 8: tty->printf("CPU Lock up\n") ;        break ;
        default: tty->printf("Unknown [%d]\n", value[0]) ;     break ;
        }
        break ; 
    case ATTR_MCU_INTERFACE:
        tty->printf("MCU Interface: ") ;
        switch(value[0]) {
        case 0:  tty->printf("No MCU\n") ;    break ;
        case 1:  tty->printf("SPI Slave\n") ; break ;
        case 2:  tty->printf("UART\n") ;      break ;
        default: tty->printf("Unknown\n") ;   break ; 
        }
        break ;
    case AF_SYSTEM_ASR_STATE:
        tty->printf("ASR state: ") ;
        switch(value[0]) {
        case MODULE_STATE_REBOOTED:
            gLinked = false ;
            tty->printf("Rebooted\n") ;
            wait_ms(100) ;
            if (edge_mgr_status == EDGE_MGR_RUNNING) {
                reboot_edge() ;
            }
            break ;
        case MODULE_STATE_LINKED:
            if (gLinked == false) { /* new link established */
                result = afero->getAttribute(ATTR_LINKED_TIMESTAMP) ;
            }
            gLinked = true ;
            tty->printf("Linked\n") ;
            break ;
        case MODULE_STATE_UPDATING:
            gLinked = true ; 
            tty->printf("Updating\n") ;
            break ;
        case MOUDLE_STATE_UPDATE_READY:
            gLinked = false ;
            tty->printf("Update ready - rebooting\n") ;
            while(afero->setAttribute32(AF_SYSTEM_COMMAND, MODULE_COMMAND_REBOOT) != afSUCCESS) {
                afero->loop() ;
                wait_us(100) ;
            }
            reboot_edge() ;
            break ;
        default:
            break ;
        }
        break ;
    default:
        assignAttribute(requestId, attributeId, valueLen, value, false) ;
        break ;
    }        
}