Example #1
0
static UA_Int32 sendHello(UA_Int32 sock, UA_String *endpointURL) {

	UA_TcpMessageHeader messageHeader;
	messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_HELF;

	UA_TcpHelloMessage hello;
	UA_String_copy(endpointURL, &hello.endpointUrl);
	hello.maxChunkCount = 1;
	hello.maxMessageSize = 16777216;
	hello.protocolVersion = 0;
	hello.receiveBufferSize = 65536;
	hello.sendBufferSize = 65536;

	messageHeader.messageSize = UA_TcpHelloMessage_calcSizeBinary((UA_TcpHelloMessage const*) &hello) +
                                UA_TcpMessageHeader_calcSizeBinary((UA_TcpMessageHeader const*) &messageHeader);
	UA_ByteString message;
	UA_ByteString_newMembers(&message, messageHeader.messageSize);

	size_t offset = 0;
	UA_TcpMessageHeader_encodeBinary((UA_TcpMessageHeader const*) &messageHeader, &message, &offset);
	UA_TcpHelloMessage_encodeBinary((UA_TcpHelloMessage const*) &hello, &message, &offset);

	UA_Int32 sendret = send(sock, message.data, offset, 0);

	UA_ByteString_deleteMembers(&message);
	free(hello.endpointUrl.data);
	if (sendret < 0)
		return 1;
	return 0;
}
Example #2
0
static UA_Int64 sendReadRequest(ConnectionInfo *connectionInfo, UA_Int32 nodeIds_size,UA_NodeId* nodeIds){
		/*UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber, UA_UInt32 requestId,
                         UA_NodeId authenticationToken, UA_Int32 nodeIds_size,UA_NodeId* nodeIds) {
                         */
	UA_ByteString *message = UA_ByteString_new();
	UA_ByteString_newMembers(message, 65536);
	UA_UInt32 tmpChannelId = connectionInfo->channelId;
	size_t offset = 0;

	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;

	UA_NodeId type;
	type.identifier.numeric = 631;
	type.identifierType = UA_NODEIDTYPE_NUMERIC;
	type.namespaceIndex = 0;

	UA_ReadRequest rq;
	UA_ReadRequest_init(&rq);
	rq.maxAge = 0;
	rq.nodesToRead = UA_Array_new(&UA_TYPES[UA_TYPES_READVALUEID], nodeIds_size);
	rq.nodesToReadSize = 1;
	for(UA_Int32 i=0;i<nodeIds_size;i++) {
		UA_ReadValueId_init(&(rq.nodesToRead[i]));
		rq.nodesToRead[i].attributeId = 6; //WriteMask
		UA_NodeId_init(&(rq.nodesToRead[i].nodeId));
		rq.nodesToRead[i].nodeId = nodeIds[i];
		UA_QualifiedName_init(&(rq.nodesToRead[0].dataEncoding));
	}
	rq.requestHeader.timeoutHint = 10000;
	rq.requestHeader.timestamp = UA_DateTime_now();
	rq.requestHeader.authenticationToken = connectionInfo->authenticationToken;
	rq.timestampsToReturn = 0x03;
	rq.requestHeader.requestHandle = 1 + connectionInfo->sequenceHdr.requestId;

	msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
                         UA_ReadRequest_calcSizeBinary(&rq);

	UA_TcpMessageHeader_encodeBinary(&msghdr,message,&offset);
	UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->tokenId, message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->sequenceHdr.sequenceNumber, message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->sequenceHdr.requestId, message, &offset);
	UA_NodeId_encodeBinary(&type,message,&offset);
	UA_ReadRequest_encodeBinary(&rq, message, &offset);

	UA_DateTime tic = UA_DateTime_now();
	UA_Int32 sendret = send(connectionInfo->socket, message->data, offset, 0);
	UA_Array_delete(rq.nodesToRead, &UA_TYPES[UA_TYPES_READVALUEID], nodeIds_size);
	UA_ByteString_delete(message);

	if (sendret < 0) {
		printf("send readrequest failed");
		return 1;
	}
	return tic;
}
Example #3
0
static UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
                                  UA_UInt32 requestId, UA_String *endpointUrl) {
    UA_ByteString message;
	UA_ByteString_newMembers(&message, 65536);
	UA_UInt32 tmpChannelId = channelId;
	size_t offset = 0;

	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;

	UA_NodeId type;
	type.identifier.numeric = 461;
	type.identifierType = UA_NODEIDTYPE_NUMERIC;
	type.namespaceIndex = 0;

	UA_CreateSessionRequest rq;
    UA_CreateSessionRequest_init(&rq);
	rq.requestHeader.requestHandle = 1;
	rq.requestHeader.timestamp = UA_DateTime_now();
	rq.requestHeader.timeoutHint = 10000;
	rq.requestHeader.authenticationToken.identifier.numeric = 10;
	rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
	rq.requestHeader.authenticationToken.namespaceIndex = 10;
	UA_String_copy(endpointUrl, &rq.endpointUrl);
	UA_String_copycstring("mysession", &rq.sessionName);
	UA_String_copycstring("abcd", &rq.clientCertificate);
	UA_ByteString_newMembers(&rq.clientNonce, 1);
	rq.clientNonce.data[0] = 0;
	rq.requestedSessionTimeout = 1200000;
	rq.maxResponseMessageSize = UA_INT32_MAX;

	msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
                         UA_CreateSessionRequest_calcSizeBinary(&rq);

	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
	UA_UInt32_encodeBinary(&tmpChannelId, &message, &offset);
	UA_UInt32_encodeBinary(&tokenId, &message, &offset);
	UA_UInt32_encodeBinary(&sequenceNumber, &message, &offset);
	UA_UInt32_encodeBinary(&requestId, &message, &offset);
	UA_NodeId_encodeBinary(&type, &message, &offset);
	UA_CreateSessionRequest_encodeBinary(&rq, &message, &offset);

	UA_Int32 sendret = send(sock, message.data, offset, 0);
	UA_ByteString_deleteMembers(&message);
	UA_CreateSessionRequest_deleteMembers(&rq);
	if (sendret < 0) {
		printf("send opensecurechannel failed");
		return 1;
	}
	return 0;
}
Example #4
0
/* HEL -> Open up the connection */
static void processHEL(UA_Connection *connection, const UA_ByteString *msg, size_t *offset) {
    UA_TcpHelloMessage helloMessage;
    if(UA_TcpHelloMessage_decodeBinary(msg, offset, &helloMessage) != UA_STATUSCODE_GOOD) {
        connection->close(connection);
        return;
    }

    /* Parameterize the connection */
    connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount; /* zero -> unlimited */
    connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize; /* zero -> unlimited */
    connection->remoteConf.protocolVersion = helloMessage.protocolVersion;
    connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize;
    if(connection->localConf.sendBufferSize > helloMessage.receiveBufferSize)
        connection->localConf.sendBufferSize = helloMessage.receiveBufferSize;
    connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize;
    if(connection->localConf.recvBufferSize > helloMessage.sendBufferSize)
        connection->localConf.recvBufferSize = helloMessage.sendBufferSize;
    connection->state = UA_CONNECTION_ESTABLISHED;
    UA_TcpHelloMessage_deleteMembers(&helloMessage);

    /* Build acknowledge response */
    UA_TcpAcknowledgeMessage ackMessage;
    ackMessage.protocolVersion = connection->localConf.protocolVersion;
    ackMessage.receiveBufferSize = connection->localConf.recvBufferSize;
    ackMessage.sendBufferSize = connection->localConf.sendBufferSize;
    ackMessage.maxMessageSize = connection->localConf.maxMessageSize;
    ackMessage.maxChunkCount = connection->localConf.maxChunkCount;

    UA_TcpMessageHeader ackHeader;
    ackHeader.messageTypeAndChunkType = UA_MESSAGETYPE_ACK + UA_CHUNKTYPE_FINAL;
    ackHeader.messageSize = 8 + 20; /* ackHeader + ackMessage */

    /* Get the send buffer from the network layer */
    UA_ByteString ack_msg;
    UA_ByteString_init(&ack_msg);
    UA_StatusCode retval =
        connection->getSendBuffer(connection, connection->localConf.sendBufferSize, &ack_msg);
    if(retval != UA_STATUSCODE_GOOD)
        return;

    /* Encode and send the response */
    size_t tmpPos = 0;
    UA_TcpMessageHeader_encodeBinary(&ackHeader, &ack_msg, &tmpPos);
    UA_TcpAcknowledgeMessage_encodeBinary(&ackMessage, &ack_msg, &tmpPos);
    ack_msg.length = ackHeader.messageSize;
    connection->send(connection, &ack_msg);
}
Example #5
0
static UA_Int32 closeSession(ConnectionInfo *connectionInfo) {
	size_t offset = 0;

	UA_ByteString message;
	UA_ByteString_newMembers(&message, 65536);

	UA_CloseSessionRequest rq;
    UA_CloseSessionRequest_init(&rq);

	rq.requestHeader.requestHandle = 1;
	rq.requestHeader.timestamp = UA_DateTime_now();
	rq.requestHeader.timeoutHint = 10000;
	rq.requestHeader.authenticationToken.identifier.numeric = 10;
	rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
	rq.requestHeader.authenticationToken.namespaceIndex = 10;
    rq.deleteSubscriptions = UA_TRUE;

	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;

	UA_NodeId type;
	type.identifier.numeric = 473;
	type.identifierType = UA_NODEIDTYPE_NUMERIC;
	type.namespaceIndex = 0;

	msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
                         UA_CloseSessionRequest_calcSizeBinary(&rq);

	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->channelId, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->tokenId, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->sequenceHdr.sequenceNumber, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->sequenceHdr.requestId, &message, &offset);
	UA_NodeId_encodeBinary(&type, &message, &offset);
	UA_CloseSessionRequest_encodeBinary(&rq, &message, &offset);

	UA_Int32 sendret = send(connectionInfo->socket, message.data, offset, 0);
	UA_ByteString_deleteMembers(&message);
	UA_CloseSessionRequest_deleteMembers(&rq);
	if(sendret < 0) {
		printf("send closesessionrequest failed");
		return 1;
	}

    return 0;
}
Example #6
0
static UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
                                    UA_UInt32 requestId, UA_NodeId authenticationToken) {
	UA_ByteString *message = UA_ByteString_new();
	UA_ByteString_newMembers(message, 65536);
	UA_UInt32 tmpChannelId = channelId;
	size_t offset = 0;

	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;
	msghdr.messageSize = 86;

	UA_NodeId type;
	type.identifier.numeric = 467;
	type.identifierType = UA_NODEIDTYPE_NUMERIC;
	type.namespaceIndex = 0;

	UA_ActivateSessionRequest rq;
	UA_ActivateSessionRequest_init(&rq);
	rq.requestHeader.requestHandle = 2;
	rq.requestHeader.authenticationToken = authenticationToken;
	rq.requestHeader.timestamp = UA_DateTime_now();
	rq.requestHeader.timeoutHint = 10000;
    
	msghdr.messageSize  = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
                          UA_ActivateSessionRequest_calcSizeBinary(&rq);

	UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
	UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
	UA_UInt32_encodeBinary(&tokenId, message, &offset);
	UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
	UA_UInt32_encodeBinary(&requestId, message, &offset);
	UA_NodeId_encodeBinary(&type, message, &offset);
	UA_ActivateSessionRequest_encodeBinary(&rq, message, &offset);

	UA_Int32 sendret = send(sock, message->data, offset, 0);
	UA_ByteString_delete(message);

	if (sendret < 0) {
		printf("send opensecurechannel failed");
		return 1;
	}
	return 0;

}
static UA_StatusCode
sendHELMessage(UA_Client *client) {
    /* Get a buffer */
    UA_ByteString message;
    UA_Connection *conn = &client->connection;
    UA_StatusCode retval = conn->getSendBuffer(conn, UA_MINMESSAGESIZE, &message);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;

    /* Prepare the HEL message and encode at offset 8 */
    UA_TcpHelloMessage hello;
    UA_String_copy(&client->endpointUrl, &hello.endpointUrl); /* must be less than 4096 bytes */
    memcpy(&hello, &client->config.localConnectionConfig,
           sizeof(UA_ConnectionConfig)); /* same struct layout */

    UA_Byte *bufPos = &message.data[8]; /* skip the header */
    const UA_Byte *bufEnd = &message.data[message.length];
    client->connectStatus = UA_TcpHelloMessage_encodeBinary(&hello, &bufPos, bufEnd);
    UA_TcpHelloMessage_deleteMembers (&hello);

    /* Encode the message header at offset 0 */
    UA_TcpMessageHeader messageHeader;
    messageHeader.messageTypeAndChunkType = UA_CHUNKTYPE_FINAL + UA_MESSAGETYPE_HEL;
    messageHeader.messageSize = (UA_UInt32) ((uintptr_t)bufPos - (uintptr_t)message.data);
    bufPos = message.data;
    retval = UA_TcpMessageHeader_encodeBinary(&messageHeader, &bufPos, bufEnd);
    if(retval != UA_STATUSCODE_GOOD) {
        conn->releaseSendBuffer(conn, &message);
        return retval;
    }

    /* Send the HEL message */
    message.length = messageHeader.messageSize;
    retval = conn->send (conn, &message);

    if(retval == UA_STATUSCODE_GOOD) {
        UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Sent HEL message");
    } else {
        UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Sending HEL failed");
    }
    return retval;
}
Example #8
0
static void processHEL(UA_Connection *connection, const UA_ByteString *msg, size_t *pos) {
    UA_TcpHelloMessage helloMessage;
    if(UA_TcpHelloMessage_decodeBinary(msg, pos, &helloMessage) != UA_STATUSCODE_GOOD) {
        connection->close(connection);
        return;
    }

    connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount;
    connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize;
    connection->remoteConf.protocolVersion = helloMessage.protocolVersion;
    connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize;
    if(connection->localConf.sendBufferSize > helloMessage.receiveBufferSize)
        connection->localConf.sendBufferSize = helloMessage.receiveBufferSize;
    if(connection->localConf.recvBufferSize > helloMessage.sendBufferSize)
        connection->localConf.recvBufferSize = helloMessage.sendBufferSize;
    connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize;
    connection->state = UA_CONNECTION_ESTABLISHED;
    UA_TcpHelloMessage_deleteMembers(&helloMessage);

    // build acknowledge response
    UA_TcpAcknowledgeMessage ackMessage;
    ackMessage.protocolVersion = connection->localConf.protocolVersion;
    ackMessage.receiveBufferSize = connection->localConf.recvBufferSize;
    ackMessage.sendBufferSize = connection->localConf.sendBufferSize;
    ackMessage.maxMessageSize = connection->localConf.maxMessageSize;
    ackMessage.maxChunkCount = connection->localConf.maxChunkCount;

    UA_TcpMessageHeader ackHeader;
    ackHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_ACKF;
    ackHeader.messageSize = UA_TcpMessageHeader_calcSizeBinary(&ackHeader) 
        + UA_TcpAcknowledgeMessage_calcSizeBinary(&ackMessage);

    UA_ByteString ack_msg;
    if(connection->getBuffer(connection, &ack_msg, ackHeader.messageSize) != UA_STATUSCODE_GOOD)
        return;

    size_t tmpPos = 0;
    UA_TcpMessageHeader_encodeBinary(&ackHeader, &ack_msg, &tmpPos);
    UA_TcpAcknowledgeMessage_encodeBinary(&ackMessage, &ack_msg, &tmpPos);
    connection->write(connection, &ack_msg);
    connection->releaseBuffer(connection, &ack_msg);
}
Example #9
0
static UA_Int32 closeSecureChannel(ConnectionInfo *connectionInfo) {
	size_t offset = 0;

	UA_ByteString message;
	UA_ByteString_newMembers(&message, 65536);

	UA_CloseSecureChannelRequest rq;
    UA_CloseSecureChannelRequest_init(&rq);

	rq.requestHeader.requestHandle = 1;
	rq.requestHeader.timestamp = UA_DateTime_now();
	rq.requestHeader.timeoutHint = 10000;
	rq.requestHeader.authenticationToken.identifier.numeric = 10;
	rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
	rq.requestHeader.authenticationToken.namespaceIndex = 10;

	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_CLOF;

	msghdr.messageSize = 4 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) +
                         UA_CloseSecureChannelRequest_calcSizeBinary(&rq);

	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->channelId, &message, &offset);
	UA_CloseSecureChannelRequest_encodeBinary(&rq, &message, &offset);

	UA_Int32 sendret = send(connectionInfo->socket, message.data, offset, 0);
	UA_ByteString_deleteMembers(&message);
	UA_CloseSecureChannelRequest_deleteMembers(&rq);
	if(sendret < 0) {
		printf("send CloseSecureChannelRequest failed");
		return 1;
	}

    return 0;
}
Example #10
0
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;
}
Example #11
0
static int sendOpenSecureChannel(UA_Int32 sock) {
	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_OPNF;

	UA_UInt32 secureChannelId = 0;
	UA_String securityPolicy;
	UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None", &securityPolicy);

	UA_String senderCert;
	senderCert.data = UA_NULL;
	senderCert.length = -1;

	UA_String receiverCertThumb;
	receiverCertThumb.data = UA_NULL;
	receiverCertThumb.length = -1;

	UA_UInt32 sequenceNumber = 51;

	UA_UInt32 requestId = 1;

	UA_NodeId type;
	type.identifier.numeric = 446; // id of opensecurechannelrequest
	type.identifierType = UA_NODEIDTYPE_NUMERIC;
	type.namespaceIndex = 0;

	UA_OpenSecureChannelRequest opnSecRq;
	UA_OpenSecureChannelRequest_init(&opnSecRq);
	opnSecRq.requestHeader.timestamp = UA_DateTime_now();
	UA_ByteString_newMembers(&opnSecRq.clientNonce, 1);
	opnSecRq.clientNonce.data[0] = 0;
	opnSecRq.clientProtocolVersion = 0;
	opnSecRq.requestedLifetime = 30000;
	opnSecRq.securityMode = UA_MESSAGESECURITYMODE_NONE;
	opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE;
	opnSecRq.requestHeader.authenticationToken.identifier.numeric = 10;
	opnSecRq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
	opnSecRq.requestHeader.authenticationToken.namespaceIndex = 10;

	msghdr.messageSize = 135; // todo: compute the message size from the actual content

	UA_ByteString message;
	UA_ByteString_newMembers(&message, 1000);
	size_t offset = 0;
	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
	UA_UInt32_encodeBinary(&secureChannelId, &message, &offset);
	UA_String_encodeBinary(&securityPolicy, &message, &offset);
	UA_String_encodeBinary(&senderCert, &message, &offset);
	UA_String_encodeBinary(&receiverCertThumb, &message, &offset);
	UA_UInt32_encodeBinary(&sequenceNumber, &message, &offset);
	UA_UInt32_encodeBinary(&requestId, &message, &offset);
	UA_NodeId_encodeBinary(&type, &message, &offset);
	UA_OpenSecureChannelRequest_encodeBinary(&opnSecRq, &message, &offset);

    UA_OpenSecureChannelRequest_deleteMembers(&opnSecRq);
	UA_String_deleteMembers(&securityPolicy);

	UA_Int32 sendret = send(sock, message.data, offset, 0);
	UA_ByteString_deleteMembers(&message);
	if (sendret < 0) {
		printf("send opensecurechannel failed");
		return 1;
	}
	return 0;
}
int main(int argc , char *argv[]) {
	int sock;
	struct sockaddr_in server;
	UA_ByteString message;
	message.data = (UA_Byte*)malloc(1000*sizeof(UA_Byte));
	message.length = 1000;
	//UA_UInt32 messageEncodedLength = 0;
	UA_Byte server_reply[2000];
	unsigned int messagepos = 0;

	//Create socket
#ifdef UA_ENABLE_NONSTANDARD_UDP
	sock = socket(AF_INET , SOCK_DGRAM , 0);
#else
	sock = socket(AF_INET , SOCK_STREAM , 0);
#endif
	if(sock == -1) {
		printf("Could not create socket");
	}
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	server.sin_family = AF_INET;
	server.sin_port = htons( 16664 );

	//Connect to remote server
	if(connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
		perror("connect failed. Error");
		return 1;
	}

	UA_TcpMessageHeader reqTcpHeader;
	UA_UInt32 reqSecureChannelId = 0;
	UA_UInt32 reqTokenId = 0;
	UA_SequenceHeader reqSequenceHeader;
	UA_NodeId reqRequestType;
	UA_ReadRequest req;
	UA_RequestHeader reqHeader;
	UA_NodeId reqHeaderAuthToken;
	UA_ExtensionObject reqHeaderAdditionalHeader;

	UA_NodeId_init(&reqRequestType);
	reqRequestType.identifierType = UA_NODEIDTYPE_NUMERIC;
	reqRequestType.identifier.numeric = 631; //read request

	UA_SequenceHeader_init(&reqSequenceHeader);
	reqSequenceHeader.sequenceNumber = 42;

	UA_ReadRequest_init(&req);
	req.requestHeader = reqHeader;
	UA_RequestHeader_init(&(req.requestHeader));
	req.requestHeader.authenticationToken = reqHeaderAuthToken;
	UA_NodeId_init(&(req.requestHeader.authenticationToken));
	req.requestHeader.additionalHeader = reqHeaderAdditionalHeader;
	UA_ExtensionObject_init(&(req.requestHeader.additionalHeader));

	req.nodesToRead= UA_Array_new(&UA_TYPES[UA_TYPES_READVALUEID], 1);
	req.nodesToReadSize = 1;

	UA_ReadValueId_init(&(req.nodesToRead[0]));
	req.nodesToRead[0].attributeId = 13; //UA_ATTRIBUTEID_VALUE
	UA_NodeId_init(&(req.nodesToRead[0].nodeId));
	req.nodesToRead[0].nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
	req.nodesToRead[0].nodeId.identifier.numeric = 2255;
	UA_QualifiedName_init(&(req.nodesToRead[0].dataEncoding));

	/**messageEncodedLength = UA_TcpMessageHeader_calcSizeBinary(&reqTcpHeader) +
			UA_UInt32_calcSizeBinary(&reqSecureChannelId)+
			UA_UInt32_calcSizeBinary(&reqTokenId)+
			UA_SequenceHeader_calcSizeBinary(&reqSequenceHeader)+
			UA_NodeId_calcSizeBinary(&reqRequestType) +
			UA_ReadRequest_calcSizeBinary(&req);**/

	UA_TcpMessageHeader_init(&reqTcpHeader);
	reqTcpHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;

	UA_TcpMessageHeader_encodeBinary(&reqTcpHeader, &message, &messagepos);
	UA_UInt32_encodeBinary(&reqSecureChannelId, &message, &messagepos);
	UA_UInt32_encodeBinary(&reqTokenId, &message, &messagepos);
	UA_SequenceHeader_encodeBinary(&reqSequenceHeader, &message, &messagepos);
	UA_NodeId_encodeBinary(&reqRequestType, &message, &messagepos);
	UA_ReadRequest_encodeBinary(&req, &message, &messagepos);
    reqTcpHeader.messageSize = messagepos;
    messagepos=0;

    UA_TcpMessageHeader_encodeBinary(&reqTcpHeader, &message, &messagepos);
    UA_UInt32_encodeBinary(&reqSecureChannelId, &message, &messagepos);
    UA_UInt32_encodeBinary(&reqTokenId, &message, &messagepos);
    UA_SequenceHeader_encodeBinary(&reqSequenceHeader, &message, &messagepos);
    UA_NodeId_encodeBinary(&reqRequestType, &message, &messagepos);
    UA_ReadRequest_encodeBinary(&req, &message, &messagepos);

	//Send some data
	if(send(sock , message.data, messagepos , 0) < 0) {
		puts("Send failed");
		return 1;
	}

	//Receive a reply from the server
	int received = recv(sock , server_reply , 2000 , 0);
	if(received < 0) {
		puts("recv failed");
		return 1;
	}


	for(int i=0;i<received;i++) {
		  //show only printable ascii
		  if(server_reply[i] >= 32 && server_reply[i]<= 126)
			  printf("%c",server_reply[i]);
	}
	printf("\n");
	close(sock);
	return 0;
}