#include <stdlib.h>
#include <string.h>
#define ldmilib_c /* Define the library */
/* Include the Lua API header files */
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "dmi/dmi.h"
static void add_string_item(lua_State *L, const char *item, const char *value_str) {
lua_pushstring(L,item);
lua_pushstring(L,value_str);
lua_settable(L,-3);
}
static void add_int_item(lua_State *L, const char *item, int value_int) {
lua_pushstring(L,item);
lua_pushnumber(L,value_int);
lua_settable(L,-3);
}
typedef int (*table_fn)(lua_State*, s_dmi*);
/* Add a Lua_String entry to the table on stack
xxx_P is the poiter version (i.e., pBase is a pointer)
xxx_S is the staic version (i.e., Base is the struct)
*/
#define LUA_ADD_STR_P(pLua_state, pBase, Field) \
add_string_item(pLua_state, #Field, pBase->Field);
#define LUA_ADD_STR_S(pLua_state, Base, Field) \
add_string_item(pLua_state, #Field, Base.Field);
/* Add a Lua_Number entry to the table on stack
xxx_P is the poiter version (i.e., pBase is a pointer)
xxx_S is the staic version (i.e., Base is the struct)
*/
#define LUA_ADD_NUM_P(pLua_state, pBase, Field) \
add_int_item(pLua_state, #Field, pBase->Field);
#define LUA_ADD_NUM_S(pLua_state, Base, Field) \
add_int_item(pLua_state, #Field, Base.Field);
/* Add a sub-DMI table to the table on stack
All (*table_fn)() have to be named as get_<tabel_name>_table() for this
macro to work. For example, for the bios subtable, the table_fn is
get_bios_table() and the subtable name is "bios".
All (*table_fn)() have to return 1 if a subtable is created on the stack
or 0 if the subtable is not created (no corresponding dim subtable found).
*/
#define LUA_ADD_TABLE(pLua_state, pDmi, tb_name) \
add_dmi_sub_table(pLua_state, pDmi, #tb_name, get_ ## tb_name ## _table);
static void add_dmi_sub_table(lua_State *L, s_dmi *dmi_ptr, char *table_name,
table_fn get_table_fn)
{
if (get_table_fn(L, dmi_ptr)) { /* only adding it when it is there */
lua_pushstring(L, table_name);
lua_insert(L, -2);
lua_settable(L,-3);
}
}
void get_bool_table(lua_State *L, const char *str_table[], int n_elem,
bool *bool_table)
{
int i;
for (i = 0; i < n_elem; i++) {
if (!str_table[i] || !*str_table[i]) /* aviod NULL/empty string */
continue;
lua_pushstring(L, str_table[i]);
lua_pushboolean(L, bool_table[i]);
lua_settable(L,-3);
}
}
/*
** {======================================================
** DMI subtables
** =======================================================
*/
static int get_bios_table(lua_State *L, s_dmi *dmi_ptr)
{
s_bios *bios = &dmi_ptr->bios;
if (!bios->filled)
return 0;
/* bios */
lua_newtable(L);
LUA_ADD_STR_P(L, bios, vendor)
LUA_ADD_STR_P(L, bios, version)
LUA_ADD_STR_P(L, bios, release_date)
LUA_ADD_STR_P(L, bios, bios_revision)
LUA_ADD_STR_P(L, bios, firmware_revision)
LUA_ADD_NUM_P(L, bios, address)
LUA_ADD_NUM_P(L, bios, runtime_size)
LUA_ADD_STR_P(L, bios, runtime_size_unit)
LUA_ADD_NUM_P(L, bios, rom_size)
LUA_ADD_STR_P(L, bios, rom_size_unit)
/* bios characteristics */
lua_pushstring(L, "chars");
lua_newtable(L);
get_bool_table(L, bios_charac_strings,
sizeof(s_characteristics)/sizeof(bool),
(bool *)(&bios->characteristics));
get_bool_table(L, bios_charac_x1_strings,
sizeof(s_characteristics_x1)/sizeof(bool),
(bool *)(&bios->characteristics_x1));
get_bool_table(L, bios_charac_x2_strings,
sizeof(s_characteristics_x2)/sizeof(bool),
(bool *)(&bios->characteristics_x2));
lua_settable(L,-3);
return 1;
}
static int get_system_table(lua_State *L, s_dmi *dmi_ptr)
{
s_system *system = &dmi_ptr->system;
if (!system->filled)
return 0;
/* system */
lua_newtable(L);
LUA_ADD_STR_P(L, system, manufacturer)
LUA_ADD_STR_P(L, system, product_name)
LUA_ADD_STR_P(L, system, version)
LUA_ADD_STR_P(L, system, serial)
LUA_ADD_STR_P(L, system, uuid)
LUA_ADD_STR_P(L, system, wakeup_type)
LUA_ADD_STR_P(L, system, sku_number)
LUA_ADD_STR_P(L, system, family)
LUA_ADD_STR_P(L, system, system_boot_status)
LUA_ADD_STR_P(L, system, configuration_options)
/* system reset */
if (system->system_reset.filled) {
lua_pushstring(L, "reset");
lua_newtable(L);
LUA_ADD_NUM_S(L, system->system_reset, status)
LUA_ADD_NUM_S(L, system->system_reset, watchdog)
LUA_ADD_STR_S(L, system->system_reset, boot_option)
LUA_ADD_STR_S(L, system->system_reset, boot_option_on_limit)
LUA_ADD_STR_S(L, system->system_reset, reset_count)
LUA_ADD_STR_S(L, system->system_reset, reset_limit)
LUA_ADD_STR_S(L, system->system_reset, timer_interval)
LUA_ADD_STR_S(L, system->system_reset, timeout)
lua_settable(L,-3);
}
return 1;
}
static int get_base_board_table(lua_State *L, s_dmi *dmi_ptr)
{
s_base_board *base_board = &dmi_ptr->base_board;
int n_dev = sizeof(base_board->devices_information) /
sizeof(base_board->devices_information[0]);
int i, j, has_dev;
if (!base_board->filled)
return 0;
/* base_board */
lua_newtable(L);
LUA_ADD_STR_P(L, base_board, manufacturer)
LUA_ADD_STR_P(L, base_board, product_name)
LUA_ADD_STR_P(L, base_board, version)
LUA_ADD_STR_P(L, base_board, serial)
LUA_ADD_STR_P(L, base_board, asset_tag)
LUA_ADD_STR_P(L, base_board, location)
LUA_ADD_STR_P(L, base_board, type)
/* base board features */
lua_pushstring(L, "features");
lua_newtable(L);
get_bool_table(L, base_board_features_strings,
sizeof(s_base_board_features)/sizeof(bool),
(bool *)(&base_board->features));
lua_settable(L,-3);
/* on-board devices */
for (has_dev = 0, i = 0; i < n_dev; i++)
if (*base_board->devices_information[i].type)
has_dev++;
if (has_dev) {
lua_pushstring(L, "devices");
lua_newtable(L);
for (i = 0, j = 1; i < n_dev; i++) {
if (!*base_board->devices_information[i].type) /* empty device */
continue;
lua_pushinteger(L, j++);
lua_newtable(L);
LUA_ADD_STR_S(L, base_board->devices_information[i], type)
LUA_ADD_STR_S(L, base_board->devices_information[i], description)
LUA_ADD_NUM_S(L, base_board->devices_information[i], status)
lua_settable(L,-3);
}
lua_settable(L,-3);
}
return 1;
}
static int get_chassis_table(lua_State *L, s_dmi *dmi_ptr)
{
s_chassis *chassis = &dmi_ptr->chassis;
if (!chassis->filled)
return 0;
/* chassis */
lua_newtable(L);
LUA_ADD_STR_P(L, chassis, manufacturer)
LUA_ADD_STR_P(L, chassis, type)
LUA_ADD_STR_P(L, chassis, lock)
LUA_ADD_STR_P(L, chassis, version)
LUA_ADD_STR_P(L, chassis, serial)
LUA_ADD_STR_P(L, chassis, asset_tag)
LUA_ADD_STR_P(L, chassis, boot_up_state)
LUA_ADD_STR_P(L, chassis, power_supply_state)
LUA_ADD_STR_P(L, chassis, thermal_state)
LUA_ADD_STR_P(L, chassis, security_status)
LUA_ADD_STR_P(L, chassis, oem_information)
LUA_ADD_NUM_P(L, chassis, height)
LUA_ADD_NUM_P(L, chassis, nb_power_cords)
return 1;
}
static int get_processor_table(lua_State *L, s_dmi *dmi_ptr)
{
s_processor *processor = &dmi_ptr->processor;
s_signature *signature = &processor->signature;
if (!processor->filled)
return 0;
/* processor */
lua_newtable(L);
LUA_ADD_STR_P(L, processor, socket_designation)
LUA_ADD_STR_P(L, processor, type)
LUA_ADD_STR_P(L, processor, family)
LUA_ADD_STR_P(L, processor, manufacturer)
LUA_ADD_STR_P(L, processor, version)
LUA_ADD_NUM_P(L, processor, external_clock)
LUA_ADD_NUM_P(L, processor, max_speed)
LUA_ADD_NUM_P(L, processor, current_speed)
LUA_ADD_NUM_P(L, processor, voltage_mv)
LUA_ADD_STR_P(L, processor, status)
LUA_ADD_STR_P(L, processor, upgrade)
LUA_ADD_STR_P(L, processor, cache1)
LUA_ADD_STR_P(L, processor, cache2)
LUA_ADD_STR_P(L, processor, cache3)
LUA_ADD_STR_P(L, processor, serial)
LUA_ADD_STR_P(L, processor, part_number)
LUA_ADD_STR_P(L, processor, id)
LUA_ADD_NUM_P(L, processor, core_count)
LUA_ADD_NUM_P(L, processor, core_enabled)
LUA_ADD_NUM_P(L, processor, thread_count)
/* processor signature */
lua_pushstring(L, "signature");
lua_newtable(L);
LUA_ADD_NUM_P(L, signature, type)
LUA_ADD_NUM_P(L, signature, family)
LUA_ADD_NUM_P(L, signature, model)
LUA_ADD_NUM_P(L, signature, stepping)
LUA_ADD_NUM_P(L, signature, minor_stepping)
lua_settable(L,-3);
/* processor flags */
lua_pushstring(L, "flags");
lua_newtable(L);
get_bool_table(L, cpu_flags_strings,
sizeof(s_dmi_cpu_flags)/sizeof(bool),
(bool *)(&processor->cpu_flags));
lua_settable(L,-3);
return 1;
}
static int get_battery_table(lua_State *L, s_dmi *dmi_ptr)
{
s_battery *battery = &dmi_ptr->battery;
if (!battery->filled)
return 0;
/* battery */
lua_newtable(L);
LUA_ADD_STR_P(L, battery, location)
LUA_ADD_STR_P(L, battery, manufacturer)
LUA_ADD_STR_P(L, battery, manufacture_date)
LUA_ADD_STR_P(L, battery, serial)
LUA_ADD_STR_P(L, battery, name)
LUA_ADD_STR_P(L, battery, chemistry)
LUA_ADD_STR_P(L, battery, design_capacity)
LUA_ADD_STR_P(L, battery, design_voltage)
LUA_ADD_STR_P(L, battery, sbds)
LUA_ADD_STR_P(L, battery, sbds_serial)
LUA_ADD_STR_P(L, battery, maximum_error)
LUA_ADD_STR_P(L, battery, sbds_manufacture_date)
LUA_ADD_STR_P(L, battery, sbds_chemistry)
LUA_ADD_STR_P(L, battery, oem_info)
return 1;
}
static int get_memory_table(lua_State *L, s_dmi *dmi_ptr)
{
s_memory *memory = dmi_ptr->memory;
int i, j, n_mem = dmi_ptr->memory_count;
if (n_mem <= 0) /* no memory info */
return 0;
/* memory */
lua_newtable(L);
for (j = 1, i = 0; i < n_mem; i++) {
if (!memory[i].filled)
continue;
lua_pushinteger(L, j++);
lua_newtable(L);
LUA_ADD_STR_S(L, memory[i], manufacturer)
LUA_ADD_STR_S(L, memory[i], error)
LUA_ADD_STR_S(L, memory[i], total_width)
LUA_ADD_STR_S(L, memory[i], data_width)
LUA_ADD_STR_S(L, memory[i], size)
LUA_ADD_STR_S(L, memory[i], form_factor)
LUA_ADD_STR_S(L, memory[i], device_set)
LUA_ADD_STR_S(L, memory[i], device_locator)
LUA_ADD_STR_S(L, memory[i], bank_locator)
LUA_ADD_STR_S(L, memory[i], type)
LUA_ADD_STR_S(L, memory[i], type_detail)
LUA_ADD_STR_S(L, memory[i], speed)
LUA_ADD_STR_S(L, memory[i], serial)
LUA_ADD_STR_S(L, memory[i], asset_tag)
LUA_ADD_STR_S(L, memory[i], part_number)
lua_settable(L,-3);
}
return 1;
}
static int get_memory_module_table(lua_State *L, s_dmi *dmi_ptr)
{
s_memory_module *memory_module = dmi_ptr->memory_module;
int i, j, n_mem = dmi_ptr->memory_module_count;
if (n_mem <= 0) /* no memory module info */
return 0;
/* memory module */
lua_newtable(L);
for (j = 1, i = 0; i < n_mem; i++) {
if (!memory_module[i].filled)
continue;
lua_pushinteger(L, j++);
lua_newtable(L);
LUA_ADD_STR_S(L, memory_module[i], socket_designation)
LUA_ADD_STR_S(L, memory_module[i], bank_connections)
LUA_ADD_STR_S(L, memory_module[i], speed)
LUA_ADD_STR_S(L, memory_module[i], type)
LUA_ADD_STR_S(L, memory_module[i], installed_size)
LUA_ADD_STR_S(L, memory_module[i], enabled_size)
LUA_ADD_STR_S(L, memory_module[i], error_status)
lua_settable(L,-3);
}
return 1;
}
static int get_cache_table(lua_State *L, s_dmi *dmi_ptr)
{
s_cache *cache = dmi_ptr->cache;
int i, n_cache = dmi_ptr->cache_count;
if (n_cache <= 0) /* no cache info */
return 0;
/* memory */
lua_newtable(L);
for (i = 0; i < n_cache; i++) {
lua_pushinteger(L, i + 1);
lua_newtable(L);
LUA_ADD_STR_S(L, cache[i], socket_designation)
LUA_ADD_STR_S(L, cache[i], configuration)
LUA_ADD_STR_S(L, cache[i], mode)
LUA_ADD_STR_S(L, cache[i], location)
LUA_ADD_NUM_S(L, cache[i], installed_size)
LUA_ADD_NUM_S(L, cache[i], max_size)
LUA_ADD_STR_S(L, cache[i], supported_sram_types)
LUA_ADD_STR_S(L, cache[i], installed_sram_types)
LUA_ADD_NUM_S(L, cache[i], speed)
LUA_ADD_STR_S(L, cache[i], error_correction_type)
LUA_ADD_STR_S(L, cache[i], system_type)
LUA_ADD_STR_S(L, cache[i], associativity)
lua_settable(L,-3);
}
return 1;
}
static int get_hardware_security_table(lua_State *L, s_dmi *dmi_ptr)
{
if (!dmi_ptr->hardware_security.filled)
return 0;
/* hardware_security */
lua_newtable(L);
LUA_ADD_STR_S(L, dmi_ptr->hardware_security, power_on_passwd_status)
LUA_ADD_STR_S(L, dmi_ptr->hardware_security, keyboard_passwd_status)
LUA_ADD_STR_S(L, dmi_ptr->hardware_security, administrator_passwd_status)
LUA_ADD_STR_S(L, dmi_ptr->hardware_security, front_panel_reset_status)
return 1;
}
static int get_dmi_info_table(lua_State *L, s_dmi *dmi_ptr)
{
dmi_table *dmitable = &dmi_ptr->dmitable;
/* dmi info */
lua_newtable(L);
LUA_ADD_NUM_P(L, dmitable, num)
LUA_ADD_NUM_P(L, dmitable, len)
LUA_ADD_NUM_P(L, dmitable, ver)
LUA_ADD_NUM_P(L, dmitable, base)
LUA_ADD_NUM_P(L, dmitable, major_version)
LUA_ADD_NUM_P(L, dmitable, minor_version)
return 1;
}
static int get_ipmi_table(lua_State *L, s_dmi *dmi_ptr)
{
s_ipmi *ipmi = &dmi_ptr->ipmi;
if (!ipmi->filled)
return 0;
/* ipmi */
lua_newtable(L);
LUA_ADD_STR_P(L, ipmi, interface_type)
LUA_ADD_NUM_P(L, ipmi, major_specification_version)
LUA_ADD_NUM_P(L, ipmi, minor_specification_version)
LUA_ADD_NUM_P(L, ipmi, I2C_slave_address)
LUA_ADD_NUM_P(L, ipmi, nv_address)
LUA_ADD_NUM_P(L, ipmi, base_address)
LUA_ADD_NUM_P(L, ipmi, irq)
return 1;
}
/*
** {======================================================
** End of DMI subtables
** =======================================================
*/
static int dmi_gettable(lua_State *L)
{
s_dmi dmi;
lua_newtable(L);
if ( ! dmi_iterate(&dmi) ) {
printf("No DMI Structure found\n");
return -1;
}
parse_dmitable(&dmi);
LUA_ADD_NUM_S(L, dmi, memory_module_count)
LUA_ADD_NUM_S(L, dmi, memory_count)
LUA_ADD_NUM_S(L, dmi, cache_count)
LUA_ADD_STR_S(L, dmi, oem_strings)
LUA_ADD_TABLE(L, &dmi, bios)
LUA_ADD_TABLE(L, &dmi, system)
LUA_ADD_TABLE(L, &dmi, base_board)
LUA_ADD_TABLE(L, &dmi, chassis)
LUA_ADD_TABLE(L, &dmi, processor)
LUA_ADD_TABLE(L, &dmi, battery)
LUA_ADD_TABLE(L, &dmi, memory)
LUA_ADD_TABLE(L, &dmi, memory_module)
LUA_ADD_TABLE(L, &dmi, cache)
LUA_ADD_TABLE(L, &dmi, ipmi)
LUA_ADD_TABLE(L, &dmi, hardware_security)
LUA_ADD_TABLE(L, &dmi, dmi_info)
/* set global variable: lua_setglobal(L, "dmitable"); */
/* return number of return values on stack */
return 1;
}
static int dmi_supported(lua_State *L)
{
s_dmi dmi;
if ( dmi_iterate(&dmi) ) {
lua_pushboolean(L, 1);
} else {
lua_pushboolean(L, 0);
}
return 1;
}
static const luaL_Reg dmilib[] = {
{"gettable", dmi_gettable},
{"supported", dmi_supported},
{NULL, NULL}
};
LUALIB_API int luaopen_dmi (lua_State *L) {
luaL_newlib(L, dmilib);
return 1;
}