Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nordic UART GATT Service for GGK #36

Open
krimp opened this issue Dec 9, 2019 · 0 comments
Open

Nordic UART GATT Service for GGK #36

krimp opened this issue Dec 9, 2019 · 0 comments

Comments

@krimp
Copy link

krimp commented Dec 9, 2019

My little contribution to this amazing project. Implemented the Nordic UART GATT Server Service (to be inserted in the Server.cpp) in the frame of GGK. Tested on RPi3A+, Stretch, Bluez 5.50 and using the Uart Service on the Adafruit Bluefruit APP for IOS.

`

// Nordic UART Service (6e400001-b5a3-f393-e0a9-e50e24dcca9e)
.gattServiceBegin("Nordic_UART_Service", "6e400001-b5a3-f393-e0a9-e50e24dcca9e")

	// Characteristic: String value (custom: 6e400002-b5a3-f393-e0a9-e50e24dcca9e)
	.gattCharacteristicBegin("UART_RX", "6e400002-b5a3-f393-e0a9-e50e24dcca9e", {"write-without-response","write"})

		// Standard characteristic "WriteValue" method call
		.onWriteValue(CHARACTERISTIC_METHOD_CALLBACK_LAMBDA
		{
			// Update the text string value
			GVariant *pAyBuffer = g_variant_get_child_value(pParameters, 0);
			self.setDataPointer("uart_rx", Utils::stringFromGVariantByteArray(pAyBuffer).c_str());

			// Since all of these methods (onReadValue, onWriteValue, onUpdateValue) are all part of the same
			// Characteristic interface (which just so happens to be the same interface passed into our self
			// parameter) we can use that parameter to call our own onUpdatedValue method
			self.callOnUpdatedValue(pConnection, pUserData);

			// Note: Even though the WriteValue method returns void, it's important to return like this, so that a
			// dbus "method_return" is sent, otherwise the client gets an error (ATT error code 0x0e"unlikely").
			// Only "write-without-response" works without this
			self.methodReturnVariant(pInvocation, NULL);
		})

		// Here we use the onUpdatedValue to set a callback that isn't exposed to BlueZ, but rather allows us to manage
		// updates to our value. These updates may have come from our own server or some other source.
		//
		// We can handle updates in any way we wish, but the most common use is to send a change notification.
		.onUpdatedValue(CHARACTERISTIC_UPDATED_VALUE_CALLBACK_LAMBDA
		{
			const char *pTextString = self.getDataPointer<const char *>("uart_rx", "");
			self.sendChangeNotificationValue(pConnection, pTextString);
			return true;
		})

		// GATT Descriptor: Characteristic User Description (0x2901)
		// 
		// See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_user_description.xml
		.gattDescriptorBegin("description", "2901", {"read"})

			// Standard descriptor "ReadValue" method call
			.onReadValue(DESCRIPTOR_METHOD_CALLBACK_LAMBDA
			{
				const char *pDescription = "Nordic UART RX";
				self.methodReturnValue(pInvocation, pDescription, true);
			})

		.gattDescriptorEnd()

	.gattCharacteristicEnd()

	// Characteristic: String value (custom: 6e400003-b5a3-f393-e0a9-e50e24dcca9e)
	.gattCharacteristicBegin("UART_TX", "6e400003-b5a3-f393-e0a9-e50e24dcca9e", {"notify"})

		// Standard characteristic "notify" method call
		.onUpdatedValue(CHARACTERISTIC_UPDATED_VALUE_CALLBACK_LAMBDA
		{
			const char *pTextString = self.getDataPointer<const char *>("uart_tx", "");
			self.sendChangeNotificationValue(pConnection, pTextString);
			return true;
		})

		// GATT Descriptor: Characteristic User Description (0x2901)
		// 
		// See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_user_description.xml
		.gattDescriptorBegin("description", "2901", {"read"})

			// Standard descriptor "ReadValue" method call
			.onReadValue(DESCRIPTOR_METHOD_CALLBACK_LAMBDA
			{
				const char *pDescription = "Nordic UART TX";
				self.methodReturnValue(pInvocation, pDescription, true);
			})

		.gattDescriptorEnd()

	.gattCharacteristicEnd()		
.gattServiceEnd()
`

Transmit data from the server by:

ggkNofifyUpdatedCharacteristic("/com/gobbledegook/Nordic_UART_Service/UART_TX");

Not shown the application specific handlers in the dataGetter for the 'uart_tx' and in the dataSetter for 'uart_rx', but those familiar with the GGK will understand the missing parts...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant