- 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); mmsMsg_createMmsRejectPdu(uint32_t* invokeId, int reason, ByteBuffer* response);
LIB61850_INTERNAL int 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 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* LIB61850_INTERNAL MmsValue*
mmsMsg_parseDataElement(Data_t* dataElement); mmsMsg_parseDataElement(Data_t* dataElement);

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

@ -411,28 +411,32 @@ handleConfirmedErrorPdu(
uint8_t* buffer, int bufPos, int maxBufPos, uint8_t* buffer, int bufPos, int maxBufPos,
ByteBuffer* response) ByteBuffer* response)
{ {
uint32_t invokeId; uint32_t invokeId = 0;
bool hasInvokeId = false;
MmsServiceError serviceError; MmsServiceError serviceError;
if (mmsMsg_parseConfirmedErrorPDU(buffer, bufPos, maxBufPos, &invokeId, &serviceError)) { if (mmsMsg_parseConfirmedErrorPDU(buffer, bufPos, maxBufPos, &invokeId, &hasInvokeId, &serviceError)) {
if (DEBUG_MMS_SERVER) 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 */ if (hasInvokeId) {
int i; /* check if message is related to an existing file upload task */
for (i = 0; i < CONFIG_MMS_SERVER_MAX_GET_FILE_TASKS; i++) { 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; self->server->fileUploadTasks[i].state = MMS_FILE_UPLOAD_STATE_SEND_OBTAIN_FILE_ERROR_SOURCE;
return; return;
} }
}
} }
} }
} }
else { else {
if (DEBUG_MMS_SERVER) if (DEBUG_MMS_SERVER)

Loading…
Cancel
Save