Hi Trey, On Fri, Jul 12, 2024 at 12:42 PM Ramsay, Trey <Trey.Ramsay@xxxxxxxx> wrote: > > Hi Luiz, > We use gatt-server for in house BMC daemon for BLE communication to and from the BMC via mobile device. When we updated the bluez libriary, the attribute for setting the IPV4 settings failed because a response was never sent for prep_write_cb Not familiar with the daemon, is that something open source? > I believe prep_write_complete_cb should be called after prep_write_cb so the BT_ATT_OP_PREP_WRITE_RSP response is sent. Not if you mark to authorize prepare write https://github.com/bluez/bluez/blob/master/src/gatt-database.c#L3276: if (opcode == BT_ATT_OP_PREP_WRITE_REQ) { if (!btd_device_is_trusted(device) && !desc->prep_authorized && desc->req_prep_authorization) send_write(att, attrib, desc->proxy, desc->pending_writes, id, value, len, offset, false, true); else gatt_db_attribute_write_result(attrib, id, 0); return; } Perhaps what you are not understanding is that this code is asynchronous, it doesn't respond inline so prep_write_complete_cb will only be called after the application authorizes/when gatt_db_attribute_write_result is called to complete the operation. > Thanks, > Trey > > -----Original Message----- > From: Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx> > Sent: Thursday, July 11, 2024 3:53 PM > To: Ramsay, Trey <Trey_Ramsay@xxxxxxxx> > Cc: linux-bluetooth@xxxxxxxxxxxxxxx > Subject: Re: [PATCH] ATT: Error (0x01) - Error: Unlikely error (14) Prepare Write req (0x16) > > > [EXTERNAL EMAIL] > > Hi Trey, > > On Thu, Jul 11, 2024 at 4:14 PM Ramsay, Trey <Trey.Ramsay@xxxxxxxx> wrote: > > > > Thanks Luiz, > > Maybe I don't understand. In bluez 5.39, prep_write_cb would send BT_ATT_OP_PREP_WRITE_RSP at the end of the function. In the new code, prep_write_complete_cb is supposed to send BT_ATT_OP_PREP_WRITE_RSP but prep_write_complete_cb is never called from gatt_db_attribute_write. Who is supposed to send the BT_ATT_OP_PREP_WRITE_RSP since prep_write_complete_cb is not getting called? With the patch, prep_write_complete_cb will get called. > > > > > > From Bluez 5.39 > > static void prep_write_cb(uint8_t opcode, const void *pdu, > > uint16_t length, void > > *user_data) { > > struct bt_gatt_server *server = user_data; > > uint16_t handle = 0; > > uint16_t offset; > > struct gatt_db_attribute *attr; > > uint8_t ecode; > > > > if (length < 4) { > > ecode = BT_ATT_ERROR_INVALID_PDU; > > goto error; > > } > > > > if (queue_length(server->prep_queue) >= server->max_prep_queue_len) { > > ecode = BT_ATT_ERROR_PREPARE_QUEUE_FULL; > > goto error; > > } > > > > handle = get_le16(pdu); > > offset = get_le16(pdu + 2); > > > > attr = gatt_db_get_attribute(server->db, handle); > > if (!attr) { > > ecode = BT_ATT_ERROR_INVALID_HANDLE; > > goto error; > > } > > > > util_debug(server->debug_callback, server->debug_data, > > "Prep Write Req - handle: 0x%04x", > > handle); > > > > ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE | > > BT_ATT_PERM_WRITE_AUTHEN | > > BT_ATT_PERM_WRITE_ENCRYPT); > > if (ecode) > > goto error; > > > > if (!store_prep_data(server, handle, offset, length - 4, > > &((uint8_t *) pdu)[4])) { > > ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES; > > goto error; > > } > > > > bt_att_send(server->att, BT_ATT_OP_PREP_WRITE_RSP, pdu, length, NULL, <------------------------- Response is sent > > NULL, NULL); > > return; > > > > error: > > bt_att_send_error_rsp(server->att, opcode, handle, ecode); } > > > > > > -------------------------------------------------------------------------------------------------------------------------------------- > > In Bluez master, the response is sent from prep_write_complete_cb but the call back is never called since gatt_db_attribute_write returns True before func is executed which is the function pointer to prep_write_complete_cb > > static void prep_write_complete_cb(struct gatt_db_attribute *attr, int err, > > void *user_data) > > { > > struct prep_write_complete_data *pwcd = user_data; > > uint16_t handle = 0; > > uint16_t offset; > > > > handle = get_le16(pwcd->pdu); > > > > if (err) { > > bt_att_chan_send_error_rsp(pwcd->chan, BT_ATT_OP_PREP_WRITE_REQ, > > handle, err); > > free(pwcd->pdu); > > free(pwcd); > > > > return; > > } > > > > offset = get_le16(pwcd->pdu + 2); > > > > if (!store_prep_data(pwcd->server, handle, offset, pwcd->length - 4, > > &((uint8_t *) pwcd->pdu)[4])) > > bt_att_chan_send_error_rsp(pwcd->chan, BT_ATT_OP_PREP_WRITE_RSP, > > handle, > > BT_ATT_ERROR_INSUFFICIENT_RESOURCES); > > > > bt_att_chan_send_rsp(pwcd->chan, BT_ATT_OP_PREP_WRITE_RSP, pwcd->pdu, <-------------- Response is sent > > pwcd->length); > > > > free(pwcd->pdu); > > free(pwcd); > > } > > It might be because of: > > commit 1ebfc68ff53ea5ed5cb424df151bf413c7ffe9be > Author: Grzegorz Kolodziejczyk <grzegorz.kolodziejczyk@xxxxxxxxxxx> > Date: Mon May 28 10:20:52 2018 +0200 > > shared/gatt-server: Request authorization for prepare writes > > This patch adds gatt-server possibility to request authorization from > application if needed and previously wasn't authorized. Authorization is > requested by sending message with set prepare write authorization reqest > to client. > > Anyway we are talking about ancient changes here, what exactly is the > attribute you are trying to use the so called long write procedure > btw? Is that using bluetoothctl to register it or is some other > application involved? Or is this some PTS test case that requires > authorization? If you use bluetoothctl for that it might be prompting > to authorize the request. -- Luiz Augusto von Dentz