#include <errno.h>
#include <gio/gunixfdlist.h>
#include <dlfcn.h>
+#include <arpa/inet.h>
#include "bt-otpserver.h"
#include "bluetooth-api.h"
}
/* Characteristic Object Properties */
- props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
- perms = BLUETOOTH_GATT_PERMISSION_READ;
+ props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ |
+ BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
+ perms = BLUETOOTH_GATT_PERMISSION_READ |
+ BLUETOOTH_GATT_PERMISSION_WRITE;
char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_PROP_UUID);
ret = add_new_characteristic(char_uuid, perms, props,
&otp_object_prop_obj_path);
g_free(uuid);
break;
case OACP_DELETE:
+ if (opcode == OACP_DELETE &&
+ ~(selected_object->props & OBJECT_DELETE)) {
+ ret = OACP_PROCEDURE_NOT_SUPPORTED;
+ goto fail;
+ }
snprintf(absolute_file_path, sizeof(absolute_file_path),
"%s%s", directory, selected_object->name);
ret = OACP_OPCODE_NOT_SUPPORTED;
break;
case OACP_EXECUTE:
+ if (opcode == OACP_EXECUTE &&
+ ~(selected_object->props & OBJECT_EXECUTE)) {
+ ret = OACP_PROCEDURE_NOT_SUPPORTED;
+ goto fail;
+ }
snprintf(absolute_file_path, sizeof(absolute_file_path),
"file://%s%s", directory, selected_object->name);
break;
case OACP_READ:
case OACP_WRITE:
+ if (opcode == OACP_WRITE &&
+ ~(selected_object->props & OBJECT_WRITE)) {
+ ret = OACP_PROCEDURE_NOT_SUPPORTED;
+ goto fail;
+ }
+
+ if (opcode == OACP_READ &&
+ ~(selected_object->props & OBJECT_READ)) {
+ ret = OACP_PROCEDURE_NOT_SUPPORTED;
+ goto fail;
+ }
+
object_offset = (uint32_t)(value[4] & 0xFF) << 24 |
(uint32_t)(value[3] & 0xFF) << 16 |
(uint32_t)(value[2] & 0xFF) << 8 |
err = _bt_otp_open_otc_and_listen(remote_addr, "ListenOtc");
if (err != BLUETOOTH_ERROR_NONE) {
- ret = OACP_OPERATION_FAILED;
+ ret = OACP_CHANNEL_UNAVAILABLE;
_bt_otp_free_oacp_op();
goto fail;
}
return BLUETOOTH_ERROR_NONE;
}
-void convert_to_hex(struct object_metadata *object, char *type, char *value)
+void convert_to_hex(struct object_metadata *object, char *metadata, char *value)
{
struct tm fc_tm;
- BT_DBG("type : %s", type);
+ BT_DBG("Metadata : %s", metadata);
+
+ memset(value, 0, 16);
+
+ if (!g_strcmp0(metadata, "type")) {
+ /* Convert UUID string to 128 bit UUID */
+ uint32_t data0, data4;
+ uint16_t data1, data2, data3, data5;
- memset(value, 0, 8);
+ if (!object->type || sscanf(object->type,
+ "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+ &data0, &data1, &data2,
+ &data3, &data4, &data5) != 6) {
+ BT_ERR("Object Type UUID not updated");
+ return;
+ }
+
+ data0 = htonl(data0);
+ data1 = htons(data1);
+ data2 = htons(data2);
+ data3 = htons(data3);
+ data4 = htonl(data4);
+ data5 = htons(data5);
- if (!g_strcmp0(type, "size")) {
+ memcpy(value, &data0, 4);
+ memcpy(value+4, &data1, 2);
+ memcpy(value+6, &data2, 2);
+ memcpy(value+8, &data3, 2);
+ memcpy(value+10, &data4, 4);
+ memcpy(value+14, &data5, 2);
+
+ } else if (!g_strcmp0(metadata, "size")) {
value[3] = (object->curr_size >> 24) & 0xFF;
value[2] = (object->curr_size >> 16) & 0xFF;
value[5] = (object->alloc_size >> 8) & 0xFF;
value[4] = object->alloc_size & 0xFF;
- } else if (!g_strcmp0(type, "date")) {
+ } else if (!g_strcmp0(metadata, "date")) {
localtime_r(&(object->first_created), &fc_tm);
value[5] = fc_tm.tm_min & 0xFF;
value[6] = fc_tm.tm_sec & 0xFF;
- } else if (!g_strcmp0(type, "id")) {
+ } else if (!g_strcmp0(metadata, "id")) {
value[5] = (object->id >> 48) & 0xFF;
value[4] = (object->id >> 32) & 0xFF;
value[1] = (object->id >> 8) & 0xFF;
value[0] = object->id & 0xFF;
- } else if (!g_strcmp0(type, "props")) {
+ } else if (!g_strcmp0(metadata, "props")) {
value[3] = (object->props >> 24) & 0xFF;
value[2] = (object->props >> 16) & 0xFF;
value[1] = (object->props >> 8) & 0xFF;
void update_obj_metadata_charc_value(struct object_metadata *object)
{
- /* Value can be of maximum eight bytes */
- char value[8];
+ /* Value can be of maximum 16 bytes */
+ char value[16];
_bt_otp_set_char_value(otp_object_name_obj_path, object->name,
strlen(object->name));
- _bt_otp_set_char_value(otp_object_type_obj_path, object->type,
- strlen(object->type));
+
+ convert_to_hex(object, "type", value);
+ _bt_otp_set_char_value(otp_object_type_obj_path, value, 16);
convert_to_hex(object, "size", value);
_bt_otp_set_char_value(otp_object_size_obj_path, value, 8);
guint16 offset = 0;
char *value = NULL;
struct indicate_info info;
+
g_variant_get(var, "(&s&s&syq@ay)",
&char_path, &svc_handle,
&addr, &req_id, &offset, &val);
if (len != 0) {
if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
- result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info);
+ if (!OACP_indicate)
+ result = BLUETOOTH_ERROR_CCC_IMPROPERLY_CONFIGURED;
+ else
+ result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info);
} else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
- result = _bt_otp_olcp_write_cb(value, len, offset, &info);
+ if (!OLCP_indicate)
+ result = BLUETOOTH_ERROR_CCC_IMPROPERLY_CONFIGURED;
+ else
+ result = _bt_otp_olcp_write_cb(value, len, offset, &info);
} else if (!g_strcmp0(char_path, otp_object_name_obj_path)) {
if (oacp_create) {
/* OACP_CREATE is ongoing */