Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regarding Parsing of Global Data in Kaitai Struct Definition #1081

Open
laosiji66666 opened this issue Jan 24, 2024 · 2 comments
Open

Regarding Parsing of Global Data in Kaitai Struct Definition #1081

laosiji66666 opened this issue Jan 24, 2024 · 2 comments
Labels

Comments

@laosiji66666
Copy link

I have a protocol definition where each frame consists of 64 bytes, with the first byte fixed at 0xAA and the last byte fixed at 0x55. The initial byte represents the frame ID, and depending on the frame ID, different data is included. Specifically, when the frame ID is 0x01, the data included is considered global, meaning that subsequent frames should also include the data associated with frame ID 0x01 during parsing. However, I am uncertain about how to include the data associated with frame ID 0x01 when parsing other data frames. The appearance of 0x01 is not fixed; it may occur at the beginning or in the middle of the file. I have been trying to address this for a while without success.

Below is my KSY file. Could you please advise on how to handle this situation or if it's possible to implement this functionality?

meta:
  id: test
  file-extension: test
  endian: le
  bit-endian: le

seq:
  - id: frames
    type: frame
    repeat: eos

types:
  frame:
    seq:
      - id: head
        type: u1
        valid: 0xaa
      - id: data_id
        type: u1
      - id: data
        size: 61
        type:
          switch-on: data_id
          cases:
            0x01: static_data
            0x42: dynamic_data
            0x43: dynamic_data
            0x44: dynamic_data
      - id: tail
        type: u1
        valid: 0x55
  static_data:
    seq:
      - id: data
        type: u4
  dynamic_data:
    seq:
      - id: data
        type: u4
      #...

I appreciate your assistance in advance.

Best regards,

@generalmimon
Copy link
Member

Specifically, when the frame ID is 0x01, the data included is considered global, meaning that subsequent frames should also include the data associated with frame ID 0x01 during parsing.

If the "global data" from the frame with ID 0x01 doesn't affect parsing decisions in subsequent frames, then the easiest way would be to handle this in your application code.

If you want to do this in Kaitai Struct, you can achieve this using a parameter that transfers the last seen "global data" from one frame to the next one:

seq:
  - id: frames
    type: |
      frame(
        _index != 0 ? frames[_index - 1].is_global_data_present : false,
        _index != 0 and frames[_index - 1].is_global_data_present ? frames[_index - 1].global_data : 0
      )
    repeat: eos

types:
  frame:
    params:
      - id: prev_is_global_data_present
        type: bool
      - id: prev_global_data
        type: u4
    seq:
      - id: head
        type: u1
        valid: 0xaa
      - id: data_id
        type: u1
      - id: data
        size: 61
        type:
          switch-on: data_id
          cases:
            0x01: static_data
            0x42: dynamic_data
            0x43: dynamic_data
            0x44: dynamic_data
      - id: tail
        type: u1
        valid: 0x55
    instances:
      global_data:
        value: 'data_id == 0x01 ? data.as<static_data>.data : prev_global_data'
        if: is_global_data_present
      is_global_data_present:
        value: 'data_id == 0x01 or prev_is_global_data_present'

This technique works when the number of things you need to keep track of is static, i.e. known at the time of authoring the .ksy spec. For the general case, #172 would need to be implemented, but this trick is sufficient in many cases.

See also #39 (comment).

@laosiji66666
Copy link
Author

Thank you for your response. Using this approach does indeed address my issue. However, when there is more than one global data ID, where should I split them? For example, if there are 10 global data IDs from 0x01 to 0x0a, how can I implement this based on the above method? Different global data IDs represent different amounts of data, so at which level should I handle the processing of these data? Kindly guide me on this. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants