FaradayRF / Faraday-Firmware

Faraday node firmware
Other
25 stars 10 forks source link

Device Configuration Factory Default - Bug #52

Closed kb1lqd closed 7 years ago

kb1lqd commented 7 years ago

When attempting to read a factory reset device the JSON decoding fails.

Reading the configuration from a unit programmed with the device configuration tool works fine.

image

I suspect that the factory default setting firmware code is slightly incorrect from that expected from the device configuration tool.

Device Configuration Software Application Packet

image

Firmware Default Configuration

//Configuration
#define CONFIG_BASIC_FLASH_CONFIG_BITMASK_ADDR 6144 /**< Configuration status bitmask memory address location */
#define CONFIG_BASIC_FLASH_CONFIG_BITMASK_INDEX 0 /**< Configuration status bitmask packet index location */
//Device Information
#define CONFIG_BASIC_LOCAL_CALLSIGN_ADDR 6145 /**< Device callsign memory address location */
#define CONFIG_BASIC_LOCAL_CALLSIGN_INDEX 1 /**< Device callsign packet index location */
#define CONFIG_BASIC_LOCAL_CALLSIGN_LEN_ADDR 6154 /**< Device callsign length in  bytes memory address location */
#define CONFIG_BASIC_LOCAL_CALLSIGN_LEN_INDEX 10 /**< Device callsign length in bytes packet index location */
#define CONFIG_BASIC_LOCAL_CALLSIGN_ID_ADDR 6155 /**< Device callsign ID number memory address location */
#define CONFIG_BASIC_LOCAL_CALLSIGN_ID_INDEX 11 /**< Device callsign ID number packet index location */
//GPIO Defaults
#define CONFIG_BASIC_P3_GPIO_ADDR 6156 /**< GPIO port 3 default PxOUT status memory address location */
#define CONFIG_BASIC_P3_GPIO_INDEX 12 /**< GPIO port 3 default PxOUT status packet index location */
#define CONFIG_BASIC_P4_GPIO_ADDR 6157 /**< GPIO port 4 default PxOUT status memory address location */
#define CONFIG_BASIC_P4_GPIO_INDEX 13 /**< GPIO port 4 default PxOUT status packet index location */
#define CONFIG_BASIC_P5_GPIO_ADDR 6158 /**< GPIO port 5 default PxOUT status memory address location */
#define CONFIG_BASIC_P5_GPIO_INDEX 14 /**< GPIO port 5 default PxOUT status packet index location */
//Radio
#define CONFIG_RF_DEFAULT_FREQ_ADDR 6168 /**< Default radio frequency memory address location */
#define CONFIG_RF_DEFAULT_FREQ_INDEX 24 /**< Default radio frequency packet index location */
#define CONFIG_RF_DEFAULT_PATABLE_ADDR 6171 /**< Default CC430 RF power setting memory address location */
#define CONFIG_RF_DEFAULT_PATABLE_INDEX 27 /**< Default CC430 RF power setting packet index location */
//GPS
#define CONFIG_GPS_DEFAULT_LATTITUDE_ADDR 6193 /**< Default GPS Lattitude memory address location */
#define CONFIG_GPS_DEFAULT_LATTITUDE_INDEX 49 /**< Default GPS Lattitude packet index location */
#define CONFIG_GPS_DEFAULT_LATTITUDE_DIR_ADDR 6202 /**< Default GPS Lattitude direction memory address location */
#define CONFIG_GPS_DEFAULT_LATTITUDE_DIR_INDEX 58 /**< Default GPS Lattitude direction packet index location */
#define CONFIG_GPS_DEFAULT_LONGITUDE_ADDR 6203 /**< Default GPS Longitude memory address location */
#define CONFIG_GPS_DEFAULT_LONGITUDE_INDEX 59 /**< Default GPS Longitude packet index location */
#define CONFIG_GPS_DEFAULT_LONGITYUDE_DIR_ADDR 6213 /**< Default GPS Longitude  direction memory address location */
#define CONFIG_GPS_DEFAULT_LONGITYUDE_DIR_INDEX 59 /**< Default GPS Longitude direction packet index location */
#define CONFIG_GPS_DEFAULT_ALTITUDE_ADDR 6214 /**< Default altitude memory address location */
#define CONFIG_GPS_DEFAULT_ALTITUDE_INDEX 70 /**< Default altitude packet index location */
#define CONFIG_GPS_DEFAULT_ALTITUDE_UNITS_ADDR 6222 /**< Default altitude units memory address location */
#define CONFIG_GPS_DEFAULT_ALTITUDE_UNITS_INDEX 78 /**< Default altitude units packet index location */
#define CONFIG_GPS_DEFAULT_BOOT_BITMASK_ADDR 6223 /**< Default GPS boot bitmask memory address location */
#define CONFIG_GPS_DEFAULT_BOOT_BITMASK_INDEX 79 /**< Default GPS boot bitmask packet index location */
//Telemetry Application
#define CONFIG_TELEMETRY_BOOT_BITMASK_ADDR 6245 /**< Default telemetry application configuration bitmask memory address location */
#define CONFIG_TELEMETRY_BOOT_BITMASK_INDEX 101 /**< Default telemetry application configuration bitmask packet index location */
#define CONFIG_TELEMETRY_UART_INTERVAL_ADDR 6246 /**< Default UART telemetry interval memory address location */
#define CONFIG_TELEMETRY_UART_INTERVAL_INDEX 102 /**< Default UART telemetry interval packet index location */
#define CONFIG_TELEMETRY_RF_INTERVAL_ADDR 6248 /**< Default RF telemetry interval memory address location */
#define CONFIG_TELEMETRY_RF_INTERVAL_INDEX 104 /**< Default RF telemetry interval packet index location */

//Bitmask locations
#define UNIT_PROGRAMMED BIT0 /**< Flash programmed configuration bitmask location */
#define GPS_BOOT_ENABLE BIT0 /**< GPS boot enabled GPS boot bitmask location */
#define UART_BEACON_BOOT_ENABLE BIT0 /**< UART beacon telemetry enabled telemetry boot bitmask location */
#define RF_BEACON_BOOT_ENABLE BIT1 /**< RF beacon telemetry enabled telemetry boot bitmask */
/** @}*/
typedef struct default_config{
            unsigned char flash_config_bitmask;
            char local_callsign [9];
            unsigned char local_callsign_len;
            unsigned char local_device_id;
            unsigned char default_gpio_p3_bitmask;
            unsigned char default_gpio_p4_bitmask;
            unsigned char default_gpio_p5_bitmask;
            unsigned char padding_basic[9];
            unsigned char boot_freq[3];
            unsigned char PATable;
            unsigned char padding_rf[21];
            char default_lattitde[9];
            char default_lattitude_dir;
            char default_longitude[10];
            char default_longitude_dir;
            char default_altitude[8];
            char default_altitude_units;
            unsigned char gps_boot_bitmask;
            unsigned char padding_gps[21];
            unsigned char telem_boot_bitmask;
            unsigned int telem_default_uart_interval;
            unsigned int telem_default_rf_interval;
            unsigned char padding_telemetry[10];
        } default_flash_config_struct;
//Check if flash programmed correctly, if not then program defaults to have something in memory. This should ONLY occur if the device has never be used before or was completely ereased!
    if((!check_bitmask(flash_programmed_bit, BIT0)) | (device_callsign_len>MAX_CALLSIGN_LENGTH)){
        //Basic Configuration
        default_flash_config_struct program_config_boot_struct;
        program_config_boot_struct.flash_config_bitmask = BIT0;
        program_config_boot_struct.local_callsign_len = sizeof("NOCALL")-1; //-1 Because string contains \n as last byte
        memcpy(program_config_boot_struct.local_callsign, "NOCALL", program_config_boot_struct.local_callsign_len);
        program_config_boot_struct.local_device_id = 0;
        program_config_boot_struct.default_gpio_p3_bitmask = 0x00;
        program_config_boot_struct.default_gpio_p4_bitmask = 0x00;
        program_config_boot_struct.default_gpio_p5_bitmask = 0x00;

        //RF
        //Default frequency is 914.5MHz
        program_config_boot_struct.boot_freq[2] = 0x23; //FREQ MSB
        program_config_boot_struct.boot_freq[1] = 0x2c;
        program_config_boot_struct.boot_freq[0] = 0x4e; //FREQ LSB
        program_config_boot_struct.PATable = 20;

        //GPS
        //Leave default location if not set yet to 0's. Or we could put it somewhere... funny...
        program_config_boot_struct.default_lattitde;
        program_config_boot_struct.default_lattitude_dir;
        program_config_boot_struct.default_longitude;
        program_config_boot_struct.default_longitude_dir;
        program_config_boot_struct.default_altitude;
        program_config_boot_struct.default_altitude_units;
        program_config_boot_struct.gps_boot_bitmask = 1;

        //Telemetry
        program_config_boot_struct.telem_boot_bitmask = BIT0; //Default RF OFF since invalid callsign
        //int_to_byte_array(&program_config_boot_struct.telem_default_uart_interval, 10);
        program_config_boot_struct.telem_default_uart_interval = 5;
        //int_to_byte_array(&program_config_boot_struct.telem_default_rf_interval, 5);
        program_config_boot_struct.telem_default_rf_interval = 0; //Default RF OFF since invalid callsign

        app_device_config_write_buffer(&program_config_boot_struct.flash_config_bitmask, CONFIG_PACKET_LEN);
    }

Device Configuration Module Library

I am getting data back from the unit but it is in a default state, the unit is transferring BASE64 data to the proxy and device configuration program but the program errors on the RETURN of the device configuration application after it has been unpacked. I think I might have been dumb and I'm trying to push non BASE64 encoded data over localhost and I got lucky that in prior configurations invalid symbols were not transferred. I believe I need to re-encoded it into BASE64.

# Retrieve the next device configuration read packet to arrive
            data = proxy.GETWait(str(callsign), str(nodeid), proxy.CMD_UART_PORT, 2)
            print "GOT DATA"
            print data

            # Create device configuration module object
            device_config_object = deviceconfig.DeviceConfigClass()

            # Decode BASE64 JSON data packet into
            data = proxy.DecodeRawPacket(data[0]["data"])  # Get first item

            print data

            data = device_config_object.extract_config_packet(data)

            parsed_config_dict = device_config_object.parse_config_packet(data)

        except ValueError as e:
            logger.error("ValueError: " + str(e))
            return json.dumps({"error": str(e)}), 400
        except IndexError as e:
            logger.error("IndexError: " + str(e))
            return json.dumps({"error": str(e)}), 400
        except KeyError as e:
            logger.error("KeyError: " + str(e))
            return json.dumps({"error": str(e)}), 400

        return json.dumps(parsed_config_dict, indent=1), 200, \
               {'Content-Type': 'application/json'}

REV B1 Faraday

Debugging the device configuration default factory and user-configured operational bug. on a known working REV B1.

Pre-Configured

Testing the device programming status of a working and configured REV B1. This unit has a good prior callsign and setup and I am running device configuration script to see if it reads and writes properly.

Yes the unit correctly reads and reprograms:

image

The CCS memory browser shows device info segment 0x1800 as:

01  4B  42  31  4C  51  44
00  00  00  06  02  00  00
00  00  00  00  00  00  00
00  00  00  4E  2C  23  14
00  00  00  00  00  00  00
00  00  00  00  00  00  00
00  00  00  00  00  00  00
30  31  32  33  34  35  36
37  38  4E  30  31  32  33
34  35  36  37  38  39  57
30  31  32  33  34  35  36
37  4D  00  00  00  00  00
00  00  00  00  00  00  00
00  00  00  00  00  00  00
00  00  00  01  05  00  05
00  00  00  00  00  00  00
00  00  00  00  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  E0  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF

Resetting to factory default (needs to be made into a command from UART):

I manually in debug mode set the programmed bit to 0.

image

The memory browser now shows the memory contents of device information segment as:

01  4E  4F  43  41  4C  4C
06  02  0D  06  00  00  00
00  E0  07  33  33  35  39
2E  37  30  4E  2C  23  0F
31  38  32  36  2E  39  34
32  31  57  3C  A9  00  00
80  00  00  00  00  00  D8
FF  00  00  14  00  00  00
5C  C8  00  00  08  A5  00
00  00  00  00  00  2B  20
00  00  F4  21  88  9F  00
00  14  01  00  00  0A  C8
00  00  62  C8  00  00  04
69  00  00  02  00  00  00
EE  C4  01  01  05  00  3C
00  00  00  5C  C8  00  00
08  A5  00  00  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  E1  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF
FF  FF  FF  FF  FF  FF  FF

The unit now fails to read the current device configuration:

image

This confirms that the origine of the root cause is the default factory reset of the device configuration.

Root Cause Analysis

The device information configuration memory definition:

image

Device Configuration Bitmask (1 Byte)

01  

Callsign (9 Bytes)

4E  4F  43  41  4C  4C
06  02  0D

Callsign Length (1 Byte)

06  

Callsign ID (1 Byte)

00

Default GPIO P3 (1 Byte)

00

Default GPIO P4 (1 Byte)

Default GPIO P5 (1 Byte)

00

Boot Frequency (3 Bytes) Assignment says max size is 1 byte which is wrong, numbers below look not correct! Maybe this is causing a calculate frequency error on parsing during a read?

E0  07  33
33  35  39
2E  37  30  4E  2C  23  0F
31  38  32  36  2E  39  34
32  31  57  3C  A9  00  00
80  00  00  00  00  00  D8
FF  00  00  14  00  00  00
5C  C8  00  00  08  A5  00
00  00  00  00  00  2B  20
00  00  F4  21  88  9F  00
00  14  01  00  00  0A  C8
00  00  62  C8  00  00  04
69  00  00  02  00  00  00
EE  C4  01  01  05  00  3C
00  00  00  5C  C8  00  00
08  A5  00  00

Catching Error - Device Configuration Application

I updated the device configuration code to have a try/except statement along with debugging print statements to determine the location of the error code.

image

image

Looks like it can't decode the BASE64. I modified the code again to print the data retrieve.

image

Data returned is None type. Not what we want...

I just realized that I had the unit debug paused.... Running it again shows a much different story!

image

The data is parsing! It looks like the error occurs during the transfer of the parsed data from the application through the GET command:

image

I believe I'm passing dangerous characters that are causing framing errors (not byte escaped!) through the FLASK server GET interface. This is a credible failure mode and the entire reason BASE64 is used. A working configured unit gets lucky not sending the frame "start byte".

I'm going to try to re-encode into BASE64 prior to transfering data over the GET command from the Tutorial #3 for device configuration I'm running.

kb1lqd commented 7 years ago

I'm closing this issue as the root cause analysis showed that the bug lives in the software FLASK interface and allowable byte values ensuring safe framing without BASE 64 encoding. Moving issue to software section.

New bug issue ticket: https://github.com/FaradayRF/Faraday-Software/issues/43