/* Adding repeated callbacks: Add an entry with the "nextTime" timestamp in the * future. This will be picked up in the next iteration and inserted at the * correct place. So that the next execution takes place ät "nextTime". */ UA_StatusCode UA_Timer_addRepeatedCallback(UA_Timer *t, UA_TimerCallback callback, void *data, UA_UInt32 interval, UA_UInt64 *callbackId) { /* A callback method needs to be present */ if(!callback) return UA_STATUSCODE_BADINTERNALERROR; /* The interval needs to be at least 5ms */ if(interval < 5) return UA_STATUSCODE_BADINTERNALERROR; /* Allocate the repeated callback structure */ UA_TimerCallbackEntry *tc = (UA_TimerCallbackEntry*)UA_malloc(sizeof(UA_TimerCallbackEntry)); if(!tc) return UA_STATUSCODE_BADOUTOFMEMORY; /* Set the repeated callback */ tc->interval = (UA_UInt64)interval * UA_DATETIME_MSEC; tc->id = ++t->idCounter; tc->callback = callback; tc->data = data; tc->nextTime = UA_DateTime_nowMonotonic() + (UA_DateTime)tc->interval; /* Set the output identifier */ if(callbackId) *callbackId = tc->id; /* Enqueue the changes in the MPSC queue */ enqueueChange(t, tc); return UA_STATUSCODE_GOOD; }
void Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel, UA_Session *session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response) { if(session->validTill < UA_DateTime_nowMonotonic()) { UA_LOG_INFO_SESSION(server->config.logger, session, "ActivateSession: SecureChannel %i wants " "to activate, but the session has timed out", channel->securityToken.channelId); response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID; return; } checkSignature(server, channel, session, request, response); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) return; /* Callback into userland access control */ response->responseHeader.serviceResult = server->config.accessControl.activateSession(&session->sessionId, &request->userIdentityToken, &session->sessionHandle); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) return; /* Detach the old SecureChannel */ if(session->channel && session->channel != channel) { UA_LOG_INFO_SESSION(server->config.logger, session, "ActivateSession: Detach from old channel"); UA_SecureChannel_detachSession(session->channel, session); } /* Attach to the SecureChannel and activate */ UA_SecureChannel_attachSession(channel, session); session->activated = true; UA_Session_updateLifetime(session); UA_LOG_INFO_SESSION(server->config.logger, session, "ActivateSession: Session activated"); }
static void processDecodedOPNResponseAsync(void *application, UA_SecureChannel *channel, UA_MessageType messageType, UA_UInt32 requestId, const UA_ByteString *message) { /* Does the request id match? */ UA_Client *client = (UA_Client*)application; if(requestId != client->requestId) { UA_Client_disconnect(client); return; } /* Is the content of the expected type? */ size_t offset = 0; UA_NodeId responseId; UA_NodeId expectedId = UA_NODEID_NUMERIC( 0, UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE].binaryEncodingId); UA_StatusCode retval = UA_NodeId_decodeBinary(message, &offset, &responseId); if(retval != UA_STATUSCODE_GOOD) { UA_Client_disconnect(client); return; } if(!UA_NodeId_equal(&responseId, &expectedId)) { UA_NodeId_deleteMembers(&responseId); UA_Client_disconnect(client); return; } UA_NodeId_deleteMembers (&responseId); /* Decode the response */ UA_OpenSecureChannelResponse response; retval = UA_OpenSecureChannelResponse_decodeBinary(message, &offset, &response); if(retval != UA_STATUSCODE_GOOD) { UA_Client_disconnect(client); return; } /* Response.securityToken.revisedLifetime is UInt32 we need to cast it to * DateTime=Int64 we take 75% of lifetime to start renewing as described in * standard */ client->nextChannelRenewal = UA_DateTime_nowMonotonic() + (UA_DateTime) (response.securityToken.revisedLifetime * (UA_Double) UA_DATETIME_MSEC * 0.75); /* Replace the token and nonce */ UA_ChannelSecurityToken_deleteMembers(&client->channel.securityToken); UA_ByteString_deleteMembers(&client->channel.remoteNonce); client->channel.securityToken = response.securityToken; client->channel.remoteNonce = response.serverNonce; UA_ResponseHeader_deleteMembers(&response.responseHeader); /* the other members were moved */ if(client->channel.state == UA_SECURECHANNELSTATE_OPEN) UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "SecureChannel renewed"); else UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "SecureChannel opened"); client->channel.state = UA_SECURECHANNELSTATE_OPEN; if(client->state < UA_CLIENTSTATE_SECURECHANNEL) setClientState(client, UA_CLIENTSTATE_SECURECHANNEL); }