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.