I'm attempting to get the characteristics of a custom BLE service. I have a NETStandard class library, making use of NETCore build 17134 for Bluetooth communication. This library is then used in a WPF application (.NET Framework 4.7.1.) I'm able to connect to my BLE peripheral, as well as read the generic service that includes Hardware Revision, etc. However, when it then goes to get the characteristics of my custom service, the status reads AccessDenied and the array of characteristics is empty. Any help would be greatly appreciated.
The same code works when it's purely UWP. However, I have no way to set Bluetooth permissions in the desktop app as I can in UWP. I've attempted running as administrator and performing the workaround using an AppID/registry entry. It didn't seem to work, but perhaps I simply did something wrong.
Is this a known issue? I've read there's been some regression since the original Creator's Update (15xxx) but the threads all seem about a year old.
protected async override Task<IList<ICharacteristic>> GetCharacteristicsNativeAsync()
{
var accessRequestResponse = await _nativeService.RequestAccessAsync();
// Returns Allowed
if (accessRequestResponse != Windows.Devices.Enumeration.DeviceAccessStatus.Allowed)
{
throw new Exception("Access to service " + _nativeService.Uuid.ToString() + " was disallowed w/ response: " + accessRequestResponse);
}
var allCharacteristics = await _nativeService.GetCharacteristicsAsync(Windows.Devices.Bluetooth.BluetoothCacheMode.Uncached);
// Status: AccessDenied
var status = allCharacteristics.Status;
// No error
var err = allCharacteristics.ProtocolError;
var nativeChars = allCharacteristics.Characteristics;
var charList = new List<ICharacteristic>();
foreach (var nativeChar in nativeChars)
{
var characteristic = new Characteristic(nativeChar, this);
charList.Add(characteristic);
}
return charList;
}
Any help would be greatly appreciated!
Related
I am looking into screen casting through Miracast in an application but am unsure of how to use the Windows.Media.Miracast namespace. Limited information exists on the internet due to the short age of the Windows 10 1903 update that the namespace comes as a part of.
The only thing I've found so far is this documentation.
My question is does anybody know what the proper way of using this namespace is? Any examples or resources found online would be a great help.
Cheers.
These three sample projects demonstrate various MiraCast source apis that can be used from UWP applications. Not sure about outside UWP.
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/BasicMediaCasting
https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/AdvancedCasting
https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/Projection
I'm personally using code like the following, on Windows IoT Core, to cast my whole screen
Scan for devices:
miraDeviceWatcher = DeviceInformation.CreateWatcher(CastingDevice.GetDeviceSelector(CastingPlaybackTypes.Video));
miraHandlerAdded = new TypedEventHandler<DeviceWatcher, DeviceInformation>(async (watcher, deviceInfo) =>
{
await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
//Add each discovered device to our listbox
CastingDevice addedDevice = await CastingDevice.FromIdAsync(deviceInfo.Id);
var disp = new CastingDisplay(addedDevice); //my viewmodel
MiraDevices.Add(disp); //ObservableCollection
});
});
miraDeviceWatcher.Added += miraHandlerAdded;
Connect to selected device:
public async Task StartCasting(CastingDisplay castee)
{
//When a device is selected, first thing we do is stop the watcher so it's search doesn't conflict with streaming
if (miraDeviceWatcher.Status != DeviceWatcherStatus.Stopped)
{
miraDeviceWatcher.Stop();
}
//Create a new casting connection to the device that's been selected
connection = castee.Device.CreateCastingConnection();
//Register for events
connection.ErrorOccurred += Connection_ErrorOccurred;
connection.StateChanged += Connection_StateChangedAsync;
var image = new Windows.UI.Xaml.Controls.Image();
await connection.RequestStartCastingAsync(image.GetAsCastingSource());
}
This Image is just used as a casting source. Once the connection is made, my whole screen is broadcast. The behavior is not documented. Hopefully it won't get 'fixed' in a future update.
Hi I am using Microsoft Cognitive Services and it's giving me an exception for some unknown reason. This is the way I declared FaceServiceRestClient:
var faceServiceClient = new FaceServiceRestClient("MY_KEY");
when I run above code it throws an exception by saying "Your Subscription key is invalid". I checked 3-4 times Key is correct, I also regenerated key and used it still exception is there.
Now, I added second parameter, thats URL so not my declaration is as follows:
var faceServiceClient = new FaceServiceRestClient("MY_KEY", "https://australiaeast.api.cognitive.microsoft.com/face/v1.0" );
For above statement I get an exception as "Java.Lang.IllegalStateException: Target host must not be null, or set in parameters. scheme=null, host=null, path=MY_KEY/detect"
This is how I am calling detect method (If you want to see)
Com.Microsoft.Projectoxford.Face.Contract.Face[] result = faceServiceClient.Detect(#params[0], true, false, null);
I do not understand exactly where to look at or which declaration is correct. & BTW this is Xamarin application and I used Xamarin.Microsoft.Cognitive.Face package. If you want to anything else in my code please Comment I will share code snippet.
Can anyone please help?
Thank you
"Java.Lang.IllegalStateException: Target host must not be null, or set in parameters. scheme=null, host=null, path=MY_KEY/detect"
That package wraps the Android/Java API and that API is different then the other platforms. In the case of FaceServiceRestClient, the Azure Face Endpoint is the first param, and your Face API key is the second.
Note: They did not even name the parameters in the binding library so you will see param names such as p0 p1 throughout the C# API :-( I ended up using Rekognition to work around the throughput limitations of Cognitive services, but that is a different story)
I stripped down a camera/photo tagger that I wrote to get you started.
Example:
await Task.Run(() =>
{
var faceServiceClient = new FaceServiceRestClient(faceEndpoint, faceAPIKey);
using (var imageFileStream = camera.SingleImageStream)
{
var faceAttributes = new FaceServiceClientFaceAttributeType[] { FaceServiceClientFaceAttributeType.Gender, FaceServiceClientFaceAttributeType.Age, FaceServiceClientFaceAttributeType.Smile, FaceServiceClientFaceAttributeType.Glasses, FaceServiceClientFaceAttributeType.FacialHair };
var faces = faceServiceClient.Detect(imageFileStream, true, false, faceAttributes);
foreach (var face in faces)
{
Log.Debug(TAG, $"{face.FaceRectangle.Left}:{face.FaceRectangle.Top}:{face.FaceRectangle.Width}:{face.FaceRectangle.Height}");
DrawFaceRect(face.FaceRectangle);
TagPhoto(face.FaceAttributes);
}
}
});
I am developing a simple app that need to send and receive some data from azure.
First of all, I have worked with a simulated device(and console app). I have configured my azure portal to work with the this data and everything works well.
At the same time, I checked my sensor with unit-tests and it works fine too.
Now, I want to send some data from my sensors to azure(with Universal App). I tried to work with this link:
https://blogs.windows.com/buildingapps/2016/03/03/connect-your-windows-app-to-azure-iot-hub-with-visual-studio/#BgxLrRq1bXolCitM.97
I choose the device that I worked with in the simulated device and got an error of "unknown host" for the client connect.
Do I need to register my raspberry pi as a device before? How I can send a simple string from known universal app (i.e: https://developer.microsoft.com/en-us/windows/iot/samples/helloblinky ) to azure?
I am working with Windows 10 IOT, c#
Thanks!
Update:
I tried to do all what you suggested without success.
Relavant code:
public static async Task SendDeviceToCloudMessageAsync()
{
CreateClient();
var currentTemperature = 20 /*getCurrentTemperature()*/;
var currentHumidity = 20/*getCurrentHumidity()*/;
var telemetryDataPoint = new
{
deviceId = DeviceId,
plantID = 7,
temperature = currentTemperature,
humidity = currentHumidity,
userId = 1
};
var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
var message = new Message(Encoding.ASCII.GetBytes(messageString));
message.Properties.Add("temperatureAlert", (currentTemperature > 30) ? "true" : "false");
Debug.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
await deviceClient.SendEventAsync(message);
}
I don't know how to validate the "sharedAccessKey" on connectionString var
Error(on await deviceClient.SendEventAsync(message) line):
Exception thrown: 'System.Exception' in System.Private.CoreLib.ni.dll
No such host is known. (Exception from HRESULT: 0x80072AF9)
You will need to do two things here.
First up, connect your device. Details here - https://developer.microsoft.com/en-us/windows/iot/docs/ConnectDeviceToCloud
Second, connect your app. - https://developer.microsoft.com/en-us/windows/iot/docs/ConnectAppToCloud
If you run into issues when doing the above two, then, you will be able to ask more specific questions.
For a project I'm working on, I need to read data from a BluetoothLE module (HM-10). I need to read and use this data from a Unity-application. To connect and read data I'm building a plugin for Unity using Visual Studio 2017. I can get a list of BluetoothLE devices using:
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };
deviceWatcher =
DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
Connecting to a device seems to work as well. I use:
BluetoothLEDevice btDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
Next, I want to read the data that this device is sending. I understand I need to collect the services and characteristics next before I can read this data. But for some reason I can't await the services. I get an error using this:var gattservices = await btDevice.GetGattServicesAsync();
The error reads:
Unable to cast object of type 'Windows.Devices.Bluetooth.BluetoothLEDevice' to type 'Windows.Devices.Bluetooth.IBluetoothLEDevice3'
Am I using the wrong methods to get my results?
Any help will be appreciated!
I have finally found how I can get all services and the characteristics per service. By creating a GattDevice I can get the services with GattDevice.GattServices.
When I found the correct GattDeviceService, I can get the Characteristics with:
GattService s = new GattService(GattDeviceService)
GattCharacteristic.GetCharacteristics(s)
Is there any API for writing a C# program that could interface with Windows update, and use it to selectively install certain updates?
I'm thinking somewhere along the lines of storing a list in a central repository of approved updates. Then the client side applications (which would have to be installed once) would interface with Windows Update to determine what updates are available, then install the ones that are on the approved list. That way the updates are still applied automatically from a client-side perspective, but I can select which updates are being applied.
This is not my role in the company by the way, I was really just wondering if there is an API for windows update and how to use it.
Add a Reference to WUApiLib to your C# project.
using WUApiLib;
protected override void OnLoad(EventArgs e){
base.OnLoad(e);
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
uSearcher.Online = false;
try {
ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
textBox1.Text = "Found " + sResult.Updates.Count + " updates" + Environment.NewLine;
foreach (IUpdate update in sResult.Updates) {
textBox1.AppendText(update.Title + Environment.NewLine);
}
}
catch (Exception ex) {
Console.WriteLine("Something went wrong: " + ex.Message);
}
}
Given you have a form with a TextBox this will give you a list of the currently installed updates. See http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx for more documentation.
This will, however, not allow you to find KB hotfixes which are not distributed via Windows Update.
The easiest way to do what you want is using WSUS. It's free and basically lets you setup your own local windows update server where you decide which updates are "approved" for your computers. Neither the WSUS server nor the clients need to be in a domain, though it makes it easier to configure the clients if they are. If you have different sets of machines that need different sets of updates approved, that's also supported.
Not only does this accomplish your stated goal, it saves your overall network bandwidth as well by only downloading the updates once from the WSUS server.
If in your context you're allowed to use Windows Server Update Service (WSUS), it will give you access to the Microsoft.UpdateServices.Administration Namespace.
From there, you should be able to do some nice things :)
P-L right. I tried first the Christoph Grimmer-Die method, and in some case, it was not working. I guess it was due to different version of .net or OS architecture (32 or 64 bits).
Then, to be sure that my program get always the Windows Update waiting list of each of my computer domain, I did the following :
Install a serveur with WSUS (may save some internet bandwith) : http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5216
Add all your workstations & servers to your WSUS server
Get SimpleImpersonation Lib to run this program with different admin right (optional)
Install only the administration console component on your dev workstation and run the following program :
It will print in the console all Windows updates with UpdateInstallationStates.Downloaded
using System;
using Microsoft.UpdateServices.Administration;
using SimpleImpersonation;
namespace MAJSRS_CalendarChecker
{
class WSUS
{
public WSUS()
{
// I use impersonation to use other logon than mine. Remove the following "using" if not needed
using (Impersonation.LogonUser("mydomain.local", "admin_account_wsus", "Password", LogonType.Batch))
{
ComputerTargetScope scope = new ComputerTargetScope();
IUpdateServer server = AdminProxy.GetUpdateServer("wsus_server.mydomain.local", false, 80);
ComputerTargetCollection targets = server.GetComputerTargets(scope);
// Search
targets = server.SearchComputerTargets("any_server_name_or_ip");
// To get only on server FindTarget method
IComputerTarget target = FindTarget(targets, "any_server_name_or_ip");
Console.WriteLine(target.FullDomainName);
IUpdateSummary summary = target.GetUpdateInstallationSummary();
UpdateScope _updateScope = new UpdateScope();
// See in UpdateInstallationStates all other properties criteria
_updateScope.IncludedInstallationStates = UpdateInstallationStates.Downloaded;
UpdateInstallationInfoCollection updatesInfo = target.GetUpdateInstallationInfoPerUpdate(_updateScope);
int updateCount = updatesInfo.Count;
foreach (IUpdateInstallationInfo updateInfo in updatesInfo)
{
Console.WriteLine(updateInfo.GetUpdate().Title);
}
}
}
public IComputerTarget FindTarget(ComputerTargetCollection coll, string computername)
{
foreach (IComputerTarget target in coll)
{
if (target.FullDomainName.Contains(computername.ToLower()))
return target;
}
return null;
}
}
}