/* Takes the raw message from the network layer */ void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *message) { UA_SecureChannel *channel = connection->channel; if(channel) { /* Assemble chunks in the securechannel and process complete messages */ UA_StatusCode retval = UA_SecureChannel_processChunks(channel, message, (UA_ProcessMessageCallback*)UA_Server_processSecureChannelMessage, server); if(retval != UA_STATUSCODE_GOOD) UA_LOG_TRACE_CHANNEL(server->config.logger, channel, "Procesing chunkgs resulted in error code 0x%08x", retval); } else { /* Process messages without a channel and no chunking */ size_t offset = 0; UA_TcpMessageHeader tcpMessageHeader; UA_StatusCode retval = UA_TcpMessageHeader_decodeBinary(message, &offset, &tcpMessageHeader); if(retval != UA_STATUSCODE_GOOD) { connection->close(connection); return; } /* Dispatch according to the message type */ switch(tcpMessageHeader.messageTypeAndChunkType & 0x00ffffff) { case UA_MESSAGETYPE_HEL: UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, "Connection %i | Process HEL message", connection->sockfd); processHEL(connection, message, &offset); break; case UA_MESSAGETYPE_OPN: { UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, "Connection %i | Process OPN message", connection->sockfd); UA_UInt32 channelId = 0; retval = UA_UInt32_decodeBinary(message, &offset, &channelId); if(retval != UA_STATUSCODE_GOOD) connection->close(connection); UA_ByteString offsetMessage = (UA_ByteString){ .data = message->data + 12, .length = message->length - 12}; processOPN(server, connection, channelId, &offsetMessage); break; } case UA_MESSAGETYPE_MSG: UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, "Connection %i | Processing a MSG message not possible " "without a SecureChannel", connection->sockfd); connection->close(connection); break; case UA_MESSAGETYPE_CLO: UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, "Connection %i | Processing a CLO message not possible " "without a SecureChannel", connection->sockfd); connection->close(connection); break; default: UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, "Connection %i | Unknown message type", connection->sockfd); connection->close(connection); } } }
/** * process binary message received from Connection * dose not modify UA_ByteString you have to free it youself. * use of connection->getSendBuffer() and connection->sent() to answer Message */ void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg) { size_t pos = 0; UA_TcpMessageHeader tcpMessageHeader; do { if(UA_TcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader)) { UA_LOG_INFO(server->logger, UA_LOGCATEGORY_NETWORK, "Decoding of message header failed"); connection->close(connection); break; } size_t targetpos = pos - 8 + tcpMessageHeader.messageSize; switch(tcpMessageHeader.messageTypeAndFinal & 0xffffff) { case UA_MESSAGETYPEANDFINAL_HELF & 0xffffff: processHEL(connection, msg, &pos); break; case UA_MESSAGETYPEANDFINAL_OPNF & 0xffffff: processOPN(connection, server, msg, &pos); break; case UA_MESSAGETYPEANDFINAL_MSGF & 0xffffff: #ifndef EXTENSION_STATELESS if(connection->state != UA_CONNECTION_ESTABLISHED) { connection->close(connection); return; } #endif processMSG(connection, server, msg, &pos); break; case UA_MESSAGETYPEANDFINAL_CLOF & 0xffffff: processCLO(connection, server, msg, &pos); connection->close(connection); return; default: UA_LOG_INFO(server->logger, UA_LOGCATEGORY_NETWORK, "Unknown request type on Connection %i", connection->sockfd); } UA_TcpMessageHeader_deleteMembers(&tcpMessageHeader); if(pos != targetpos) { UA_LOG_INFO(server->logger, UA_LOGCATEGORY_NETWORK, "Message on Connection %i was not entirely processed. " "Arrived at position %i, skip after the announced length to position %i", connection->sockfd, pos, targetpos); pos = targetpos; } } while(msg->length > pos); }
void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, UA_ByteString *msg) { if(msg->length <= 0) return; size_t pos = 0; UA_TcpMessageHeader tcpMessageHeader; do { if(UA_TcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader)) { UA_LOG_INFO(server->logger, UA_LOGCATEGORY_COMMUNICATION, "Decoding of message header failed"); connection->close(connection); break; } size_t targetpos = pos - 8 + tcpMessageHeader.messageSize; switch(tcpMessageHeader.messageTypeAndFinal & 0xffffff) { case UA_MESSAGETYPEANDFINAL_HELF & 0xffffff: processHEL(connection, msg, &pos); break; case UA_MESSAGETYPEANDFINAL_OPNF & 0xffffff: processOPN(connection, server, msg, &pos); break; case UA_MESSAGETYPEANDFINAL_MSGF & 0xffffff: #ifndef EXTENSION_STATELESS if(connection->state != UA_CONNECTION_ESTABLISHED) connection->close(connection); else #endif processMSG(connection, server, msg, &pos); break; case UA_MESSAGETYPEANDFINAL_CLOF & 0xffffff: processCLO(connection, server, msg, &pos); connection->close(connection); return; } UA_TcpMessageHeader_deleteMembers(&tcpMessageHeader); if(pos != targetpos) { UA_LOG_INFO(server->logger, UA_LOGCATEGORY_COMMUNICATION, "The message was not entirely processed, skipping to the end"); pos = targetpos; } } while(msg->length > (UA_Int32)pos); }