static uint8_t check_permissions(struct bt_gatt_server *server, struct gatt_db_attribute *attr, uint32_t mask) { uint32_t perm; int security; perm = gatt_db_attribute_get_permissions(attr); if (perm && mask & BT_ATT_PERM_READ && !(perm & BT_ATT_PERM_READ)) return BT_ATT_ERROR_READ_NOT_PERMITTED; if (perm && mask & BT_ATT_PERM_WRITE && !(perm & BT_ATT_PERM_WRITE)) return BT_ATT_ERROR_WRITE_NOT_PERMITTED; perm &= mask; if (!perm) return 0; security = bt_att_get_security(server->att); if (perm & BT_ATT_PERM_SECURE && security < BT_ATT_SECURITY_FIPS) return BT_ATT_ERROR_AUTHENTICATION; if (perm & BT_ATT_PERM_AUTHEN && security < BT_ATT_SECURITY_HIGH) return BT_ATT_ERROR_AUTHENTICATION; if (perm & BT_ATT_PERM_ENCRYPT && security < BT_ATT_SECURITY_MEDIUM) return BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION; return 0; }
static uint8_t check_permissions(struct bt_gatt_server *server, struct gatt_db_attribute *attr, uint32_t mask) { uint8_t enc_size; uint32_t perm; int security; perm = gatt_db_attribute_get_permissions(attr); if (perm && mask & BT_ATT_PERM_READ && !(perm & BT_ATT_PERM_READ)) return BT_ATT_ERROR_READ_NOT_PERMITTED; if (perm && mask & BT_ATT_PERM_WRITE && !(perm & BT_ATT_PERM_WRITE)) return BT_ATT_ERROR_WRITE_NOT_PERMITTED; perm &= mask; if (!perm) return 0; security = bt_att_get_security(server->att, &enc_size); if (security < 0) return BT_ATT_ERROR_UNLIKELY; if (perm & BT_ATT_PERM_SECURE) { if (security < BT_ATT_SECURITY_FIPS) return BT_ATT_ERROR_AUTHENTICATION; if (!check_min_key_size(server->min_enc_size, enc_size)) return BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE; } if (perm & BT_ATT_PERM_AUTHEN) { if (security < BT_ATT_SECURITY_HIGH) return BT_ATT_ERROR_AUTHENTICATION; if (!check_min_key_size(server->min_enc_size, enc_size)) return BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE; } if (perm & BT_ATT_PERM_ENCRYPT) { if (security < BT_ATT_SECURITY_MEDIUM) return BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION; if (!check_min_key_size(server->min_enc_size, enc_size)) return BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE; } return 0; }
static bool change_security(struct bt_att *att, uint8_t ecode) { int security; security = bt_att_get_security(att); if (security != BT_ATT_SECURITY_AUTO) return false; if (ecode == BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION && security < BT_ATT_SECURITY_MEDIUM) security = BT_ATT_SECURITY_MEDIUM; else if (ecode == BT_ATT_ERROR_AUTHENTICATION && security < BT_ATT_SECURITY_HIGH) security = BT_ATT_SECURITY_HIGH; else return false; return bt_att_set_security(att, security); }