How do I renename a Bluetooth device - c#

I'm trying to rename a Bluetooth device from a Windows Phone 8 app. I know the AT commands to send to the device but i belive I connecto to the device somhow wrong.
I have an old PDA program that can rename my device, and that program is the source of my AT commands som I'm pretty sure they are correct.
If I start a Datalogger and rename my device from my PDA no data appears in the log, if I do the same from my phone I get all the commands in my Datalogger.
Here is how I connect to my device in my windows phone App:
public void Rename()
{
var info = GetPeerInfo();
/*
GetPeerInfo() gives me the PeerInformation of my device and it works as expected.
*/
if (info == null)
return;
socket = new StreamSocket();
Task.Run(async () => { await socket.ConnectAsync(info.HostName, "1"); }).Wait();
var dataWriter = new DataWriter(socket.OutputStream);
/*
Note
"to" is an internal class containg the new name of my bluetooth device, its bluetooth config etc.
"newLaneNumber" is an integer indicading a postfix to the new name
*/
UpdateDisplayName(dataWriter, to, newLaneNumber);
Task.Run(async () => { await dataWriter.StoreAsync(); }).Wait();
socket.Dispose();
socket = null;
return;
}
This is the method sending the AT commands
private void UpdateDisplayName_Other(DataWriter dataWriter, InspectionTester newDisplayname, int newLaneNumber)
{
//Login
Thread.Sleep(6000);
dataWriter.WriteString("///");
Thread.Sleep(6000);
var bluetoothDefault = new string[]
{
"AT*AGLC=0,1",
"AT*AGCM=2,1",
"AT*AGDM=3,1",
"AT*AGPM=2,1", // pairable (not pairable: "AT*AGPM=1,1")
"AT*AGFP="+'"'+"0"+'"'+",1",
"AT*AGSM=1,1",
"AT*ADDSP=0,1",
"AT*AGMSP=1,1",
"AT*ADDCP=255,1",
"AT*ADNRP=0,1",
"AT*AMSIT=1,1",
"AT*AMET=5000,5000,1",
"AT*AMLP=0,0,1",
"AT*AMMP=255,1",
"AT*AMWFM=1,6,1",
"AT*AMPM=1,1",
"AT*ACCB=1,1",
"AT*AMDS=1,1,1",
"AT*AMWS=0,0,0,0,0,1"
};
var tmpString = string.Empty;
foreach (var element in bluetoothDefault)
{
tmpString = element + "\r";
dataWriter.WriteString(tmpString);
Thread.Sleep(100);
}
//Name
tmpString = "AT*AGLN=\"" + to.BluetoothName + newLaneNumber.ToString("D2") + "\",1\r";
dataWriter.WriteString(tmpString);
Thread.Sleep(100);
//Baudrate
tmpString = "AT*AMRS=" + to.BluetoothConfig + "\r";
dataWriter.WriteString(tmpString);
//Logout
tmpString = "AT*AMWS=0,0,0,0,1,0\r";
dataWriter.WriteString(tmpString);
}
Some where I'm doing something wrong, I belive I connect the wrong way but I can't find any information about how else to do it.
Here is a log taken from an update attempt from the phone :
///AT*AGLC=0,1
AT*AGCM=2,1
AT*AGDM=3,1
AT*AGPM=2,1
AT*AGFP="0",1
AT*AGSM=1,1
AT*ADDSP=0,1
AT*AGMSP=1,1
AT*ADDCP=255,1
AT*ADNRP=0,1
AT*AMSIT=1,1
AT*AMET=5000,5000,1
AT*AMLP=0,0,1
AT*AMMP=255,1
AT*AMWFM=1,6,1
AT*AMPM=1,1
AT*ACCB=1,1
AT*AMDS=1,1,1
AT*AMWS=0,0,0,0,0,1
AT*AGLN="BMGTMGA1-01",1
AT*AMRS=5,1,2,2,2,1,1
AT*AMWS=0,0,0,0,1,0
If you need some more information please say so.

1point: most of the device don,t support the rename. Some of them just support it by saving the infomation in the RAM ,not the flash or EEPROM .

Related

Program crashes on StartScanningForDevicesAsync() PLUGIN.BLE

I am working on a Xamarin app based on TX/RX serial com, particularly with Xamarin.iOS. I am trying to connect an Arduino to my iOS app, with Plugin.BLE NuGet package. At the time I try to start scanning for devices, the app crashes without debugging logs. This is the command that holds the Task for known device:
public async Task Button_ConnectBT()
{
connected = false;
_handler = CrossBluetoothLE.Current;
_adapter = CrossBluetoothLE.Current.Adapter;
devicelist = new ObservableCollection<IDevice>();
bt_state = "Not Connected";
if (!_adapter.IsScanning)
{
devicelist.Clear();
_adapter.ScanTimeout = 10000;
_adapter.ScanMode = ScanMode.LowPower;
_adapter.DeviceDiscovered += (s, a) =>
{
devicelist.Add(a.Device);
};
if(!_handler.Adapter.IsScanning)
await _adapter.StartScanningForDevicesAsync(); //Breaks here
foreach (var device in devicelist)
{
if (device.Id.ToString() == "96af0bb8-cafa-5b07-a0d2-79c01a414e7ee")
{
...
}
bt_state = "Connected";
}
}
Does anybody know why StartScanningForDevicesASync() is not working? Are there any permissions required by the ios app? If permissions are the impediment, how can I figure them out?
Thank you in advance.
Regards,
Raúl.

Android Notification Sound Causes Media Volume to Duck (Lower) & It Never Comes Back

I just converted one of my apps to target Android API 9 (was targeting API 8); now when notifications are sent out, the volume of media is lowered and never comes back to full volume.
The app uses WebView to play media files. This was not happening prior to targeting API 9. I had to convert the app into level 9 so that I could upload to the Google Play Store. I am running a Samsung S7 which was originally designed for API level 6 (with the OS upgraded to 8.0), not sure if that has something to do with the issue. Another detail is that I use Xamarin.Android for development, not sure if that matters either.
Additionally, I forced the notifications to play a blank sound (a very short[couple ms] blank mp3) in the same build that I converted the app to target API 9:
var channelSilent = new Android.App.NotificationChannel(CHANNEL_ID, name + " Silent", Android.App.NotificationImportance.High)
{
Description = description
};
var alarmAttributes = new Android.Media.AudioAttributes.Builder()
.SetContentType(Android.Media.AudioContentType.Sonification)
.SetUsage(Android.Media.AudioUsageKind.Notification).Build()
//blank is blank mp3 file with nothing in it, a few ms in duration
var uri = Android.Net.Uri.Parse("file:///Assets/blank.mp3")
channelSilent.SetSound(uri, alarmAttributes);
...so it could also be the blank sound that is causing the ducking to malfunction, not the API change. Is there something to do with notification sound ducking that could be causing the issue? Is there any other way to mute a notification with Xamarin.Android other than playing a blank sound? That is one route I think would be worth trying to fix this issue.
Here is the code I am using to generate notifications:
private static List<CustomNotification> _sentNotificationList = new List<CustomNotification>();
private static NotificationManagerCompat _notificationManager;
public async void SendNotifications(List<CustomNotification> notificationList)
{
await Task.Run(() =>
{
try
{
var _ctx = Android.App.Application.Context;
if (_notificationManager == null)
{
_notificationManager = Android.Support.V4.App.NotificationManagerCompat.From(_ctx);
}
if (notificationList.Count == 0)
{
return;
}
int notePos = 0;
foreach (var note in notificationList)
{
var resultIntent = new Intent(_ctx, typeof(MainActivity));
var valuesForActivity = new Bundle();
valuesForActivity.PutInt(MainActivity.COUNT_KEY, _count);
valuesForActivity.PutString("URL", note._noteLink);
resultIntent.PutExtras(valuesForActivity);
var resultPendingIntent = PendingIntent.GetActivity(_ctx, MainActivity.NOTIFICATION_ID, resultIntent, PendingIntentFlags.UpdateCurrent);
resultIntent.AddFlags(ActivityFlags.SingleTop);
var alarmAttributes = new Android.Media.AudioAttributes.Builder()
.SetContentType(Android.Media.AudioContentType.Sonification)
.SetUsage(Android.Media.AudioUsageKind.Notification).Build();
//I am playing this blank sound to prevent android from spamming sounds as the notifications get sent out
var uri = Android.Net.Uri.Parse("file:///Assets/blank.mp3");
//if the notification is the first in our batch then use this
//code block to send the notifications with sound
if (!_sentNotificationList.Contains(note) && notePos == 0)
{
var builder = new Android.Support.V4.App.NotificationCompat.Builder(_ctx, MainActivity.CHANNEL_ID + 1)
.SetAutoCancel(true)
.SetContentIntent(resultPendingIntent) // Start up this activity when the user clicks the intent.
.SetContentTitle(note._noteText) // Set the title
.SetNumber(1) // Display the count in the Content Info
.SetSmallIcon(Resource.Drawable.bitchute_notification2)
.SetContentText(note._noteType)
.SetPriority(NotificationCompat.PriorityMin);
MainActivity.NOTIFICATION_ID++;
_notificationManager.Notify(MainActivity.NOTIFICATION_ID, builder.Build());
_sentNotificationList.Add(note);
notePos++;
}
//if the notification isn't the first in our batch, then use this
//code block to send the notifications without sound
else if (!_sentNotificationList.Contains(note))
{
var builder = new Android.Support.V4.App.NotificationCompat.Builder(_ctx, MainActivity.CHANNEL_ID)
.SetAutoCancel(true) // Dismiss the notification from the notification area when the user clicks on it
.SetContentIntent(resultPendingIntent) // Start up this activity when the user clicks the intent.
.SetContentTitle(note._noteText) // Set the title
.SetNumber(1) // Display the count in the Content Info
.SetSmallIcon(Resource.Drawable.bitchute_notification2)
.SetContentText(note._noteType)
.SetPriority(NotificationCompat.PriorityHigh);
MainActivity.NOTIFICATION_ID++;
_notificationManager.Notify(MainActivity.NOTIFICATION_ID, builder.Build());
_sentNotificationList.Add(note);
notePos++;
}
ExtStickyService._notificationsHaveBeenSent = true;
}
}
catch
{
}
});
}
In my MainActivity I've created two different notification channels: one is silent; the other uses default notification setting for the device:
void CreateNotificationChannel()
{
var alarmAttributes = new Android.Media.AudioAttributes.Builder()
.SetContentType(Android.Media.AudioContentType.Sonification)
.SetUsage(Android.Media.AudioUsageKind.Notification).Build();
var uri = Android.Net.Uri.Parse("file:///Assets/blank.mp3");
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var name = "BitChute";
var description = "BitChute for Android";
var channelSilent = new Android.App.NotificationChannel(CHANNEL_ID, name + " Silent", Android.App.NotificationImportance.High)
{
Description = description
};
var channel = new Android.App.NotificationChannel(CHANNEL_ID + 1, name, Android.App.NotificationImportance.High)
{
Description = description
};
channel.LockscreenVisibility = NotificationVisibility.Private;
//here is where I set the sound for the silent channel... this could be the issue?
var notificationManager = (Android.App.NotificationManager)GetSystemService(NotificationService);
channelSilent.SetSound(uri, alarmAttributes);
notificationManager.CreateNotificationChannel(channel);
notificationManager.CreateNotificationChannel(channelSilent);
}
Full source: https://github.com/hexag0d/BitChute_Mobile_Android_BottomNav/tree/APILevel9
EDIT: something really interesting is that if I pulldown the system ui bar, the volume goes back to normal. Very strange workaround but it might help diagnose the cause.
DOUBLE EDIT: I used .SetSound(null, null) instead of using the blank .mp3 and the ducking works fine now. See comments

Bluetooth BLE Battery Level - C#

I have an specific issue about the Bluetooth BLE API on Windows 10.
At the moment I'm programming a tool on C# (Visual Studio) which connects itself to a given BLE - Device. Currently the connection works perfect and I can read out the ServiceUUIDs and the CharacterUUIDs.
The main Problem is after I try to read the value of the Character its always returns me 00. I heard that implementing a notification will change that and I followed these instructions but they didn't help me.
(Here are the Specifications from bluetooth.com:)
My Code:
//connect to BluetoothDevice
var device = await BluetoothLEDevice.FromIdAsync(address);
//get UUID of Services
var services = await device.GetGattServicesAsync();
if (services != null)
{
foreach (var servicesID in services.Services)
{
//if there is a service thats same like the Battery Service
if (servicesID.Uuid.ToString() == BluetoothBLE.Constants.BATTERY_SERVICE)
{
//updateServiceList is like a console logging in my tool
updateServiceList($"Service: {servicesID.Uuid}");
var characteristics = await servicesID.GetCharacteristicsAsync();
foreach (var character in characteristics.Characteristics)
{
if (Constants.BATTERY_LEVEL == character.Uuid.ToString())
{
updateServiceList("C - UUID: "+ character.Uuid.ToString());
GattReadResult result = await character.ReadValueAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var reader = DataReader.FromBuffer(result.Value);
byte[] input = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(input);
System.Diagnostics.Debug.WriteLine(BitConverter.ToString(input));
}
}
}
}
After Running my Code, the system logs 00. The characterUUID for battery level (0x2A19, from https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.battery_level.xml) was read successfully but the value is strange..

C# SerialDevice no port information (Raspberry Pi 3)

I have two USB receivers for bar-code scanners connected to a raspberry pi3 (Windows IOT Core).
I can connect to them and list the USB Virtual COM devices and connect to them and receive data. But I can't differentiate between the two, the IDs are identical and the system is not providing Port numbers.
When I call Current.portnumber.ToString() the string is empty.
I am hoping to assign each device to a person and have them scan a bar-code for their username and would like to display which scanner is associated with which person (Such as Com5 = Bill Com6 = Dave) but just can't find a unique identifier for each virtual com
private async void ListAvailablePorts()
{
try
{
string aqs = SerialDevice.GetDeviceSelector();
var infos = await DeviceInformation.FindAllAsync(aqs);
foreach (var info in infos)
{
var serialDevice = await SerialDevice.FromIdAsync(info.Id);
DeviceInformation Current = info as DeviceInformation;
if (serialDevice != null && Current.Name == "USB Virtual COM")
{
listOfDevices.Add(Current);
ComList.Items.Add(Current.Name.ToString());
}
}
DeviceList.ItemsSource = listOfDevices;
ComList.SelectedIndex = -1;
DeviceList.SelectedIndex = -1;
}
catch (Exception ex)
{
txtUser.Text = ex.Message;
}
}
After additional scrutiny I found that the ID fields are different on a single digit within an 86 character string.
\\?\USB#VID_0416&PID_5011#5&3753427a&0&5#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
VS
\\?\USB#VID_0416&PID_5011#5&3753427a&0&2#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
Thanks

Recording Audio and Playing sound at the same time - C# - Windows Phone 8.1

I am trying to record audio and play it directly (I want to hear my voice in the headphone without saving it) however the MediaElement and the MediaCapture seems non to work at the same time.
I initialized my MediaCapture so:
_mediaCaptureManager = new MediaCapture();
var settings = new MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
settings.MediaCategory = MediaCategory.Other;
settings.AudioProcessing = AudioProcessing.Default;
await _mediaCaptureManager.InitializeAsync(settings);
However I don't really know how to proceed; I am wonderign if one of these ways could work (I tryied implement them without success, and I have not found examples):
Is there a way to use StartPreviewAsync() recording Audio, or it only works for Videos? I noticed that I get the following error:"The specified object or value does not exist" while setting my CaptureElement Source; it only happens if I write "settings.StreamingCaptureMode = StreamingCaptureMode.Audio;" while everyting works for .Video.
How can I record to a stream using StartRecordToStreamAsync(); I mean, how have I to initialize the IRandomAccessStream and read from it? Can I write on a stream while I keep reading for it?
I read that changing AudioCathegory of the MediaElement and the MediaCathegory of the MediaCapture to Communication there is a possibility it could work. However, while my code works (it just have to record and save in a file) with the previous setting, it don't works if I wrote "settings.MediaCategory = MediaCategory.Communication;" instead of "settings.MediaCategory = MediaCategory.Other;". Can you tell me why?
Here is my current program that just record, save and play:
private async void CaptureAudio()
{
try
{
_recordStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
MediaEncodingProfile recordProfile = MediaEncodingProfile.CreateWav(AudioEncodingQuality.Auto);
await _mediaCaptureManager.StartRecordToStorageFileAsync(recordProfile, this._recordStorageFile);
_recording = true;
}
catch (Exception e)
{
Debug.WriteLine("Failed to capture audio:"+e.Message);
}
}
private async void StopCapture()
{
if (_recording)
{
await _mediaCaptureManager.StopRecordAsync();
_recording = false;
}
}
private async void PlayRecordedCapture()
{
if (!_recording)
{
var stream = await _recordStorageFile.OpenAsync(FileAccessMode.Read);
playbackElement1.AutoPlay = true;
playbackElement1.SetSource(stream, _recordStorageFile.FileType);
playbackElement1.Play();
}
}
If you have any suggestion I'll be gratefull.
Have a good day.
Would you consider targeting Windows 10 instead? The new AudioGraph API allows you to do just this, and the Scenario 2 (Device Capture) in the SDK sample demonstrates it well.
First, the sample populates all output devices into a list:
private async Task PopulateDeviceList()
{
outputDevicesListBox.Items.Clear();
outputDevices = await DeviceInformation.FindAllAsync(MediaDevice.GetAudioRenderSelector());
outputDevicesListBox.Items.Add("-- Pick output device --");
foreach (var device in outputDevices)
{
outputDevicesListBox.Items.Add(device.Name);
}
}
Then it gets to building the AudioGraph:
AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);
settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.LowestLatency;
// Use the selected device from the outputDevicesListBox to preview the recording
settings.PrimaryRenderDevice = outputDevices[outputDevicesListBox.SelectedIndex - 1];
CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);
if (result.Status != AudioGraphCreationStatus.Success)
{
// TODO: Cannot create graph, propagate error message
return;
}
AudioGraph graph = result.Graph;
// Create a device output node
CreateAudioDeviceOutputNodeResult deviceOutputNodeResult = await graph.CreateDeviceOutputNodeAsync();
if (deviceOutputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
{
// TODO: Cannot create device output node, propagate error message
return;
}
deviceOutputNode = deviceOutputNodeResult.DeviceOutputNode;
// Create a device input node using the default audio input device
CreateAudioDeviceInputNodeResult deviceInputNodeResult = await graph.CreateDeviceInputNodeAsync(MediaCategory.Other);
if (deviceInputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
{
// TODO: Cannot create device input node, propagate error message
return;
}
deviceInputNode = deviceInputNodeResult.DeviceInputNode;
// Because we are using lowest latency setting, we need to handle device disconnection errors
graph.UnrecoverableErrorOccurred += Graph_UnrecoverableErrorOccurred;
// Start setting up the output file
FileSavePicker saveFilePicker = new FileSavePicker();
saveFilePicker.FileTypeChoices.Add("Pulse Code Modulation", new List<string>() { ".wav" });
saveFilePicker.FileTypeChoices.Add("Windows Media Audio", new List<string>() { ".wma" });
saveFilePicker.FileTypeChoices.Add("MPEG Audio Layer-3", new List<string>() { ".mp3" });
saveFilePicker.SuggestedFileName = "New Audio Track";
StorageFile file = await saveFilePicker.PickSaveFileAsync();
// File can be null if cancel is hit in the file picker
if (file == null)
{
return;
}
MediaEncodingProfile fileProfile = CreateMediaEncodingProfile(file);
// Operate node at the graph format, but save file at the specified format
CreateAudioFileOutputNodeResult fileOutputNodeResult = await graph.CreateFileOutputNodeAsync(file, fileProfile);
if (fileOutputNodeResult.Status != AudioFileNodeCreationStatus.Success)
{
// TODO: FileOutputNode creation failed, propagate error message
return;
}
fileOutputNode = fileOutputNodeResult.FileOutputNode;
// Connect the input node to both output nodes
deviceInputNode.AddOutgoingConnection(fileOutputNode);
deviceInputNode.AddOutgoingConnection(deviceOutputNode);
Once all of that is done, you can record to a file while at the same time playing the recorded audio like so:
private async Task ToggleRecordStop()
{
if (recordStopButton.Content.Equals("Record"))
{
graph.Start();
recordStopButton.Content = "Stop";
}
else if (recordStopButton.Content.Equals("Stop"))
{
// Good idea to stop the graph to avoid data loss
graph.Stop();
TranscodeFailureReason finalizeResult = await fileOutputNode.FinalizeAsync();
if (finalizeResult != TranscodeFailureReason.None)
{
// TODO: Finalization of file failed. Check result code to see why, propagate error message
return;
}
recordStopButton.Content = "Record";
}
}

Categories

Resources