Add support for reading from a raw fru dump
This is a squashed and rebased PR #9.
It works for the most part, except for custom fields, time and multi-records.
Source file:
{
/* The internal use area, if specified, must list all the data as hex string,
the length is calculated automatically */
"internal" : "010203040A0B0C0D",
"chassis" : {
"type": 10,
"pn" : "CHAS-C00L-12",
/* Fields may be given explicit types by setting to object with keys `type` and `data`*/
/* Supported types are: "bcdplus", "6bitascii" and "text" */
"serial": {
"type": "bcdplus",
"data": "45678"
},
"custom" : [
{ "data" : "Auto-typed text custom field" },
{ "type" : "binary", "data": "B14A87" },
/* For explicit text types range is not checked, so be careful */
{ "type" : "bcdplus", "data": "1234" },
{ "type" : "6bitascii", "data": "1234" },
{ "type" : "text", "data": "1234" }
]
},
"board" : {
/* The date, if not specified, will be taken automatically from
* the current system time. You may specify the `-u` option to
* `frugen` in order to leave the date 'Unspecified' */
/* "date" : "1/10/2016 3:00:45",*/
"mfg" : "Biggest International Corp.",
"pname" : "Some Cool Product",
"serial" : "123456",
"pn" : "BRD-PN-345",
"file" : "example1.json",
"custom" : [
{ "type" : "binary", "data" : "0123DEADBABE" },
{ "type" : "auto", "data" : "This is a text custom field" },
{ "type" : "auto", "data" : "This is test2" }
]
},
"product" : {
"lang": 1,
"mfg" : "Super OEM Company",
"pn" : "PRD-PN-1234",
"pname" : "Label-engineered Super Product",
"serial" : "OEM12345",
"atag" : "Accounting Dept.",
"ver" : "v1.1",
"file" : "example2.json",
"custom" : [
{ "type" : "auto", "data" : "Product Custom 1" },
{ "type" : "auto", "data" : "PRDCSTM" },
{ "type" : "auto", "data" : "PRDCSTM2" },
{ "type" : "binary", "data" : "C001BEEF" }
]
},
"multirecord" : [
{ "type" : "management", "subtype" : "uuid", "uuid" : "9bd70799-ccf0-4915-a7f9-7ce7d64385cf" }
]
}
Is converted using commands:
./build/frugen-static -j -z example.json example.bin
./build/frugen-static -r -z example.bin
Output:
Chassis
type: 10
pn(sixbitascii): CHAS-C00L-12
serial(bcdplus): 45678
custom: Auto-typed text custom field
custom: J
custom: 4
custom: 4Q
custom: 4
Product
lang: 25
mfg(text): Super OEM Company
pname(text): Label-engineered Super Product
serial(sixbitascii): OEM12345
pn(sixbitascii): PRD-PN-1234
ver(text): v1.1
atag(text): Accounting Dept.
file(text): example2.json
custom: Product Custom 1
custom: L 3
custom: L 3 J
custom:
Board
lang: 25
time: 13/55/2067 08:07:24
mfg(text): Biggest International Corp.
pname(text): Some Cool Product
serial(bcdplus): 123456
pn(sixbitascii): BRD-PN-345
file(text): example1.json
custom: #ޭ
custom: This is a text custom field
custom: This is test2
Multirecord
Fixed custom fields:
Chassis
type: 10
pn(sixbitascii): CHAS-C00L-12
serial(bcdplus): 45678
custom(text): Auto-typed text custom field
custom(binary): b14a87
custom(bcdplus): 1234
custom(sixbitascii): 1234
custom(text): 1234
Product
lang: 25
mfg(text): Super OEM Company
pname(text): Label-engineered Super Product
serial(sixbitascii): OEM12345
pn(sixbitascii): PRD-PN-1234
ver(text): v1.1
atag(text): Accounting Dept.
file(text): example2.json
custom(text): Product Custom 1
custom(sixbitascii): PRDCSTM
custom(sixbitascii): PRDCSTM2
custom(binary): c001beef
Board
lang: 25
time: 13/29/2067 10:07:24
mfg(text): Biggest International Corp.
pname(text): Some Cool Product
serial(bcdplus): 123456
pn(sixbitascii): BRD-PN-345
file(text): example1.json
custom(binary): 0123deadbabe
custom(text): This is a text custom field
custom(text): This is test2
Multirecord
Fixed time decoding:
time: 15/11/2022 09:35:33
I think, the only thing left to do for now is JSON dump.
I think, it's ready for review.
Basic command usage
- Generate FRU dump from
example.json:
fugen-static -j -z example.json example.bin
- Parse FRU dump to
jqorexample2.json
frugen-static -r -z example.bin > example2.json
frugen-static -r -z example.bin | jq
- ...
- Profit!
More involved example: parse FRU dump, replace one of the fields and save to JSON file
frugen-static -r -z example.bin | jq '.board.file.data |= "otherexample.json"' > otherexample.json
Motivation
The motivation for this is to use ipmitool to dump the current fru contents and then modify/add fields before writing it back. (From #9)
As may be seen from the examples above, dumping parsed data to stdout is more flexible than just using FRU dump in new dump generation:
- data can be examined
- data can be easily modified
Further work
Internal area and multi-record parsers are not implemented yet.
It's not very convenient to use functions defined in fru_reader.h as they work with file descriptor. It would be more flexible to expose functions that operate on a buffer (and maybe a set of helper functions for file descriptor and/or stream access).
Refactored decoder functions a bit for better library API
I've pushed edits, resolving most of the notes. Later, I will squash commits and split changed into separate commits, but first, library API and CLI arguments need to be thought over.
frugen is coupled too tight to the fru library, moving parsing functions from frugen to fru requires a lot of changes. This adds to an already big patch. @AlexanderAmelkin, maybe you could create a new branch for the reader feature, so these things could be added one PR at a time?
I've updated the code according to your comments and split it into separate commits. The following remains for the following PRs:
- Extract JSON and raw reader logic into separate function. This requires a lot of changes because of statically allocated data in the
mainfunction. It would be easier to navigate in diff in separate PR. - Change CLI behaviour (from the table in previous messages). It makes sense to do this together with the previous task.
I propose to leave these improvements for the separate PR.
I've updated the code according to your comments and split it into separate commits. The following remains for the following PRs:
- Extract JSON and raw reader logic into separate function. This requires a lot of changes because of statically allocated data in the
mainfunction. It would be easier to navigate in diff in separate PR.- Change CLI behaviour (from the table in previous messages). It makes sense to do this together with the previous task.
I propose to leave these improvements for the separate PR.
I agree that those changes can go in separate PRs.
Since there're a lot of indentation problems, maybe it would be better to add a formatting rules for clang-format or indent.
This is a clang-format file I use for my projects and It's close to the format of the project (drop the .txt extension):
.clang-format.txt
Since there're a lot of indentation problems, maybe it would be better to add a formatting rules for clang-format or indent
As far as I'm aware, clang-format doesn't support the concept of 'tabs for indent, spaces for alignment', and I wouldn't like to use any less. If you know how to teach it that, please tell.
I will look into indent's capabilities.
clang-format doesn't support the concept of 'tabs for indent, spaces for alignment'
I think it is using it: fru.c.txt
