/// <summary> /// Flushes all button states /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="requireReply">indicate if the brick should reply</param> /// <returns></returns> public static async Task Flush(ISocket socket, bool requireReply = true) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(requireReply ? CommandType.DIRECT_COMMAND_REPLY : CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.Raw((byte)OP.opUI_BUTTON); cb.Raw((byte)UI_BUTTON_SUBCODE.FLUSH); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
private static async Task <Response> ContinueDownload(ISocket socket, byte handle, ushort payLoad) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.SYSTEM_COMMAND_REPLY)) { cb.OpCode(SYSTEM_OP.CONTINUE_UPLOAD); cb.Raw(handle); cb.Raw(payLoad); cmd = cb.ToCommand(); } return(await socket.Execute(cmd)); }
private static async Task <Response> BeginDownload(ISocket socket, string brickFilePath) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.SYSTEM_COMMAND_REPLY)) { cb.OpCode(SYSTEM_OP.BEGIN_UPLOAD); cb.Raw((ushort)0); // set to 0 to just have handle and filesize returned cb.Raw(brickFilePath); cmd = cb.ToCommand(); } return(await socket.Execute(cmd)); }
private static async Task <Response> BeginUpload(ISocket socket, int fileSize, string brickFilePath) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.SYSTEM_COMMAND_REPLY)) { cb.OpCode(SYSTEM_OP.BEGIN_DOWNLOAD); cb.Raw((uint)fileSize); cb.Raw(brickFilePath); cmd = cb.ToCommand(); } return(await socket.Execute(cmd)); }
/// <summary> /// Plays a tone based on frequency for given duration and at a given volume. /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="volume">Specify volume for playback, [0 - 100]</param> /// <param name="frequency">Specify frequency, [250 - 10000]</param> /// <param name="duration">Specify duration in milliseconds [1 - n]</param> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <remarks> /// Instruction opSound (CMD, …) /// Opcode 0x94 /// Arguments (Data8) CMD => Specific command parameter documented below /// Dispatch status Unchanged /// Description Sound control entry /// CMD: TONE = 0x01 /// Arguments /// (Data8) VOLUME – Specify volume for playback, [0 - 100] /// (Data16) FREQUENCY – Specify frequency, [250 - 10000] /// (Data16) DURATION – Specify duration in millisecond /// </remarks> internal static async Task Tone(ISocket socket, int volume, int frequency, int duration) { if (volume < 0 || volume > 100) { throw new ArgumentOutOfRangeException("Volume must be between 0 and 100", "volume"); } if (frequency < 250 || frequency > 10000) { throw new ArgumentOutOfRangeException("Frequency must be between 250 and 10000", "frequency"); } if (duration < 1) { throw new ArgumentOutOfRangeException("Duration must be longer than 0", "duration"); } Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opSOUND); cb.Raw((byte)SOUND_SUBCODE.TONE); cb.PAR8(volume); cb.PAR16(frequency); cb.PAR16(duration); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Read information about external device /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="port">Port number [0-31]</param> /// <returns>Format</returns> /// <remarks> /// Instruction opInput_Device (CMD, …) /// Opcode 0x99 /// CMD: GET_FORMAT = 0x02 /// Arguments /// (Data8) LAYER – Specify chain layer number [0-3] /// (Data8) NO – Port number /// Returns /// (Data8) Datasets – Number of data sets /// (Data8) FORMAT – Format [0-3], (0: 8-bit, 1: 16-bit, 2: 32-bit, 3: Float point) /// (Data8) MODES – Number of modes [1-8] /// (Data8) VIEW – Number of modes visible within port view app [1-8] /// </remarks> internal static async Task <Format> GetFormat(ISocket socket, ChainLayer layer, int port) { if (port < 0 || port > 31) { throw new ArgumentException("Number of port must be between 0 and 31", nameof(port)); } Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_REPLY, 4, 0)) { cb.OpCode(OP.opINPUT_DEVICE); cb.Raw((byte)INPUT_DEVICE_SUBCODE.GET_FORMAT); cb.PAR8((byte)layer); cb.PAR8((byte)port); cb.GlobalIndex(0); cb.GlobalIndex(1); cb.GlobalIndex(2); cb.GlobalIndex(3); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); byte[] data = response.PayLoad; return(new Format(data[0], (DataType)data[1], data[2], data[3])); }
/// <summary> /// Reads the type and mode of the connected device /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="port">Port [0-31]</param> /// <returns>TypeMode</returns> /// <remarks> /// Instruction opInput_Device (CMD, …) /// Opcode 0x99 /// CMD: GET_TYPEMODE = 0x05 /// Arguments /// (Data8) LAYER – Specify chain layer number [0-3] /// (Data8) NO – Port number /// Returns /// (Data8) TYPE – See device type list (Please reference section 0) /// (Data8) MODE – Device mode [0-7] /// </remarks> internal static async Task <DeviceTypeMode> GetTypeMode(ISocket socket, int port) { if (port < 0 || port > 31) { throw new ArgumentException("Number of port must be between 0 and 31", nameof(port)); } ChainLayer layer = GetLayer(port); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_REPLY, 2, 0)) { cb.OpCode(OP.opINPUT_DEVICE); cb.Raw((byte)INPUT_DEVICE_SUBCODE.GET_TYPEMODE); cb.PAR8((byte)layer); cb.PAR8((byte)port); cb.GlobalIndex(0); cb.GlobalIndex(1); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); byte[] data = response.PayLoad; return(new DeviceTypeMode((DeviceType)data[0], (DeviceMode)data[1])); }
/// <summary> /// Gets the connection type for the given port /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="port">Port number [0 - 31]</param> /// <returns></returns> /// <remarks> /// Instruction opInput_Device (CMD, …) /// Opcode 0x99 /// CMD: GET_CONNECTION = 0x0C /// Arguments /// (Data8) LAYER – Specify chain layer number [0-3] /// (Data8) NO – Port number /// Returns /// (Data8) CONN – Connection type /// </remarks> internal static async Task <ConnectionType> GetConnection(ISocket socket, int port) { if (port < 0 || port > 31) { throw new ArgumentException("Number of port must be between 0 and 31", "port"); } ChainLayer layer = GetLayer(port); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_REPLY, 1, 0)) { cb.OpCode(OP.opINPUT_DEVICE); cb.Raw((byte)INPUT_DEVICE_SUBCODE.GET_CONNECTION); cb.PAR8((byte)layer); cb.PAR8((ushort)port); cb.GlobalIndex(0); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); ConnectionType type = ConnectionType.CONN_UNKNOW; if (response.Type == ResponseType.OK) { byte[] data = response.PayLoad; if (data.Length > 0) { type = (ConnectionType)data[0]; } } return(type); }
//CMD: BMPFILE = 0x1C //Arguments //(DATA8) Color – Specify either black or white, [0: White, 1: Black] //(Data16) X0 – Specify X start point, [0 - 177] //(Data16) Y0 – Specify Y start point, [0 - 127] //(Data8) NAME – First character in filename(Character string) //Description //Enable displaying BMP file from icon file within running project. internal static async Task BMPFile(ISocket socket, string path, int x = 0, int y = 0, UIColor color = UIColor.Black) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opUI_DRAW); cb.Raw((byte)UI_DRAW_SUBCODE.BMPFILE); cb.PAR8((int)color); cb.PAR16(x); cb.PAR16(y); cb.PARS(path); cb.OpCode(OP.opUI_DRAW); cb.Raw((byte)UI_DRAW_SUBCODE.UPDATE); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Stops current sound playback. /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <remarks> /// Instruction opSound (CMD, …) /// Opcode 0x94 /// Arguments (Data8) CMD => Specific command parameter documented below /// Dispatch status Unchanged /// Description Sound control entry /// CMD: BREAK = 0x00 (Stop current sound playback) /// </remarks> internal static async Task Break(ISocket socket) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opSOUND); cb.Raw((byte)SOUND_SUBCODE.BREAK); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
//CMD: UPDATE = 0x00 //Description //Automatically triggers a refreshes of the display. internal static async Task Update(ISocket socket) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opUI_DRAW); cb.Raw((byte)UI_DRAW_SUBCODE.UPDATE); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Stop all input devices /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="layer">Specify chain layer number [0 - 3]</param> /// <returns></returns> /// <remarks> /// Instruction opInput_Device (CMD, …) /// Opcode 0x99 /// CMD: STOP_ALL= 0x0D (Stop all devices) /// Arguments /// (Data8) LAYER – Specify chain layer number [0-3] (-1 = All) /// </remarks> internal static async Task Stop(ISocket socket, ChainLayer layer) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opINPUT_DEVICE); cb.Raw((byte)INPUT_DEVICE_SUBCODE.STOP_ALL); cb.PAR8((byte)layer); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Set Led mode /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="ledMode">Pattern of the led</param> public static async Task Led(ISocket socket, LedMode ledMode, bool requireReply = false) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(requireReply ? CommandType.DIRECT_COMMAND_REPLY : CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opUI_WRITE); cb.Raw((byte)UI_WRITE_SUBCODE.LED); cb.PAR8((byte)ledMode); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Clear all device counters and values on all layers /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <returns></returns> /// <remarks> /// Instruction opInput_Device (CMD, …) /// Opcode 0x99 /// CMD: CLR_ALL = 0x0A /// Arguments /// (Data8) LAYER – Specify chain layer number [0-3] (-1 = All) /// Description /// Clear all device counters and values /// </remarks> internal static async Task Reset(ISocket socket) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { int all = -1; cb.OpCode(OP.opINPUT_DEVICE); cb.Raw((byte)INPUT_DEVICE_SUBCODE.CLR_ALL); cb.PAR8((byte)all); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Apply the default minimum and maximum raw value for device type to be used in scaling PCT and SI value /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="type">Device type</param> /// <param name="mode">Device mode [0-7]</param> /// <returns></returns> /// <remarks> /// Instruction opInput_Device (CMD, …) /// Opcode 0x99 /// CMD: CAL_DEFAULT = 0x04 /// Arguments /// (Data8) TYPE – Device type (Please reference section 0) /// (Data8) MODE – Device mode [0-7] /// Description /// Apply the default minimum and maximum raw value for device type to be used in scaling PCT and SI value /// </remarks> internal static async Task SetDefaultMinMax(ISocket socket, DeviceType type, DeviceMode mode) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opINPUT_DEVICE); cb.Raw((byte)INPUT_DEVICE_SUBCODE.CAL_DEFAULT); cb.PAR8((byte)type); cb.PAR8((byte)mode); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Delete a file or folder on the brick /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="brickPath">relative path to file or folder on brick</param> /// <returns><c>true</c> if success, otherwise <c>false</c></returns> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> public static async Task <bool> Delete(ISocket socket, string brickPath) { brickPath.IsBrickPath(); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.SYSTEM_COMMAND_REPLY)) { cb.OpCode(SYSTEM_OP.DELETE_FILE); cb.Raw(brickPath); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); return(response.Status == ResponseStatus.SUCCESS); }
/// <summary> /// Create a directory on the brick /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="brickDirectoryPath">relative path to folder on brick. e.g. "../[prjs|apps|tools]/directory*/"</param> /// <returns><c>true</c> if success, otherwise <c>false</c></returns> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> public static async Task <bool> CreateDirectory(ISocket socket, string brickDirectoryPath) { brickDirectoryPath = FileSystem.ToBrickDirectoryPath(brickDirectoryPath); brickDirectoryPath.IsBrickDirectoryPath(); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.SYSTEM_COMMAND_REPLY)) { cb.OpCode(SYSTEM_OP.CREATE_DIR); cb.Raw(brickDirectoryPath); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); return(response.Status == ResponseStatus.SUCCESS); }
/// <summary> /// Check if file or folder exists /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="brickPath">relative path to file or folder on brick</param> /// <returns><c>true</c> if file or folder exists otherwise <c>false</c></returns> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> /// <exception cref="FirmwareException"/> public static async Task <bool> Exists(ISocket socket, string brickPath) { brickPath.IsBrickPath(); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_REPLY, 1, 0)) { cb.OpCode(OP.opFILENAME); cb.Raw((byte)FILENAME_SUBCODE.EXIST); cb.PARS(brickPath); cb.GlobalIndex(0); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); return(response.PayLoad[0] == 1); }
/// <summary> /// Clear changes and bumps /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="port">Port number [0 - 31]</param> /// <returns></returns> /// <remarks> /// Instruction opInput_Device (CMD, …) /// Opcode 0x99 /// CMD: CLR_CHANGES = 0x1A /// Arguments /// (Data8) LAYER – Specify chain layer number [0-3] /// (Data8) NO – Port number /// Description /// Clear changes and bumps /// </remarks> internal static async Task ClearChanges(ISocket socket, int port) { if (port < 0 || port > 31) { throw new ArgumentException("Number of port must be between 0 and 31", "port"); } ChainLayer layer = GetLayer(port); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opINPUT_DEVICE); cb.Raw((byte)INPUT_DEVICE_SUBCODE.CLR_CHANGES); cb.PAR8((byte)layer); cb.PAR8((ushort)port); cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Gets the Operating System version /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <returns></returns> public static async Task <string> GetOSVersion(ISocket socket) { Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_REPLY, 255, 0)) { cb.OpCode(OP.opUI_READ); cb.Raw((byte)UI_READ_SUBCODE.GET_OS_VERS); cb.PAR32(255); cb.GlobalIndex(0); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); byte[] data = response.PayLoad; int index = Array.IndexOf(data, (byte)0); return(Encoding.UTF8.GetString(data, 0, index)); }
/// <summary> /// Repeats playing a sound file on the brick at a given volume. /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="volume">Specify volume for playback, [0 - 100]</param> /// <param name="filePath">FilePath to sound file: ../prjs/myproject/file.rsf</param> /// <remarks> /// Instruction opSound (CMD, …) /// Opcode 0x94 /// Arguments (Data8) CMD => Specific command parameter documented below /// Dispatch status Unchanged /// Description Sound control entry /// CMD: REPEAT = 0x03 /// Arguments /// (Data8) VOLUME – Specify volume for playback, [0 - 100] /// (Data8) NAME – First character in filename (Character string) /// </remarks> internal static async Task Repeat(ISocket socket, int volume, string filePath) { if (volume < 0 || volume > 100) { throw new ArgumentOutOfRangeException("Volume must be between 0 and 100", "volume"); } //soundfiles will not play when extension in path filePath = Path.ChangeExtension(filePath, null); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_NO_REPLY)) { cb.OpCode(OP.opSOUND); cb.Raw((byte)SOUND_SUBCODE.REPEAT); cb.PAR8(volume); // (Data8) VOLUME cb.PARS(filePath); // (Data8) NAME – First character in filename (Character string) ? cmd = cb.ToCommand(); } await socket.Execute(cmd); }
/// <summary> /// Gets directoryinfo item count and total size /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="brickDirectoryPath">relative path to folder on brick</param> /// <returns>DirectoryInfo</returns> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> /// <exception cref="FirmwareException"/> public static async Task <DirectoryInfo> GetDirectoryInfo(ISocket socket, string brickDirectoryPath) { brickDirectoryPath = FileSystem.ToBrickDirectoryPath(brickDirectoryPath); brickDirectoryPath.IsBrickDirectoryPath(); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_REPLY, 8, 0)) { cb.OpCode(OP.opFILENAME); cb.Raw((byte)FILENAME_SUBCODE.TOTALSIZE); cb.PARS(brickDirectoryPath); cb.GlobalIndex(0); cb.GlobalIndex(4); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); byte[] data = response.PayLoad; int items = BitConverter.ToInt32(data, 0); int size = BitConverter.ToInt32(data, 4); return(new DirectoryInfo(items, size)); }
public void StartEventMonitor(Brick brick) { Dictionary <int, InputPort> inputPorts = brick.IOPort.Input.Ports; Buttons buttons = brick.Buttons; Battery battery = brick.Battery; BrickConsole console = brick.Console; int INTERVAL = Brick.Options.EventMonitor.Interval; Task task = Task.Factory.StartNew(async() => { while (!_socket.CancellationToken.IsCancellationRequested) { try { //do not overload event message pump if (_socket.EventBuffer.Count == 0) { byte[] batch = null; ushort index = 0; ushort buttonByteLength = 0; ushort batteryByteLength = 0; ushort warningByteLength = 0; Dictionary <InputPort, DataType> triggeredPorts = new Dictionary <InputPort, DataType>(); using (PayLoadBuilder cb = new PayLoadBuilder()) { foreach (int key in inputPorts.Keys) { InputPort port = inputPorts[key]; if (port.Status != PortStatus.OK) { continue; // no device connected so continue } InputDevice device = (InputDevice)port.Device; if (!device.MonitorEvents) { continue; // device will get value on manual poll } DataType type = device.BatchCommand(cb, index); // get batchcommand if (type == DataType.NONE) { continue; } index += type.ByteLength(); triggeredPorts.Add(port, type); } buttonByteLength = buttons.BatchCommand(cb, index); index += buttonByteLength; batteryByteLength = battery.BatchCommand(cb, index); index += batteryByteLength; warningByteLength = console.BatchCommand(cb, index); index += warningByteLength; batch = cb.ToBytes(); } //no need to send batch, it has no content. if (batch.Length == 0) { try { await Task.Delay(INTERVAL, _socket.CancellationToken); } catch (TaskCanceledException) { } continue; } Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_REPLY, index, 0, useEventId: true)) { cb.Raw(batch); cmd = cb.ToCommand(); } Response response = await Brick.Socket.Execute(cmd, true); if (response.Type == ResponseType.ERROR) { continue; } byte[] data = response.PayLoad; if (data.Length != index) { if (!_socket.CancellationToken.IsCancellationRequested) { throw new FirmwareException(response); } else { continue; } } index = 0; foreach (InputPort port in triggeredPorts.Keys) { InputDevice device = (InputDevice)port.Device; bool hasChanged = false; DataType type = triggeredPorts[port]; switch (type) { case DataType.DATA8: { hasChanged = device.SetDeviceValue(data[index]); break; } case DataType.DATAF: { hasChanged = device.SetDeviceValue(BitConverter.ToSingle(data, index)); break; } case DataType.DATA32: { hasChanged = device.SetDeviceValue(BitConverter.ToInt32(data, index)); break; } case DataType.DATA16: { hasChanged = device.SetDeviceValue(BitConverter.ToInt16(data, index)); break; } case DataType.DATA_A4: { byte[] values = new byte[4]; Array.Copy(data, index, values, 0, 4); hasChanged = device.SetDeviceValue(values); break; } } index += type.ByteLength(); } if (buttonByteLength > 0) { byte[] buttonData = new byte[buttonByteLength]; Array.Copy(data, index, buttonData, 0, buttonByteLength); buttons.BatchCommandReturn(buttonData); index += buttonByteLength; } if (batteryByteLength > 0) { byte[] batteryData = new byte[batteryByteLength]; Array.Copy(data, index, batteryData, 0, batteryByteLength); battery.SetValue(batteryData); index += batteryByteLength; } if (warningByteLength > 0) { console.SetValue(data[index]); index += warningByteLength; } } } catch (Exception e) { Brick.Logger.LogError(e, e.Message); } try { await Task.Delay(INTERVAL, _socket.CancellationToken); } catch (TaskCanceledException) { } } }, _socket.CancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); }
/// <summary> /// Gets a list of folders and/or files for given path /// </summary> /// <param name="socket">socket for executing command to brick</param> /// <param name="brickDirectoryPath">relative path to folder on brick</param> /// <returns>DirectoryContent</returns> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> /// <exception cref="FirmwareException"/> public static async Task <DirectoryContent> GetDirectoryContent(ISocket socket, string brickDirectoryPath) { await semaPhoreSlim.WaitAsync(); try { brickDirectoryPath = FileSystem.ToBrickDirectoryPath(brickDirectoryPath); brickDirectoryPath.IsBrickDirectoryPath(); Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.SYSTEM_COMMAND_REPLY)) { cb.OpCode(SYSTEM_OP.LIST_FILES); cb.Raw((ushort)PAYLOAD_SIZE); cb.Raw(brickDirectoryPath); cmd = cb.ToCommand(); } Response response = await socket.Execute(cmd); if (!(response.Status == ResponseStatus.SUCCESS || response.Status == ResponseStatus.END_OF_FILE)) { throw new FirmwareException(response); } byte[] data = response.PayLoad; ushort listSize = (ushort)BitConverter.ToUInt32(data, 0); byte handle = data[4]; List <byte> list = new List <byte>(); if (data.Length > 5) { byte[] chunk = new byte[data.Length - 5]; Array.Copy(data, 5, chunk, 0, chunk.Length); list.AddRange(chunk); int bytesRead = chunk.Length; while (bytesRead < listSize) { ushort payLoadSize = (ushort)Math.Min(PAYLOAD_SIZE, listSize - bytesRead); response = await ContinueList(socket, handle, payLoadSize); if (!(response.Status == ResponseStatus.SUCCESS || response.Status == ResponseStatus.END_OF_FILE)) { throw new FirmwareException(response); } data = response.PayLoad; if (data.Length > 1) { chunk = new byte[data.Length - 1]; Array.Copy(data, 1, chunk, 0, chunk.Length); list.AddRange(chunk); } bytesRead += payLoadSize; } } data = list.ToArray(); string value = Encoding.UTF8.GetString(data, 0, data.Length).TrimEnd(LIST_DELIMITER); string[] entries = value.Split(LIST_DELIMITER); DirectoryContent contents = new DirectoryContent(); List <Directory> directories = new List <Directory>(); List <File> files = new List <File>(); foreach (string entry in entries) { string item = entry.Trim(); if (string.IsNullOrWhiteSpace(item)) { continue; } switch (item) { case FileSystem.ROOT_PATH: { contents.Root = new Directory(item); break; } case FileSystem.PARENT_PATH: { if (brickDirectoryPath == FileSystem.ROOT_PATH) { contents.Parent = new Directory(FileSystem.ROOT_PATH); } else { string parent = brickDirectoryPath.Substring(0, brickDirectoryPath.LastIndexOf(FileSystem.DIRECTORY_SEPERATOR)); contents.Parent = new Directory(parent); } break; } default: { if (item.EndsWith(FileSystem.DIRECTORY_SEPERATOR)) { string directoryPath = $"{brickDirectoryPath}{item}"; directories.Add(new Directory(directoryPath)); } else { string[] fileInfo = entry.Split(' '); if (fileInfo.Length >= 3) { string md5sum = fileInfo[0].Trim(); long byteSize = Convert.ToInt64(fileInfo[1].Trim(), 16); string fileName = string.Join(" ", fileInfo, 2, fileInfo.Length - 2); if (!string.IsNullOrWhiteSpace(fileName)) { files.Add(new File(brickDirectoryPath, fileName, md5sum, byteSize)); } } } break; } } } directories.Sort(delegate(Directory obj1, Directory obj2) { return(obj1.Name.CompareTo(obj2.Name)); }); contents.Directories = directories.ToArray(); files.Sort(delegate(File obj1, File obj2) { return(obj1.FileName.CompareTo(obj2.FileName)); }); contents.Files = files.ToArray(); return(contents); } finally { semaPhoreSlim.Release(); } }