END_TEST /* Send an async message and receive the response when the securechannel timed out */ START_TEST(SecureChannel_networkfail) { UA_Client *client = UA_Client_new(); UA_ClientConfig_setDefault(UA_Client_getConfig(client)); UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840"); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); UA_ReadRequest rq; UA_ReadRequest_init(&rq); UA_ReadValueId rvi; UA_ReadValueId_init(&rvi); rvi.attributeId = UA_ATTRIBUTEID_VALUE; rvi.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE); rq.nodesToRead = &rvi; rq.nodesToReadSize = 1; /* Forward the clock after recv in the client */ UA_ClientConfig *cconfig = UA_Client_getConfig(client); UA_Client_recv = client->connection.recv; client->connection.recv = UA_Client_recvTesting; UA_Client_recvSleepDuration = cconfig->secureChannelLifeTime + 1; UA_Variant val; UA_Variant_init(&val); UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE); retval = UA_Client_readValueAttribute(client, nodeId, &val); ck_assert_msg(retval == UA_STATUSCODE_BADSECURECHANNELCLOSED); UA_Client_disconnect(client); UA_Client_delete(client); }
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; }
void UA_MonitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *monitoredItem) { UA_Subscription *sub = monitoredItem->subscription; UA_Session *session = &server->adminSession; if(sub) session = sub->session; UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Subscription %u | " "MonitoredItem %i | Sample callback called", sub ? sub->subscriptionId : 0, monitoredItem->monitoredItemId); UA_assert(monitoredItem->attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER); /* Get the node */ const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &monitoredItem->monitoredNodeId); /* Sample the value. The sample can still point into the node. */ UA_DataValue value; UA_DataValue_init(&value); if(node) { UA_ReadValueId rvid; UA_ReadValueId_init(&rvid); rvid.nodeId = monitoredItem->monitoredNodeId; rvid.attributeId = monitoredItem->attributeId; rvid.indexRange = monitoredItem->indexRange; ReadWithNode(node, server, session, monitoredItem->timestampsToReturn, &rvid, &value); } else { value.hasStatus = true; value.status = UA_STATUSCODE_BADNODEIDUNKNOWN; } /* Operate on the sample */ UA_Boolean movedValue = false; UA_StatusCode retval = sampleCallbackWithValue(server, session, sub, monitoredItem, &value, &movedValue); if(retval != UA_STATUSCODE_GOOD) { UA_LOG_WARNING_SESSION(&server->config.logger, session, "Subscription %u | " "MonitoredItem %i | Sampling returned the statuscode %s", sub ? sub->subscriptionId : 0, monitoredItem->monitoredItemId, UA_StatusCode_name(retval)); } /* Delete the sample if it was not moved to the notification. */ if(!movedValue) UA_DataValue_deleteMembers(&value); /* Does nothing for UA_VARIANT_DATA_NODELETE */ if(node) UA_Nodestore_releaseNode(server->nsCtx, node); }
/* Used in inline functions exposing the Read service with more syntactic sugar * for individual attributes */ UA_StatusCode __UA_Server_read(UA_Server *server, const UA_NodeId *nodeId, const UA_AttributeId attributeId, void *v) { /* Call the read service */ UA_ReadValueId item; UA_ReadValueId_init(&item); item.nodeId = *nodeId; item.attributeId = attributeId; UA_DataValue dv = UA_Server_read(server, &item, UA_TIMESTAMPSTORETURN_NEITHER); /* Check the return value */ UA_StatusCode retval = UA_STATUSCODE_GOOD; if(dv.hasStatus) retval = dv.status; else if(!dv.hasValue) retval = UA_STATUSCODE_BADUNEXPECTEDERROR; if(retval != UA_STATUSCODE_GOOD) { UA_DataValue_deleteMembers(&dv); return retval; } /* Prepare the result */ if(attributeId == UA_ATTRIBUTEID_VALUE || attributeId == UA_ATTRIBUTEID_ARRAYDIMENSIONS) { /* Return the entire variant */ if(dv.value.storageType == UA_VARIANT_DATA_NODELETE) { retval = UA_Variant_copy(&dv.value,(UA_Variant *) v); } else { /* storageType is UA_VARIANT_DATA. Copy the entire variant * (including pointers and all) */ memcpy(v, &dv.value, sizeof(UA_Variant)); } } else { /* Return the variant content only */ if(dv.value.storageType == UA_VARIANT_DATA_NODELETE) { retval = UA_copy(dv.value.data, v, dv.value.type); } else { /* storageType is UA_VARIANT_DATA. Copy the content of the type * (including pointers and all) */ memcpy(v, dv.value.data, dv.value.type->memSize); /* Delete the "carrier" in the variant */ UA_free(dv.value.data); } } return retval; }
UA_StatusCode __UA_Client_readAttribute(UA_Client *client, const UA_NodeId *nodeId, UA_AttributeId attributeId, void *out, const UA_DataType *outDataType) { UA_ReadValueId item; UA_ReadValueId_init(&item); item.nodeId = *nodeId; item.attributeId = attributeId; UA_ReadRequest request; UA_ReadRequest_init(&request); request.nodesToRead = &item; request.nodesToReadSize = 1; UA_ReadResponse response = UA_Client_Service_read(client, request); UA_StatusCode retval = response.responseHeader.serviceResult; if(retval == UA_STATUSCODE_GOOD && response.resultsSize != 1) retval = UA_STATUSCODE_BADUNEXPECTEDERROR; if(retval != UA_STATUSCODE_GOOD) { UA_ReadResponse_deleteMembers(&response); return retval; } UA_DataValue *res = response.results; if(res->hasStatus != UA_STATUSCODE_GOOD) retval = res->hasStatus; else if(!res->hasValue || !UA_Variant_isScalar(&res->value)) retval = UA_STATUSCODE_BADUNEXPECTEDERROR; if(retval != UA_STATUSCODE_GOOD) { UA_ReadResponse_deleteMembers(&response); return retval; } if(attributeId == UA_ATTRIBUTEID_VALUE) { memcpy(out, &res->value, sizeof(UA_Variant)); UA_Variant_init(&res->value); } else if(UA_Variant_isScalar(&res->value) && res->value.type == outDataType) { memcpy(out, res->value.data, res->value.type->memSize); UA_free(res->value.data); res->value.data = NULL; } else { retval = UA_STATUSCODE_BADUNEXPECTEDERROR; } UA_ReadResponse_deleteMembers(&response); return retval; }
UA_StatusCode UA_Client_readArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId, UA_Int32 **outArrayDimensions, size_t *outArrayDimensionsSize) { UA_ReadValueId item; UA_ReadValueId_init(&item); item.nodeId = nodeId; item.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS; UA_ReadRequest request; UA_ReadRequest_init(&request); request.nodesToRead = &item; request.nodesToReadSize = 1; UA_ReadResponse response = UA_Client_Service_read(client, request); UA_StatusCode retval = response.responseHeader.serviceResult; if(retval == UA_STATUSCODE_GOOD && response.resultsSize != 1) retval = UA_STATUSCODE_BADUNEXPECTEDERROR; if(retval != UA_STATUSCODE_GOOD) goto cleanup; UA_DataValue *res = response.results; if(res->hasStatus != UA_STATUSCODE_GOOD) retval = res->hasStatus; else if(!res->hasValue || UA_Variant_isScalar(&res->value)) retval = UA_STATUSCODE_BADUNEXPECTEDERROR; if(retval != UA_STATUSCODE_GOOD) goto cleanup; if(UA_Variant_isScalar(&res->value) || res->value.type != &UA_TYPES[UA_TYPES_INT32]) { retval = UA_STATUSCODE_BADUNEXPECTEDERROR; goto cleanup; } *outArrayDimensions = res->value.data; *outArrayDimensionsSize = res->value.arrayLength; UA_free(res->value.data); res->value.data = NULL; res->value.arrayLength = 0; cleanup: UA_ReadResponse_deleteMembers(&response); return retval; }
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; }