Skip to content
This repository has been archived by the owner on Dec 20, 2023. It is now read-only.

Commit

Permalink
Work on Issue #142 -- Add support for Rendezvous WiFi ESSID Suffix to…
Browse files Browse the repository at this point in the history
… Device Descriptor

-- Extended WeaveDeviceDescriptor class with a new Flags field containing a single
flag, (IsRendezvousWiFiESSIDSuffix) signaling that the RendezvousWiFiESSID field
contains a suffix string, rather than the entire ESSID string.

-- Modified the encode/decode methods for WeaveDeviceDescriptor to support device
descriptors containing the new RendezvousWiFiESSIDSuffix tag/text key.

-- Updated the WeaveDeviceDescriptor wrapper classes for Java and Python to support
the ESSID suffix field.

-- Modified the weave-device-descriptor command line tool to support encoding and
decoding device descriptors containing an ESSID suffix.

-- Added a unit test to the test-weave-device-descriptor-encode.sh test script.

-- Updated the TestWeaveDeviceMangerJNI script so that it properly locates the Device
Manager jar and shared library files.

-- Corrected bugs in the Java WeaveDeviceManager unit test class (TestMain) that
prevented the unit tests from passing against the latest mock device.
  • Loading branch information
Jay Logue committed Mar 8, 2019
1 parent 0c9d7e9 commit 6fb3782
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/device-manager/WeaveDeviceManager-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3214,7 +3214,7 @@ WEAVE_ERROR N2J_DeviceDescriptor(JNIEnv *env, const WeaveDeviceDescriptor& inDev
SuccessOrExit(err);
}

constructor = env->GetMethodID(sWeaveDeviceDescriptorCls, "<init>", "(IIIIII[B[BLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JJLjava/lang/String;I)V");
constructor = env->GetMethodID(sWeaveDeviceDescriptorCls, "<init>", "(IIIIII[B[BLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JJLjava/lang/String;II)V");
VerifyOrExit(constructor != NULL, err = WDM_JNI_ERROR_METHOD_NOT_FOUND);

env->ExceptionClear();
Expand All @@ -3224,7 +3224,7 @@ WEAVE_ERROR N2J_DeviceDescriptor(JNIEnv *env, const WeaveDeviceDescriptor& inDev
primary802154MACAddress, primaryWiFiMACAddress,
serialNumber, rendezvousWiFiESSID, pairingCode,
(jlong)inDeviceDesc.DeviceId, (jlong)inDeviceDesc.FabricId, softwareVersion,
(jint)inDeviceDesc.DeviceFeatures);
(jint)inDeviceDesc.DeviceFeatures, (jint)inDeviceDesc.Flags);
VerifyOrExit(!env->ExceptionCheck(), err = WDM_JNI_ERROR_EXCEPTION_THROWN);

exit:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ void RunUnitTests()
System.out.println("GetNetworks Test");
System.out.println(" Getting configured networks...");
ExpectedNetworkCount = 2;
DeviceMgr.beginGetNetworks(GetNetworkFlags.IncludeCredentials);
DeviceMgr.beginGetNetworks(GetNetworkFlags.None);
ExpectSuccess("GetNetworks");
System.out.println("GetNetworks Test Succeeded");

Expand All @@ -205,16 +205,14 @@ void RunUnitTests()
System.out.println("GetNetworks Test");
System.out.println(" Getting configured networks...");
ExpectedNetworkCount = 1;
DeviceMgr.beginGetNetworks(GetNetworkFlags.IncludeCredentials);
DeviceMgr.beginGetNetworks(GetNetworkFlags.None);
ExpectSuccess("GetNetworks");
System.out.println("GetNetworks Test Succeeded");

TestResult = null;
System.out.println("GetCameraAuthData Test");
System.out.println(" Getting camera auth data...");
String ExpectedCameraMACAddress = "112233445566";
String ExpectedCameraSignedPayload = "Ceci n'est pas un hash.";
DeviceMgr.beginGetCameraAuthData("Ceci n'est pas un nonce.");
DeviceMgr.beginGetCameraAuthData("Ceci n'est pas un nonce.012345670123456789ABCDEF0123456789ABCDEF");
ExpectSuccess("GetCameraAuthData");
System.out.println("GetCameraAuthData Test Succeeded");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,13 @@ public class WeaveDeviceDescriptor
*/
public String softwareVersion;

/** ESSID for pairing WiFi network (null = not present).
/** ESSID or ESSID suffix for device's rendezvous WiFi network (null = not present).
*/
public String rendezvousWiFiESSID;

/** True if the rendezvousWiFiESSID field contains a suffix string.
*/
public boolean isRendezvousWiFiESSIDSuffix;

/** Device pairing code (null = not present).
*/
Expand All @@ -82,7 +86,8 @@ public WeaveDeviceDescriptor(int vendorCode, int productCode, int productRevisio
int manufacturingYear, int manufacturingMonth, int manufacturingDay,
byte[] primary802154MACAddress, byte[] primaryWiFiMACAddress,
String serialNumber, String rendezvousWiFiESSID, String pairingCode,
long deviceId, long fabricId, String softwareVersion, int deviceFeatures)
long deviceId, long fabricId, String softwareVersion, int deviceFeatures,
int flags)
{
this.vendorCode = vendorCode;
this.productCode = productCode;
Expand All @@ -105,12 +110,14 @@ public WeaveDeviceDescriptor(int vendorCode, int productCode, int productRevisio
this.fabricId = fabricId;
this.softwareVersion = softwareVersion;
this.deviceFeatures = DeviceFeatures.fromFlags(deviceFeatures);

this.isRendezvousWiFiESSIDSuffix = ((flags & FLAG_IS_RENDEZVOUS_WIFI_ESSID_SUFFIX) != 0);
}

public static native WeaveDeviceDescriptor decode(byte[] encodedDeviceDesc);

static {
System.loadLibrary("WeaveDeviceManager");
}

static final int FLAG_IS_RENDEZVOUS_WIFI_ESSID_SUFFIX = 0x01;
}
16 changes: 13 additions & 3 deletions src/device-manager/python/WeaveDeviceMgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
SystemTest_ProductList = { 'thermostat' : 0x235A000A,
'topaz' : 0x235A0003}

DeviceDescriptorFlag_IsRendezvousWiFiESSIDSuffix = 0x01


def _VoidPtrToByteArray(ptr, len):
if ptr:
v = bytearray(len)
Expand Down Expand Up @@ -189,7 +192,7 @@ def __init__(self, deviceId=None, fabricId=None, vendorId=None, productId=None,
primary802154MACAddress=None, primaryWiFiMACAddress=None,
serialNumber=None, softwareVersion=None, rendezvousWiFiESSID=None, pairingCode=None,
pairingCompatibilityVersionMajor=None, pairingCompatibilityVersionMinor=None,
deviceFeatures=None):
deviceFeatures=None, flags=None):
self.DeviceId = deviceId
self.FabricId = fabricId
self.VendorId = vendorId
Expand All @@ -213,6 +216,7 @@ def __init__(self, deviceId=None, fabricId=None, vendorId=None, productId=None,
if (deviceFeatures & featureVal) == featureVal:
self.DeviceFeatures.append(featureVal)
featureVal <<= 1
self.Flags = flags if flags != None else 0

def Print(self, prefix=""):
if self.DeviceId != None:
Expand All @@ -239,7 +243,7 @@ def Print(self, prefix=""):
if self.PrimaryWiFiMACAddress != None:
print "%sPrimary WiFi MAC Address: %s" % (prefix, _ByteArrayToHex(self.PrimaryWiFiMACAddress))
if self.RendezvousWiFiESSID != None:
print "%sRendezvous WiFi ESSID: %s" % (prefix, self.RendezvousWiFiESSID)
print "%sRendezvous WiFi ESSID%s: %s" % (prefix, " Suffix" if self.IsRendezvousWiFiESSIDSuffix else "", self.RendezvousWiFiESSID)
if self.PairingCode != None:
print "%sPairing Code: %s" % (prefix, self.PairingCode)
if self.PairingCompatibilityVersionMajor != None:
Expand All @@ -249,6 +253,10 @@ def Print(self, prefix=""):
if self.DeviceFeatures != None:
print "%sDevice Features: %s" % (prefix, " ".join([DeviceFeatureToString(val) for val in self.DeviceFeatures]))

@property
def IsRendezvousWiFiESSIDSuffix(self):
return (self.Flags & DeviceDescriptorFlag_IsRendezvousWiFiESSIDSuffix) != 0


class DeviceManagerException(Exception):
pass
Expand Down Expand Up @@ -373,6 +381,7 @@ class _DeviceDescriptorStruct(Structure):
('PairingCode', c_char * 17), # Device pairing code (nul terminated, 0 length = not present)
('PairingCompatibilityVersionMajor', c_uint16), # Pairing software compatibility major version
('PairingCompatibilityVersionMinor', c_uint16), # Pairing software compatibility minor version
('Flags', c_ubyte), # Flags
]

def toDeviceDescriptor(self):
Expand All @@ -393,7 +402,8 @@ def toDeviceDescriptor(self):
pairingCode = self.PairingCode if len(self.PairingCode) != 0 else None,
pairingCompatibilityVersionMajor = self.PairingCompatibilityVersionMajor,
pairingCompatibilityVersionMinor = self.PairingCompatibilityVersionMinor,
deviceFeatures = self.DeviceFeatures)
deviceFeatures = self.DeviceFeatures,
flags = self.Flags)

# Library path name. Can be overridden my module user.
currentDirPath = os.path.dirname(os.path.abspath( __file__ ))
Expand Down
30 changes: 26 additions & 4 deletions src/lib/profiles/device-description/DeviceDescription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ enum
kTextKey_Primary802154MACAddress = 'L', // [ 8 hex digits ] MAC address for device's primary 802.15.4 interface.
kTextKey_PrimaryWiFiMACAddress = 'W', // [ 6 hex digits ] MAC address for device's primary WiFi interface.
kTextKey_RendezvousWiFiESSID = 'I', // [ 1-32 char string ] ESSID for device's WiFi rendezvous network.
kTextKey_PairingCode = 'C', // [ 1-16 char string ] The pairing code for the device.
kTextKey_RendezvousWiFiESSIDSuffix = 'H', // [ 1-32 char string ] ESSID for device's WiFi rendezvous network.
kTextKey_PairingCode = 'C', // [ 6-16 char string ] The pairing code for the device.
kTextKey_PairingCompatibilityVersionMajor = 'J', // [ 1-4 hex digits ] Pairing software compatibility major version.
kTextKey_PairingCompatibilityVersionMinor = 'N', // [ 1-4 hex digits ] Pairing software compatibility minor version.

Expand Down Expand Up @@ -452,7 +453,11 @@ WEAVE_ERROR WeaveDeviceDescriptor::EncodeText(const WeaveDeviceDescriptor& desc,

if (desc.RendezvousWiFiESSID[0] != 0)
{
err = writer.WriteString(kTextKey_RendezvousWiFiESSID, desc.RendezvousWiFiESSID);
const char fieldId = ((desc.Flags & kFlag_IsRendezvousWiFiESSIDSuffix) != 0)
? kTextKey_RendezvousWiFiESSIDSuffix
: kTextKey_RendezvousWiFiESSID;

err = writer.WriteString(fieldId, desc.RendezvousWiFiESSID);
SuccessOrExit(err);
}

Expand Down Expand Up @@ -582,7 +587,11 @@ WEAVE_ERROR WeaveDeviceDescriptor::EncodeTLV(const WeaveDeviceDescriptor& desc,

if (desc.RendezvousWiFiESSID[0] != 0)
{
err = writer.PutString(ContextTag(kTag_RendezvousWiFiESSID), desc.RendezvousWiFiESSID);
const uint64_t tag = ((desc.Flags & kFlag_IsRendezvousWiFiESSIDSuffix) != 0)
? ContextTag(kTag_RendezvousWiFiESSIDSuffix)
: ContextTag(kTag_RendezvousWiFiESSID);

err = writer.PutString(tag, desc.RendezvousWiFiESSID);
SuccessOrExit(err);
}

Expand Down Expand Up @@ -746,6 +755,11 @@ WEAVE_ERROR WeaveDeviceDescriptor::DecodeText(const char *data, uint32_t dataLen
SuccessOrExit(err);
break;
case kTextKey_RendezvousWiFiESSID:
outDesc.Flags &= ~kFlag_IsRendezvousWiFiESSIDSuffix;
goto readRendezvousWiFiESSID;
case kTextKey_RendezvousWiFiESSIDSuffix:
outDesc.Flags |= kFlag_IsRendezvousWiFiESSIDSuffix;
readRendezvousWiFiESSID:
err = reader.ReadString(outDesc.RendezvousWiFiESSID, sizeof(outDesc.RendezvousWiFiESSID));
SuccessOrExit(err);
break;
Expand Down Expand Up @@ -899,11 +913,19 @@ WEAVE_ERROR WeaveDeviceDescriptor::DecodeTLV(nl::Weave::TLV::TLVReader& reader,
err = reader.GetBytes(outDesc.PrimaryWiFiMACAddress, sizeof(outDesc.PrimaryWiFiMACAddress));
SuccessOrExit(err);
}
else if (tag == ContextTag(kTag_RendezvousWiFiESSID))
else if (tag == ContextTag(kTag_RendezvousWiFiESSID) || tag == ContextTag(kTag_RendezvousWiFiESSIDSuffix))
{
err = reader.GetString(outDesc.RendezvousWiFiESSID, sizeof(outDesc.RendezvousWiFiESSID));
SuccessOrExit(err);
VerifyOrExit(outDesc.RendezvousWiFiESSID[0] != 0, err = WEAVE_ERROR_INVALID_TLV_ELEMENT);
if (tag == ContextTag(kTag_RendezvousWiFiESSID))
{
outDesc.Flags &= ~kFlag_IsRendezvousWiFiESSIDSuffix;
}
else
{
outDesc.Flags |= kFlag_IsRendezvousWiFiESSIDSuffix;
}
}
else if (tag == ContextTag(kTag_PairingCode))
{
Expand Down
21 changes: 17 additions & 4 deletions src/lib/profiles/device-description/DeviceDescription.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ enum
kTag_SerialNumber = 4, /**< [ UTF-8 string, len 1-32 ] Device serial number. Context-specific Tag */
kTag_Primary802154MACAddress = 5, /**< [ byte string, len = 8 ] MAC address for device's primary 802.15.4 interface. Context-specific Tag */
kTag_PrimaryWiFiMACAddress = 6, /**< [ byte string, len = 6 ] MAC address for device's primary WiFi interface. Context-specific Tag */
kTag_RendezvousWiFiESSID = 7, /**< [ UTF-8 string, len 1-32 ] ESSID for device's WiFi rendezvous network. Context-specific Tag */
kTag_PairingCode = 8, /**< [ UTF-8 string, len 1-16 ] The pairing code for the device. Context-specific Tag
kTag_RendezvousWiFiESSID = 7, /**< [ UTF-8 string, len 1-32 ] ESSID for device's WiFi rendezvous network. Context-specific Tag.
@note: This tag is mutually exclusive with the RendezvousWiFiESSIDSuffix tag. */
kTag_PairingCode = 8, /**< [ UTF-8 string, len 6-16 ] The pairing code for the device. Context-specific Tag
@note @b IMPORTANT: For security reasons, the PairingCode field should *never*
be sent over the network. It is present in a WeaveDeviceDescriptor structure so
that is can encoded in a data label (e.g. QR-code) that is physically associated
Expand All @@ -98,6 +99,8 @@ enum
kTag_FabricId = 11, /**< [ uint, 2^64 max ] ID of Weave fabric to which the device belongs. Context-specific Tag */
kTag_PairingCompatibilityVersionMajor = 12, /**< [ uint, range 1-65535 ] Pairing software compatibility major version. Context-specific Tag */
kTag_PairingCompatibilityVersionMinor = 13, /**< [ uint, range 1-65535 ] Pairing software compatibility minor version. Context-specific Tag */
kTag_RendezvousWiFiESSIDSuffix = 14, /**< [ UTF-8 string, len 1-32 ] ESSID suffix for device's WiFi rendezvous network. Context-specific Tag.
@note: This tag is mutually exclusive with the RendezvousWiFiESSID tag. */

// Feature Tags (Context-specific Tags in WeaveDeviceDescriptor that indicate presence of device features)
// NOTE: The absence of a specific tag indicates that the device does not support the associated feature.
Expand Down Expand Up @@ -126,14 +129,23 @@ class NL_DLL_EXPORT WeaveDeviceDescriptor
};

/**
* Flags indicating specific device capabilities.
* Feature flags indicating specific device capabilities.
*/
enum
{
kFeature_HomeAlarmLinkCapable = 0x00000001, /**< Indicates a Nest Protect that supports connection to a home alarm panel. */
kFeature_LinePowered = 0x00000002 /**< Indicates a device that requires line power. */
};

/**
* Flags field definitions.
*/
enum
{
kFlag_IsRendezvousWiFiESSIDSuffix = 0x01, /**< Indicates that the RendezvousWiFiESSID value is a suffix string that
appears at the end of the ESSID of the device's WiFi rendezvous network. */
};

// Device specific characteristics
uint64_t DeviceId; /**< Weave device ID (0 = not present) */
uint64_t FabricId; /**< ID of Weave fabric to which the device belongs (0 = not present) */
Expand All @@ -150,10 +162,11 @@ class NL_DLL_EXPORT WeaveDeviceDescriptor
uint8_t PrimaryWiFiMACAddress[6]; /**< MAC address for primary WiFi interface (big-endian, all zeros = not present) */
char SerialNumber[kMaxSerialNumberLength+1]; /**< Serial number of device (NUL terminated, 0 length = not present) */
char SoftwareVersion[kMaxSoftwareVersionLength+1]; /**< Active software version (NUL terminated, 0 length = not present) */
char RendezvousWiFiESSID[kMaxRendezvousWiFiESSID+1]; /**< ESSID for pairing WiFi network (NUL terminated, 0 length = not present) */
char RendezvousWiFiESSID[kMaxRendezvousWiFiESSID+1]; /**< ESSID for device WiFi rendezvous network (NUL terminated, 0 length = not present) */
char PairingCode[kMaxPairingCodeLength+1]; /**< Device pairing code (NUL terminated, 0 length = not present) */
uint16_t PairingCompatibilityVersionMajor; /**< Major device pairing software compatibility version. */
uint16_t PairingCompatibilityVersionMinor; /**< Minor device pairing software compatibility version. */
uint8_t Flags; /**< Bit field containing additional information about the device. */

void Clear(void);

Expand Down
16 changes: 12 additions & 4 deletions src/test-apps/TestWeaveDeviceMangerJNI
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,28 @@

SCRIPT_DIR=`DIR=\`dirname "$0"\` && (cd $DIR && pwd )`

OPENWEAVE_ROOT=`(cd $SCRIPT_DIR/../.. && pwd )`

BUILD_TARGET_DIR=`${OPENWEAVE_ROOT}/third_party/nlbuild-autotools/repo/third_party/autoconf/config.guess`

JAR_FILE=WeaveDeviceManager.jar
if [ \! -f ${JAR_FILE} ]; then
if [ -f ${SCRIPT_DIR}/../device-manager/${JAR_FILE} ]; then
if [ -f ${OPENWEAVE_ROOT}/output/share/java/${JAR_FILE} ]; then
JAR_FILE=${OPENWEAVE_ROOT}/output/share/java/${JAR_FILE}
elif [ -f ${SCRIPT_DIR}/../device-manager/${JAR_FILE} ]; then
JAR_FILE=${SCRIPT_DIR}/../device-manager/${JAR_FILE}
else
echo "Unable to find ${JAR_FILE}"
exit -1
exit -1
fi
fi

LIB_DIR=.
LIB_FILE=libWeaveDeviceManager.so
if [ \! -f ${LIB_DIR}/${LIB_FILE} ]; then
if [ -f ${SCRIPT_DIR}/../device-manager/${LIB_FILE} ]; then
if [ -f ${OPENWEAVE_ROOT}/output/${BUILD_TARGET_DIR}/lib/${LIB_FILE} ]; then
LIB_DIR=${OPENWEAVE_ROOT}/output/${BUILD_TARGET_DIR}/lib
elif [ -f ${SCRIPT_DIR}/../device-manager/${LIB_FILE} ]; then
LIB_DIR=${SCRIPT_DIR}/../device-manager
else
echo "Unable to find ${LIB_FILE}"
Expand All @@ -42,5 +50,5 @@ fi

export WEAVE_IPV4_LISTEN_ADDR=127.0.0.2

java -verbose:jni -Xcheck:jni -Djava.library.path=${LIB_DIR} -jar ${JAR_FILE} nl.Weave.DeviceManager.TestMain
java --add-modules java.xml.bind -verbose:jni -Xcheck:jni -Djava.library.path=${LIB_DIR} -jar ${JAR_FILE} nl.Weave.DeviceManager.TestMain

2 changes: 2 additions & 0 deletions src/test-apps/test-weave-device-descriptor-encode.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ program="${builddir}/weave-device-descriptor"
tests=(
'--vendor 0x235A --product 6 --revision 1 --serial-num 05CA01AC29130044 --mfg-date 2014/03/26 --802-15-4-mac 18:B4:30:00:00:1E:8E:E5 --wifi-mac 18:B4:30:27:83:47 --ssid PROTECT-8EE5 --pairing-code K4H9ET'
'--vendor 0x235A --product 0x13 --revision 1 --serial-num 15AA01ZZ01160101 --mfg-date 2016/08/05 --device-id 18B4300400000101'
'--vendor 0x235A --product 6 --revision 1 --serial-num 05CA01AC29130044 --mfg-date 2014/03/26 --802-15-4-mac 18:B4:30:00:00:1E:8E:E5 --wifi-mac 18:B4:30:27:83:47 --ssid-suffix 8EE5 --pairing-code K4H9ET'
)

expectedResults=(
'1V:235A$P:6$R:1$D:140326$S:05CA01AC29130044$L:18B43000001E8EE5$W:18B430278347$I:PROTECT-8EE5$C:K4H9ET$'
'1V:235A$P:13$R:1$D:160805$S:15AA01ZZ01160101$E:18B4300400000101$'
'1V:235A$P:6$R:1$D:140326$S:05CA01AC29130044$L:18B43000001E8EE5$W:18B430278347$H:8EE5$C:K4H9ET$'
)

numTests=${#tests[@]}
Expand Down
Loading

0 comments on commit 6fb3782

Please sign in to comment.