Mini Shell
# Copyright (c) 2014 Kontron Europe GmbH
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import time
from .errors import CompletionCodeError, RetryError
from .utils import check_completion_code, ByteBuffer
from .msgs import constants
def get_sdr_chunk_helper(send_fn, req, reserve_fn, retry=5):
while True:
retry -= 1
if retry == 0:
raise RetryError()
rsp = send_fn(req)
if rsp.completion_code == constants.CC_OK:
break
elif rsp.completion_code == constants.CC_RES_CANCELED:
time.sleep(1)
req.reservation_id = reserve_fn()
continue
elif rsp.completion_code == constants.CC_TIMEOUT:
time.sleep(0.1)
continue
elif rsp.completion_code == constants.CC_RESP_COULD_NOT_BE_PRV:
time.sleep(0.1 * retry)
continue
else:
check_completion_code(rsp.completion_code)
return rsp
def get_sdr_data_helper(reserve_fn, get_fn, record_id, reservation_id=None):
"""Helper function to retrieve the sdr data.
A specified helper function is used to retrieve the chunks.
This can be used for SDRs from the Sensor Device or form the SDR
repository.
"""
if reservation_id is None:
reservation_id = reserve_fn()
(next_id, data) = get_fn(reservation_id, record_id, 0, 5)
header = ByteBuffer(data)
record_id = header.pop_unsigned_int(2)
record_version = header.pop_unsigned_int(1) # noqa:F841
record_type = header.pop_unsigned_int(1) # noqa:F841
record_payload_length = header.pop_unsigned_int(1)
record_length = record_payload_length + 5
record_data = ByteBuffer(data)
offset = len(record_data)
max_req_len = 20
retry = 20
# now get the other record data
while True:
retry -= 1
if retry == 0:
raise RetryError()
length = max_req_len
if (offset + length) > record_length:
length = record_length - offset
try:
(next_id, data) = get_fn(reservation_id, record_id, offset, length)
except CompletionCodeError as e:
if e.cc == constants.CC_CANT_RET_NUM_REQ_BYTES:
# reduce max lenght
max_req_len -= 4
if max_req_len <= 0:
retry = 0
else:
raise CompletionCodeError(e.cc)
record_data.extend(data[:])
offset = len(record_data)
if len(record_data) >= record_length:
break
return (next_id, record_data)
def _clear_repository(reserve_fn, clear_fn, ctrl, retry, reservation):
while True:
retry -= 1
if retry <= 0:
raise RetryError()
try:
in_progress = clear_fn(ctrl, reservation)
except CompletionCodeError as e:
if e.cc == constants.CC_RES_CANCELED:
time.sleep(0.2)
reservation = reserve_fn()
continue
else:
check_completion_code(e.cc)
if in_progress == constants.REPOSITORY_ERASURE_IN_PROGRESS:
time.sleep(0.5)
continue
break
return reservation
def clear_repository_helper(reserve_fn, clear_fn, retry=5, reservation=None):
"""Helper function to start repository erasure and wait until finish.
This helper is used by clear_sel and clear_sdr_repository.
"""
if reservation is None:
reservation = reserve_fn()
# start erasure
reservation = _clear_repository(reserve_fn, clear_fn,
constants.REPOSITORY_INITIATE_ERASE,
retry, reservation)
# give some time to clear
time.sleep(0.5)
# wait until finish
reservation = _clear_repository(reserve_fn, clear_fn,
constants.REPOSITORY_GET_ERASE_STATUS,
retry, reservation)
Zerion Mini Shell 1.0