unsafe void WriteCharacteristic(BleCharacteristic characteristic, byte[] value, int offset, int count, NativeMethods.BLUETOOTH_GATT_FLAGS flags) { Throw.If.Null(characteristic, "characteristic").Null(value, "value").OutOfRange(value, offset, count); HandleAcquireIfOpenOrFail(); try { lock (_writeSync) { int error; var wc = (WinBleCharacteristic)characteristic; var cb = stackalloc byte[NativeMethods.BTH_LE_GATT_CHARACTERISTIC_VALUE.Size + count]; var cv = (NativeMethods.BTH_LE_GATT_CHARACTERISTIC_VALUE *)cb; cv->DataSize = (uint)count; Marshal.Copy(value, offset, (IntPtr)(void *)&cv->Data[0], count); error = NativeMethods.BluetoothGATTSetCharacteristicValue(_handle, ref wc.NativeData, cv, 0, flags); if (error != 0) { var message = string.Format("Failed to write {0} bytes to characteristic {1}.", count, characteristic); throw DeviceException.CreateIOException(Device, message, error); } } } finally { HandleRelease(); } }
internal void Init(string devicePath) { IntPtr handle = NativeMethods.CreateFileFromDevice(devicePath, NativeMethods.EFileAccess.Read | NativeMethods.EFileAccess.Write, NativeMethods.EFileShare.None); if (handle == (IntPtr)(-1)) { int hr = Marshal.GetHRForLastWin32Error(); throw DeviceException.CreateIOException(Device, "Unable to open serial device (" + devicePath + ").", hr); } var timeouts = new NativeMethods.COMMTIMEOUTS(); timeouts.ReadIntervalTimeout = uint.MaxValue; timeouts.ReadTotalTimeoutConstant = uint.MaxValue - 1; // CP210x fails if this is set to uint.MaxValue. timeouts.ReadTotalTimeoutMultiplier = uint.MaxValue; if (!NativeMethods.SetCommTimeouts(handle, out timeouts)) { int hr = Marshal.GetHRForLastWin32Error(); NativeMethods.CloseHandle(handle); throw DeviceException.CreateIOException(Device, "Unable to set serial timeouts.", hr); } _handle = handle; HandleInitAndOpen(); }
/* * public override bool GetConnectionState() * { * uint devInst; * if (0 == NativeMethods.CM_Locate_DevNode(out devInst, _id)) * { * uint dnStatus, dnProblemNumber; * if (0 == NativeMethods.CM_Get_DevNode_Status(out dnStatus, out dnProblemNumber, devInst)) * { * if (0 == (dnStatus & NativeMethods.DN_DEVICE_DISCONNECTED)) { return true; } * } * } * * return false; * } */ void RequiresServices() { lock (_syncObject) { if (!TryOpenToGetInfo(handle => { var nativeServices = NativeMethods.BluetoothGATTGetServices(handle); if (nativeServices == null) { return(false); } var services = new List <WinBleService>(); foreach (var nativeService in nativeServices) { var service = new WinBleService(this, nativeService); services.Add(service); } _services = services.ToArray(); return(true); })) { throw DeviceException.CreateIOException(this, "BLE service list could not be retrieved."); } } }
public override string GetManufacturer() { if (_manufacturer == null) { throw DeviceException.CreateIOException(this, "Unnamed manufacturer."); } return(_manufacturer); }
public override string GetProductName() { if (_productName == null) { throw DeviceException.CreateIOException(this, "Unnamed product."); } return(_productName); }
public override string GetSerialNumber() { if (_serialNumber == null) { throw DeviceException.CreateIOException(this, "No serial number."); } return(_serialNumber); }
public DeviceExceptionDTO(DeviceException exception) { RowKey = DateTime.UtcNow.ToInverseTicksRowKey(); PartitionKey = exception.DeviceUniqueId; DeviceId = exception.DeviceId; DeviceUniqueId = exception.DeviceUniqueId; DeviceRepositoryId = exception.DeviceRepositoryId; Timestamp = exception.Timestamp; ErrorCode = exception.ErrorCode; Details = exception.Details; }
public void ExceptionTest() { // Arrange. const string expectedMessage = "Exception of type 'Sensit.TestSDK.Exceptions.DeviceException' was thrown."; // Act var exception = new DeviceException(); // Assert Assert.IsNull(exception.InnerException); Assert.AreEqual(expectedMessage, exception.Message); }
public void MessageTest() { // Arrange. const string expectedMessage = "message"; // Act. var exception = new DeviceException(expectedMessage); // Assert. Assert.IsNull(exception.InnerException); Assert.AreEqual(expectedMessage, exception.Message); }
public override unsafe byte[] ReadCharacteristic(BleCharacteristic characteristic, BleRequestFlags requestFlags) { Throw.If.Null(characteristic, "characteristic"); HidSharpDiagnostics.PerformStrictCheck(characteristic.IsReadable, "Characteristic doesn't support Read."); var flags = GetGattFlags(requestFlags); HandleAcquireIfOpenOrFail(); try { lock (_readSync) { int error; var wc = (WinBleCharacteristic)characteristic; ushort valueSize; error = NativeMethods.BluetoothGATTGetCharacteristicValue(_handle, ref wc.NativeData, 0, null, out valueSize, flags | ((requestFlags & BleRequestFlags.Cacheable) == 0 ? NativeMethods.BLUETOOTH_GATT_FLAGS.FORCE_READ_FROM_DEVICE : 0)); if (error != NativeMethods.ERROR_MORE_DATA || valueSize < NativeMethods.BTH_LE_GATT_CHARACTERISTIC_VALUE.Size) { var message = string.Format("Failed to read characteristic {0}.", characteristic); throw DeviceException.CreateIOException(Device, message, error); } var cb = stackalloc byte[valueSize]; var cv = (NativeMethods.BTH_LE_GATT_CHARACTERISTIC_VALUE *)cb; ushort valueSize2; error = NativeMethods.BluetoothGATTGetCharacteristicValue(_handle, ref wc.NativeData, valueSize, cv, out valueSize2, flags); if (error != 0 || valueSize != valueSize2 || cv->DataSize > valueSize - NativeMethods.BTH_LE_GATT_CHARACTERISTIC_VALUE.Size) { var message = string.Format("Failed to read characteristic {0}.", characteristic); throw DeviceException.CreateIOException(Device, message, error); } var bytes = new byte[cv->DataSize]; Marshal.Copy((IntPtr)(void *)&cv->Data[0], bytes, 0, checked ((int)cv->DataSize)); return(bytes); } } finally { HandleRelease(); } }
internal MacSerialStream(MacSerialDevice device) : base(device) { string fileSystemName = device.GetFileSystemName(); int ret; int handle = NativeMethods.retry(() => NativeMethods.open(fileSystemName, NativeMethods.oflag.RDWR | NativeMethods.oflag.NOCTTY | NativeMethods.oflag.NONBLOCK)); if (handle < 0) { var error = (NativeMethods.error)Marshal.GetLastWin32Error(); if (error == NativeMethods.error.EACCES) { throw DeviceException.CreateUnauthorizedAccessException(device, "Not permitted to open serial device at " + fileSystemName + "."); } else { throw DeviceException.CreateIOException(device, "Unable to open serial device (" + error.ToString() + ")."); } } ret = NativeMethods.retry(() => NativeMethods.ioctl(handle, NativeMethods.TIOCEXCL)); if (ret < 0) { NativeMethods.retry(() => NativeMethods.close(handle)); throw new IOException("Unable to open serial device exclusively."); } /* * ret = NativeMethods.retry(() => NativeMethods.fcntl(handle, NativeMethods.F_SETFL, 0)); * if (ret < 0) * { * NativeMethods.retry(() => NativeMethods.ioctl(handle, NativeMethods.TIOCNXCL)); * NativeMethods.retry(() => NativeMethods.close(handle)); * throw new IOException("Unable to remove blocking from port."); * } */ ret = NativeMethods.retry(() => NativeMethods.tcgetattr(handle, out _oldSettings)); if (ret < 0) { NativeMethods.retry(() => NativeMethods.ioctl(handle, NativeMethods.TIOCNXCL)); NativeMethods.retry(() => NativeMethods.close(handle)); throw new IOException("Unable to get serial port settings."); } _newSettings = _oldSettings; NativeMethods.cfmakeraw(ref _newSettings); _handle = handle; InitSettings(); UpdateSettings(); }
internal void Init(NativeMethods.io_string_t path) { IntPtr handle; int retryCount = 0, maxRetries = 10; while (true) { var newPath = path.Clone(); using (var service = NativeMethods.IORegistryEntryFromPath(0, ref newPath).ToIOObject()) { string error; if (service.IsSet) { handle = NativeMethods.IOHIDDeviceCreate(IntPtr.Zero, service); if (handle != IntPtr.Zero) { var ret = NativeMethods.IOHIDDeviceOpen(handle); if (ret == NativeMethods.IOReturn.Success) { break; } NativeMethods.CFRelease(handle); // TODO: Only count up if IOReturn is ExclusiveAccess or Offline. error = string.Format("Unable to open HID class device (error {1}): {0}", newPath.ToString(), ret); } else { error = string.Format("HID class device not found: {0}", newPath.ToString()); } } else { error = string.Format("HID class device path not found: {0}", newPath.ToString()); } if (++retryCount == maxRetries) { throw DeviceException.CreateIOException(Device, error); } Debug.WriteLine(string.Format("Retrying ({0})", error)); Thread.Sleep(100); } } _handle = handle; HandleInitAndOpen(); _readThread.Start(); _writeThread.Start(); }
public void InnerExceptionTest() { // Arrange. const string expectedMessage = "message"; var innerException = new Exception("foo"); // Act. var exception = new DeviceException(expectedMessage, innerException); // Assert. Assert.AreEqual(innerException, exception.InnerException); Assert.AreEqual(expectedMessage, exception.Message); }
internal unsafe void Init(string path) { IntPtr handle = NativeMethods.CreateFileFromDevice(path, NativeMethods.EFileAccess.Read | NativeMethods.EFileAccess.Write, 0); if (handle == (IntPtr)(-1)) { throw DeviceException.CreateIOException(Device, "Unable to open BLE service (" + path + ")."); } _handle = handle; HandleInitAndOpen(); // Let's register to watch all possible characteristics. var watchedCharacteristics = new List <WinBleCharacteristic>(); foreach (var characteristic in Service.GetCharacteristics()) { if (characteristic.IsNotifiable || characteristic.IsIndicatable) { watchedCharacteristics.Add((WinBleCharacteristic)characteristic); } } if (watchedCharacteristics.Count > 0) { var eb = stackalloc byte[checked (NativeMethods.BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION.Size + NativeMethods.BTH_LE_GATT_CHARACTERISTIC.Size * watchedCharacteristics.Count)]; var er = (NativeMethods.BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION *)eb; er->NumCharacteristics = (ushort)watchedCharacteristics.Count; eb += NativeMethods.BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION.Size; for (int i = 0; i < watchedCharacteristics.Count; i++) { var wc = watchedCharacteristics[i]; Marshal.StructureToPtr(wc.NativeData, (IntPtr)eb, false); eb += NativeMethods.BTH_LE_GATT_CHARACTERISTIC.Size; _watchMap[wc.NativeData.AttributeHandle] = wc; } _watchCallback = new NativeMethods.BLUETOOTH_GATT_EVENT_CALLBACK(EventCallback); int error = NativeMethods.BluetoothGATTRegisterEvent(handle, NativeMethods.BTH_LE_GATT_EVENT_TYPE.CharacteristicValueChangedEvent, er, _watchCallback, IntPtr.Zero, out _watchRegisterEventHandle); if (error != 0) { Debug.Assert(error == 0); _watchRegisterEventHandle = IntPtr.Zero; } } }
public override BleCharacteristic[] GetCharacteristics() { lock (_syncObject) { if (_characteristics == null) { if (!_device.TryOpenToGetInfo(handle => { var nativeCharacteristics = NativeMethods.BluetoothGATTGetCharacteristics(handle, ref NativeData); if (nativeCharacteristics == null) { return(false); } var characteristics = new List <WinBleCharacteristic>(); foreach (var nativeCharacteristic in nativeCharacteristics) { var characteristic = new WinBleCharacteristic(nativeCharacteristic); characteristics.Add(characteristic); var nativeDescriptors = NativeMethods.BluetoothGATTGetDescriptors(handle, ref characteristic.NativeData); if (nativeDescriptors == null) { return(false); } var descriptors = new List <WinBleDescriptor>(); foreach (var nativeDescriptor in nativeDescriptors) { var descriptor = new WinBleDescriptor(nativeDescriptor); descriptors.Add(descriptor); } characteristic._characteristicDescriptors = descriptors.ToArray(); } _characteristics = characteristics.ToArray(); return(true); })) { throw DeviceException.CreateIOException(_device, "BLE service information could not be retrieved."); } } } return((BleCharacteristic[])_characteristics.Clone()); }
internal static int DeviceHandleFromPath(string path, HidDevice hidDevice, NativeMethods.oflag oflag) { IntPtr udev = NativeMethodsLibudev.Instance.udev_new(); if (IntPtr.Zero != udev) { try { IntPtr device = NativeMethodsLibudev.Instance.udev_device_new_from_syspath(udev, path); if (IntPtr.Zero != device) { try { string devnode = NativeMethodsLibudev.Instance.udev_device_get_devnode(device); if (devnode != null) { int handle = NativeMethods.retry(() => NativeMethods.open(devnode, oflag)); if (handle < 0) { var error = (NativeMethods.error)Marshal.GetLastWin32Error(); if (error == NativeMethods.error.EACCES) { throw DeviceException.CreateUnauthorizedAccessException(hidDevice, "Not permitted to open HID class device at " + devnode + "."); } else { throw DeviceException.CreateIOException(hidDevice, "Unable to open HID class device (" + error.ToString() + ")."); } } return(handle); } } finally { NativeMethodsLibudev.Instance.udev_device_unref(device); } } } finally { NativeMethodsLibudev.Instance.udev_unref(udev); } } throw new FileNotFoundException("HID class device not found."); }
public override string GetIndexedString(int stringIndex) { string indexedString = null; if (!TryOpenToGetInfo(handle => { char[] buffer = new char[128]; if (!NativeMethods.HidD_GetIndexedString(handle, stringIndex, buffer, Marshal.SystemDefaultCharSize * buffer.Length)) { return(Marshal.GetLastWin32Error() == NativeMethods.ERROR_GEN_FAILURE); } indexedString = NativeMethods.NTString(buffer); return(true); })) { throw DeviceException.CreateIOException(this, "Failed to get info."); } return(indexedString); }
void UpdateSettings() { lock (_lock) { // This assumes the handle is acquired. if (!_settingsChanged) { return; } _settingsChanged = false; var dcb = new NativeMethods.DCB(); dcb.DCBlength = Marshal.SizeOf(typeof(NativeMethods.DCB)); if (!NativeMethods.GetCommState(_handle, ref dcb)) { int hr = Marshal.GetHRForLastWin32Error(); throw DeviceException.CreateIOException(Device, "Failed to get serial state.", hr); } int baudRate = _ser.BaudRate; int dataBits = _ser.DataBits; var parity = _ser.Parity; int stopBits = _ser.StopBits; SetDcbDefaults(ref dcb); dcb.BaudRate = checked ((uint)baudRate); dcb.ByteSize = checked ((byte)_ser.DataBits); dcb.Parity = parity == SerialParity.Even ? NativeMethods.EVENPARITY : parity == SerialParity.Odd ? NativeMethods.ODDPARITY : NativeMethods.NOPARITY; dcb.StopBits = stopBits == 2 ? NativeMethods.TWOSTOPBITS : NativeMethods.ONESTOPBIT; if (!NativeMethods.SetCommState(_handle, ref dcb)) { int hr = Marshal.GetHRForLastWin32Error(); throw DeviceException.CreateIOException(Device, "Failed to set serial state.", hr); } var purgeFlags = NativeMethods.PURGE_RXABORT | NativeMethods.PURGE_RXCLEAR | NativeMethods.PURGE_TXABORT | NativeMethods.PURGE_TXCLEAR; if (!NativeMethods.PurgeComm(_handle, purgeFlags)) { int hr = Marshal.GetHRForLastWin32Error(); throw DeviceException.CreateIOException(Device, "Failed to purge serial port.", hr); } } }
internal void Init(string path) { IntPtr handle = NativeMethods.CreateFileFromDevice(path, NativeMethods.EFileAccess.Read | NativeMethods.EFileAccess.Write, NativeMethods.EFileShare.Read | NativeMethods.EFileShare.Write); if (handle == (IntPtr)(-1)) { throw DeviceException.CreateIOException(Device, "Unable to open HID class device (" + path + ")."); } int maxInputBuffers = Environment.OSVersion.Version >= new Version(5, 1) ? 512 : 200; // Windows 2000 supports 200. Windows XP supports 512. if (!NativeMethods.HidD_SetNumInputBuffers(handle, maxInputBuffers)) { NativeMethods.CloseHandle(handle); throw new IOException("Failed to set input buffers.", new Win32Exception()); } _handle = handle; HandleInitAndOpen(); }
bool TryParseReportDescriptor(out Reports.ReportDescriptor parser, out byte[] reportDescriptor) { parser = null; reportDescriptor = null; int handle; try { handle = LinuxHidStream.DeviceHandleFromPath(_path, this, NativeMethods.oflag.NONBLOCK); } catch (FileNotFoundException) { throw DeviceException.CreateIOException(this, "Failed to read report descriptor."); } try { uint descsize; if (NativeMethods.ioctl(handle, NativeMethods.HIDIOCGRDESCSIZE, out descsize) < 0) { return(false); } if (descsize > NativeMethods.HID_MAX_DESCRIPTOR_SIZE) { return(false); } var desc = new NativeMethods.hidraw_report_descriptor() { size = descsize }; if (NativeMethods.ioctl(handle, NativeMethods.HIDIOCGRDESC, ref desc) < 0) { return(false); } Array.Resize(ref desc.value, (int)descsize); parser = new Reports.ReportDescriptor(desc.value); reportDescriptor = desc.value; return(true); } finally { NativeMethods.retry(() => NativeMethods.close(handle)); } }
void RequiresGetInfo() { lock (_getInfoLock) { if (_reportDescriptor != null) { return; } Reports.ReportDescriptor parser; byte[] reportDescriptor; if (!TryParseReportDescriptor(out parser, out reportDescriptor)) { throw DeviceException.CreateIOException(this, "Failed to read report descriptor."); } _maxInput = parser.MaxInputReportLength; _maxOutput = parser.MaxOutputReportLength; _maxFeature = parser.MaxFeatureReportLength; _reportsUseID = parser.ReportsUseID; _reportDescriptor = reportDescriptor; } }
public async Task <InvokeResult> ClearDeviceExcptionAsync([FromBody] DeviceException deviceExcpetion) { await ValidateRequest(HttpContext.Request); return(await _ticketCreator.ClearDeviceExceptionAsync(deviceExcpetion, OrgEntityHeader, UserEntityHeader)); }
public override unsafe byte[] ReadDescriptor(BleDescriptor descriptor, BleRequestFlags requestFlags) { Throw.If.Null(descriptor, "descriptor"); var flags = GetGattFlags(requestFlags); HandleAcquireIfOpenOrFail(); try { lock (_readSync) { int error; var wd = (WinBleDescriptor)descriptor; ushort valueSize; error = NativeMethods.BluetoothGATTGetDescriptorValue(_handle, ref wd.NativeData, 0, null, out valueSize, flags | ((requestFlags & BleRequestFlags.Cacheable) == 0 ? NativeMethods.BLUETOOTH_GATT_FLAGS.FORCE_READ_FROM_DEVICE : 0)); if (error != NativeMethods.ERROR_MORE_DATA || valueSize < NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE.Size) { var message = string.Format("Failed to read descriptor {0}.", descriptor); throw DeviceException.CreateIOException(Device, message, error); } var cb = stackalloc byte[valueSize]; var cv = (NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE *)cb; ushort valueSize2; error = NativeMethods.BluetoothGATTGetDescriptorValue(_handle, ref wd.NativeData, valueSize, cv, out valueSize2, flags); if (error != 0 || valueSize != valueSize2 || cv->Value.DataSize > valueSize - NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE.Size) { var message = string.Format("Failed to read descriptor {0}.", descriptor); throw DeviceException.CreateIOException(Device, message, error); } byte[] data; switch (cv->DescriptorType) { case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.CharacteristicExtendedProperties: data = new byte[2]; if (0 != cv->Params.ExtendedProperties.IsReliableWriteEnabled) { data[0] |= 1; } if (0 != cv->Params.ExtendedProperties.IsAuxiliariesWritable) { data[0] |= 2; } break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.ClientCharacteristicConfiguration: data = new byte[2]; if (0 != cv->Params.Cccd.IsSubscribeToNotification) { data[0] |= 1; } if (0 != cv->Params.Cccd.IsSubscribeToIndication) { data[0] |= 2; } break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.ServerCharacteristicConfiguration: data = new byte[2]; if (0 != cv->Params.Sccd.IsBroadcast) { data[0] |= 1; } break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.CharacteristicFormat: throw new NotImplementedException(); default: //Console.WriteLine(string.Format("{0} {1} {2}", valueSize, cv->DescriptorType, cv->Value.DataSize)); data = new byte[cv->Value.DataSize]; Marshal.Copy((IntPtr)(void *)&cv->Value.Data[0], data, 0, data.Length); break; } return(data); } } finally { HandleRelease(); } }
public async Task <InvokeResult> ClearDeviceExceptionAsync(DeviceException exception, EntityHeader org, EntityHeader user) { if (exception == null) { throw new ArgumentNullException(nameof(exception)); } if (org == null) { throw new ArgumentNullException(nameof(org)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } var repo = await _repoManager.GetDeviceRepositoryWithSecretsAsync(exception.DeviceRepositoryId, org, user); var device = await _deviceManager.GetDeviceByIdAsync(repo, exception.DeviceUniqueId, org, user); var deviceConfig = await _deviceConfigManager.GetDeviceConfigurationAsync(device.DeviceConfiguration.Id, org, user); var deviceErrorCode = deviceConfig.ErrorCodes.FirstOrDefault(err => err.Key == exception.ErrorCode); if (deviceErrorCode == null) { return(InvokeResult.FromError($"Could not find error code [{exception.ErrorCode}] on device configuration [{deviceConfig.Name}] for device [{device.Name}]")); } Console.ForegroundColor = ConsoleColor.Magenta; Console.WriteLine("Clear Device Exception."); if (!EntityHeader.IsNullOrEmpty(deviceErrorCode.ServiceTicketTemplate)) { var tickets = await _repo.GetOpenTicketOnDeviceAsync(device.Id, deviceErrorCode.ServiceTicketTemplate.Id, org.Id); foreach (var ticket in tickets) { ticket.IsClosed = true; ticket.ClosedBy = user; await _repo.UpdateServiceTicketAsync(ticket); } } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("No service ticket, skipping."); } if (!EntityHeader.IsNullOrEmpty(deviceErrorCode.DistroList)) { var distroList = await _distroManager.GetListAsync(deviceErrorCode.DistroList.Id, org, user); var subject = "[CLEARED] -" + (String.IsNullOrEmpty(deviceErrorCode.EmailSubject) ? deviceErrorCode.Name : deviceErrorCode.EmailSubject.Replace("[DEVICEID]", device.DeviceId).Replace("[DEVICENAME]", device.Name)); foreach (var notificationUser in distroList.AppUsers) { var appUser = await _userManager.FindByIdAsync(notificationUser.Id); if (deviceErrorCode.SendEmail) { var body = $"The error code [{deviceErrorCode.Key}] was cleared on the device {device.Name}<br>{deviceErrorCode.Description}<br>{exception.Details}"; await _emailSender.SendAsync(appUser.Email, subject, body); } if (deviceErrorCode.SendSMS) { var body = $"Device {device.Name} cleared error code [${deviceErrorCode.Key}] {deviceErrorCode.Description} {exception.Details}"; await _smsSender.SendAsync(appUser.PhoneNumber, body); } } } else { Console.WriteLine("No distro, skipping."); } Console.ResetColor(); return(InvokeResult.Success); }
public async Task <InvokeResult> HandleDeviceExceptionAsync(DeviceException exception, EntityHeader org, EntityHeader user) { if (exception == null) { throw new ArgumentNullException(nameof(exception)); } if (org == null) { throw new ArgumentNullException(nameof(org)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } Console.ForegroundColor = ConsoleColor.Magenta; Console.WriteLine("Handling Device Exception."); var repo = await _repoManager.GetDeviceRepositoryWithSecretsAsync(exception.DeviceRepositoryId, org, user); var device = await _deviceManager.GetDeviceByDeviceIdAsync(repo, exception.DeviceUniqueId, org, user); var deviceConfig = await _deviceConfigManager.GetDeviceConfigurationAsync(device.DeviceConfiguration.Id, org, user); var deviceErrorCode = deviceConfig.ErrorCodes.FirstOrDefault(err => err.Key == exception.ErrorCode); if (deviceErrorCode == null) { return(InvokeResult.FromError($"Could not find error code [{exception.ErrorCode}] on device configuration [{deviceConfig.Name}] for device [{device.Name}]")); } if (!EntityHeader.IsNullOrEmpty(deviceErrorCode.ServiceTicketTemplate)) { Console.WriteLine("Generating service ticket (every occurence."); var request = new CreateServiceTicketRequest() { TemplateId = deviceErrorCode.ServiceTicketTemplate.Id, DeviceId = device.DeviceId, Details = exception.Details, DontCreateIfOpenForDevice = !deviceErrorCode.TriggerOnEachOccurrence, RepoId = repo.Id }; var result = await CreateServiceTicketAsync(request, org, user); if (!result.Successful) { return(result.ToInvokeResult()); } } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("No service ticket, skipping."); } var deviceError = device.Errors.Where(err => err.DeviceErrorCode == exception.ErrorCode).FirstOrDefault(); if (deviceError == null) { deviceError = new DeviceError() { Count = 1, DeviceErrorCode = exception.ErrorCode, FirstSeen = DateTime.UtcNow.ToJSONString(), LastDetails = exception.Details, Timestamp = DateTime.UtcNow.ToJSONString(), Expires = deviceErrorCode.AutoexpireTimespan.Value.AddTimeSpan(deviceErrorCode.AutoexpireTimespanQuantity.Value) }; device.Errors.Add(deviceError); } if (!EntityHeader.IsNullOrEmpty(deviceErrorCode.DistroList)) { if (deviceError == null || String.IsNullOrEmpty(deviceError.NextNotification) || (deviceError.NextNotification.ToDateTime().ToUniversalTime() < DateTime.UtcNow)) { var result = await _distroManager.GetListAsync(deviceErrorCode.DistroList.Id, org, user); var subject = String.IsNullOrEmpty(deviceErrorCode.EmailSubject) ? deviceErrorCode.Name : deviceErrorCode.EmailSubject.Replace("[DEVICEID]", device.DeviceId).Replace("[DEVICENAME]", device.Name); foreach (var notificationUser in result.AppUsers) { var appUser = await _userManager.FindByIdAsync(notificationUser.Id); if (deviceErrorCode.SendEmail) { var body = $"The error code [{deviceErrorCode.Key}] was detected on the device {device.Name}<br>{deviceErrorCode.Description}<br>{exception.Details}"; if (exception.AdditionalDetails.Any()) { body += "<br>"; body += "<b>Additional Details:<br /><b>"; body += "<ul>"; foreach (var detail in exception.AdditionalDetails) { body += $"<li>{detail}</li>"; } body += "</ul>"; } await _emailSender.SendAsync(appUser.Email, subject, body); } if (deviceErrorCode.SendSMS) { var body = $"Device {device.Name} generated error code [${deviceErrorCode.Key}] {deviceErrorCode.Description} {exception.Details}"; await _smsSender.SendAsync(appUser.PhoneNumber, body); } } if (EntityHeader.IsNullOrEmpty(deviceErrorCode.NotificationIntervalTimeSpan)) { deviceError.NextNotification = null; } else if (deviceErrorCode.NotificationIntervalQuantity.HasValue && deviceErrorCode.NotificationIntervalTimeSpan.Value != TimeSpanIntervals.NotApplicable) { deviceError.NextNotification = deviceErrorCode.NotificationIntervalTimeSpan.Value.AddTimeSpan(deviceErrorCode.NotificationIntervalQuantity.Value); } else { deviceError.NextNotification = null; Logger.AddCustomEvent(Core.PlatformSupport.LogLevel.Error, "ServiceTicketManager__HandleDeviceExceptionAsync", "Invalid quantity on NotificationIntervalQuantity", device.DeviceId.ToKVP("deviceId"), exception.ErrorCode.ToKVP("errorCode")); } } else { if (String.IsNullOrEmpty(deviceError.NextNotification)) { Console.WriteLine("NExt Notification is null...."); } else { Console.WriteLine("When to send next notification: " + deviceError.NextNotification); } } } else { Console.WriteLine("No distro, skipping."); } Console.ResetColor(); await _deviceManager.UpdateDeviceAsync(repo, device, org, user); return(InvokeResult.Success); }
private async Task <InvokeResult> HandleSystemMessageAsync(string path, string payload) { Metrics.MessagesProcessed++; PEMBus.InstanceLogger.AddCustomEvent(LagoVista.Core.PlatformSupport.LogLevel.Message, "ListenerMOdule_HandleSystemMessageAsync", "Received System Message", path.ToKVP("topic"), payload.ToKVP("body")); var parts = path.Split('/'); if (parts.Length < 5) { var errMsg = $"NuvIoT service messages must be at least 5 segments {path} is {parts.Length} segments"; PEMBus.InstanceLogger.AddError("ListenerModule__HandleSystemMessage", errMsg); return(InvokeResult.FromError(errMsg)); } var deviceId = parts[3]; var device = await PEMBus.DeviceStorage.GetDeviceByDeviceIdAsync(deviceId); if (device == null) { var errMsg = $"Could not find device with device id {deviceId}."; PEMBus.InstanceLogger.AddError("ListenerModule__HandleSystemMessage", errMsg); return(InvokeResult.FromError(errMsg)); } device.LastContact = DateTime.UtcNow.ToJSONString(); if (parts[4] == "state") { device.DeviceTwinDetails.Insert(0, new DeviceManagement.Models.DeviceTwinDetails() { Timestamp = DateTime.UtcNow.ToJSONString(), Details = payload }); var payloadSegements = payload.Split(','); foreach (var segement in payloadSegements) { var fieldParts = segement.Split('='); if (fieldParts.Length == 2) { var nameParts = fieldParts[0].Split('-'); if (nameParts.Length == 2) { var typeName = nameParts[0]; var key = nameParts[1]; var value = fieldParts[1]; if (typeName != "readonly") { var prop = device.Properties.FirstOrDefault(prp => prp.Key == key); if (prop != null) { if (prop.Value != value) { prop.Value = value; prop.LastUpdated = DateTime.UtcNow.ToJSONString(); prop.LastUpdatedBy = "Device Twin"; } } } else { if (key == "firmwareSku") { device.ActualFirmware = value; device.ActualFirmwareDate = DateTime.Now.ToJSONString(); } if (key == "firmwareVersion") { device.ActualFirmwareRevision = value; device.ActualFirmwareDate = DateTime.Now.ToJSONString(); } } } } } } else if (parts[4] == "err") { var err = parts[5]; var action = parts[6]; var exception = new DeviceException() { ErrorCode = err, DeviceId = device.DeviceId, DeviceUniqueId = device.Id, DeviceRepositoryId = device.DeviceRepository.Id, Timestamp = DateTime.UtcNow.ToString(), }; exception.AdditionalDetails.Add(payload); if (action == "raise") { await PEMBus.InstanceConnector.HandleDeviceExceptionAsync(exception); } else if (action == "clear") { await PEMBus.InstanceConnector.ClearDeviceExceptionAsync(exception); } } else if (parts[4] == "iovalues") { var values = payload.Split(','); if (values.Length != 16) { throw new InvalidDataException($"IO Configuration from device should consist of 16 comma delimited values, message consists of ${values.Length} items."); } for (int idx = 0; idx < 8; ++idx) { if (!String.IsNullOrEmpty(values[idx + 8])) { var sensor = device.SensorCollection.Where(sns => sns.Technology != null && sns.Technology.Value == DeviceManagement.Models.SensorTechnology.ADC && sns.PortIndex == idx).FirstOrDefault(); if (sensor != null) { sensor.Value = values[idx + 8]; sensor.LastUpdated = DateTime.UtcNow.ToJSONString(); } } } for (int idx = 0; idx < 8; ++idx) { if (!String.IsNullOrEmpty(values[idx])) { var sensor = device.SensorCollection.Where(sns => sns.Technology != null && sns.Technology.Value == DeviceManagement.Models.SensorTechnology.IO && sns.PortIndex == idx).FirstOrDefault(); if (sensor != null) { sensor.Value = values[idx]; sensor.LastUpdated = DateTime.UtcNow.ToJSONString(); } } } await PEMBus.SensorEvaluator.EvaluateAsync(device); } else if (parts[4] == "geo") { var values = payload.Split(','); if (values.Length < 2) { throw new InvalidDataException($"Geo Location Data type must contain a minimum of 2 fields for latitude and longitude, message consists of ${values.Length} items."); } if (!double.TryParse(values[0], out double lat)) { throw new InvalidDataException($"Invalid Latitude value [{values[0]}]."); } if (lat > 90 || lat < -90) { throw new InvalidDataException($"Invalid Latitude value [{values[0]}], must be between -90 and 90."); } if (!double.TryParse(values[1], out double lon)) { throw new InvalidDataException($"Invalid Longitude value [{values[1]}]."); } if (lon > 180 || lon < -180) { throw new InvalidDataException($"Invalid Latitude value [{values[1]}], must be between -180 and 180."); } device.GeoLocation = new LagoVista.Core.Models.Geo.GeoLocation() { LastUpdated = DateTime.UtcNow.ToJSONString(), Latitude = lat, Longitude = lon, }; } else if (parts[4] == "online") { device.ConnectionTimeStamp = DateTime.UtcNow.ToJSONString(); var rssi = -1.0; var reconnect = false; var payloadSegements = payload.Split(','); foreach (var segement in payloadSegements) { var fieldParts = segement.Split('='); if (fieldParts.Length == 2) { var nameParts = fieldParts[0].Split('-'); if (nameParts.Length == 2) { var typeName = nameParts[0]; var key = nameParts[1]; var value = fieldParts[1]; if (typeName != "readonly") { var prop = device.Properties.FirstOrDefault(prp => prp.Key == key); if (prop != null) { if (prop.Value != value) { if (prop.AttributeType.Value == DeviceAdmin.Models.ParameterTypes.TrueFalse) { if (value == "1") { value = "true"; } else if (value == "0") { value = "false"; } else { value = value.ToLower(); } } prop.Value = value; prop.LastUpdated = DateTime.UtcNow.ToJSONString(); prop.LastUpdatedBy = "Device Twin"; } } } else { if (key == "firmwareSku") { device.ActualFirmware = value; device.ActualFirmwareDate = DateTime.Now.ToJSONString(); } if (key == "firmwareVersion") { device.ActualFirmwareRevision = value; device.ActualFirmwareDate = DateTime.Now.ToJSONString(); } if (key == "rssi") { double.TryParse(value, out rssi); } if (key == "reconnect") { reconnect = value != "0"; } } } } } var connectionEvent = new DeviceConnectionEvent() { DeviceId = device.Id, FirmwareRevision = device.ActualFirmwareRevision, FirmwareSKU = device.ActualFirmware, TimeStamp = DateTime.UtcNow.ToJSONString(), RSSI = rssi, Reconnect = reconnect }; await PEMBus.DeviceConnectionEvent.AddDeviceEventConnectionEvent(connectionEvent); } await PEMBus.DeviceStorage.UpdateDeviceAsync(device); var json = JsonConvert.SerializeObject(Models.DeviceForNotification.FromDevice(device), _camelCaseSettings); var notification = new Notification() { Payload = json, Channel = EntityHeader <Channels> .Create(Channels.Device), ChannelId = device.Id, PayloadType = "Device", DateStamp = DateTime.UtcNow.ToJSONString(), MessageId = Guid.NewGuid().ToId(), Text = "Device Updated", Title = "Device Updated" }; await PEMBus.NotificationPublisher.PublishAsync(Targets.WebSocket, notification); notification = new Notification() { Payload = json, Channel = EntityHeader <Channels> .Create(Channels.DeviceRepository), ChannelId = device.DeviceRepository.Id, PayloadType = "Device", DateStamp = DateTime.UtcNow.ToJSONString(), MessageId = Guid.NewGuid().ToId(), Text = "Device Updated", Title = "Device Updated" }; await PEMBus.NotificationPublisher.PublishAsync(Targets.WebSocket, notification); foreach (var group in device.DeviceGroups) { notification = new Notification() { Payload = json, Channel = EntityHeader <Channels> .Create(Channels.DeviceGroup), ChannelId = group.Id, PayloadType = "Device", DateStamp = DateTime.UtcNow.ToJSONString(), MessageId = Guid.NewGuid().ToId(), Text = "Device Updated", Title = "Device Updated" }; await PEMBus.NotificationPublisher.PublishAsync(Targets.WebSocket, notification); } return(InvokeResult.Success); }
public override unsafe void WriteDescriptor(BleDescriptor descriptor, byte[] value, int offset, int count, BleRequestFlags requestFlags) { Throw.If.Null(descriptor, "descriptor").Null(value, "value").OutOfRange(value, offset, count); var flags = GetGattFlags(requestFlags); HandleAcquireIfOpenOrFail(); try { lock (_writeSync) { int error; var wd = (WinBleDescriptor)descriptor; var dvp = new NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE_PARAMS(); byte[] data = null; int dataOffset = 0, dataCount = 0; switch (wd.NativeData.DescriptorType) { case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.CharacteristicExtendedProperties: dvp.ExtendedProperties.IsReliableWriteEnabled = (byte)(value.Length >= 1 && 0 != (value[offset] & 1) ? 1 : 0); dvp.ExtendedProperties.IsAuxiliariesWritable = (byte)(value.Length >= 1 && 0 != (value[offset] & 2) ? 1 : 0); data = new byte[0]; break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.ClientCharacteristicConfiguration: dvp.Cccd.IsSubscribeToNotification = (byte)(value.Length >= 1 && 0 != (value[offset] & 1) ? 1 : 0); dvp.Cccd.IsSubscribeToIndication = (byte)(value.Length >= 1 && 0 != (value[offset] & 2) ? 1 : 0); data = new byte[0]; break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.ServerCharacteristicConfiguration: dvp.Sccd.IsBroadcast = (byte)(value.Length >= 1 && 0 != (value[offset] & 1) ? 1 : 0); data = new byte[0]; break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.CharacteristicFormat: throw new NotImplementedException(); default: data = value; dataOffset = offset; dataCount = count; break; } var db = stackalloc byte[NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE.Size + dataCount]; var dv = (NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE *)db; dv->DescriptorType = wd.NativeData.DescriptorType; dv->DescriptorUuid = wd.NativeData.DescriptorUuid; dv->Params = dvp; dv->Value.DataSize = (uint)dataCount; if (data != null) { Marshal.Copy(data, dataOffset, (IntPtr)(void *)&dv->Value.Data[0], dataCount); } error = NativeMethods.BluetoothGATTSetDescriptorValue(_handle, ref wd.NativeData, dv, flags); if (error != 0) { var message = string.Format("Failed to write {0} bytes to descriptor {1}.", count, descriptor); throw DeviceException.CreateIOException(Device, message, error); } } } finally { HandleRelease(); } }
public async Task <InvokeResult> AddDeviceExceptionAsync(DeviceRepository deviceRepo, DeviceException deviceException) { await _deviceExceptionRepo.AddDeviceExceptionAsync(deviceRepo, deviceException); return(InvokeResult.Success); }
void RequiresGetInfo(GetInfoFlags flags) { lock (_getInfoLock) { flags &= ~_getInfoFlags; // Remove flags we already have. if (flags == 0) { return; } if (!TryOpenToGetInfo(handle => { if ((flags & GetInfoFlags.Manufacturer) != 0) { if (!TryGetDeviceString(handle, NativeMethods.HidD_GetManufacturerString, out _manufacturer)) { return(false); } } if ((flags & GetInfoFlags.ProductName) != 0) { if (!TryGetDeviceString(handle, NativeMethods.HidD_GetProductString, out _productName)) { return(false); } } if ((flags & GetInfoFlags.SerialNumber) != 0) { if (!TryGetDeviceString(handle, NativeMethods.HidD_GetSerialNumberString, out _serialNumber)) { return(false); } } if ((flags & GetInfoFlags.ReportInfo) != 0) { IntPtr preparsed; if (!NativeMethods.HidD_GetPreparsedData(handle, out preparsed)) { return(false); } try { NativeMethods.HIDP_CAPS caps; int statusCaps = NativeMethods.HidP_GetCaps(preparsed, out caps); if (statusCaps != NativeMethods.HIDP_STATUS_SUCCESS) { return(false); } _maxInput = caps.InputReportByteLength; _maxOutput = caps.OutputReportByteLength; _maxFeature = caps.FeatureReportByteLength; try { _reportDescriptor = new ReportDescriptorReconstructor().Run(preparsed, caps); } catch (NotImplementedException) { _reportDescriptor = null; } catch { return(false); } } finally { NativeMethods.HidD_FreePreparsedData(preparsed); } } return(true); })) { throw DeviceException.CreateIOException(this, "Failed to get info."); } _getInfoFlags |= flags; } }
protected override string GetStreamPath(OpenConfiguration openConfig) { var service = GetService(openConfig); if (service == null) { throw DeviceException.CreateIOException(this, "BLE service not specified."); } if (service.Device != this) { throw DeviceException.CreateIOException(this, "BLE service is on a different device."); } uint devInst; if (0 == NativeMethods.CM_Locate_DevNode(out devInst, _id)) { if (0 == NativeMethods.CM_Get_Child(out devInst, devInst)) { do { string serviceDeviceID; if (0 == NativeMethods.CM_Get_Device_ID(devInst, out serviceDeviceID)) { NativeMethods.HDEVINFO devInfo = NativeMethods.SetupDiGetClassDevs( service.Uuid, serviceDeviceID, IntPtr.Zero, NativeMethods.DIGCF.DeviceInterface | NativeMethods.DIGCF.Present ); if (devInfo.IsValid) { try { NativeMethods.SP_DEVINFO_DATA dvi = new NativeMethods.SP_DEVINFO_DATA(); dvi.Size = Marshal.SizeOf(dvi); for (int j = 0; NativeMethods.SetupDiEnumDeviceInfo(devInfo, j, ref dvi); j++) { NativeMethods.SP_DEVICE_INTERFACE_DATA did = new NativeMethods.SP_DEVICE_INTERFACE_DATA(); did.Size = Marshal.SizeOf(did); for (int k = 0; NativeMethods.SetupDiEnumDeviceInterfaces(devInfo, ref dvi, service.Uuid, k, ref did); k++) { string devicePath; if (NativeMethods.SetupDiGetDeviceInterfaceDevicePath(devInfo, ref did, out devicePath)) { // FIXME: Take the attribute handle into account as well. // Right now, if there are multiple services with the same GUID, we do not distinguish between them. return(devicePath); } } } } finally { NativeMethods.SetupDiDestroyDeviceInfoList(devInfo); } } } }while (0 == NativeMethods.CM_Get_Sibling(out devInst, devInst)); } } throw DeviceException.CreateIOException(this, string.Format("BLE service {0} not found.", service.Uuid)); }