static void sendError(UA_SecureChannel *channel, const UA_ByteString *msg, size_t pos, UA_UInt32 requestId, UA_StatusCode error) { UA_RequestHeader p; if(UA_RequestHeader_decodeBinary(msg, &pos, &p) != UA_STATUSCODE_GOOD) return; UA_ResponseHeader r; UA_ResponseHeader_init(&r); init_response_header(&p, &r); r.serviceResult = error; UA_SecureChannel_sendBinaryMessage(channel, requestId, &r, &UA_TYPES[UA_TYPES_SERVICEFAULT]); UA_RequestHeader_deleteMembers(&p); UA_ResponseHeader_deleteMembers(&r); }
static void sendError(UA_SecureChannel *channel, const UA_ByteString *msg, size_t offset, const UA_DataType *responseType, UA_UInt32 requestId, UA_StatusCode error) { UA_RequestHeader requestHeader; UA_StatusCode retval = UA_RequestHeader_decodeBinary(msg, &offset, &requestHeader); if(retval != UA_STATUSCODE_GOOD) return; void *response = UA_alloca(responseType->memSize); UA_init(response, responseType); UA_ResponseHeader *responseHeader = (UA_ResponseHeader*)response; responseHeader->requestHandle = requestHeader.requestHandle; responseHeader->timestamp = UA_DateTime_now(); responseHeader->serviceResult = error; UA_SecureChannel_sendBinaryMessage(channel, requestId, response, responseType); UA_RequestHeader_deleteMembers(&requestHeader); UA_ResponseHeader_deleteMembers(responseHeader); }
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); }