bt property object
diff --git a/btcore/Android.mk b/btcore/Android.mk
index ec5fe6a..8c3e368 100644
--- a/btcore/Android.mk
+++ b/btcore/Android.mk
@@ -53,6 +53,7 @@
     ./test/bdaddr_test.cpp \
     ./test/counter_test.cpp \
     ./test/device_class_test.cpp \
+    ./test/property_test.cpp \
     ./test/uuid_test.cpp \
     ../osi/test/AllocationTestHarness.cpp
 
diff --git a/btcore/include/property.h b/btcore/include/property.h
index 4c6a1b2..7340601 100644
--- a/btcore/include/property.h
+++ b/btcore/include/property.h
@@ -19,18 +19,27 @@
 #pragma once
 
 #include <hardware/bluetooth.h>
+#include <stdint.h>
 #include <stdlib.h>
 
+#include "btcore/include/device_class.h"
+
 bt_property_t *property_copy_array(const bt_property_t *properties, size_t count);
-bt_property_t *property_new_discovery_timeout(uint32_t timeout);
+bt_property_t *property_copy(bt_property_t *dest, const bt_property_t *src);
+
+bt_property_t *property_new_addr(const bt_bdaddr_t *addr);
+bt_property_t *property_new_device_class(const bt_device_class_t *dc);
+bt_property_t *property_new_device_type(bt_device_type_t *device_type);
+bt_property_t *property_new_discovery_timeout(uint32_t *timeout);
 bt_property_t *property_new_name(const char *name);
+bt_property_t *property_new_rssi(int8_t *rssi);
 bt_property_t *property_new_scan_mode(bt_scan_mode_t scan_mode);
 
 const char *property_extract_name(const bt_property_t *property);
 
 const bt_bdaddr_t *property_extract_bdaddr(const bt_property_t *property);
 const bt_bdname_t *property_extract_bdname(const bt_property_t *property);
-uint32_t property_extract_device_class(const bt_property_t *property);
+const bt_device_class_t *property_extract_device_class(const bt_property_t *property);
 const bt_device_type_t *property_extract_device_type(const bt_property_t *property);
 int32_t property_extract_remote_rssi(const bt_property_t *property);
 const bt_uuid_t *property_extract_uuid(const bt_property_t *property);
diff --git a/btcore/src/property.c b/btcore/src/property.c
index 5d58d20..8f0577e 100644
--- a/btcore/src/property.c
+++ b/btcore/src/property.c
@@ -16,10 +16,14 @@
  *
  ******************************************************************************/
 
-#include "allocator.h"
-#include "property.h"
+#include <assert.h>
+#include "osi/include/allocator.h"
+#include "btcore/include/property.h"
+#include "btcore/include/bdaddr.h"
+#include "btcore/include/device_class.h"
 
 bt_property_t *property_copy_array(const bt_property_t *properties, size_t count) {
+  assert(properties != NULL);
   bt_property_t *clone = osi_calloc(sizeof(bt_property_t) * count);
   if (!clone) {
     return NULL;
@@ -34,29 +38,111 @@
   return clone;
 }
 
+bt_property_t *property_copy(bt_property_t *dest, const bt_property_t *src) {
+  assert(dest != NULL);
+  assert(src != NULL);
+  return (bt_property_t *)memcpy(dest, src, sizeof(bt_property_t));
+}
+
 bt_property_t *property_new_name(const char *name) {
-  bt_bdname_t *bdname = osi_calloc(sizeof(bt_bdname_t));
+  assert(name != NULL);
+
   bt_property_t *property = osi_calloc(sizeof(bt_property_t));
+  assert(property != NULL);
+
+  bt_bdname_t *bdname = osi_calloc(sizeof(bt_bdname_t));
+  assert(bdname != NULL);
+  strlcpy((char *)bdname->name, name, sizeof(bdname->name));
 
   property->type = BT_PROPERTY_BDNAME;
-  property->val = bdname;
+  property->val = (void *)bdname;
   property->len = sizeof(bt_bdname_t);
 
-  strlcpy((char *)bdname->name, name, sizeof(bdname->name));
-
   return property;
 }
 
-bt_property_t *property_new_discovery_timeout(uint32_t timeout) {
-  uint32_t *val = osi_malloc(sizeof(uint32_t));
-  bt_property_t *property = osi_malloc(sizeof(bt_property_t));
+bt_property_t *property_new_addr(const bt_bdaddr_t *addr) {
+  assert(addr != NULL);
+
+  bt_property_t *property = osi_calloc(sizeof(bt_property_t));
+  assert(property != NULL);
+
+  bt_bdaddr_t *bdaddr = osi_calloc(sizeof(bt_bdaddr_t));
+  assert(bdaddr != NULL);
+  bdaddr_copy(bdaddr, addr);
+
+  property->type = BT_PROPERTY_BDADDR;
+  property->val = (void *)bdaddr;
+  property->len = sizeof(bt_bdaddr_t);
+
+  return property;
+}
+
+bt_property_t *property_new_device_class(const bt_device_class_t *dc) {
+  assert(dc != NULL);
+
+  bt_property_t *property = osi_calloc(sizeof(bt_property_t));
+  assert(property != NULL);
+
+  bt_device_class_t *device_class = osi_calloc(sizeof(bt_device_class_t));
+  assert(device_class != NULL);
+  device_class_copy(device_class, dc);
+
+  property->type = BT_PROPERTY_CLASS_OF_DEVICE;
+  property->val = (void *)device_class;
+  property->len = sizeof(bt_device_class_t);
+
+  return property;
+}
+
+bt_property_t *property_new_device_type(bt_device_type_t *type) {
+  assert(type != NULL);
+
+  bt_property_t *property = osi_calloc(sizeof(bt_property_t));
+  assert(property != NULL);
+
+  bt_device_type_t *device_type = (bt_device_type_t *)osi_calloc(sizeof(bt_device_type_t));
+  assert(device_type != NULL);
+  *device_type = *type;
+
+  property->type = BT_PROPERTY_TYPE_OF_DEVICE;
+  property->val = (void *)device_type;
+  property->len = sizeof(bt_device_type_t);
+
+  return property;
+}
+
+bt_property_t *property_new_rssi(int8_t *rssi) {
+  assert(rssi != NULL);
+
+  bt_property_t *property = osi_calloc(sizeof(bt_property_t));
+  assert(property != NULL);
+
+  int *val = (int *)osi_calloc(sizeof(rssi));
+  assert(val != NULL);
+  *val = *rssi;
+
+  property->type = BT_PROPERTY_REMOTE_RSSI;
+  property->val = (void *)val;
+  property->len = sizeof(int);
+
+  return property;
+}
+
+bt_property_t *property_new_discovery_timeout(uint32_t *timeout) {
+  assert(timeout != NULL);
+
+  bt_property_t *property = osi_calloc(sizeof(bt_property_t));
+  assert(property != NULL);
+
+  uint32_t *val = osi_calloc(sizeof(uint32_t));
+  assert(val != NULL);
+  *val = *timeout;
 
   property->type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
   property->val = val;
   property->len = sizeof(uint32_t);
 
-  *val = timeout;
-
   return property;
 }
 
@@ -100,11 +186,11 @@
   return (const bt_bdname_t *)property->val;
 }
 
-uint32_t property_extract_device_class(const bt_property_t *property) {
+const bt_device_class_t *property_extract_device_class(const bt_property_t *property) {
   if (!property || property->type != BT_PROPERTY_CLASS_OF_DEVICE || !property->val) {
     return 0;
   }
-  return *(const uint32_t *)property->val;
+  return (const bt_device_class_t *)property->val;
 }
 
 const bt_device_type_t *property_extract_device_type(const bt_property_t *property) {
@@ -160,6 +246,9 @@
 }
 
 void property_free_array(bt_property_t *properties, size_t count) {
+  if (properties == NULL)
+    return;
+
   for (size_t i = 0; i < count; ++i) {
     osi_free(properties[i].val);
   }
diff --git a/btcore/test/property_test.cpp b/btcore/test/property_test.cpp
new file mode 100644
index 0000000..f2bef6b
--- /dev/null
+++ b/btcore/test/property_test.cpp
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Google, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+#include "osi/test/AllocationTestHarness.h"
+
+extern "C" {
+#include "btcore/include/device_class.h"
+#include "btcore/include/property.h"
+}  // "C"
+
+class PropertyTest : public AllocationTestHarness {};
+
+TEST_F(PropertyTest, device_class) {
+  bt_device_class_t dc0 = {{ 0x01, 0x23, 0x45 }};
+  bt_property_t *property = property_new_device_class(&dc0);
+
+  const bt_device_class_t *dc1 = property_extract_device_class(property);
+  int dc_int = device_class_to_int(dc1);
+  EXPECT_EQ(0x452301, dc_int);
+
+  property_free(property);
+}
diff --git a/tools/bdtool/adapter.c b/tools/bdtool/adapter.c
index 8bf111f..21de774 100644
--- a/tools/bdtool/adapter.c
+++ b/tools/bdtool/adapter.c
@@ -259,14 +259,15 @@
 
       case BT_PROPERTY_CLASS_OF_DEVICE:
         {
-          const uint32_t device_class = property_extract_device_class(property);
-          fprintf(stdout, " device_class:%u\n", device_class);
+          const bt_device_class_t *dc = property_extract_device_class(property);
+          int dc_int = device_class_to_int(dc);
+          fprintf(stdout, " device_class:0x%x\n", dc_int);
         }
         break;
 
       case BT_PROPERTY_REMOTE_RSSI:
         {
-          const int32_t rssi = property_extract_remote_rssi(property);
+          const int8_t rssi = property_extract_remote_rssi(property);
           fprintf(stdout, " rssi:%d\n", rssi);
         }
         break;