static void processMSG(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, size_t *pos) { /* Read in the securechannel */ UA_UInt32 secureChannelId; UA_StatusCode retval = UA_UInt32_decodeBinary(msg, pos, &secureChannelId); if(retval != UA_STATUSCODE_GOOD) return; /* the anonymous channel is used e.g. to allow getEndpoints without a channel */ UA_SecureChannel *clientChannel = connection->channel; UA_SecureChannel anonymousChannel; if(!clientChannel) { UA_SecureChannel_init(&anonymousChannel); anonymousChannel.connection = connection; clientChannel = &anonymousChannel; #ifdef EXTENSION_STATELESS anonymousChannel.session = &anonymousSession; #endif } /* Read the security header */ UA_UInt32 tokenId; UA_SequenceHeader sequenceHeader; retval = UA_UInt32_decodeBinary(msg, pos, &tokenId); retval |= UA_SequenceHeader_decodeBinary(msg, pos, &sequenceHeader); if(retval != UA_STATUSCODE_GOOD) return; /* Read the request type */ UA_NodeId requestType; if(UA_NodeId_decodeBinary(msg, pos, &requestType) != UA_STATUSCODE_GOOD) return; if(requestType.identifierType != UA_NODEIDTYPE_NUMERIC) { UA_NodeId_deleteMembers(&requestType); return; } switch(requestType.identifier.numeric - UA_ENCODINGOFFSET_BINARY) { case UA_NS0ID_GETENDPOINTSREQUEST: { UA_GetEndpointsRequest p; UA_GetEndpointsResponse r; if(UA_GetEndpointsRequest_decodeBinary(msg, pos, &p)) return; UA_GetEndpointsResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_GetEndpoints(server, &p, &r); UA_GetEndpointsRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); UA_GetEndpointsResponse_deleteMembers(&r); break; } case UA_NS0ID_FINDSERVERSREQUEST: { UA_FindServersRequest p; UA_FindServersResponse r; if(UA_FindServersRequest_decodeBinary(msg, pos, &p)) return; UA_FindServersResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_FindServers(server, &p, &r); UA_FindServersRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); UA_FindServersResponse_deleteMembers(&r); break; } case UA_NS0ID_CREATESESSIONREQUEST: { UA_CreateSessionRequest p; UA_CreateSessionResponse r; if(UA_CreateSessionRequest_decodeBinary(msg, pos, &p)) return; UA_CreateSessionResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_CreateSession(server, clientChannel, &p, &r); UA_CreateSessionRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); UA_CreateSessionResponse_deleteMembers(&r); break; } case UA_NS0ID_ACTIVATESESSIONREQUEST: { UA_ActivateSessionRequest p; UA_ActivateSessionResponse r; if(UA_ActivateSessionRequest_decodeBinary(msg, pos, &p)) return; UA_ActivateSessionResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_ActivateSession(server, clientChannel, &p, &r); UA_ActivateSessionRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); UA_ActivateSessionResponse_deleteMembers(&r); break; } case UA_NS0ID_CLOSESESSIONREQUEST: INVOKE_SERVICE(CloseSession, UA_TYPES_CLOSESESSIONRESPONSE); break; case UA_NS0ID_READREQUEST: INVOKE_SERVICE(Read, UA_TYPES_READRESPONSE); break; case UA_NS0ID_WRITEREQUEST: INVOKE_SERVICE(Write, UA_TYPES_WRITERESPONSE); break; case UA_NS0ID_BROWSEREQUEST: INVOKE_SERVICE(Browse, UA_TYPES_BROWSERESPONSE); break; case UA_NS0ID_BROWSENEXTREQUEST: INVOKE_SERVICE(BrowseNext, UA_TYPES_BROWSENEXTRESPONSE); break; case UA_NS0ID_ADDREFERENCESREQUEST: INVOKE_SERVICE(AddReferences, UA_TYPES_ADDREFERENCESRESPONSE); break; case UA_NS0ID_REGISTERNODESREQUEST: INVOKE_SERVICE(RegisterNodes, UA_TYPES_REGISTERNODESRESPONSE); break; case UA_NS0ID_UNREGISTERNODESREQUEST: INVOKE_SERVICE(UnregisterNodes, UA_TYPES_UNREGISTERNODESRESPONSE); break; case UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST: INVOKE_SERVICE(TranslateBrowsePathsToNodeIds, UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE); break; default: { if(requestType.namespaceIndex == 0 && requestType.identifier.numeric==787) UA_LOG_INFO(server->logger, UA_LOGCATEGORY_COMMUNICATION, "Client requested a subscription that are not supported, the message will be skipped"); else UA_LOG_INFO(server->logger, UA_LOGCATEGORY_COMMUNICATION, "Unknown request: NodeId(ns=%d, i=%d)", requestType.namespaceIndex, requestType.identifier.numeric); UA_RequestHeader p; UA_ResponseHeader r; if(UA_RequestHeader_decodeBinary(msg, pos, &p) != UA_STATUSCODE_GOOD) return; UA_ResponseHeader_init(&r); init_response_header(&p, &r); r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED; #ifdef EXTENSION_STATELESS if(retval != UA_STATUSCODE_GOOD) r.serviceResult = retval; #endif UA_RequestHeader_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_RESPONSEHEADER]); break; } } }
static void processMSG(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, size_t *pos) { /* Read in the securechannel */ UA_UInt32 secureChannelId; UA_StatusCode retval = UA_UInt32_decodeBinary(msg, pos, &secureChannelId); if(retval != UA_STATUSCODE_GOOD) return; /* the anonymous channel is used e.g. to allow getEndpoints without a channel */ UA_SecureChannel *clientChannel = connection->channel; UA_SecureChannel anonymousChannel; if(!clientChannel) { UA_SecureChannel_init(&anonymousChannel); anonymousChannel.connection = connection; clientChannel = &anonymousChannel; } /* Read the security header */ UA_UInt32 tokenId = 0; UA_SequenceHeader sequenceHeader; retval = UA_UInt32_decodeBinary(msg, pos, &tokenId); retval |= UA_SequenceHeader_decodeBinary(msg, pos, &sequenceHeader); #ifndef EXTENSION_STATELESS if(retval != UA_STATUSCODE_GOOD || tokenId == 0) // 0 is invalid return; #else if(retval != UA_STATUSCODE_GOOD) return; #endif if(clientChannel != &anonymousChannel && tokenId != clientChannel->securityToken.tokenId) { if(tokenId != clientChannel->nextSecurityToken.tokenId) { /* close the securechannel but keep the connection open */ UA_LOG_INFO(server->logger, UA_LOGCATEGORY_SECURECHANNEL, "Request with a wrong security token. Closing the SecureChannel %i.", clientChannel->securityToken.channelId); Service_CloseSecureChannel(server, clientChannel->securityToken.channelId); return; } UA_SecureChannel_revolveTokens(clientChannel); } /* Read the request type */ UA_NodeId requestType; if(UA_NodeId_decodeBinary(msg, pos, &requestType) != UA_STATUSCODE_GOOD) return; if(requestType.identifierType != UA_NODEIDTYPE_NUMERIC) { UA_NodeId_deleteMembers(&requestType); return; } switch(requestType.identifier.numeric - UA_ENCODINGOFFSET_BINARY) { case UA_NS0ID_GETENDPOINTSREQUEST: { if(clientChannel == &anonymousChannel) UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_NETWORK, "Processing GetEndpointsRequest on Connection %i", connection->sockfd); else UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_SECURECHANNEL, "Processing GetEndpointsRequest on SecureChannel %i", clientChannel->securityToken.channelId); UA_GetEndpointsRequest p; UA_GetEndpointsResponse r; if(UA_GetEndpointsRequest_decodeBinary(msg, pos, &p)) return; UA_GetEndpointsResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_GetEndpoints(server, &p, &r); UA_GetEndpointsRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); UA_GetEndpointsResponse_deleteMembers(&r); break; } case UA_NS0ID_FINDSERVERSREQUEST: { if(clientChannel == &anonymousChannel) UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_NETWORK, "Processing FindServerRequest on Connection %i", connection->sockfd); else UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_SECURECHANNEL, "Processing FindServerRequest on SecureChannel %i", clientChannel->securityToken.channelId); UA_FindServersRequest p; UA_FindServersResponse r; if(UA_FindServersRequest_decodeBinary(msg, pos, &p)) return; UA_FindServersResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_FindServers(server, &p, &r); UA_FindServersRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); UA_FindServersResponse_deleteMembers(&r); break; } case UA_NS0ID_CREATESESSIONREQUEST: { UA_CreateSessionRequest p; UA_CreateSessionResponse r; if(UA_CreateSessionRequest_decodeBinary(msg, pos, &p)) return; UA_CreateSessionResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_CreateSession(server, clientChannel, &p, &r); UA_CreateSessionRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); UA_CreateSessionResponse_deleteMembers(&r); break; } case UA_NS0ID_ACTIVATESESSIONREQUEST: { UA_ActivateSessionRequest p; UA_ActivateSessionResponse r; if(UA_ActivateSessionRequest_decodeBinary(msg, pos, &p)) return; UA_ActivateSessionResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_ActivateSession(server, clientChannel, &p, &r); UA_ActivateSessionRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); UA_ActivateSessionResponse_deleteMembers(&r); break; } case UA_NS0ID_CLOSESESSIONREQUEST: INVOKE_SERVICE(CloseSession, UA_TYPES_CLOSESESSIONRESPONSE); break; case UA_NS0ID_READREQUEST: INVOKE_SERVICE(Read, UA_TYPES_READRESPONSE); break; case UA_NS0ID_WRITEREQUEST: INVOKE_SERVICE(Write, UA_TYPES_WRITERESPONSE); break; case UA_NS0ID_BROWSEREQUEST: INVOKE_SERVICE(Browse, UA_TYPES_BROWSERESPONSE); break; case UA_NS0ID_BROWSENEXTREQUEST: INVOKE_SERVICE(BrowseNext, UA_TYPES_BROWSENEXTRESPONSE); break; case UA_NS0ID_REGISTERNODESREQUEST: INVOKE_SERVICE(RegisterNodes, UA_TYPES_REGISTERNODESRESPONSE); break; case UA_NS0ID_UNREGISTERNODESREQUEST: INVOKE_SERVICE(UnregisterNodes, UA_TYPES_UNREGISTERNODESRESPONSE); break; case UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST: INVOKE_SERVICE(TranslateBrowsePathsToNodeIds, UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE); break; #ifdef ENABLE_SUBSCRIPTIONS case UA_NS0ID_CREATESUBSCRIPTIONREQUEST: INVOKE_SERVICE(CreateSubscription, UA_TYPES_CREATESUBSCRIPTIONRESPONSE); break; case UA_NS0ID_PUBLISHREQUEST: INVOKE_SERVICE(Publish, UA_TYPES_PUBLISHRESPONSE); break; case UA_NS0ID_MODIFYSUBSCRIPTIONREQUEST: INVOKE_SERVICE(ModifySubscription, UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE); break; case UA_NS0ID_DELETESUBSCRIPTIONSREQUEST: INVOKE_SERVICE(DeleteSubscriptions, UA_TYPES_DELETESUBSCRIPTIONSRESPONSE); break; case UA_NS0ID_CREATEMONITOREDITEMSREQUEST: INVOKE_SERVICE(CreateMonitoredItems, UA_TYPES_CREATEMONITOREDITEMSRESPONSE); break; case UA_NS0ID_DELETEMONITOREDITEMSREQUEST: INVOKE_SERVICE(DeleteMonitoredItems, UA_TYPES_DELETEMONITOREDITEMSRESPONSE); break; #endif #ifdef ENABLE_METHODCALLS case UA_NS0ID_CALLREQUEST: INVOKE_SERVICE(Call, UA_TYPES_CALLRESPONSE); break; #endif #ifdef ENABLE_NODEMANAGEMENT case UA_NS0ID_ADDNODESREQUEST: INVOKE_SERVICE(AddNodes, UA_TYPES_ADDNODESRESPONSE); break; case UA_NS0ID_ADDREFERENCESREQUEST: INVOKE_SERVICE(AddReferences, UA_TYPES_ADDREFERENCESRESPONSE); break; case UA_NS0ID_DELETENODESREQUEST: INVOKE_SERVICE(DeleteNodes, UA_TYPES_DELETENODESRESPONSE); break; case UA_NS0ID_DELETEREFERENCESREQUEST: INVOKE_SERVICE(DeleteReferences, UA_TYPES_DELETEREFERENCESRESPONSE); break; #endif default: { if(requestType.namespaceIndex == 0 && requestType.identifier.numeric==787) UA_LOG_INFO(server->logger, UA_LOGCATEGORY_NETWORK, "Client requested a subscription that are not supported, the message will be skipped"); else UA_LOG_INFO(server->logger, UA_LOGCATEGORY_NETWORK, "Unknown request: NodeId(ns=%d, i=%d)", requestType.namespaceIndex, requestType.identifier.numeric); UA_RequestHeader p; UA_ServiceFault r; if(UA_RequestHeader_decodeBinary(msg, pos, &p) != UA_STATUSCODE_GOOD) return; UA_ServiceFault_init(&r); init_response_header(&p, &r.responseHeader); r.responseHeader.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED; UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_SERVICEFAULT]); UA_RequestHeader_deleteMembers(&p); UA_ServiceFault_deleteMembers(&r); break; } } }