This file is indexed.

/usr/sbin/smbios-battery-ctl is in smbios-utils 2.4.1-1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#!/usr/bin/python3
# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:tw=0

  #############################################################################
  #
  # Copyright (c) 2016 Dell Computer Corporation
  # by Srinivas Gowda <srinivas_g_gowda@dell.com>
  # Dual Licenced under GNU GPL and OSL
  #
  #############################################################################
"""smbios-battery-ctl"""



# import arranged alphabetically
import gettext
import locale
import os
import sys

# the following vars are all substituted on install
# this bin isnt byte-compiled, so this is ok
pythondir="/usr/lib/python3/dist-packages"
clidir="/usr/share/smbios-utils"
# end vars

# import all local modules after this.
sys.path.insert(0,pythondir)
sys.path.insert(0,clidir)

import cli
from libsmbios_c import smbios_token, smbios, smi, system_info as sysinfo, localedir, GETTEXT_PACKAGE
from libsmbios_c.trace_decorator import traceLog, getLog

__VERSION__="2.4.1"

locale.setlocale(locale.LC_ALL, '')
gettext.install(GETTEXT_PACKAGE, localedir)

moduleLog = getLog()
verboseLog = getLog(prefix="verbose.")

class RunTimeBatteryErr(Exception): pass


def command_parse():
    parser = cli.OptionParser(usage=__doc__, version=__VERSION__)
    cli.addStdOptions(parser, passwordOpts=True, securityKeyOpt=True)
    parser.add_option("--battery-charge", "-c", action="store_true", default=False, help=_("This will get the Current Battery Charging State"))

    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit()
    return parser.parse_args()


def is_set(num, pos):
    mask = 1 << pos
    return True if (num & mask) else False

# Return a the byte specified by byte_pos from a double word num
def get_byte(num, byte_pos):
    try :
        if byte_pos < 0 or byte_pos > 3:
            raise RunTimeBatteryErr( "Internal Error: Byte position out of bound - ", byte_pos )
    except RunTimeBatteryErr as e:
        print("\t%s" % e)

    return ((num >> (byte_pos*8)) & 0xFF)


def print_express_charge_status(n):
    if n == 0: print('\t Battery is not present')
    elif n == 1: print('\t Standard')
    elif n == 2: print('\t Express')
    elif n == 3: print('\t One-time express')
    elif n == 0xFF: print('\t Battery is present, and it does not support express charge')
    else : print('\t Unknown')


def PrintBatteryChargingState():
    try:
        res = smi.simple_ci_smi( 4, 12, 0 )
        verboseLog.info( _(" Get Charging State : res[smi.cbRES1]=0x%X,res[smi.cbRES2]=0x%X, res[smi.cbRES3]=0x%X") %
                              (res[smi.cbRES1],res[smi.cbRES2],res[smi.cbRES3]) )

        if res[smi.cbRES1] != 0:
            raise RunTimeBatteryErr( _(" Info: Unable to read Current Battery Charging State on this system\n") )

        # cbRES2 byte 0 gives supported Features
        print(_(" \n Supported battery charging features: "))
        if is_set (res[smi.cbRES2], 0): print("\t Express Charging")
        if is_set (res[smi.cbRES2], 1): print("\t Charge Disable")
        if (get_byte(res[smi.cbRES2], 0) == 0 ): print("\t NIL")

        print(_(" \n Battery charging Status: "))
        # cbRES2 byte 1 gives the status of supported Features
        if is_set ((get_byte(res[smi.cbRES2], 1)), 0): print("\t One or more batteries are present that support Express charge")
        if is_set ((get_byte(res[smi.cbRES2], 1)), 1): print("\t Charging is disabled")
        if (get_byte(res[smi.cbRES2], 1) == 0 ): print("\t NIL")

        # cbRes3, bytes 0-3 contain the status of batteries 0-3 respectively
        for i in range(4):
            expr_status = get_byte(res[smi.cbRES3], i)
            if(expr_status):
                print(_("\n Battery %d Express Charge State:") % (i))
                print_express_charge_status(expr_status)

    except RunTimeBatteryErr as e:
        print("\t%s" % e)


def main():
    exit_code = 0
    (options, args) = command_parse()
    cli.setup_std_options(options)

    try:
        if options.battery_charge:
            print(_("Libsmbios version : %s") % sysinfo.get_library_version_string())
            print(_("smbios-battery-ctl version : %s") % __VERSION__)
            verboseLog.info( _(" You can use smbios-battery-ctl utility to view/modify battery settings"))
            PrintBatteryChargingState()

    except (smi.SMIExecutionError, ) as e:
        exit_code=3
        moduleLog.info( _("ERROR: Could not execute SMI.") )
        verboseLog.info( _("The smi library returned this error:") )
        verboseLog.info( str(e) )
        moduleLog.info( cli.standardFailMessage )

    except (smbios.TableParseError, token.TokenTableParseError) as e:
        exit_code=3
        moduleLog.info( _("ERROR: Could not parse system SMBIOS table.") )
        verboseLog.info( _("The smbios library returned this error:") )
        verboseLog.info( str(e) )
        moduleLog.info( cli.standardFailMessage )

    except (token.TokenManipulationFailure,) as e:
        exit_code=4
        moduleLog.info( _("ERROR: Could not manipulate system token.") )
        verboseLog.info( _("The token library returned this error:") )
        verboseLog.info( str(e) )
        moduleLog.info( cli.standardFailMessage )

    return exit_code

if __name__ == "__main__":
    sys.exit( main() )


# cbClass 4
# cbSelect 12
# Battery Charging
#
# cbArg1 determines the function to be performed
# On return:
# cbRES1         Standard return codes (0, -1, -2)
#
# cbArg1 0x0 = Get Current State
# cbRes2, byte 0	Supported feature bits
#	bit 0	Express charge is supported (by the BIOS)
#	bit 1	Charge disable is supported
#	bits 2-7	Reserved for future use
# cbRes2, byte 1	Status bits
#	bit 0	One or more batteries are present that support Express charge
#	bit 1	Charging is disabled
#	bits 2-7	Reserved for future use
# If the system supports Express Charge, cbRes3, bytes 0-3 contain the status of batteries 0-3 respectively (numbered as with the Class 8 function).
# cbRes3, byte n	Battery n express charge status:
#	0	Battery is not present
#	1	Standard
#	2	Express
#	3	One-time express
#	0xFF	Battery is present, and it does not support express charge
#
# cbArg2, byte 0	Set charge disable state:
#	0	Off (enable charging)
#	1	On (disable charging)
#
# cbArg2, bytes 0-3 contain the new state of batteries 0-3 respectively
# 	Battery Status:
#	00h	High
#	01h	Low
#	02h 	Critical
#	03h	Charging
#
# cbArg2, byte n Battery n state:
#	0	No change (state remains as it was previously)
#	1	Standard . Express charge not supported by the battery
#	2	Express
#	3	One-time express
#
#
# cbClass 8
# cbSelect 16
# Set Battery Desktop Mode
#
# cbArg1 determines the function to be performed
# On return:
# cbRES1         Standard return codes (0, -1, -2)
#
# cbArg1, byte 0
#	Mode Enablement
#	0		Disable desktop mode
#	1		Fully enable desktop mode
#	2 - 255	Undefined
#
# On return:
# cbRES1         Standard return codes (0, -1, -2)
#
#
# cbClass 8
# cbSelect 17
# Get Battery Desktop Mode
#
# On return:
# cbRES1         Standard return codes (0, -1, -2)
#
# cbRes2	Status
#		Bit 0		1 = Supported, 0 = Not Supported
#		Bit 1		1 = Desktop Mode, 0 = Laptop Mode
#		Bit 2		1 = Battery is ready to enter desktop mode, 0 = Not ready
#		Bit 3 to 31	Unused