/*receives hello ack, opens secure channel*/ UA_StatusCode processACKResponseAsync(void *application, UA_Connection *connection, UA_ByteString *chunk) { UA_Client *client = (UA_Client*)application; /* Decode the message */ size_t offset = 0; UA_TcpMessageHeader messageHeader; UA_TcpAcknowledgeMessage ackMessage; client->connectStatus = UA_TcpMessageHeader_decodeBinary (chunk, &offset, &messageHeader); client->connectStatus |= UA_TcpAcknowledgeMessage_decodeBinary( chunk, &offset, &ackMessage); if (client->connectStatus != UA_STATUSCODE_GOOD) { UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Decoding ACK message failed"); return client->connectStatus; } UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Received ACK message"); client->connectStatus = UA_Connection_processHELACK(connection, &client->config.localConnectionConfig, (const UA_ConnectionConfig*)&ackMessage); if(client->connectStatus != UA_STATUSCODE_GOOD) return client->connectStatus; client->state = UA_CLIENTSTATE_CONNECTED; /* Open a SecureChannel. TODO: Select with endpoint */ client->channel.connection = &client->connection; client->connectStatus = openSecureChannelAsync(client/*, false*/); return client->connectStatus; }
static UA_StatusCode HelAckHandshake(UA_Client *c) { UA_TcpMessageHeader messageHeader; messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_HELF; UA_TcpHelloMessage hello; UA_String_copy(&c->endpointUrl, &hello.endpointUrl); /* must be less than 4096 bytes */ UA_Connection *conn = &c->connection; hello.maxChunkCount = conn->localConf.maxChunkCount; hello.maxMessageSize = conn->localConf.maxMessageSize; hello.protocolVersion = conn->localConf.protocolVersion; hello.receiveBufferSize = conn->localConf.recvBufferSize; hello.sendBufferSize = conn->localConf.sendBufferSize; UA_ByteString message; UA_StatusCode retval; retval = c->connection.getSendBuffer(&c->connection, c->connection.remoteConf.recvBufferSize, &message); if(retval != UA_STATUSCODE_GOOD) return retval; size_t offset = 8; retval |= UA_TcpHelloMessage_encodeBinary(&hello, &message, &offset); messageHeader.messageSize = offset; offset = 0; retval |= UA_TcpMessageHeader_encodeBinary(&messageHeader, &message, &offset); UA_TcpHelloMessage_deleteMembers(&hello); if(retval != UA_STATUSCODE_GOOD) { c->connection.releaseSendBuffer(&c->connection, &message); return retval; } message.length = messageHeader.messageSize; retval = c->connection.send(&c->connection, &message); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_DEBUG(c->logger, UA_LOGCATEGORY_NETWORK, "Sending HEL failed"); return retval; } UA_LOG_DEBUG(c->logger, UA_LOGCATEGORY_NETWORK, "Sent HEL message"); UA_ByteString reply; UA_ByteString_init(&reply); do { retval = c->connection.recv(&c->connection, &reply, c->config.timeout); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_DEBUG(c->logger, UA_LOGCATEGORY_NETWORK, "Receiving ACK message failed"); return retval; } } while(!reply.data); offset = 0; UA_TcpMessageHeader_decodeBinary(&reply, &offset, &messageHeader); UA_TcpAcknowledgeMessage ackMessage; retval = UA_TcpAcknowledgeMessage_decodeBinary(&reply, &offset, &ackMessage); UA_ByteString_deleteMembers(&reply); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_DEBUG(c->logger, UA_LOGCATEGORY_NETWORK, "Decoding ACK message failed"); return retval; } UA_LOG_DEBUG(c->logger, UA_LOGCATEGORY_NETWORK, "Received ACK message"); conn->remoteConf.maxChunkCount = ackMessage.maxChunkCount; conn->remoteConf.maxMessageSize = ackMessage.maxMessageSize; conn->remoteConf.protocolVersion = ackMessage.protocolVersion; conn->remoteConf.recvBufferSize = ackMessage.receiveBufferSize; conn->remoteConf.sendBufferSize = ackMessage.sendBufferSize; conn->state = UA_CONNECTION_ESTABLISHED; return UA_STATUSCODE_GOOD; }