Windows 8.1 aplikácia môže pre prístup k zariadeniam cez Bluetooth používať nové API rozhrania API RFCOMM a GATT (Generic Attribute Profile). Tieto rozhrania dokážu komunikovať cez Bluetooth BR / EDR aj cez Bluetooth LE. Bluetooth zariadenia, či už klasické, alebo “smart” sa musia najskôr zistiť a spárovať cez rozhranie Nastavenie počítača (Počítače a zariadenie> Zariadenie> Pridať zariadenie) Až potom budú prístupné cez Bluetooth WinRT API.
Informácie o svojom zariadení, alebo o všeobecnej triede zariadení musíte pridať do aplikačného manifestu napríklad pre ľubovoľné zariadenie podporujúce RFCOMM:
<Capabilities>
<m2:DeviceCapability Name=”bluetooth.rfcomm”>
<m2:Device Id=”any”>
<m2:Function Type=”name:serialPort” />
</m2:Device>
</m2:DeviceCapability>
</Capabilities>
Pre overenie komunikácie si môžete napísať jednoduchú aplikáciu, ktorá bude prijímať dáta z externého zariadenia, napríklad Bluetooth GPS, prípadne Bluetooth modulu pripojeného k vašej hobby konštrukcii na báze mikrokontroléru. Pod názvom Bluetooth analyzer je dostupná vo Windows store http://apps.microsoft.com/windows/app/bluetooth-analyzer/e632b14b-268e-458b-99ee-7a6b858a72be
V príklade popisujem používateľské rozhranie triviálneho, ale funkčného príkladu, ktorý prijíma bajty z RFCOMM cez Bluetooth pozostáva z dvoch prvkov – ComboBoxu pre výber zariadenia a prvku TextBlock pre výpis prijatých znakov.
<StackPanel Orientation=”Vertical” Margin=”120,10,0,0″ Grid.Row=”1″>
<ComboBox x:Name=”cbZariadenia” Header=”Bluetooth RF comm zariadenia”
PlaceholderText=”Vyber zariadenie…” ItemsSource=”{Binding}”
HorizontalAlignment=”Left” VerticalAlignment=”Top”
Width=”400″ Height=”70″
SelectionChanged=”cbZariadenia_SelectionChanged” />
<TextBlock x:Name=”tbStatus” Text=”čakám na výber zariadenia”
FontSize=”24″ Width=”400″ Height=”40″ HorizontalAlignment=”Left”/>
<ScrollViewer x:Name=”scrollViewer” Height=”300″ Width=”600″
HorizontalAlignment=”Left”>
<TextBlock x:Name=” tbBajty” TextWrapping=”Wrap” />
</ScrollViewer>
</StackPanel>
Fungovanie objasnia fragmenty kódu Procedúra BtInit sa volá v metóde LoadState. Úlohou metódy je získať informácie o pripojených Bluetooth zariadeniach podporujúcich RFCOMM.
private StreamSocket _socket = new StreamSocket();
private string _buffer = string.Empty;
public List<cZariadenia> lZariadenia = new List<cZariadenia>();
public List<string> lNazvyZariadeni = new List<string>();
private async void BtInit()
{
Windows.Devices.Enumeration.DeviceInformationCollection zariadenia
= await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync( RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
foreach (var zar in zariadenia)
{
cZariadenia zz = new cZariadenia();
zz.id = zar.Id;
zz.name = zar.Name;
lZariadenia.Add(zz);
string ss = zz.name;
lNazvyZariadeni.Add(ss);
}
cbZariadenia.DataContext = lNazvyZariadeni;
}
Samozrejme, dal by sa napojiť ComboBox priamo na zoznam zariadení, osobitný zoznam názvov bol zavedený z dôvodu možnosti neskoršej konverzie technokratických názvov na používateľské.
Výber zariadenia, ktoré chcete použiť a inicializovat je v obsluhe udalosti SelectionChanged. Samotná inicializácia je v metóde InitBtDevice().
private void cbZariadenia_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
string sNazov;
string sID = “”;
ComboBox cb = (ComboBox)sender;
if (cb.SelectedItem != null)
{
sNazov = cb.SelectedItem.ToString();
//najdem id
foreach (cZariadenia oo in lZariadenia)
{
if (oo.name == sNazov) sID = oo.id;
}
//ak som nasiel vybrane zariadenie inicializujem
if (sID.Length > 1) InitBtDevice(sID);
}
}
private async void InitBtDevice(string sID)
{
RfcommDeviceService service = await RfcommDeviceService.FromIdAsync(sID);
_socket.Control.KeepAlive = true;
_socket.Control.NoDelay = true;
await _socket.ConnectAsync(service.ConnectionHostName,
service.ConnectionServiceName);
await WaitForData(_socket);
}
V asynchrónnej procedúre, ktorá prijíma dáta môžete v cvičnom príklade použiť aj rekurzívne volanie procedúry aby sa po prijatí znaku čakalo na ďalší znak.
async private Task WaitForData(StreamSocket socket)
{
try
{
byte[] bytes = new byte[1];
await socket.InputStream.ReadAsync(bytes.AsBuffer(), 1,
InputStreamOptions.Partial);
string str = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
_buffer += str;
tbBajty.Text = _buffer;
}
catch (Exception e){}
finally
{
WaitForData(socket);
}
}
Predchádzajúca procedúra síce funguje, ale oveľa lepšie riešenie je čakanie na udalosť ktorú vyvolá prijatie znaku. V druhom príklade ukážeme inicializáciu komunikácie využívajúcej sockety. V reálnej aplikácii by ste samozrejme použili konštrukciu Try…catch
private async void ConnectToServiceAsync(IUICommand command)
{
DeviceInformation serviceInfo = (DeviceInformation)command.Id;
this.State = BluetoothConnectionState.Connecting;
connectService = RfcommDeviceService.FromIdAsync(serviceInfo.Id);
rfcommService = await connectService;
if (rfcommService != null)
{
//Vytvorenie socketu
socket = new StreamSocket();
connectAction = socket.ConnectAsync(rfcommService.ConnectionHostName,
rfcommService.ConnectionServiceName );
await connectAction;
writer = new DataWriter(socket.OutputStream);
reader = new DataReader(socket.InputStream);
Task listen = ListenForMessagesAsync();
this.State = BluetoothConnectionState.Connected;
tbStatus.Text = “Connection succesfull”;
}
}
Procedúra čakajúca na znaky:
private async Task ListenForMessagesAsync()
{
while (reader != null)
{
uint sizeFieldCount = await reader.LoadAsync(1);
//socket zatvoreny skor nez sa nacitali data
if (sizeFieldCount != 1) return;
byte[] bytes = new byte[1];
reader.ReadBytes(bytes);
string str = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
tbBajty.Text += str;
}
}
Do mozaiky skladačky použiteľnej aplikácie chýba už len procedúra na vyslanie znaku.
public async Task<uint> SendMessageAsync(string message)
{
uint sentMessageSize = 0;
if (writer != null)
{
uint messageSize = writer.MeasureString(message);
writer.WriteByte((byte)messageSize);
sentMessageSize = writer.WriteString(message);
await writer.StoreAsync();
}
return sentMessageSize;
}
Bluetooth1.png
Obrázek 8.x: Príklad používateľského rozhrania aplikácie na monitorovanie sériovej komunikácie cez Bluetooth RFCOMM. Pripojené je externé GPS zariadenie