diff --git a/src/FIT.jl b/src/FIT.jl index cd100b2..e2b3da6 100644 --- a/src/FIT.jl +++ b/src/FIT.jl @@ -8,6 +8,4 @@ using .file end using .FIT -open("test.FIT", "r") do f - h = FIT.read_header(f) -end \ No newline at end of file +ffr = FIT.read_file("test.FIT") \ No newline at end of file diff --git a/src/file.jl b/src/file.jl index 7fe0ce0..21200a1 100644 --- a/src/file.jl +++ b/src/file.jl @@ -31,7 +31,7 @@ mutable struct RecordHeader end struct FieldDefinition - number::UInt8 + type::AbstractString sz_bytes::UInt8 base_type::Type # TODO: This needs to be translated into an actual base type. end @@ -126,7 +126,7 @@ function decode_header(v::Vector{UInt8})::RecordHeader record = blank_header_byte() record.definition = v[7] === 0x01 record.data = !record.definition - record.local_mesg_type = sum_bits(v[end-3:end]) + record.local_mesg_type = sum_bits(v[1:4]) record end @@ -135,9 +135,10 @@ end Parse a field definition in the definition message into a struct """ -function parse_field(bytes::Vector{UInt8})::FieldDefinition +function parse_field(mesg_type::AbstractString, bytes::Vector{UInt8})::FieldDefinition + # TODO the first byte of the field definition, the field num, is definiedre-defined by each mesg definitionn FieldDefinition( - bytes[1], + get_field_description(mesg_type, bytes[1]), bytes[2], get_base_type(bytes[3]) ) @@ -153,11 +154,11 @@ function read_record_content!(f::FITFileReader, hdr::RecordHeader)::Union{Defini if hdr.definition # Read the fixed 5 bytes first. def_header_bytes = read_bytes!(f, 5) + global_mesg_type = get_mesg_num_string(byte_vec_to_int(def_header_bytes[3:4])) def_header_fields = read_bytes!(f, def_header_bytes[end] * 3) - # Should always be a multiple of 3 - # TODO: There is a missing byte here that complicates parsing - field_definitions = [parse_field(def_header_fields[i:i+2]) for i ∈ 1:3:length(def_header_fields)] + # Parse the field. global_mesg_type needed to decode the field number description + field_definitions = [parse_field(global_mesg_type, def_header_fields[i:i+2]) for i ∈ 1:3:length(def_header_fields)] # See if there is developer data def_header_developer_flag = read_bytes!(f, 1) @@ -166,7 +167,6 @@ function read_record_content!(f::FITFileReader, hdr::RecordHeader)::Union{Defini end # Associate the global message type with this local message type. - global_mesg_type = get_mesg_num_string(byte_vec_to_int(def_header_bytes[3:4])) f.mesg_map[hdr.local_mesg_type] = global_mesg_type DefinitionBody( diff --git a/src/mesg_num.jl b/src/mesg_num.jl index 1903187..9c56e27 100644 --- a/src/mesg_num.jl +++ b/src/mesg_num.jl @@ -2,7 +2,7 @@ module mesg_num -export get_mesg_num_string, get_field_definition_string +export get_mesg_num_string, get_field_definition_string, get_mesg_num, get_field_description FILE_ID = 0 CAPABILITIES = 1 @@ -138,14 +138,14 @@ MESG_NUM_MAP = Dict( MONITORING => "MONITORING", TRAINING_FILE => "TRAINING_FILE", HRV => "HRV", - ANT_RX => "ANT_RX", + ANT_RX => "ANT_RX", ANT_TX => "ANT_TX", ANT_CHANNEL_ID => "ANT_CHANNEL_ID", LENGTH => "LENGTH", MONITORING_INFO => "MONITORING_INFO", PAD => "PAD", SLAVE_DEVICE => "SLAVE_DEVICE", - CONNECTIVITY => "CONNECTIVITY", + CONNECTIVITY => "CONNECTIVITY", WEATHER_CONDITIONS => "WEATHER_CONDITIONS", WEATHER_ALERT => "WEATHER_ALERT", CADENCE_ZONE => "CADENCE_ZONE", @@ -216,6 +216,16 @@ function get_mesg_num_string(mesg_num::Real)::Union{AbstractString,Nothing} end end +function get_mesg_num(mesg_type::AbstractString)::Union{Real,Nothing} + for (key, value) ∈ MESG_NUM_MAP + if value == mesg_type + return key + end + end + + return nothing +end + FIELD_DEFINITION_MAP = Dict( 0xFF => "Invalid", 254 => "MessageIndex", @@ -230,4 +240,22 @@ function get_field_definition_string(num::Real)::Union{AbstractString,Nothing} end end +FIELD_DESCRIPTIONS = Dict(FILE_ID => Dict( + 0 => "type", + 1 => "manufacturer", + 2 => "product", + 3 => "serial_number", + 4 => "time_created", + 5 => "number", + 8 => "product_name" +)) + +function get_field_description(mesg_type::AbstractString, field_num::Real)::Union{AbstractString, Nothing} + try + FIELD_DESCRIPTIONS[get_mesg_num(mesg_type)][field_num] + catch + "nothing" + end +end + end \ No newline at end of file