- MMS client/server: handle missing invoke ID in reject/error PDUs

pull/179/head
Michael Zillgith 6 years ago
parent 4c123c0c3c
commit 84fcfbbd22

@ -92,10 +92,10 @@ LIB61850_INTERNAL void
mmsMsg_createMmsRejectPdu(uint32_t* invokeId, int reason, ByteBuffer* response);
LIB61850_INTERNAL int
mmsMsg_parseConfirmedErrorPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invokeId, MmsServiceError* serviceError);
mmsMsg_parseConfirmedErrorPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invokeId, bool* hasInvokeId, MmsServiceError* serviceError);
LIB61850_INTERNAL int
mmsMsg_parseRejectPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invokeId, int* rejectType, int* rejectReason);
mmsMsg_parseRejectPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invokeId, bool* hasInvokeId, int* rejectType, int* rejectReason);
LIB61850_INTERNAL MmsValue*
mmsMsg_parseDataElement(Data_t* dataElement);

@ -533,10 +533,13 @@ parseServiceError(uint8_t* buffer, int bufPos, int maxLength, MmsServiceError* e
}
int
mmsMsg_parseConfirmedErrorPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invokeId, MmsServiceError* serviceError)
mmsMsg_parseConfirmedErrorPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invokeId, bool* hasInvokeId, MmsServiceError* serviceError)
{
int length;
if (hasInvokeId)
*hasInvokeId = false;
uint8_t tag = buffer[bufPos++];
if (tag != 0xa2)
goto exit_error;
@ -561,6 +564,8 @@ mmsMsg_parseConfirmedErrorPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32
switch (tag)
{
case 0x80: /* invoke Id */
if (hasInvokeId)
*hasInvokeId = true;
if (invokeId != NULL)
*invokeId = BerDecoder_decodeUint32(buffer, length, bufPos);
bufPos += length;
@ -589,10 +594,13 @@ exit_error:
}
int
mmsMsg_parseRejectPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invokeId, int* rejectType, int* rejectReason)
mmsMsg_parseRejectPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invokeId, bool* hasInvokeId, int* rejectType, int* rejectReason)
{
int length;
if (hasInvokeId)
*hasInvokeId = false;
uint8_t tag = buffer[bufPos++];
if (tag != 0xa4)
@ -619,6 +627,8 @@ mmsMsg_parseRejectPDU(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* invo
goto exit_error;
if (tag == 0x80) { /* invoke id */
if (hasInvokeId)
*hasInvokeId = true;
if (invokeId != NULL)
*invokeId = BerDecoder_decodeUint32(buffer, length, bufPos);
}
@ -1080,9 +1090,11 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload)
printf("MMS_CLIENT: Confirmed error PDU!\n");
uint32_t invokeId;
bool hasInvokeId = false;
MmsServiceError serviceError = { 0, 0 };
if (mmsMsg_parseConfirmedErrorPDU(payload->buffer, 0, payload->size, &invokeId, &serviceError) < 0) {
if (mmsMsg_parseConfirmedErrorPDU(payload->buffer, 0, payload->size, &invokeId, &hasInvokeId, &serviceError) < 0) {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: Error parsing confirmedErrorPDU!\n");
@ -1090,26 +1102,35 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload)
}
else {
MmsOutstandingCall call = checkForOutstandingCall(self, invokeId);
if (hasInvokeId) {
MmsOutstandingCall call = checkForOutstandingCall(self, invokeId);
if (call) {
if (call) {
MmsError err = convertServiceErrorToMmsError(serviceError);
MmsError err = convertServiceErrorToMmsError(serviceError);
if (call->type != MMS_CALL_TYPE_NONE) {
handleAsyncResponse(self, NULL, 0, call, err);
if (call->type != MMS_CALL_TYPE_NONE) {
handleAsyncResponse(self, NULL, 0, call, err);
}
else {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: internal problem (unexpected call type - error PDU)\n");
}
}
else {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: internal problem (unexpected call type - error PDU)\n");
printf("MMS_CLIENT: server sent unexpected confirmed error PDU!\n");
return;
}
}
else {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: unexpected message from server!\n");
printf("MMS_CLIENT: server sent confirmed error PDU without invoke ID!\n");
return;
}
}
}
else if (tag == 0xa4) { /* reject PDU */
@ -1117,33 +1138,40 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload)
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: reject PDU!\n");
uint32_t invokeId;
bool hasInvokeId = false;
uint32_t invokeId = 0;
int rejectType;
int rejectReason;
if (mmsMsg_parseRejectPDU(payload->buffer, 0, payload->size, &invokeId, &rejectType, &rejectReason) >= 0) {
if (mmsMsg_parseRejectPDU(payload->buffer, 0, payload->size, &invokeId, &hasInvokeId, &rejectType, &rejectReason) >= 0) {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: reject PDU invokeID: %i type: %i reason: %i\n", (int) invokeId, rejectType, rejectReason);
printf("MMS_CLIENT: reject PDU invokeID: %u type: %i reason: %i\n", invokeId, rejectType, rejectReason);
MmsOutstandingCall call = checkForOutstandingCall(self, invokeId);
if (hasInvokeId) {
MmsOutstandingCall call = checkForOutstandingCall(self, invokeId);
if (call) {
if (call) {
MmsError err = convertRejectCodesToMmsError(rejectType, rejectReason);
MmsError err = convertRejectCodesToMmsError(rejectType, rejectReason);
if (call->type != MMS_CALL_TYPE_NONE) {
handleAsyncResponse(self, NULL, 0, call, err);
if (call->type != MMS_CALL_TYPE_NONE) {
handleAsyncResponse(self, NULL, 0, call, err);
}
else {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: internal problem (unexpected call type - reject PDU)\n");
}
}
else {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: internal problem (unexpected call type - reject PDU)\n");
return;
}
}
else {
return;
}
}
else
goto exit_with_error;

@ -411,28 +411,32 @@ handleConfirmedErrorPdu(
uint8_t* buffer, int bufPos, int maxBufPos,
ByteBuffer* response)
{
uint32_t invokeId;
uint32_t invokeId = 0;
bool hasInvokeId = false;
MmsServiceError serviceError;
if (mmsMsg_parseConfirmedErrorPDU(buffer, bufPos, maxBufPos, &invokeId, &serviceError)) {
if (mmsMsg_parseConfirmedErrorPDU(buffer, bufPos, maxBufPos, &invokeId, &hasInvokeId, &serviceError)) {
if (DEBUG_MMS_SERVER)
printf("MMS_SERVER: Handle confirmed error PDU: invokeID: %i\n", invokeId);
printf("MMS_SERVER: Handle confirmed error PDU: invokeID: %u\n", invokeId);
/* check if message is related to an existing file upload task */
int i;
for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++) {
if (hasInvokeId) {
/* check if message is related to an existing file upload task */
int i;
for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++) {
if (self->server->fileUploadTasks[i].state != MMS_FILE_UPLOAD_STATE_NOT_USED) {
if (self->server->fileUploadTasks[i].state != MMS_FILE_UPLOAD_STATE_NOT_USED) {
if (self->server->fileUploadTasks[i].lastRequestInvokeId == invokeId) {
if (self->server->fileUploadTasks[i].lastRequestInvokeId == invokeId) {
self->server->fileUploadTasks[i].state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE;
return;
}
self->server->fileUploadTasks[i].state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE;
return;
}
}
}
}
}
else {
if (DEBUG_MMS_SERVER)

Loading…
Cancel
Save