1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "ua_util.h"
- #include "ua_connection.h"
- size_t
- UA_readNumber(UA_Byte *buf, size_t buflen, UA_UInt32 *number) {
- UA_assert(buf);
- UA_assert(number);
- UA_UInt32 n = 0;
- size_t progress = 0;
- /* read numbers until the end or a non-number character appears */
- while(progress < buflen) {
- UA_Byte c = buf[progress];
- if(c < '0' || c > '9')
- break;
- n = (n*10) + (UA_UInt32)(c-'0');
- ++progress;
- }
- *number = n;
- return progress;
- }
- UA_StatusCode
- UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname,
- UA_UInt16 *outPort, UA_String *outPath) {
- /* Url must begin with "opc.tcp://" */
- if(endpointUrl->length < 11 || strncmp((char*)endpointUrl->data, "opc.tcp://", 10) != 0)
- return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
- /* Where does the hostname end? */
- size_t pos = 10;
- if(endpointUrl->data[pos] == '[') {
- /* IPv6: opc.tcp://[2001:0db8:85a3::8a2e:0370:7334]:1234/path */
- for(; pos < endpointUrl->length; ++pos) {
- if(endpointUrl->data[pos] == ']')
- break;
- }
- if(pos == endpointUrl->length)
- return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
- pos++;
- } else {
- /* IPv4 or hostname: opc.tcp://something.something:1234/path */
- for(; pos < endpointUrl->length; ++pos) {
- if(endpointUrl->data[pos] == ':' || endpointUrl->data[pos] == '/')
- break;
- }
- }
- /* Set the hostname */
- outHostname->data = &endpointUrl->data[10];
- outHostname->length = pos - 10;
- if(pos == endpointUrl->length)
- return UA_STATUSCODE_GOOD;
- /* Set the port */
- if(endpointUrl->data[pos] == ':') {
- if(++pos == endpointUrl->length)
- return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
- UA_UInt32 largeNum;
- size_t progress = UA_readNumber(&endpointUrl->data[pos], endpointUrl->length - pos, &largeNum);
- if(progress == 0 || largeNum > 65535)
- return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
- /* Test if the end of a valid port was reached */
- pos += progress;
- if(pos == endpointUrl->length || endpointUrl->data[pos] == '/')
- *outPort = (UA_UInt16)largeNum;
- if(pos == endpointUrl->length)
- return UA_STATUSCODE_GOOD;
- }
- /* Set the path */
- UA_assert(pos < endpointUrl->length);
- if(endpointUrl->data[pos] != '/')
- return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
- if(++pos == endpointUrl->length)
- return UA_STATUSCODE_GOOD;
- outPath->data = &endpointUrl->data[pos];
- outPath->length = endpointUrl->length - pos;
- /* Remove trailing slash from the path */
- if(endpointUrl->data[endpointUrl->length - 1] == '/')
- outPath->length--;
- return UA_STATUSCODE_GOOD;
- }
|