Diff between 705762aee4ab2af8f0e93d7cb9d369cfd001b184 and 9dddc36f55dc4cec08a975a1e05a54138f4d3479

Changed Files

File Additions Deletions Status
android/gatt.c +98 -0 modified

Full Patch

diff --git a/android/gatt.c b/android/gatt.c
index fdce558..a51b281 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -3715,6 +3715,102 @@ static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
 		error("gatt: Could not attach to server");
 }
 
+struct gap_srvc_handles {
+	uint16_t srvc;
+
+	/* Characteristics */
+	uint16_t dev_name;
+	uint16_t appear;
+	uint16_t priv;
+};
+
+static struct gap_srvc_handles gap_srvc_data;
+
+#define APPEARANCE_GENERIC_PHONE 0x0040
+#define PERIPHERAL_PRIVACY_DISABLE 0x00
+
+static void gap_read_cb(uint16_t handle, uint16_t offset, uint8_t att_opcode,
+					bdaddr_t *bdaddr, void *user_data)
+{
+	uint8_t pdu[ATT_DEFAULT_LE_MTU];
+	uint16_t len;
+	struct gatt_device *dev;
+
+	DBG("");
+
+	dev = find_device_by_addr(bdaddr);
+	if (!dev) {
+		error("gatt: Could not find device ?!");
+		return;
+	}
+
+	if (handle == gap_srvc_data.dev_name) {
+		const char *name = bt_get_adapter_name();
+
+		len = enc_read_resp((uint8_t *)name, strlen(name),
+							pdu, sizeof(pdu));
+		goto done;
+	}
+
+	if (handle == gap_srvc_data.appear) {
+		uint8_t val[2];
+		put_le16(APPEARANCE_GENERIC_PHONE, val);
+		len = enc_read_resp(val, sizeof(val), pdu, sizeof(pdu));
+		goto done;
+	}
+
+	if (handle == gap_srvc_data.priv) {
+		uint8_t val = PERIPHERAL_PRIVACY_DISABLE;
+		len = enc_read_resp(&val, sizeof(val), pdu, sizeof(pdu));
+		goto done;
+	}
+
+	error("gatt: Unknown handle 0x%02x", handle);
+	len = enc_error_resp(ATT_OP_READ_REQ, handle,
+					ATT_ECODE_UNLIKELY, pdu, sizeof(pdu));
+
+done:
+	g_attrib_send(dev->attrib, 0, pdu, len, NULL, NULL, NULL);
+}
+
+static void register_gap_service(void)
+{
+	bt_uuid_t uuid;
+
+	/* GAP UUID */
+	bt_uuid16_create(&uuid, 0x1800);
+	gap_srvc_data.srvc = gatt_db_add_service(gatt_db, &uuid, true, 7);
+
+	/* Device name characteristic */
+	bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
+	gap_srvc_data.dev_name =
+			gatt_db_add_characteristic(gatt_db, gap_srvc_data.srvc,
+							&uuid, 0,
+							GATT_CHR_PROP_READ,
+							gap_read_cb, NULL,
+							NULL);
+
+	/* Appearance */
+	bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
+	gap_srvc_data.appear =
+			gatt_db_add_characteristic(gatt_db, gap_srvc_data.srvc,
+							&uuid, 0,
+							GATT_CHR_PROP_READ,
+							gap_read_cb, NULL,
+							NULL);
+
+	/* Pripheral privacy flag */
+	bt_uuid16_create(&uuid, GATT_CHARAC_PERIPHERAL_PRIV_FLAG);
+	gap_srvc_data.priv =
+			gatt_db_add_characteristic(gatt_db, gap_srvc_data.srvc,
+							&uuid, 0,
+							GATT_CHR_PROP_READ,
+							gap_read_cb, NULL,
+							NULL);
+
+	gatt_db_service_set_active(gatt_db, gap_srvc_data.srvc , true);
+}
+
 static bool start_listening_io(void)
 {
 	GError *gerr = NULL;
@@ -3780,6 +3876,8 @@ bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr)
 	ipc_register(hal_ipc, HAL_SERVICE_ID_GATT, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
+	register_gap_service();
+
 	return true;
 }