python-ipmi 0.6.0__py3-none-any.whl → 0.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyipmi/__init__.py CHANGED
@@ -14,10 +14,38 @@
14
14
  # License along with this library; if not, write to the Free Software
15
15
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
+ """A pure Python IPMI library.
18
+
19
+ A connection to an IPMI device is an :class:`Ipmi` object, created by
20
+ :func:`create_connection` for an interface (see
21
+ :func:`pyipmi.interfaces.create_interface`).
22
+ The connection sends the requests to its :class:`Target`, the BMC or a
23
+ controller behind it, which is reached over the :class:`Routing` hops of
24
+ the target. The IPMI commands are the methods of :class:`Ipmi`, which
25
+ inherits them from the command groups of the modules, e.g.
26
+ :mod:`pyipmi.bmc` and :mod:`pyipmi.sdr`.
27
+
28
+ Example:
29
+ Print the device ID of a BMC over RMCP+::
30
+
31
+ import pyipmi
32
+ import pyipmi.interfaces
33
+
34
+ interface = pyipmi.interfaces.create_interface('rmcpplus')
35
+ ipmi = pyipmi.create_connection(interface)
36
+ ipmi.session.set_session_type_rmcp('10.0.0.1', port=623)
37
+ ipmi.session.set_auth_type_user('admin', 'admin')
38
+ ipmi.target = pyipmi.Target(ipmb_address=0x20)
39
+
40
+ with ipmi:
41
+ print(ipmi.get_device_id())
42
+ """
43
+
17
44
  from __future__ import annotations
18
45
 
19
46
  import time
20
47
  import ast
48
+ import warnings
21
49
  from typing import Any, Literal
22
50
 
23
51
  from . import bmc
@@ -49,6 +77,19 @@ except ImportError:
49
77
 
50
78
 
51
79
  def create_connection(interface: Any) -> Ipmi:
80
+ """Create a connection for an interface.
81
+
82
+ The connection gets a new :class:`pyipmi.session.Session` for the
83
+ interface. The target is not set, assign it to :attr:`Ipmi.target`
84
+ before sending requests.
85
+
86
+ Args:
87
+ interface: The interface, e.g. created by
88
+ :func:`pyipmi.interfaces.create_interface`.
89
+
90
+ Returns:
91
+ The connection.
92
+ """
52
93
  session = Session()
53
94
  session.interface = interface
54
95
  return Ipmi(interface=interface, session=session)
@@ -78,9 +119,17 @@ class NullRequester:
78
119
 
79
120
 
80
121
  class Routing:
81
- """The Target class represents an IPMI target."""
122
+ """One hop of the path to a target, see :meth:`Target.set_routing`."""
82
123
 
83
124
  def __init__(self, rq_sa: int, rs_sa: int, channel: int | None) -> None:
125
+ """Initialize the hop.
126
+
127
+ Args:
128
+ rq_sa: The requester slave address.
129
+ rs_sa: The responder slave address.
130
+ channel: The channel of the bridge to the next hop, None for
131
+ the last hop.
132
+ """
84
133
  self.rq_sa = rq_sa
85
134
  self.rs_sa = rs_sa
86
135
  self.channel = channel
@@ -99,11 +148,14 @@ class Target:
99
148
 
100
149
  def __init__(self, ipmb_address: int | None = None,
101
150
  routing: str | list[tuple] | None = None) -> None:
102
- """Initializer for the Target class.
151
+ """Initialize the target.
103
152
 
104
- `ipmb_address` is the IPMB target address
105
- `routing` is the bridging information used to build send message
106
- commands.
153
+ Args:
154
+ ipmb_address: The IPMB address of the target, e.g. 0x20 for
155
+ the BMC.
156
+ routing: The path over which the target is reachable, used to
157
+ build the bridged Send Message requests, see
158
+ :meth:`set_routing`.
107
159
  """
108
160
  if ipmb_address:
109
161
  self.ipmb_address = ipmb_address
@@ -112,6 +164,10 @@ class Target:
112
164
  self.set_routing(routing)
113
165
 
114
166
  def set_routing_information(self, routing: str | list[tuple]) -> None:
167
+ """Set the path over which a target is reachable.
168
+
169
+ An alias of :meth:`set_routing`.
170
+ """
115
171
  self.set_routing(routing)
116
172
 
117
173
  def set_routing(self, routing: str | list[tuple]) -> None:
@@ -171,10 +227,32 @@ class Target:
171
227
  class Ipmi(bmc.Bmc, chassis.Chassis, dcmi.Dcmi, fru.Fru, picmg.Picmg, hpm.Hpm,
172
228
  sdr.Sdr, sensor.Sensor, event.Event, sel.Sel, lan.Lan,
173
229
  messaging.Messaging, vita.Vita):
230
+ """A connection to an IPMI device.
231
+
232
+ The IPMI commands are the methods of this class, which it inherits
233
+ from the command groups, e.g. :meth:`get_device_id` from the one of
234
+ :mod:`pyipmi.bmc`. The requests are sent over the interface to
235
+ the target.
236
+
237
+ The connection is a context manager, which opens the interface and
238
+ establishes the session on entry and closes them on exit. Set up the
239
+ session before, see the example of :mod:`pyipmi`.
240
+ """
174
241
 
175
242
  def __init__(self, interface: Any = None, target: Target | None = None,
176
243
  session: Session | None = None,
177
244
  requester: Any = None) -> None:
245
+ """Initialize the connection.
246
+
247
+ Args:
248
+ interface: The interface the requests are sent over.
249
+ target: The target of the requests.
250
+ session: The session, a new one if not given. The interface
251
+ of the session is set to ``interface``.
252
+ requester: The requester of the requests, needed by interfaces
253
+ that send the requests on the IPMB, a
254
+ :class:`NullRequester` if not given.
255
+ """
178
256
  self._interface = interface
179
257
 
180
258
  # we need a session, set if not passed
@@ -200,30 +278,83 @@ class Ipmi(bmc.Bmc, chassis.Chassis, dcmi.Dcmi, fru.Fru, picmg.Picmg, hpm.Hpm,
200
278
  return False
201
279
 
202
280
  def open(self) -> None:
281
+ """Open the interface and establish the session."""
203
282
  self.interface.open()
204
283
  if self.session is not None:
205
284
  self.session.establish()
206
285
 
207
286
  def close(self) -> None:
287
+ """Close the session and the interface."""
208
288
  if self.session is not None:
209
289
  self.session.close()
210
290
  self.interface.close()
211
291
 
292
+ def is_target_accessible(self) -> bool:
293
+ """Check if the target answers.
294
+
295
+ Returns:
296
+ True if the target answers. Depending on the interface, False
297
+ is returned or an exception is raised if it does not.
298
+ """
299
+ return self.interface.is_target_accessible(self.target)
300
+
212
301
  def is_ipmc_accessible(self) -> bool:
213
- return self.interface.is_ipmc_accessible(self.target)
302
+ """Deprecated, the old name of :meth:`is_target_accessible`."""
303
+ warnings.warn('is_ipmc_accessible is deprecated, use '
304
+ 'is_target_accessible', DeprecationWarning,
305
+ stacklevel=2)
306
+ return self.is_target_accessible()
214
307
 
215
- def wait_until_ipmb_is_accessible(self, timeout: float,
216
- interval: float = 0.25) -> None:
308
+ def wait_until_target_is_accessible(self, timeout: float,
309
+ interval: float = 0.25) -> None:
310
+ """Wait until the target is accessible.
311
+
312
+ Args:
313
+ timeout: The time to wait in seconds.
314
+ interval: The time between the checks in seconds.
315
+
316
+ Raises:
317
+ IpmiTimeoutError: The target is not accessible after the
318
+ timeout, if the interface raises it, see
319
+ :meth:`is_target_accessible`.
320
+ """
217
321
  start_time = time.time()
218
322
  while time.time() < start_time + (timeout):
219
323
  try:
220
- self.is_ipmc_accessible()
324
+ if self.is_target_accessible():
325
+ return
221
326
  except IpmiTimeoutError:
222
- time.sleep(interval)
327
+ pass
328
+ time.sleep(interval)
329
+
330
+ self.is_target_accessible()
223
331
 
224
- self.is_ipmc_accessible()
332
+ def wait_until_ipmb_is_accessible(self, timeout: float,
333
+ interval: float = 0.25) -> None:
334
+ """Deprecated, use :meth:`wait_until_target_is_accessible`."""
335
+ warnings.warn('wait_until_ipmb_is_accessible is deprecated, use '
336
+ 'wait_until_target_is_accessible', DeprecationWarning,
337
+ stacklevel=2)
338
+ self.wait_until_target_is_accessible(timeout, interval)
225
339
 
226
340
  def send_message(self, req: Message, retry: int = 3) -> Message:
341
+ """Send a request to the target and return the response.
342
+
343
+ The request is sent again if the target is busy. The completion
344
+ code of the response is not checked.
345
+
346
+ Args:
347
+ req: The request message.
348
+ retry: The number of tries.
349
+
350
+ Returns:
351
+ The response message.
352
+
353
+ Raises:
354
+ RetryError: The target is still busy after ``retry`` tries.
355
+ CompletionCodeError: The interface failed with another
356
+ completion code, e.g. of a bridged Send Message request.
357
+ """
227
358
  req.target = self.target
228
359
  req.requester = self.requester
229
360
  rsp = None
@@ -236,13 +367,28 @@ class Ipmi(bmc.Bmc, chassis.Chassis, dcmi.Dcmi, fru.Fru, picmg.Picmg, hpm.Hpm,
236
367
  except CompletionCodeError as e:
237
368
  if e.cc == msgs.constants.CC_NODE_BUSY:
238
369
  continue
370
+ raise
239
371
  else:
240
372
  raise RetryError()
241
373
 
242
374
  return rsp
243
375
 
244
- def send_message_with_name(self, name: str, *args: Any,
245
- **kwargs: Any) -> Message:
376
+ def send_message_by_name(self, name: str, *args: Any,
377
+ **kwargs: Any) -> Message:
378
+ """Send a request by its name and return the response.
379
+
380
+ Args:
381
+ name: The name of the request, e.g. ``'GetDeviceId'``.
382
+ *args: Not used.
383
+ **kwargs: The fields of the request, set as attributes.
384
+
385
+ Returns:
386
+ The response message.
387
+
388
+ Raises:
389
+ CompletionCodeError: The completion code of the response is
390
+ not successful.
391
+ """
246
392
  req = create_request_by_name(name)
247
393
 
248
394
  for key, value in kwargs.items():
@@ -252,20 +398,37 @@ class Ipmi(bmc.Bmc, chassis.Chassis, dcmi.Dcmi, fru.Fru, picmg.Picmg, hpm.Hpm,
252
398
  check_rsp_completion_code(rsp)
253
399
  return rsp
254
400
 
255
- def raw_command(self, lun: int, netfn: int, raw_bytes: bytes) -> bytes:
256
- """Send the raw command data and return the raw response.
401
+ def send_message_with_name(self, name: str, *args: Any,
402
+ **kwargs: Any) -> Message:
403
+ """Deprecated, the old name of :meth:`send_message_by_name`."""
404
+ warnings.warn('send_message_with_name is deprecated, use '
405
+ 'send_message_by_name', DeprecationWarning,
406
+ stacklevel=2)
407
+ return self.send_message_by_name(name, *args, **kwargs)
257
408
 
258
- lun: the logical unit number
259
- netfn: the network function
260
- raw_bytes: the raw message as bytestring
409
+ def send_raw(self, lun: int, netfn: int, raw_bytes: bytes) -> bytes:
410
+ """Send a raw request to the target and return the raw response.
261
411
 
262
- Returns the response as bytestring.
412
+ Args:
413
+ lun: The logical unit number.
414
+ netfn: The network function.
415
+ raw_bytes: The request, starting with the command ID.
416
+
417
+ Returns:
418
+ The response, starting with the completion code.
263
419
  """
264
420
  return self.interface.send_and_receive_raw(self.target, lun, netfn,
265
421
  raw_bytes)
266
422
 
423
+ def raw_command(self, lun: int, netfn: int, raw_bytes: bytes) -> bytes:
424
+ """Deprecated, the old name of :meth:`send_raw`."""
425
+ warnings.warn('raw_command is deprecated, use send_raw',
426
+ DeprecationWarning, stacklevel=2)
427
+ return self.send_raw(lun, netfn, raw_bytes)
428
+
267
429
  @property
268
430
  def interface(self) -> Any:
431
+ """The interface the requests are sent over."""
269
432
  try:
270
433
  return self._interface
271
434
  except AttributeError:
@@ -277,6 +440,7 @@ class Ipmi(bmc.Bmc, chassis.Chassis, dcmi.Dcmi, fru.Fru, picmg.Picmg, hpm.Hpm,
277
440
 
278
441
  @property
279
442
  def session(self) -> Session:
443
+ """The session of the connection."""
280
444
  try:
281
445
  return self._session
282
446
  except AttributeError:
@@ -288,6 +452,7 @@ class Ipmi(bmc.Bmc, chassis.Chassis, dcmi.Dcmi, fru.Fru, picmg.Picmg, hpm.Hpm,
288
452
 
289
453
  @property
290
454
  def target(self) -> Target | None:
455
+ """The target of the requests."""
291
456
  try:
292
457
  return self._target
293
458
  except AttributeError:
pyipmi/bmc.py CHANGED
@@ -48,7 +48,7 @@ class Bmc(IpmiMixin):
48
48
  The device ID, firmware version, IPMI version and supported
49
49
  functions of the controller.
50
50
  """
51
- return DeviceId(self.send_message_with_name('GetDeviceId'))
51
+ return DeviceId(self.send_message_by_name('GetDeviceId'))
52
52
 
53
53
  def get_device_guid(self) -> DeviceGuid:
54
54
  """Get the GUID of the controller.
@@ -56,15 +56,15 @@ class Bmc(IpmiMixin):
56
56
  Returns:
57
57
  The device GUID.
58
58
  """
59
- return DeviceGuid(self.send_message_with_name('GetDeviceGuid'))
59
+ return DeviceGuid(self.send_message_by_name('GetDeviceGuid'))
60
60
 
61
61
  def cold_reset(self) -> None:
62
62
  """Cold reset the controller, it is reinitialized."""
63
- self.send_message_with_name('ColdReset')
63
+ self.send_message_by_name('ColdReset')
64
64
 
65
65
  def warm_reset(self) -> None:
66
66
  """Warm reset the controller, its state is kept."""
67
- self.send_message_with_name('WarmReset')
67
+ self.send_message_by_name('WarmReset')
68
68
 
69
69
  def i2c_write_read(self, bus_type: int, bus_id: int, channel: int,
70
70
  address: int, count: int,
@@ -169,7 +169,7 @@ class Bmc(IpmiMixin):
169
169
  Returns:
170
170
  The watchdog timer, ``dont_stop`` is not set.
171
171
  """
172
- return Watchdog(self.send_message_with_name('GetWatchdogTimer'))
172
+ return Watchdog(self.send_message_by_name('GetWatchdogTimer'))
173
173
 
174
174
  def reset_watchdog_timer(self) -> None:
175
175
  """Start or restart the watchdog timer with its initial countdown.
@@ -177,7 +177,7 @@ class Bmc(IpmiMixin):
177
177
  Raises:
178
178
  CompletionCodeError: The timer was not set before (0x80).
179
179
  """
180
- self.send_message_with_name('ResetWatchdogTimer')
180
+ self.send_message_by_name('ResetWatchdogTimer')
181
181
 
182
182
 
183
183
  class Watchdog(State):
pyipmi/chassis.py CHANGED
@@ -207,7 +207,7 @@ class Chassis(IpmiMixin):
207
207
  Returns:
208
208
  The chassis status.
209
209
  """
210
- return ChassisStatus(self.send_message_with_name('GetChassisStatus'))
210
+ return ChassisStatus(self.send_message_by_name('GetChassisStatus'))
211
211
 
212
212
  def chassis_control(self, option: int) -> None:
213
213
  """Control the chassis power.
pyipmi/dcmi.py CHANGED
@@ -92,8 +92,8 @@ class Dcmi(IpmiMixin):
92
92
  (bits ``major`` and ``minor``, the DCMI version),
93
93
  ``parameter_revision`` and ``parameter_data``.
94
94
  """
95
- rsp = self.send_message_with_name('GetDcmiCapabilities',
96
- parameter_selector=selector)
95
+ rsp = self.send_message_by_name('GetDcmiCapabilities',
96
+ parameter_selector=selector)
97
97
  return rsp
98
98
 
99
99
  def get_power_reading(self, mode: int, attributes: int = 0) -> Message:
@@ -113,8 +113,8 @@ class Dcmi(IpmiMixin):
113
113
  ``reading_state`` (bit 6 is set if the power measurement is
114
114
  active).
115
115
  """
116
- rsp = self.send_message_with_name('GetPowerReading',
117
- mode=mode, attributes=attributes)
116
+ rsp = self.send_message_by_name('GetPowerReading',
117
+ mode=mode, attributes=attributes)
118
118
  return rsp
119
119
 
120
120
  def _get_all_instances(self, name: str, entity_id: int,
@@ -131,11 +131,11 @@ class Dcmi(IpmiMixin):
131
131
  items: list[Any] = []
132
132
  start = 0
133
133
  while True:
134
- rsp = self.send_message_with_name(name,
135
- sensor_type=1,
136
- entity_id=entity_id,
137
- entity_instance=0,
138
- entity_instance_start=start)
134
+ rsp = self.send_message_by_name(name,
135
+ sensor_type=1,
136
+ entity_id=entity_id,
137
+ entity_instance=0,
138
+ entity_instance_start=start)
139
139
  received = decode(rsp)
140
140
  new = [(k, i) for (k, i) in received if k not in keys]
141
141
  for (k, i) in new:
@@ -204,7 +204,7 @@ class Dcmi(IpmiMixin):
204
204
  CompletionCodeError: The BMC rejected the request, e.g. if no
205
205
  power limit is set (0x80).
206
206
  """
207
- return self.send_message_with_name('GetPowerLimit')
207
+ return self.send_message_by_name('GetPowerLimit')
208
208
 
209
209
  def set_power_limit(self, power_limit: int, correction_time_limit: int,
210
210
  statistics_sampling_period: int,
@@ -223,7 +223,7 @@ class Dcmi(IpmiMixin):
223
223
  exception_actions: The action if the limit is exceeded, one of
224
224
  the ``POWER_LIMIT_EXCEPTION_*`` constants.
225
225
  """
226
- self.send_message_with_name(
226
+ self.send_message_by_name(
227
227
  'SetPowerLimit',
228
228
  exception_actions=exception_actions,
229
229
  power_limit=power_limit,
@@ -232,13 +232,13 @@ class Dcmi(IpmiMixin):
232
232
 
233
233
  def activate_power_limit(self) -> None:
234
234
  """Activate the power limit."""
235
- self.send_message_with_name('ActivateDeactivatePowerLimit',
236
- activation=1)
235
+ self.send_message_by_name('ActivateDeactivatePowerLimit',
236
+ activation=1)
237
237
 
238
238
  def deactivate_power_limit(self) -> None:
239
239
  """Deactivate the power limit."""
240
- self.send_message_with_name('ActivateDeactivatePowerLimit',
241
- activation=0)
240
+ self.send_message_by_name('ActivateDeactivatePowerLimit',
241
+ activation=0)
242
242
 
243
243
  def get_thermal_limit(self, entity_id: int,
244
244
  entity_instance: int) -> Message:
@@ -254,9 +254,9 @@ class Dcmi(IpmiMixin):
254
254
  ``temperature_limit`` in degree Celsius and ``exception_time``
255
255
  in seconds.
256
256
  """
257
- return self.send_message_with_name('GetThermalLimit',
258
- entity_id=entity_id,
259
- entity_instance=entity_instance)
257
+ return self.send_message_by_name('GetThermalLimit',
258
+ entity_id=entity_id,
259
+ entity_instance=entity_instance)
260
260
 
261
261
  def set_thermal_limit(self, entity_id: int, entity_instance: int,
262
262
  temperature_limit: int, exception_time: int,
@@ -301,9 +301,9 @@ class Dcmi(IpmiMixin):
301
301
  (bits ``major`` and ``minor``), ``parameter_revision`` and
302
302
  ``parameter_data``.
303
303
  """
304
- return self.send_message_with_name('GetDcmiConfigurationParameters',
305
- parameter_selector=selector,
306
- set_selector=set_selector)
304
+ return self.send_message_by_name('GetDcmiConfigurationParameters',
305
+ parameter_selector=selector,
306
+ set_selector=set_selector)
307
307
 
308
308
  def set_dcmi_configuration_parameters(self, selector: int, data: bytes,
309
309
  set_selector: int = 0) -> None:
@@ -314,21 +314,21 @@ class Dcmi(IpmiMixin):
314
314
  data: The parameter data.
315
315
  set_selector: The set selector of the parameter.
316
316
  """
317
- self.send_message_with_name('SetDcmiConfigurationParameters',
318
- parameter_selector=selector,
319
- set_selector=set_selector,
320
- parameter_data=data)
317
+ self.send_message_by_name('SetDcmiConfigurationParameters',
318
+ parameter_selector=selector,
319
+ set_selector=set_selector,
320
+ parameter_data=data)
321
321
 
322
322
  def _get_dcmi_string(self, name: str, length_request_size: int) -> bytes:
323
323
  # the first request is only used to get the total length
324
- rsp = self.send_message_with_name(name, offset=0,
325
- number_of_bytes=length_request_size)
324
+ rsp = self.send_message_by_name(name, offset=0,
325
+ number_of_bytes=length_request_size)
326
326
  total_length = rsp.total_length
327
327
  data = b''
328
328
  while len(data) < total_length:
329
329
  count = min(MAX_STRING_CHUNK_SIZE, total_length - len(data))
330
- rsp = self.send_message_with_name(name, offset=len(data),
331
- number_of_bytes=count)
330
+ rsp = self.send_message_by_name(name, offset=len(data),
331
+ number_of_bytes=count)
332
332
  chunk = rsp.data.tobytes()
333
333
  if not chunk:
334
334
  break
@@ -338,9 +338,9 @@ class Dcmi(IpmiMixin):
338
338
  def _set_dcmi_string(self, name: str, data: bytes) -> None:
339
339
  for offset in range(0, len(data), MAX_STRING_CHUNK_SIZE):
340
340
  chunk = data[offset:offset + MAX_STRING_CHUNK_SIZE]
341
- self.send_message_with_name(name, offset=offset,
342
- number_of_bytes=len(chunk),
343
- data=chunk)
341
+ self.send_message_by_name(name, offset=offset,
342
+ number_of_bytes=len(chunk),
343
+ data=chunk)
344
344
 
345
345
  def get_asset_tag(self) -> str:
346
346
  """Return the asset tag of the system.
pyipmi/fields.py CHANGED
@@ -53,7 +53,13 @@ class VersionField:
53
53
 
54
54
 
55
55
  def _unpack6bitascii(data: Sequence[int]) -> str:
56
- """Unpack the 6bit ascii encoded string."""
56
+ """Unpack the 6bit ascii encoded string.
57
+
58
+ The characters are packed in groups of 3 bytes, the last group can be
59
+ shorter, e.g. 5 characters take 4 bytes.
60
+ """
61
+ count = len(data) * 8 // 6
62
+ data = list(data) + [0] * (-len(data) % 3)
57
63
  string = ''
58
64
  for i in range(0, len(data), 3):
59
65
  d = data[i:i+3]
@@ -61,7 +67,7 @@ def _unpack6bitascii(data: Sequence[int]) -> str:
61
67
  string += chr(0x20 + (((d[0] & 0xc0) >> 6) | ((d[1] & 0xf) << 2)))
62
68
  string += chr(0x20 + (((d[1] & 0xf0) >> 4) | ((d[2] & 0x3) << 4)))
63
69
  string += chr(0x20 + ((d[2] & 0xfc) >> 2))
64
- return string
70
+ return string[:count]
65
71
 
66
72
 
67
73
  class TypeLengthString:
pyipmi/fru.py CHANGED
@@ -82,8 +82,8 @@ class Fru(IpmiMixin):
82
82
  Returns:
83
83
  The size of the FRU inventory area in bytes.
84
84
  """
85
- rsp = self.send_message_with_name('GetFruInventoryAreaInfo',
86
- fru_id=fru_id)
85
+ rsp = self.send_message_by_name('GetFruInventoryAreaInfo',
86
+ fru_id=fru_id)
87
87
  return rsp.area_size
88
88
 
89
89
  def write_fru_data(self, data: bytes, offset: int = 0,
@@ -101,10 +101,10 @@ class Fru(IpmiMixin):
101
101
  Exception: The device wrote fewer bytes than were sent.
102
102
  """
103
103
  for chunk in chunks(data, self.write_length):
104
- write_rsp = self.send_message_with_name('WriteFruData',
105
- fru_id=fru_id,
106
- offset=offset,
107
- data=chunk)
104
+ write_rsp = self.send_message_by_name('WriteFruData',
105
+ fru_id=fru_id,
106
+ offset=offset,
107
+ data=chunk)
108
108
 
109
109
  # check if device wrote the same number of bytes sent
110
110
  if write_rsp.count_written != len(chunk):
@@ -147,8 +147,8 @@ class Fru(IpmiMixin):
147
147
  req_size = min(read_length.length, area_size - off)
148
148
 
149
149
  try:
150
- rsp = self.send_message_with_name('ReadFruData', fru_id=fru_id,
151
- offset=off, count=req_size)
150
+ rsp = self.send_message_by_name('ReadFruData', fru_id=fru_id,
151
+ offset=off, count=req_size)
152
152
  except CompletionCodeError as ex:
153
153
  if ex.cc in (constants.CC_CANT_RET_NUM_REQ_BYTES,
154
154
  constants.CC_REQ_DATA_FIELD_EXCEED,