Beispiel #1
0
        public async Task <Result> ReadVariable(string pVarName)
        {
            Result result = new Result();

            // Read Variable request packet structure example:
            //   0  1     2  3        4       5  6
            //  xx xx  | 00 0A   |   00    | 00 07        | 24 4F 56 5F 50 52 4F
            //         |   10    |    0    |     7        | $  O  V  _  P  R  O
            //  REQ ID | REQ LEN | READ=00 | VAR NAME LEN | VAR NAME CHARS
            // (RANDOM)|

            if (pVarName.Length == 0)
            {
                result.ErrorMessage = "No variable was written";
                return(result);
            }

            var PKT_var_name = new byte[pVarName.Length];

            PKT_var_name = Encoding.UTF8.GetBytes(pVarName);

            var PKT_name_length = new byte[2];

            PKT_name_length[0] = (byte)((pVarName.Length >> 8) & 255);
            PKT_name_length[1] = (byte)(pVarName.Length & 255);

            byte PKT_mode_is_read = 0;

            var PKT_req_len = new byte[2];

            PKT_req_len[0] = (byte)(((pVarName.Length + 3) >> 8) & 255);
            PKT_req_len[1] = (byte)((pVarName.Length + 3) & 255);

            var PKT_req_id = new byte[2];

            PKT_req_id[0] = (byte)((_msgID >> 8) & 255);
            PKT_req_id[1] = (byte)(_msgID & 255);
            _msgID++;
            if (_msgID > _lastID)
            {
                _msgID = _firstID;
            }

            var REQ_packet = new byte[pVarName.Length + 7 + 1];

            REQ_packet[0] = PKT_req_id[0];
            REQ_packet[1] = PKT_req_id[1];
            REQ_packet[2] = PKT_req_len[0];
            REQ_packet[3] = PKT_req_len[1];
            REQ_packet[4] = PKT_mode_is_read;
            REQ_packet[5] = PKT_name_length[0];
            REQ_packet[6] = PKT_name_length[1];
            PKT_var_name.CopyTo(REQ_packet, 7);

            DataWriter writer;

            using (writer = new DataWriter(_socket.OutputStream))
            {
                // Set the Unicode character encoding for the output stream
                writer.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
                // Specify the byte order of a stream.
                writer.ByteOrder = ByteOrder.LittleEndian;

                // Gets the size of UTF-8 string.
                writer.MeasureString(Encoding.UTF8.GetString(REQ_packet));
                // Write a string value to the output stream.
                writer.WriteBytes(REQ_packet);

                // Send the contents of the writer to the backing stream.
                try
                {
                    await writer.StoreAsync();

                    await writer.FlushAsync();
                }
                catch (Exception ex)
                {
                    SocketErrorStatus webErrorStatus = Windows.Networking.Sockets.SocketError.GetStatus(ex.GetBaseException().HResult);
                    result.ErrorMessage = (webErrorStatus.ToString() != "Unknown" ? webErrorStatus.ToString() : ex.Message);
                    return(result);
                }
                // In order to prolong the lifetime of the stream, detach it from the DataWriter
                writer.DetachStream();
            }

            // Read Variable response packet structure example:
            // 0  1     2  3      4         5  6
            // xx xx  | 00 0A   | 00      | 00 06       | 35 35 33 39 39 33 | 00 01 01
            //        |   10    |  0      |     6       | 5  5  3  9  9  3  |  0  1  1
            // SAME AS| RSP LEN | READ=00 | VALUE LEN   | VALUE CHARS       |  TRAILER
            // REQUEST|

            DataReader  reader;
            ByteBuilder byteBuilder = new ByteBuilder();

            using (reader = new DataReader(_socket.InputStream))
            {
                // Read the length of the payload that will be received.
                reader.InputStreamOptions = InputStreamOptions.Partial;
                // The encoding and byte order need to match the settings of the writer we previously used.
                reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
                reader.ByteOrder       = ByteOrder.LittleEndian;
                // Send the contents of the writer to the backing stream.
                // Get the size of the buffer that has not been read.
                try
                {
                    do
                    {
                        await reader.LoadAsync(_readBuffer);

                        var bytes = new Byte[reader.UnconsumedBufferLength];
                        reader.ReadBytes(bytes);
                        byteBuilder.AppendBytes(bytes);
                        // Keep reading until we consume the complete stream.
                    }while (reader.UnconsumedBufferLength > 0);
                }
                catch (Exception ex)
                {
                    SocketErrorStatus webErrorStatus = SocketError.GetStatus(ex.GetBaseException().HResult);
                    result.ErrorMessage = (webErrorStatus.ToString() != "Unknown" ? webErrorStatus.ToString() : ex.Message);
                    return(result);
                }
                finally
                {
                    reader.DetachStream();
                }
            }

            var flattenedList = byteBuilder._bytes.SelectMany(bytes => bytes);
            var RSP_packet    = flattenedList.ToArray();

            try
            {
                int RSP_len     = (RSP_packet[2] << 8) | RSP_packet[3];
                int RSP_val_len = (RSP_packet[5] << 8) | RSP_packet[6];
                result.Data = Encoding.ASCII.GetString(RSP_packet, 7, RSP_val_len);
                int RSP_read_status = RSP_packet[7 + (RSP_val_len + 2)];
                if ((RSP_read_status > 0) & (RSP_val_len > 0) &
                    (RSP_packet[0] == PKT_req_id[0]) & (RSP_packet[1] == PKT_req_id[1]))
                {
                    result.Succeeded = true;
                    return(result);
                }
                else
                {
                    result.ErrorMessage = "Cannot be read";
                    return(result);
                }
            }
            catch (Exception ex)
            {
                result.ErrorMessage = ex.Message;
                return(result);
            }
        }