Skip to content

Commit

Permalink
More BLE prototyping
Browse files Browse the repository at this point in the history
  • Loading branch information
Psychlist1972 committed Mar 8, 2024
1 parent 0f66a25 commit 31298ac
Showing 1 changed file with 33 additions and 145 deletions.
178 changes: 33 additions & 145 deletions src/prototypes/ble-midi1-proto/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,28 +138,38 @@ void OnDeviceAdded(enumeration::DeviceWatcher, enumeration::DeviceInformation in

void OnDeviceRemoved(enumeration::DeviceWatcher, enumeration::DeviceInformationUpdate upd)
{
std::cout << "Removed: " << upd.Id().c_str() << std::endl;
std::cout << "Removed: " << winrt::to_string(upd.Id()) << std::endl;
}

void OnDeviceUpdated(enumeration::DeviceWatcher, enumeration::DeviceInformationUpdate upd)
{
std::cout << "Updated: " << upd.Id().c_str() << std::endl;
std::cout << "-----------" << std::endl;

std::cout << "Updated: " << winrt::to_string(upd.Id()).c_str() << std::endl;

auto bleDevice = bt::BluetoothLEDevice::FromIdAsync(upd.Id()).get();

if (bleDevice != nullptr)
{
std::cout << "BLE Name: " << winrt::to_string(bleDevice.Name()) << std::endl;
std::cout << "Name: " << winrt::to_string(bleDevice.Name()) << " : ";

if (bleDevice.ConnectionStatus() == bt::BluetoothConnectionStatus::Connected)
{
std::cout << "Current status: Connected " << std::endl;
std::cout << "Connected " << std::endl;
}
else
{
std::cout << "Current status: Disconnected " << std::endl;
std::cout << "Disconnected " << std::endl;
}
}

// spit out the updated properties
for (auto prop : upd.Properties())
{
std::cout << winrt::to_string(prop.Key()) << std::endl;
}

std::cout << "-----------" << std::endl;
}

void OnDeviceStopped(enumeration::DeviceWatcher, foundation::IInspectable)
Expand Down Expand Up @@ -213,7 +223,7 @@ void TestEnumeration()
m_DeviceStopped = m_Watcher.Stopped(winrt::auto_revoke, deviceStoppedHandler);
m_DeviceEnumerationCompleted = m_Watcher.EnumerationCompleted(winrt::auto_revoke, deviceEnumerationCompletedHandler);

// need to control-c to kill this for now. By design.
// this blocks
m_Watcher.Start();

}
Expand All @@ -225,140 +235,6 @@ IAsyncAction TestReceivingData()

winrt::hstring id = L"BluetoothLE#BluetoothLE3c:6a:a7:f0:4e:b0-48:b6:20:1a:71:9d";

std::cout << "Attempting with id " << winrt::to_string(id) << std::endl;

auto bleDevice = bt::BluetoothLEDevice::FromIdAsync(id).get();

if (bleDevice != nullptr)
{
std::cout << "Using device " << winrt::to_string(bleDevice.Name()) << std::endl;

auto service = bleDevice.GetGattService(MIDI_BLE_SERVICE_UUID);


if (service != nullptr)
{
std::cout << "Found service" << std::endl;;

// we may need to test to see if we can open it shared instead
auto openStatus = service.OpenAsync(gatt::GattSharingMode::SharedReadAndWrite).get();

if (openStatus == gatt::GattOpenStatus::Success)
{
std::cout << "Service opened" << std::endl;
}
else
{
std::cout << "Unable to open service" << std::endl;
return;
}


// get the characteristic for MIDI

std::cout << "Getting MIDI Data IO characteristic" << std::endl;

auto characteristicsResult = service.GetCharacteristicsForUuidAsync(MIDI_BLE_DATA_IO_CHARACTERISTIC_UUID).get();

if (characteristicsResult.Status() == gatt::GattCommunicationStatus::Success)
{
if (characteristicsResult.Characteristics().Size() == 0)
{
// this is unexpected
std::cout << "Returned no characteristics for the required UUID" << std::endl;
}
else if (characteristicsResult.Characteristics().Size() > 1)
{
// TODO: Need to find out under which cases this happens
std::cout << "Returned more than one characteristic for the same UUID" << std::endl;
}
else
{
// exactly one characteristic returned
std::cout << "Returned single characteristic for the required UUID" << std::endl;

// create the session
gatt::GattSession session{ nullptr };

try
{
std::cout << "Creating session" << std::endl;

session = co_await gatt::GattSession::FromDeviceIdAsync(bleDevice.BluetoothDeviceId());

//session = sessionResult.get();
}
catch (winrt::hresult_error err)
{
// Important: using .get() means we don't actually get to handle these exceptions.

if (err.code() == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION))
{
std::cout << "Cannot access the BLE device because it's being used by another process" << std::endl;
}
else
{
std::cout << "HRESULT exception 0x" << std::hex << err.code() << std::endl;
}

co_return;
}
catch (...)
{
std::cout << "Exception" << std::endl;

co_return;
}

session.MaintainConnection(true);

// wait for incoming data indefinitely

auto characteristic = characteristicsResult.Characteristics().GetAt(0);

auto readResult = characteristic.ReadValueAsync().get();

if (readResult.Status() == gatt::GattCommunicationStatus::Success)
{
// we get an IBuffer here

for (int i = 0; i < readResult.Value().Length(); i++)
{
// read next byte
auto b = *(readResult.Value().data() + i);

std::cout << std::hex << b << " ";
}

std::cout << std::endl;

}
session.Close();

}
}
else
{
std::cout << "Unable to get characteristics" << std::endl;
}


}
else
{
std::cout << "Unable to get service" << std::endl;
}
}

}


IAsyncAction TestReceivingData2()
{
std::cout << "Test Receiving Data ---------------------------------------------------------" << std::endl;

winrt::hstring id = L"BluetoothLE#BluetoothLE3c:6a:a7:f0:4e:b0-48:b6:20:1a:71:9d";

try
{
gatt::GattSession session{ nullptr };
Expand Down Expand Up @@ -425,11 +301,13 @@ IAsyncAction TestReceivingData2()

auto valueChangedHandler = [&](gatt::GattCharacteristic const& sender, gatt::GattValueChangedEventArgs const& args)
{
std::cout << "Value changed" << std::endl;
//std::cout << "Value changed" << std::endl;

// we get an IBuffer here

std::cout << "Data size is " << args.CharacteristicValue().Length() << " bytes" << std::endl;
//std::cout << "Data size is " << args.CharacteristicValue().Length() << " bytes" << std::endl;

std::cout << "> ";

for (int i = 0; i < args.CharacteristicValue().Length(); i++)
{
Expand Down Expand Up @@ -524,9 +402,19 @@ int main()
{
init_apartment();

// TestEnumeration();
// TestReceivingData().get();
TestReceivingData2().get();
//TestEnumeration();

std::thread enumerationThread(TestEnumeration);

enumerationThread.detach();


while (!m_enumerationCompleted)
{
Sleep(1000);
}

TestReceivingData().get();

//system("pause > nul");
system("pause");
Expand Down

0 comments on commit 31298ac

Please sign in to comment.