- MMS client: add asynchronous function for MMS identify service

pull/93/head
Michael Zillgith 7 years ago
parent 7600c0f3cf
commit c80a87d5e8

@ -856,6 +856,14 @@ MmsConnection_getLocalDetail(MmsConnection self);
MmsServerIdentity*
MmsConnection_identify(MmsConnection self, MmsError* mmsError);
typedef void
(*MmsConnection_IdentifyHandler) (int invokeId, void* parameter, MmsError mmsError,
char* vendorName, char* modelName, char* revision);
uint32_t
MmsConnection_identifyAsync(MmsConnection self, MmsError* mmsError,
MmsConnection_IdentifyHandler handler, void* parameter);
void
MmsServerIdentity_destroy(MmsServerIdentity* self);

@ -71,7 +71,8 @@ typedef enum {
MMS_CALL_TYPE_DEFINE_NVL,
MMS_CALL_TYPE_DELETE_NVL,
MMS_CALL_TYPE_GET_VAR_ACCESS_ATTR,
MMS_CALL_TYPE_GET_SERVER_STATUS
MMS_CALL_TYPE_GET_SERVER_STATUS,
MMS_CALL_TYPE_IDENTIFY
} eMmsOutstandingCallType;
struct sMmsOutstandingCall
@ -277,8 +278,8 @@ mmsClient_createDeleteAssociationSpecificNamedVariableListRequest(
void
mmsClient_createIdentifyRequest(uint32_t invokeId, ByteBuffer* request);
MmsServerIdentity*
mmsClient_parseIdentifyResponse(MmsConnection self);
bool
mmsClient_parseIdentifyResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, uint32_t invokeId, MmsConnection_IdentifyHandler handler, void* parameter);
void
mmsClient_createStatusRequest(uint32_t invokeId, ByteBuffer* request, bool extendedDerivation);

@ -931,6 +931,24 @@ handleAsyncResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, M
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, vmdLogicalStatus, vmdPhysicalStatus);
}
}
else if (outstandingCall->type == MMS_CALL_TYPE_IDENTIFY) {
MmsConnection_IdentifyHandler handler =
(MmsConnection_IdentifyHandler) outstandingCall->userCallback;
if (err != MMS_ERROR_NONE) {
handler(outstandingCall->invokeId, outstandingCall->userParameter, err, NULL, NULL, NULL);
}
else {
if (mmsClient_parseIdentifyResponse(self, response, bufPos, outstandingCall->invokeId, handler,
outstandingCall->userParameter) == false)
{
handler(outstandingCall->invokeId, outstandingCall->userParameter, MMS_ERROR_PARSING_RESPONSE,
NULL, NULL, NULL);
}
}
}
removeFromOutstandingCalls(self, outstandingCall->invokeId);
@ -2679,31 +2697,86 @@ exit_function:
return invokeId;
}
struct identifyParameters
{
Semaphore waitForResponse;
MmsError err;
MmsServerIdentity* identify;
};
static void
identifyHandler(int invokeId, void* parameter, MmsError mmsError, char* vendorName, char* modelName, char* revision)
{
struct identifyParameters* parameters = (struct identifyParameters*) parameter;
parameters->err = mmsError;
parameters->identify = (MmsServerIdentity*) GLOBAL_MALLOC(sizeof(MmsServerIdentity));
parameters->identify->vendorName = StringUtils_copyString(vendorName);
parameters->identify->modelName = StringUtils_copyString(modelName);
parameters->identify->revision = StringUtils_copyString(revision);
/* unblock user thread */
Semaphore_post(parameters->waitForResponse);
}
MmsServerIdentity*
MmsConnection_identify(MmsConnection self, MmsError* mmsError)
{
MmsServerIdentity* identity = NULL;
struct identifyParameters parameter;
MmsError err = MMS_ERROR_NONE;
parameter.waitForResponse = Semaphore_create(1);
parameter.err = MMS_ERROR_NONE;
parameter.identify = NULL;
Semaphore_wait(parameter.waitForResponse);
MmsConnection_identifyAsync(self, &err, identifyHandler, &parameter);
if (err == MMS_ERROR_NONE) {
Semaphore_wait(parameter.waitForResponse);
err = parameter.err;
identity = parameter.identify;
}
Semaphore_destroy(parameter.waitForResponse);
if (mmsError)
*mmsError = err;
return identity;
}
uint32_t
MmsConnection_identifyAsync(MmsConnection self, MmsError* mmsError,
MmsConnection_IdentifyHandler handler, void* parameter)
{
uint32_t invokeId = 0;
if (getAssociationState(self) != MMS_STATE_CONNECTED) {
*mmsError = MMS_ERROR_CONNECTION_LOST;
if (mmsError)
*mmsError = MMS_ERROR_CONNECTION_LOST;
goto exit_function;
}
ByteBuffer* payload = IsoClientConnection_allocateTransmitBuffer(self->isoClient);
uint32_t invokeId = getNextInvokeId(self);
invokeId = getNextInvokeId(self);
mmsClient_createIdentifyRequest(invokeId, payload);
ByteBuffer* responseMessage = sendRequestAndWaitForResponse(self, invokeId, payload, mmsError);
if (responseMessage != NULL)
identity = mmsClient_parseIdentifyResponse(self);
MmsError err = sendAsyncRequest(self, invokeId, payload, MMS_CALL_TYPE_IDENTIFY, handler, parameter);
releaseResponse(self);
if (mmsError)
*mmsError = err;
exit_function:
return identity;
exit_function:
return invokeId;
}
struct getServerStatusParameters

@ -49,14 +49,12 @@ mmsClient_createIdentifyRequest(uint32_t invokeId, ByteBuffer* request)
request->size = bufPos;
}
MmsServerIdentity*
mmsClient_parseIdentifyResponse(MmsConnection self)
bool
mmsClient_parseIdentifyResponse(MmsConnection self, ByteBuffer* response, uint32_t bufPos, uint32_t invokeId, MmsConnection_IdentifyHandler handler, void* parameter)
{
uint8_t* buffer = self->lastResponse->buffer;
int maxBufPos = self->lastResponse->size;
int bufPos = self->lastResponseBufPos;
uint8_t* buffer = ByteBuffer_getBuffer(response);
int maxBufPos = ByteBuffer_getSize(response);
int length;
MmsServerIdentity* identityInfo = NULL;
uint8_t tag = buffer[bufPos++];
if (tag != 0xa2)
@ -73,6 +71,10 @@ mmsClient_parseIdentifyResponse(MmsConnection self)
goto exit_error;
}
char vendorNameBuf[100];
char modelNameBuf[100];
char revisionBuf[100];
char* vendorName = NULL;
char* modelName = NULL;
char* revision = NULL;
@ -85,15 +87,15 @@ mmsClient_parseIdentifyResponse(MmsConnection self)
switch (tag) {
case 0x80: /* vendorName */
vendorName = StringUtils_createStringFromBuffer(buffer + bufPos, length);
vendorName = StringUtils_createStringFromBufferInBuffer(vendorNameBuf, buffer + bufPos, length);
bufPos += length;
break;
case 0x81: /* modelName */
modelName = StringUtils_createStringFromBuffer(buffer + bufPos, length);
modelName = StringUtils_createStringFromBufferInBuffer(modelNameBuf, buffer + bufPos, length);
bufPos += length;
break;
case 0x82: /* revision */
revision = StringUtils_createStringFromBuffer(buffer + bufPos, length);
revision = StringUtils_createStringFromBufferInBuffer(revisionBuf, buffer + bufPos, length);
bufPos += length;
break;
case 0x83: /* list of abstract syntaxes */
@ -105,14 +107,18 @@ mmsClient_parseIdentifyResponse(MmsConnection self)
}
}
identityInfo = (MmsServerIdentity*) GLOBAL_MALLOC(sizeof(MmsServerIdentity));
// identityInfo = (MmsServerIdentity*) GLOBAL_MALLOC(sizeof(MmsServerIdentity));
//
// identityInfo->vendorName = vendorName;
// identityInfo->modelName = modelName;
// identityInfo->revision = revision;
handler(invokeId, parameter, MMS_ERROR_NONE, vendorName, modelName, revision);
identityInfo->vendorName = vendorName;
identityInfo->modelName = modelName;
identityInfo->revision = revision;
return true;
exit_error:
return identityInfo;
return false;
}

@ -1,7 +1,7 @@
/*
* mms_client_status.c
*
* Copyright 2013, 2014 Michael Zillgith
* Copyright 2013-2018 Michael Zillgith
*
* This file is part of libIEC61850.
*

Loading…
Cancel
Save