Loading...
Searching...
No Matches
Common

Common definitions for the library. More...

## Data Structures

struct | fru_errno_t
struct | fru_t
| Exploded/decoded FRU data structure. More...

## Macros

#define | LIBFRU_MAJOR
| Major component of the library version.
#define | LIBFRU_MINOR
| Minor component of the library version.
#define | LIBFRU_SUBMINOR
| Subminor component of the library version.
#define | LIBFRU_VERSION
| Integer representation of the library version.
#define | FRU_IS_VALID_AREA(atype)
| Check if atype is any valid area type.
#define | FRU_FOREACH_AREA(it)
| Iterate through all area types using it as an iterator.
#define | FRU_ATYPE_HAS_TYPE(atype)
| Check if the area has a 'type' field.
#define | FRU_ATYPE_HAS_LANG(atype)
| Check if the area has a 'lang' field.
#define | FRU_LIST_HEAD
| Add entry at the head of the list, used by fru_add_mr() and alike.
#define | FRU_LIST_TAIL
| Add entry at the end of the list, used by fru_add_mr() and alike.
#define | FRU_IS_APOS_VALID(pos)
#define | fru_free(fru)
| Deallocate a dynamically allocated fru structure.

## Enumerations

enum

fru_error_code_t {
FENONE ,
FEGENERIC ,
FEINIT ,
FENONPRINT ,
FENONHEX ,
FERANGE ,
FENOTEVEN ,
FEAUTOENC ,
FEBADENC ,
FE2SMALL ,
FE2BIG ,
FESIZE ,
FEHDRVER ,
FEHDRCKSUM ,
FEHDRBADPTR ,
FEDATACKSUM ,
FEAREADUP ,
FEAREANOTSUP ,
FEAREABADTYPE ,
FENOTERM ,
FEBDATE ,
FENOFIELD ,
FENOREC ,
FEBADDATA ,
FENODATA ,
FEMRMGMTBAD ,
FEMRNOTSUP ,
FEMREND ,
FEAPOS ,
FENOTEMPTY ,
FEAENABLED ,
FEADISABLED ,
FELIB ,
FETOTALCOUNT
}

| Defines the errors specific to libfru. More...
enum | fru_error_source_t { FERR_LOC_INTERNAL , FERR_LOC_CHASSIS , FERR_LOC_BOARD , FERR_LOC_PRODUCT , FERR_LOC_MR , FERR_LOC_GENERAL , FERR_LOC_CALLER , FERR_LOC_SYSTEM , FERR_LOC_COUNT }
| Describes an offending area, see fru_errno_t. More...
enum | fru_area_type_t { FRU_INTERNAL_USE , FRU_MIN_AREA , FRU_CHASSIS_INFO , FRU_BOARD_INFO , FRU_PRODUCT_INFO , FRU_MR , FRU_MAX_AREA , FRU_TOTAL_AREAS }
| FRU area types. More...
enum | fru_flags_t { FRU_NOFLAGS , FRU_IGNFVER , FRU_IGNFHCKSUM , FRU_IGNFDCKSUM , FRU_IGNAVER , FRU_IGNRVER , FRU_IGNACKSUM , FRU_IGNRHCKSUM , FRU_IGNRDCKSUM , FRU_IGNRNOEOL , FRU_IGNBIG , FRU_IGNAEOF , FRU_IGNMRVER , FRU_IGNMRDATALEN }
| Debug flags to FRU decoding functions. More...
enum | fru_area_position_t { FRU_APOS_LAST , FRU_APOS_FIRST , FRU_APOS_AUTO , FRU_AFTER_INTERNAL , FRU_APOS_MIN , FRU_AFTER_CHASSIS , FRU_AFTER_BOARD , FRU_AFTER_PRODUCT , FRU_AFTER_MR , FRU_APOS_MAX }
| Define FRU area position in the binary file. More...

## Functions

const char * | fru_strerr (fru_errno_t)
| Get a description of the given `fru_errno` value.
void | fru_clearerr (void)
| Clear the error status of the library.
fru_t * | fru_init (fru_t *fru)
| Initialize/allocate a fru structure.
fru_t * | fru_loadfile (fru_t *fru, const char *filename, fru_flags_t flags)
| Load FRU information from a binary file.
fru_t * | fru_loadbuffer (fru_t *fru, const void *buf, size_t size, fru_flags_t flags)
| Load FRU information from a binary file.
void | fru_wipe (fru_t *fru)
| Wipe the contents of a fru_t structure.
bool | fru_enable_area (fru_t *fru, fru_area_type_t area, fru_area_position_t after)
| Enable a previously disabled / non-present area.
bool | fru_disable_area (fru_t *fru, fru_area_type_t atype)
| Disable a previously enabled / present area.
bool | fru_move_area (fru_t *fru, fru_area_type_t area, fru_area_position_t after)
| Move an enabled/present area.
bool | fru_savebuffer (void **bufptr, size_t *size, const fru_t *fru)
| Encode a FRU info structure into a binary buffer.
bool | fru_savefile (const char *fname, const fru_t *fru)
| Encode a FRU info structure into a binary file.

## Variables

fru_error_code_t | fru_errno_t::code
| The error code.
fru_error_source_t | fru_errno_t::src
| The source of error.
int | fru_errno_t::index
| Index of the offending entity within the source, that is, an index of a field (for FRU_*_INFO) or a record (for FRU_MR).
FRU_THREAD_LOCAL fru_errno_t | fru_errno
| Numeric code of an error.

## Detailed Description

Common definitions for the library.

Common definitions for the library

## Macro Definition Documentation

## FRU_ATYPE_HAS_LANG

#define FRU_ATYPE_HAS_LANG | ( |  | atype | ) |

Check if the area has a 'lang' field.

## FRU_ATYPE_HAS_TYPE

#define FRU_ATYPE_HAS_TYPE | ( |  | atype | ) |

Check if the area has a 'type' field.

## FRU_FOREACH_AREA

#define FRU_FOREACH_AREA | ( |  | it | ) |

Iterate through all area types using it as an iterator.

It is recommended to declare it as fru_area_type_t.

Example

const char * const area_names[FRU_TOTAL_AREAS] = {
[FRU_INTERNAL_USE] = "Internal Use",
[FRU_CHASSIS_INFO] = "Chassis",
[FRU_BOARD_INFO] = "Board",
[FRU_PRODUCT_INFO] = "Product",
[FRU_MR] = "Multirecord"
};
fru_area_type_t atype;
FRU_FOREACH_AREA(atype) {
if (fru->present[atype]) {
printf("%s %sArea is present\n",
area_names[atype],
FRU_IS_INFO_AREA(atype) ? "Information " : "");
}
}
fru_area_type_t
fru_area_type_t
FRU area types.
Definition fru.h:519
FRU_FOREACH_AREA
#define FRU_FOREACH_AREA(it)
Iterate through all area types using it as an iterator.
Definition fru.h:556
FRU_BOARD_INFO
@ FRU_BOARD_INFO
Board information area.
Definition fru.h:523
FRU_INTERNAL_USE
@ FRU_INTERNAL_USE
Internal use area.
Definition fru.h:520
FRU_MR
@ FRU_MR
Multirecord area.
Definition fru.h:525
FRU_TOTAL_AREAS
@ FRU_TOTAL_AREAS
Maximum total count of areas in a FRU file.
Definition fru.h:527
FRU_PRODUCT_INFO
@ FRU_PRODUCT_INFO
Product information area.
Definition fru.h:524
FRU_CHASSIS_INFO
@ FRU_CHASSIS_INFO
Chassis information area.
Definition fru.h:522
FRU_IS_INFO_AREA
#define FRU_IS_INFO_AREA(atype)
Check if atype is an information area type.
Definition fru.h:150

## fru_free

#define fru_free | ( |  | fru | ) |

Deallocate a dynamically allocated fru structure.

Same as fru_wipe(), but also deallocates the fru structure itself. Use on dynamically allocated structures only.

Sets fru to NULL upon successful deletion.

Parameters

  [in] | fru | Pointer to the decoded FRU information structure to delete

## FRU_IS_APOS_VALID

#define FRU_IS_APOS_VALID | ( |  | pos | ) |

## FRU_IS_VALID_AREA

#define FRU_IS_VALID_AREA | ( |  | atype | ) |

Check if atype is any valid area type.

## FRU_LIST_HEAD

#define FRU_LIST_HEAD

Add entry at the head of the list, used by fru_add_mr() and alike.

## FRU_LIST_TAIL

#define FRU_LIST_TAIL

Add entry at the end of the list, used by fru_add_mr() and alike.

## LIBFRU_MAJOR

#define LIBFRU_MAJOR

Major component of the library version.

## LIBFRU_MINOR

#define LIBFRU_MINOR

Minor component of the library version.

## LIBFRU_SUBMINOR

#define LIBFRU_SUBMINOR

Subminor component of the library version.

## LIBFRU_VERSION

#define LIBFRU_VERSION

Integer representation of the library version.

You may use this as a feature test macro, e.g.:

#if (LIBFRU_VERSION >= 0x020000) // Library is at least version 3.0.0
// Do something
#endif

## Enumeration Type Documentation

## fru_area_position_t

enum fru_area_position_t

Define FRU area position in the binary file.

Use with fru_enable_area() and fru_move_area().

The order and meaning of non-negative values matches that of fru_area_type_t and follows the FRU specification. It is always safe to compare variables of the two types as well as type cast one to another if the value of fru_area_position_t is non-negative.

Enumerator
FRU_APOS_LAST | Put an area last in the order.
FRU_APOS_FIRST | Put an area first in the order.
FRU_APOS_AUTO | Position an area automatically as per the default order given in FRU Spec.
FRU_AFTER_INTERNAL | Put an area after Internal Use Area.
FRU_APOS_MIN | Minimum 'real' position.
FRU_AFTER_CHASSIS | Put an area after Chassis Info Area.
FRU_AFTER_BOARD | Put an area after Board Info Area.
FRU_AFTER_PRODUCT | Put an area after Product Info Area.
FRU_AFTER_MR | Put an area after Multirecord Area.
FRU_APOS_MAX | Maximum 'real' position.

## fru_area_type_t

enum fru_area_type_t

FRU area types.

Also area indices inside the FRU information structure header

Enumerator
FRU_INTERNAL_USE | Internal use area.
FRU_MIN_AREA | Minimum area type (equals FRU_INTERNAL_USE).
FRU_CHASSIS_INFO | Chassis information area.
FRU_BOARD_INFO | Board information area.
FRU_PRODUCT_INFO | Product information area.
FRU_MR | Multirecord area.
FRU_MAX_AREA | Maximum area type (equals FRU_MR).
FRU_TOTAL_AREAS | Maximum total count of areas in a FRU file.

## fru_error_code_t

enum fru_error_code_t

Defines the errors specific to libfru.

These values are applicable to fru_errno.code

Enumerator
FENONE | No libfru error.
FEGENERIC | Generic error, check errno.
FEINIT | Uninitialized FRU structure.
FENONPRINT | Field data contains non-printable bytes.
FENONHEX | Input string contains non-hex characters.
FERANGE | Field data exceeds range for the requested encoding.
FENOTEVEN | Not an even number of nibbles.
FEAUTOENC | Unable to auto-detect encoding.
FEBADENC | Invalid encoding for a field.
FE2SMALL | File is too small.
FE2BIG | Data or file is too big.
FESIZE | Data size mismatch.
FEHDRVER | Bad header version.
FEHDRCKSUM | Bad header checksum.
FEHDRBADPTR | Area starts/spans beyond the end of file/buffer or overlaps next area.
FEDATACKSUM | Bad data checksum.
FEAREADUP | Duplicate area in area order.
FEAREANOTSUP | Unsupported area type (For a particular operation).
FEAREABADTYPE | Bad area type (A completely wrong value).
FENOTERM | Unterminated area.
FEBDATE | Board manufacturing date is out of range.
FENOFIELD | No such field.
FENOREC | No such record.
FEBADDATA | Malformed data.
FENODATA | No data.
FEMRMGMTBAD | Bad management record subtype.
FEMRNOTSUP | Unsupported record type.
FEMREND | End of MR records (not an error).
FEAPOS | Invalid area position.
FENOTEMPTY | List is not empty.
FEAENABLED | Area is (already) enabled.
FEADISABLED | Area is (already) disabled.
FELIB | Internal library error (bug).
FETOTALCOUNT | The total count of possible libfru error codes.

## fru_error_source_t

enum fru_error_source_t

Describes an offending area, see fru_errno_t.

For area-related values this enum matches fru_area_type_t

Enumerator
FERR_LOC_INTERNAL | The error is in the internal use area.
FERR_LOC_CHASSIS | The error is in the chassis information area.
FERR_LOC_BOARD | The error is in the board information area.
FERR_LOC_PRODUCT | The error is in the product information area.
FERR_LOC_MR | The error is in the multirecord area.
FERR_LOC_GENERAL | The error is about FRU file or structure in general, not about any specific area. This is also used when a non-area specific call, such as fru_setfield(), encounters an error.
FERR_LOC_CALLER | The error is in the calling code (bad arguments?).
FERR_LOC_SYSTEM | The error occurred in a system call.
FERR_LOC_COUNT | The total count of possible error locations.

## fru_flags_t

enum fru_flags_t

Debug flags to FRU decoding functions.

Sometimes some vendors make errors in their FRU info files. These flags are needed to ignore those possible errors and load as much information as possible. Without these flags, the fru_loadfile() and fru_loadbuffer() will fail immediately upon detection of an error in the input.

Enumerator
FRU_NOFLAGS | No flags, operate normally.
FRU_IGNFVER | Ignore FRU version in FRU header.
FRU_IGNFHCKSUM | Ignore FRU header checksum.
FRU_IGNFDCKSUM | Ignore FRU data checksum.
FRU_IGNAVER | Ignore area version.
FRU_IGNRVER | Ignore record version for multirecord area.
FRU_IGNACKSUM | Ignore area checksum.
FRU_IGNRHCKSUM | Ignore record header checksum for multirecord area.
FRU_IGNRDCKSUM | Ignore record data checksum for multirecord area.
FRU_IGNRNOEOL | Ignore absence of EOL-flagged MR area record, use any previous valid records.
FRU_IGNBIG | Don't fail on binary file load if the file is bigger than 64K, attempt to load it anyway (may be dangerous).
FRU_IGNAEOF | Ignore no end-of-fields marker in info areas.
FRU_IGNMRVER | Ignore invalid MR record version where possible.
FRU_IGNMRDATALEN | Ignore invalid MR record data length where possible.

## Function Documentation

## fru_clearerr()

void fru_clearerr | ( | void |  | ) |

Clear the error status of the library.

Use this before library calls that may set fru_errno without returning an error status to ensure that the value of fru_errno that you get has indeed been set by the function you've called.

## fru_disable_area()

bool fru_disable_area | ( | fru_t * | fru,
|  | fru_area_type_t | atype )

Disable a previously enabled / present area.

Marks the requested area type as non-present and resets its order relative to other areas. Disabled areas will not be saved by fru_savefile() or fru_savebuffer().

Note
  This function does NOT delete any area data, it just marks it disabled. You may then re-enable it back using fru_enable_area(), and all the data will stay in place.

Parameters

  [in,out] | fru | A pointer to the FRU structure to modify
  [in] | atype | The area type to disable

Returns
  A success status

Return values

  true | Success, will also set fru_errno.code to FEADISABLED if the area was already disabled before the call
  false | Error, see fru_errno for details

## fru_enable_area()

bool fru_enable_area | ( | fru_t * | fru,
|  | fru_area_type_t | area,
|  | fru_area_position_t | after )

Enable a previously disabled / non-present area.

Marks the requested area type as present and sets up its order relative to other areas as requested. Can either position the area automatically if after is FRU_APOS_AUTO, or put it at the requested position. See fru_area_position_t for the values of after.

If the area specified by after is not enabled, then the function will behave as if after was FRU_APOS_AUTO.

When after is FRU_APOS_AUTO, the area will be put:

- At the head of the list if area is FRU_INTERNAL_USE, or
- After the area immediately preceding area in the IPMI FRU Specification, if such an area is enabled, or
- After the area of the highest order that is less than that of area according to IPMI FRU Specification

Thus, if you always use FRU_APOS_AUTO, all areas will be then saved in the the natural order of their respective offset locations in the FRU header, as per the specification. That is:

1. Internal Use Area
2. Chassis Info Area
3. Board Info Area
4. Product Info Area
5. Multirecord Area

It is advised that you first enable areas that you want to be in the natural order, then enable the areas that you want to go after some other specific areas, and finally enable the ones that you want to go first or last.

Otherwise, if you, for example, first enable FRU_BOARD_INFO to go after FRU_PRODUCT_INFO, and then enable FRU_MR with FRU_APOS_AUTO, then MR area will be placed between the product and board areas, which may be contrary to what you intended.

Alternatively, you may set the order manually by modifying fru->order array, but be careful there.

Note
  The function will fail if the area is already enabled. Use fru_move_area() if you want to move an enabled area to a new position.

Parameters

  [in,out] | fru | A pointer to the FRU structure to modify
  [in] | area | The area type to enable
  [in] | after | An area position where to put the enabled area, or FRU_APOS_AUTO for automatic placement. Specify FRU_APOS_FIRST to make the enableed area first or FRU_APOS_LAST to make it last. Use any of FRU_AFTER_* to select a relative position.

Returns
  A success status

Return values

  true | Success
  false | Error, see fru_errno for details

## fru_init()

fru_t * fru_init | ( | fru_t * | fru | ) |

Initialize/allocate a fru structure.

Initializes a statically allocated fru structure for later modification and saving with fru_savebuffer() or fru_savefile().

If a fru is `NULL`, then a new FRU structure is allocated, otherwise the supplied one will be initialized. Any previously existing values or pointers will be reset, so make sure to never call this function on a previously loaded or otherwise actively used fru structure as that may result in memory leakage.

In the initialized structure:

- All mandatory fields in all areas are set to empty strings;
- All custom field list pointers are set to NULL (empty lists);
- Board manufacturing date is set to current date;
- Chassis type is set to 'Rack mount' (0x17);
- Area order is set to default:
  1. Internal Use Area
  2. Chassis Information Area
  3. Board Information Area
  4. Product Information Area
  5. Multirecord Area
- All areas are marked non-present.

Parameters

  [in,out] | fru | Pointer to an initial FRU structure (can be `NULL`)

Returns
  A pointer to the initialized fru_t structure.

Return values

  NULL | Error detected, fru_errno is set accordingly.

## fru_loadbuffer()

fru_t * fru_loadbuffer | ( | fru_t * | fru,
|  | const void * | buf,
|  | size_t | size,
|  | fru_flags_t | flags )

Load FRU information from a binary file.

Same as fru_loadfile(), but takes a binary buffer as input. In fact, fru_loadfile() calls this one under the hood after memory-mapping the binary FRU file.

Parameters

  [in,out] | fru | Pointer to an initial FRU structure (can be `NULL`)
  [in] | buf | Buffer containing a binary FRU information file
  [in] | size | Buffer size
  [in] | flags | Debug flags or FRU_NOFLAGS

Returns
  A pointer to the filled in fru_t structure.

Return values

  NULL | Error detected, fru_errno is set accordingly.

## fru_loadfile()

fru_t * fru_loadfile | ( | fru_t * | fru,
|  | const char * | filename,
|  | fru_flags_t | flags )

Load FRU information from a binary file.

Takes a binary FRU information file (e.g. EEPROM dump or the output of ipmitool fru read, and loads it as a fru_t structure for further modification.

If fru is `NULL`, then a new FRU structure is allocated, otherwise the supplied one will be filled in, and the existing values will be overwritten with the contents of the file. The function will fail if fru_t.internal, fru_t.mr, or any of the cust lists in the info area members of fru are non-NULL.

Supported are:

- All generic info areas (chassis, board, product), including the custom fields (decoded as hex strings of FRU_FE_BINARY encoding type)
- Internal Use area (decoded as hex string)
- Multirecord area:
  - Management Access record:
    - System Unique ID (UUID), treated as per SMBIOS definition, decoded as a big-endian hex string
    - All other MA types, as plain text strings
  - All other types of MR records as 'raw' records

Note
  On load, if there was a manufacturing date/time specified for the board information area, then fru->board.tv_auto will be set to `false`. Otherwise that option will be set to `true`.

Parameters

  [in,out] | fru | Pointer to an initial FRU structure (can be `NULL`)
  [in] | filename | Name of the file to load
  [in] | flags | flags or FRU_NOFLAGS

Returns
  A pointer to the filled in fru_t structure.

Return values

  NULL | Error detected, fru_errno is set accordingly.

## fru_move_area()

bool fru_move_area | ( | fru_t * | fru,
|  | fru_area_type_t | area,
|  | fru_area_position_t | after )

Move an enabled/present area.

Effectively performs a call to fru_disable_area() followed by a call to fru_enable_area(), but will fail on already disabled areas unlike the former.

See the description for fru_enable_area() for the info on this function's arguments and return values.

## fru_savebuffer()

bool fru_savebuffer | ( | void ** | bufptr,
|  | size_t * | size,
|  | const fru_t * | fru )

Encode a FRU info structure into a binary buffer.

If the pointer at bufptr is `NULL`, allocates a new one and saves it to bufptr. bufptr itself must NOT be `NULL`.

Always calculates the resulting size and stores it in size in the event of successful completion.

The caller is responsible for freeing the allocated buffer with free() if automatic allocation was requested.

Example:

uint8_t * buffer = NULL;
size_t bufsize = 0;
if (!fru_savebuffer(&buffer, &bufsize, fru)) {
// Handle the error using fru_errno
exit(1);
}
printf("FRU data saved as %zd bytes\n", bufsize);
// Do some buffer processing
...
// Now free the buffer
free(buffer);
buffer = NULL;
fru_savebuffer
bool fru_savebuffer(void **bufptr, size_t *size, const fru_t *fru)
Encode a FRU info structure into a binary buffer.

Parameters

  [in] | fru | The FRU information structure to encode/export
  [in,out] | bufptr | Pointer to a pointer to a buffer to save the binary FRU information file to. The target pointer is allocated if `NULL`.
  [in,out] | size | Pointer to the size of the output buffer (size is adjusted upon return to the actual size of the encoded data). The input value pointed to by size can be 0 if bufptr is `NULL`.

Returns
  Encoding status

Return values

  true | Encoded successfully, size adjusted.
  false | Failed to encode. fru_errno is set accordingly.

## fru_savefile()

bool fru_savefile | ( | const char * | fname,
|  | const fru_t * | fru )

Encode a FRU info structure into a binary file.

Creates/overwrites the specified file with the encoded FRU info data. Calls fru_savebuffer() under the hood.

Parameters

  [in] | fru | The decoded FRU information structure to encode
  [in] | fname | Name of the file to create

Returns
  Success status

Return values

  true | Encoded and written successfully.
  false | Failed to encode or write, fru_errno is set accordingly.

## fru_strerr()

const char * fru_strerr | ( | fru_errno_t |  | ) |

Get a description of the given `fru_errno` value.

Converts a numeric error represented by fru_errno into a string description of the error. If fru_errno is FEGENERIC, this function will call `strerror()` to obtain the description of the generic libc error.

Returns
  A pointer to a constant string with the description of the error

Return values

  NULL | No description found for the given value.

## fru_wipe()

void fru_wipe | ( | fru_t * | fru | ) |

Wipe the contents of a fru_t structure.

Will free any memory allocated by fru_loadfile(), fru_loadbuffer(), fru_add_mr(), and fru_add_custom() functions for the members of fru. Any deallocated members will be set to NULL.

Will zero all fields of fru, but will not free fru itself to allow for static allocation of the top-level structure. If it was dynamically allocated (e.g, by a call to fru_loadfile() with `NULL` for fru argument), then your are to explicitly call `free()` on it after calling fru_wipe().

If you're only dealing with dynamically allocated fru structures, consider using fru_free() instead.

Parameters

  [in,out] | fru | Pointer to a FRU structure to free

## Variable Documentation

## code

fru_error_code_t fru_errno_t::code

The error code.

## fru_errno

FRU_THREAD_LOCAL fru_errno_t fru_errno

extern

Numeric code of an error.

Similar to errno, this thread-local variable is modified by most functons in libfru in the event of an error.

Call fru_clearerr() before invocation of any libfru function, check for non-zero values of the code field after the invocation.

Unlike errno, this variable contains the information about not just the error, but also about the part of FRU where it was detected. If the fru_errno.code is FEGENERIC, then you need to check errno for the actual error.

Please also see fru_strerr()

## index

int fru_errno_t::index

Index of the offending entity within the source, that is, an index of a field (for FRU_*_INFO) or a record (for FRU_MR).

This is (-1) when not applicable. That is, the area indicated by src doesn't have any fields/records, or the error is in the area as a whole, not in some particular field/record, or the error is not in a FRU area at all (e.g., src == FERR_LOC_CALLER).

For info areas this is less than the respective FRU_*_FIELD_COUNT for the standard/mandatory fields, or is FRU_*_FIELD_COUNT + X, where X is the index of the offending custom field.

For FEAREANOTSUP and FEAREABADTYPE this field contains the bad area type (see fru_area_type_t).

## src

fru_error_source_t fru_errno_t::src

The source of error.