diff --git a/src/mms/inc_private/mms_client_internal.h b/src/mms/inc_private/mms_client_internal.h index 86253325..45c64c25 100644 --- a/src/mms/inc_private/mms_client_internal.h +++ b/src/mms/inc_private/mms_client_internal.h @@ -79,8 +79,12 @@ struct sMmsConnection { uint32_t connectTimeout; IsoClientConnection isoClient; - AssociationState associationState; - ConnectionState connectionState; + + volatile AssociationState associationState; + Semaphore associationStateLock; + + volatile ConnectionState connectionState; + Semaphore connectionStateLock; MmsConnectionParameters parameters; IsoConnectionParameters isoParameters; @@ -97,7 +101,8 @@ struct sMmsConnection { #endif /* state of an active connection conclude/release process */ - int concludeState; + volatile int concludeState; + Semaphore concludeStateLock; #if (MMS_OBTAIN_FILE_SERVICE == 1) int32_t nextFrsmId; diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index 7111b657..a9251905 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -39,6 +39,66 @@ #define CONFIG_MMS_CONNECTION_DEFAULT_CONNECT_TIMEOUT 10000 #define OUTSTANDING_CALLS 10 +static void +setAssociationState(MmsConnection self, AssociationState newState) +{ + Semaphore_wait(self->associationStateLock); + self->associationState = newState; + Semaphore_post(self->associationStateLock); +} + +static AssociationState +getAssociationState(MmsConnection self) +{ + AssociationState state; + + Semaphore_wait(self->associationStateLock); + state = self->associationState; + Semaphore_post(self->associationStateLock); + + return state; +} + +static void +setConnectionState(MmsConnection self, ConnectionState newState) +{ + Semaphore_wait(self->connectionStateLock); + self->connectionState = newState; + Semaphore_post(self->connectionStateLock); +} + +static ConnectionState +getConnectionState(MmsConnection self) +{ + ConnectionState state; + + Semaphore_wait(self->connectionStateLock); + state = self->connectionState; + Semaphore_post(self->connectionStateLock); + + return state; +} + +static void +setConcludeState(MmsConnection self, int newState) +{ + Semaphore_wait(self->concludeStateLock); + self->concludeState = newState; + Semaphore_post(self->concludeStateLock); +} + +static int +getConcludeState(MmsConnection self) +{ + int state; + + Semaphore_wait(self->concludeStateLock); + state = self->concludeState; + Semaphore_post(self->concludeStateLock); + + return state; +} + static void handleUnconfirmedMmsPdu(MmsConnection self, ByteBuffer* message) { @@ -310,7 +370,7 @@ sendRequestAndWaitForResponse(MmsConnection self, uint32_t invokeId, ByteBuffer* while (currentTime < waitUntilTime) { uint32_t receivedInvokeId; - if (self->associationState == MMS_STATE_CLOSED) { + if (getAssociationState(self) == MMS_STATE_CLOSED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto connection_lost; } @@ -688,8 +748,8 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) if (indication == ISO_IND_CLOSED) { if (DEBUG_MMS_CLIENT) printf("MMS_CLIENT: mmsIsoCallback: Connection lost or closed by client!\n"); - self->connectionState = MMS_CON_IDLE; - self->associationState = MMS_STATE_CLOSED; + setConnectionState(self, MMS_CON_IDLE); + setAssociationState(self, MMS_STATE_CLOSED); /* Call user provided callback function */ if (self->connectionLostHandler != NULL) @@ -701,8 +761,8 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) if (indication == ISO_IND_ASSOCIATION_FAILED) { if (DEBUG_MMS_CLIENT) printf("MMS_CLIENT: mmsIsoCallback: association failed!\n"); - self->connectionState = MMS_CON_ASSOCIATION_FAILED; - self->associationState = MMS_STATE_CLOSED; + setConnectionState(self, MMS_CON_ASSOCIATION_FAILED); + setAssociationState(self, MMS_STATE_CLOSED); return; } @@ -728,12 +788,12 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) printf("MMS_CLIENT: MMS-PDU: %02x\n", tag); if (tag == 0xa9) { /* initiate response PDU */ - if (indication == ISO_IND_ASSOCIATION_SUCCESS) { - self->connectionState = MMS_CON_ASSOCIATED; - } - else { - self->connectionState = MMS_CON_ASSOCIATION_FAILED; - } + + if (indication == ISO_IND_ASSOCIATION_SUCCESS) + setConnectionState(self, MMS_CON_ASSOCIATED); + else + setConnectionState(self, MMS_CON_ASSOCIATION_FAILED); + self->lastResponse = payload; IsoClientConnection_releaseReceiveBuffer(self->isoClient); @@ -746,7 +806,7 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) if (DEBUG_MMS_CLIENT) printf("MMS_CLIENT: received conclude.request\n"); - self->concludeState = CONCLUDE_STATE_REQUESTED; + setConcludeState(self, CONCLUDE_STATE_REQUESTED); /* TODO block all new user requests? */ @@ -756,7 +816,7 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) if (DEBUG_MMS_CLIENT) printf("MMS_CLIENT: received conclude.reponse+\n"); - self->concludeState = CONCLUDE_STATE_ACCEPTED; + setConcludeState(self, CONCLUDE_STATE_ACCEPTED); IsoClientConnection_release(self->isoClient); @@ -766,7 +826,7 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload) if (DEBUG_MMS_CLIENT) printf("MMS_CLIENT: received conclude.reponse-\n"); - self->concludeState = CONCLUDE_STATE_REJECTED; + setConcludeState(self, CONCLUDE_STATE_REJECTED); IsoClientConnection_releaseReceiveBuffer(self->isoClient); } @@ -1030,6 +1090,10 @@ MmsConnection_create() self->lastResponseLock = Semaphore_create(1); self->outstandingCallsLock = Semaphore_create(1); + self->connectionStateLock = Semaphore_create(1); + self->concludeStateLock = Semaphore_create(1); + self->associationStateLock = Semaphore_create(1); + self->lastResponseError = MMS_ERROR_NONE; self->outstandingCalls = (uint32_t*) GLOBAL_CALLOC(OUTSTANDING_CALLS, sizeof(uint32_t)); @@ -1065,6 +1129,10 @@ MmsConnection_destroy(MmsConnection self) Semaphore_destroy(self->lastResponseLock); Semaphore_destroy(self->outstandingCallsLock); + Semaphore_destroy(self->associationStateLock); + Semaphore_destroy(self->connectionStateLock); + Semaphore_destroy(self->concludeStateLock); + GLOBAL_FREEMEM(self->outstandingCalls); #if (MMS_OBTAIN_FILE_SERVICE == 1) @@ -1172,7 +1240,7 @@ waitForConnectResponse(MmsConnection self) uint64_t waitUntilTime = currentTime + self->requestTimeout; while (currentTime < waitUntilTime) { - if (self->connectionState != MMS_CON_WAITING) + if (getConnectionState(self) != MMS_CON_WAITING) break; Thread_sleep(10); @@ -1200,7 +1268,7 @@ MmsConnection_connect(MmsConnection self, MmsError* mmsError, const char* server } #endif /* (CONFIG_MMS_RAW_MESSAGE_LOGGING == 1) */ - self->connectionState = MMS_CON_WAITING; + setConnectionState(self, MMS_CON_WAITING); IsoClientConnection_associate(self->isoClient, self->isoParameters, payload, self->connectTimeout); @@ -1208,25 +1276,24 @@ MmsConnection_connect(MmsConnection self, MmsError* mmsError, const char* server waitForConnectResponse(self); if (DEBUG_MMS_CLIENT) - printf("MmsConnection_connect: received response conState: %i\n", self->connectionState); + printf("MmsConnection_connect: received response conState: %i\n", getConnectionState(self)); - if (self->connectionState == MMS_CON_ASSOCIATED) { + if (getConnectionState(self) == MMS_CON_ASSOCIATED) { mmsClient_parseInitiateResponse(self); releaseResponse(self); - self->associationState = MMS_STATE_CONNECTED; - } - else { - self->associationState = MMS_STATE_CLOSED; + setAssociationState(self, MMS_STATE_CONNECTED); } + else + setAssociationState(self, MMS_STATE_CLOSED); - self->connectionState = MMS_CON_IDLE; + setConnectionState(self, MMS_CON_IDLE); if (DEBUG_MMS_CLIENT) - printf("MmsConnection_connect: states: con %i ass %i\n", self->connectionState, self->associationState); + printf("MmsConnection_connect: states: con %i ass %i\n", getConnectionState(self), getAssociationState(self)); - if (self->associationState == MMS_STATE_CONNECTED) { + if (getAssociationState(self) == MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_NONE; return true; } @@ -1241,7 +1308,7 @@ MmsConnection_close(MmsConnection self) { self->connectionLostHandler = NULL; - if (self->associationState == MMS_STATE_CONNECTED) + if (getAssociationState(self) == MMS_STATE_CONNECTED) IsoClientConnection_close(self->isoClient); } @@ -1254,7 +1321,7 @@ MmsConnection_abort(MmsConnection self, MmsError* mmsError) bool success = true; - if (self->associationState == MMS_STATE_CONNECTED) + if (getAssociationState(self) == MMS_STATE_CONNECTED) success = IsoClientConnection_abort(self->isoClient); if (success == false) { @@ -1278,16 +1345,16 @@ sendConcludeRequestAndWaitForResponse(MmsConnection self) mmsClient_createConcludeRequest(self, concludeMessage); - self->concludeState = CONCLUDE_STATE_REQUESTED; + setConcludeState(self, CONCLUDE_STATE_REQUESTED); IsoClientConnection_sendMessage(self->isoClient, concludeMessage); while (currentTime < waitUntilTime) { - if (self->associationState == MMS_STATE_CLOSED) + if (getAssociationState(self) == MMS_STATE_CLOSED) goto exit_function; - if (self->concludeState != CONCLUDE_STATE_REQUESTED) { + if (getConcludeState(self) != CONCLUDE_STATE_REQUESTED) { success = true; break; } @@ -1310,7 +1377,7 @@ exit_function: void MmsConnection_conclude(MmsConnection self, MmsError* mmsError) { - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1324,12 +1391,12 @@ MmsConnection_conclude(MmsConnection self, MmsError* mmsError) releaseResponse(self); - if (self->concludeState != CONCLUDE_STATE_ACCEPTED) { + if (getConcludeState(self) != CONCLUDE_STATE_ACCEPTED) { - if (self->associationState == MMS_STATE_CLOSED) + if (getAssociationState(self) == MMS_STATE_CLOSED) *mmsError = MMS_ERROR_CONNECTION_LOST; - if (self->concludeState == CONCLUDE_STATE_REJECTED) + if (getConcludeState(self) == CONCLUDE_STATE_REJECTED) *mmsError = MMS_ERROR_CONCLUDE_REJECTED; } @@ -1359,7 +1426,7 @@ mmsClient_getNameListSingleRequest( { bool moreFollows = false; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1462,7 +1529,7 @@ MmsConnection_readVariable(MmsConnection self, MmsError* mmsError, { MmsValue* value = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1491,7 +1558,7 @@ MmsConnection_readArrayElements(MmsConnection self, MmsError* mmsError, { MmsValue* value = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1520,7 +1587,7 @@ MmsConnection_readMultipleVariables(MmsConnection self, MmsError* mmsError, { MmsValue* value = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1549,7 +1616,7 @@ MmsConnection_readNamedVariableListValues(MmsConnection self, MmsError* mmsError { MmsValue* value = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1580,7 +1647,7 @@ MmsConnection_readNamedVariableListValuesAssociationSpecific( { MmsValue* value = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1609,7 +1676,7 @@ MmsConnection_readNamedVariableListDirectory(MmsConnection self, MmsError* mmsEr { LinkedList attributes = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1639,7 +1706,7 @@ MmsConnection_readNamedVariableListDirectoryAssociationSpecific(MmsConnection se { LinkedList attributes = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1667,7 +1734,7 @@ void MmsConnection_defineNamedVariableList(MmsConnection self, MmsError* mmsError, const char* domainId, const char* listName, LinkedList variableSpecs) { - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1695,7 +1762,7 @@ void MmsConnection_defineNamedVariableListAssociationSpecific(MmsConnection self, MmsError* mmsError, const char* listName, LinkedList variableSpecs) { - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1726,7 +1793,7 @@ MmsConnection_deleteNamedVariableList(MmsConnection self, MmsError* mmsError, { bool isDeleted = false; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1755,7 +1822,7 @@ MmsConnection_deleteAssociationSpecificNamedVariableList(MmsConnection self, { bool isDeleted = false; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1785,7 +1852,7 @@ MmsConnection_getVariableAccessAttributes(MmsConnection self, MmsError* mmsError { MmsVariableSpecification* typeSpec = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; } @@ -1812,7 +1879,7 @@ MmsConnection_identify(MmsConnection self, MmsError* mmsError) { MmsServerIdentity* identity = NULL; - if (self->associationState != MMS_STATE_CONNECTED) { + if (getAssociationState(self) != MMS_STATE_CONNECTED) { *mmsError = MMS_ERROR_CONNECTION_LOST; goto exit_function; }