-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
question on error behavior #27
Comments
Hi @slowCoder72 . Please share an example client code noting expected and actual behavior. |
Hello James,
This is a bit complex: we wrapped your lib so that we can use it in a lua script and then try reading data by identifier. So we try to update targets and trigger an image activation where we do not know how long the target needs to reboot. After the reboot we poll and for some time have no targets being up. Then the reported alternating errors occur.
The wrapper for drbi looks like:
static int lua_UDSSendRDBI(lua_State *L)
{
UDSClient_t *client;
client = (UDSClient_t *)luaL_checkudata(L, 1, LUA_UDS_CLIENT_METATABLE_NAME);
uint16_t *didList;
uint16_t numDataIdentifiers = 0;
UDSErr_t ret = 0;
/* 2nd argument must be a table with the Data Identifiers (DIDs) */
luaL_checktype(L, 2, LUA_TTABLE);
numDataIdentifiers = (uint16_t)luaL_len(L, 2);
if (numDataIdentifiers > 0)
{
didList = (uint16_t *)malloc(sizeof(uint16_t) * numDataIdentifiers);
if (didList == NULL)
return pushErrAndMsg(L, 1, "Failed allocating memory for data didList ...\n");
}
else
{
return pushErrAndMsg(L, 1, "Table length is zero. No identifiers to read from. Not sending RDBI request ...\n");
}
/* parsing the Lua table on the stack to uint16_t array */
if (luaTableToUint16Array(L, 2, didList, numDataIdentifiers))
{
free(didList);
return pushErrAndMsg(L, 1, "Could not parse Lua table to an uint16_t array...\n");
}
uint8_t functionalReq = (uint8_t)lua_toboolean(L, 3);
if (functionalReq)
client->options |= UDS_FUNCTIONAL;
if ((ret = UDSSendRDBI(client, (const uint16_t *)didList, numDataIdentifiers)))
{
client->options &= ~UDS_FUNCTIONAL;
free(didList);
return pushErrAndMsg(L, ret, UDSErrortoString(ret));
}
client->options &= ~UDS_FUNCTIONAL;
free(didList);
return pushErrAndMsg(L, UDS_OK, NULL);
}
The lua script uses the snippet:
…-- fetch all responses from image activation
for _, scannedTarget in pairs(transferResults) do -- loop through scanned targets to check for status 0x08
if scannedTarget.matched and scannedTarget.transferredImage then
local msg = string.format(
"checking if board type = 0X%X and board address = 0X%X is in HEALTH_CHECK, IMAGE_ACTIVATED or UPDATE_FAIL",
scannedTarget.boardType, scannedTarget.boardAddress)
swupdate.notify(swupdate.RECOVERY_STATUS.IDLE, 0, msg)
scannedTarget.imageActivated = false
local UDSClient, msg = initUDSClient("can0", scannedTarget.boardType, scannedTarget.boardAddress)
if not UDSClient then
swupdate.notify(swupdate.RECOVERY_STATUS.RUN, 0, msg)
else
local maxAttempts = 60
local attemptCounter = 0
local switch = 1
repeat
local response, err, msg = requestRdbi(UDSClient, enums.DataIDs.BOARD_STATE, 2)
if not response then
msg = string.format(
"error requesting state from board type = 0X%02X with address = 0X%02X, err = %d, msg = %s",
scannedTarget.boardType, scannedTarget.boardAddress, err, msg)
swupdate.notify(swupdate.RECOVERY_STATUS.RUN, 0, msg)
else
msg = string.format("requested state = 0X%02X from board type = 0X%02X, address = 0X%02X, ",
response[1], scannedTarget.boardType, scannedTarget.boardAddress)
swupdate.notify(swupdate.RECOVERY_STATUS.RUN, 0, msg)
-- check states
if response[1] == enums.SMStates.IMAGE_ACTIVATED then -- CHECK STATE RESPONSE AND ACTIVATE IMAGE
scannedTarget.imageActivated = true
switch = 0
elseif response[1] == enums.SMStates.UPDATE_FAIL then
switch = 0
msg = string.format("update failed for board type = 0X%X with address = 0X%X, state = 0X%X",
scannedTarget.boardType, scannedTarget.boardAddress, response[1])
swupdate.notify(swupdate.RECOVERY_STATUS.FAILURE, 0, msg)
-- send cancel command if update failed
local err, msg = requestWdbi(UDSClient, enums.WriteIDs.Update_Cancel_ID, {0x00})
if err ~= 0 then
msg = string.format("error sending cancel command: error %d, msg = '%s'", err, msg)
swupdate.notify(swupdate.RECOVERY_STATUS.FAILURE, 0, msg)
else
msg = string.format("sent cancel command to board type = 0X%02X and address = 0X%02X",
scannedTarget.boardType, scannedTarget.boardAddress)
swupdate.notify(swupdate.RECOVERY_STATUS.RUN, 0, msg)
break
end
elseif response[1] == enums.SMStates.DEVICE_HEALTH_CHECK then
-- continue asking since the target is not done with the health check
else
switch = 0
msg = string.format(
"board type = 0X%X with address = 0X%X is not meant to be in state = 0X%X after activate image command",
scannedTarget.boardType, scannedTarget.boardAddress, response[1])
swupdate.notify(swupdate.RECOVERY_STATUS.RUN, 0, msg)
end
end
attemptCounter = attemptCounter + 1 -- counting attempts
swupdate.notify(swupdate.RECOVERY_STATUS.RUN, 0, "attemptCounter " .. attemptCounter)
sleep(3)
until switch == 0 or attemptCounter >= maxAttempts
UDSClient:deinit()
UDSClient = nil
if attemptCounter >= maxAttempts then
msg = string.format(
"tried too many times to request state IMAGE_ACTIVATED, board type = 0X%X, address = 0X%X not responding ...",
scannedTarget.boardType, scannedTarget.boardAddress)
swupdate.notify(swupdate.RECOVERY_STATUS.FAILURE, 0, msg)
end
end
end
end
and the lua script uses:
function requestRdbi(UDSClient, did, didSize)
assert(type(UDSClient) == "userdata", "UDSClient has to be of type userdata")
assert(getmetatable(UDSClient).__name == "LuaUDSClient", "UDSClient has to have the metatable LuaUDSClient")
assert(type(did) == "number", "did has to be of type number")
assert(type(didSize) == "number", "didSize has to be of type number")
assert(didSize > 0, "didSize has to be greater than zero")
local response
UDSClient:awaitIdle()
local err, msg = UDSClient:sendRdbi({did})
if err ~= 0 then
msg = string.format("error sending RDBI to request ID 0X%02X: %s", tableprint.dump(did), msg)
UDSClient:setError(enums.UDSError.UDS_OK)
else
err, msg = awaitAndCheckPositiveResponse(UDSClient)
if err ~= 0 then
msg =
string.format("error receiving response from RDBI to request ID 0X%02X: %s", tableprint.dump(did), msg)
UDSClient:setError(enums.UDSError.UDS_OK)
else
local buf = UDSClient:getRecvBuffer()
response = {table.unpack(buf, 1 + didSize + 1, #buf)}
if next(response) == nil then
response, err, msg = nil, 1, "No data received or didSize is wrong (greater than actual size of DID)"
UDSClient:setError(enums.UDSError.UDS_OK)
end
end
end
hope this can somehow be understood!
Hi @slowCoder72<https://github.com/slowCoder72> . Please share an example client code noting expected and actual behavior.
—
Reply to this email directly, view it on GitHub<#27 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AMOSMJ5QOMT6IMEWR4QXSNDYWFZJHAVCNFSM6AAAAABEAENUFGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNZUGQ3TSOJYGY>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
I do not see |
In the lua script we do "initUDSClient" and this via our wrapper executes UDSClientInit() in the lib. The communication to the targets also works and we took the above client.c as an inspiration. It is just the error behavior when there is no communication partner that i wanted to mention and probably discuss. |
Hi @slowCoder72 , are you still having this issue? Using the information you've provided I cannot tell whether the issues is in |
the following might not be a real issue, but i would like to discuss the observation. We have a situation in which we act as a tester and the other nodes go into reboot/health check after an update. We then poll repeatedly to be aware when the nodes have rebooted. We needed to request idle in this situation, otherwise the lib stayed in UDS_ERR_BUSY even after the nodes had been back - no issue this is according to the examples.
However when we repeatedly send SendRDBI requests to get the status of the nodes while they are still not present, we get an oscillating pattern of errors: UDS_ERR_TIMEOUT, UDS_ERR_TPORT, UDS_ERR_TIMEOUT, UDS_ERR_TPORT etc.
we tried to understand how this happens and enabled the debug outputs:
client state: AwaitSendComplete (2) -> AwaitResponse (3)
read failed: -1 with errno: 70
timeout: 1
client state: AwaitResponse (3) -> Idle (0)
client state: Idle (0) -> Sending (1)
Condition met: client->send_size (3, 3), == ret (3)
Sending (1) -> AwaitSendComplete (2)
client state: AwaitSendComplete (2) -> AwaitResponse (3)
timeout: 1
client state: AwaitResponse (3) -> Idle (0)
awaiting idle failed with err = 1 and msg = 'UDS_ERR_TIMEOUT'
client state: Idle (0) -> Sending (1)
tport err: -1, nsend=3 bytes
Condition met: client->send_size (3, 3), == ret (3)
client state: Sending (1) -> AwaitSendComplete (2)
awaiting idle failed with err = 6 and msg = 'UDS_ERR_TPORT'
in the code imho this happens in:
case kRequestStateSending: {
UDSTpAddr_t ta_type = client->_options_copy & UDS_FUNCTIONAL ? UDS_A_TA_TYPE_FUNCTIONAL
: UDS_A_TA_TYPE_PHYSICAL;
UDSSDU_t info = {
.A_Mtype = UDS_A_MTYPE_DIAG,
.A_TA_Type = ta_type,
};
ssize_t ret = UDSTpSend(client->tp, client->send_buf, client->send_size, &info);
if (ret < 0) {
client->err = UDS_ERR_TPORT;
UDS_DBG_PRINT("tport err: %zd\n", ret);
} else if (0 == ret) {
UDS_DBG_PRINT("send in progress...\n");
; // 等待发送成功
} else if (client->send_size == ret) {
changeState(client, kRequestStateAwaitSendComplete);
} else {
client->err = UDS_ERR_BUFSIZ;
}
break;
and we are puzzled how ret < 0 can be true and shortly after client->send_size == ret??
Any idea from your experience?
The text was updated successfully, but these errors were encountered: