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

Commit 8942ff6

Browse files
committed
Python 3 migration -- Weave Device Manager
This commit adds a wrapper between C strings and Python strings. We wrap every argument specified to be of type `c_char_p` in a call to `_StringToCString` and wrap every result of type `c_char_p` in a call to `_CStringToString`. Additional check is made against fixed-size, NUL terminated `char` arrays (i.e. `c_char * N`). binascii.hexlify has changed signature -- in Python 3 it returns an array of ascii bytes, which needs to be decoded into a string. Additionally, we update the singleton decorator to be python 3 compatible -- the previous version yielded an error `WeaveDeviceManager is not callable`
1 parent a210c73 commit 8942ff6

File tree

1 file changed

+41
-29
lines changed

1 file changed

+41
-29
lines changed

src/device-manager/python/openweave/WeaveDeviceMgr.py

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,21 @@ def _ByteArrayToVoidPtr(array):
106106
else:
107107
return c_void_p(0)
108108

109+
def _CStringToString(s):
110+
return None if s is None else s.decode()
111+
112+
def _StringToCString(s):
113+
return None if s is None else s.encode()
114+
109115
def _IsByteArrayAllZeros(array):
110116
for i in range(len(array)):
111117
if (array[i] != 0):
112118
return False
113119
return True
114120

115121
def _ByteArrayToHex(array):
116-
return binascii.hexlify(bytes(array))
122+
return binascii.hexlify(bytes(array)).decode()
123+
117124
WeaveDeviceMgrDLLBaseName = '_WeaveDeviceMgr.so'
118125

119126
def _AllDirsToRoot(dir):
@@ -374,12 +381,12 @@ def toNetworkInfo(self):
374381
return NetworkInfo(
375382
networkType = self.NetworkType if self.NetworkType != -1 else None,
376383
networkId = self.NetworkId if self.NetworkId != -1 else None,
377-
wifiSSID = self.WiFiSSID,
384+
wifiSSID = _CStringToString(self.WiFiSSID),
378385
wifiMode = self.WiFiMode if self.WiFiMode != -1 else None,
379386
wifiRole = self.WiFiRole if self.WiFiRole != -1 else None,
380387
wifiSecurityType = self.WiFiSecurityType if self.WiFiSecurityType != -1 else None,
381388
wifiKey = _VoidPtrToByteArray(self.WiFiKey, self.WiFiKeyLen),
382-
threadNetworkName = self.ThreadNetworkName,
389+
threadNetworkName = _CStringToString(self.ThreadNetworkName),
383390
threadExtendedPANId = _VoidPtrToByteArray(self.ThreadExtendedPANId, 8),
384391
threadNetworkKey = _VoidPtrToByteArray(self.ThreadNetworkKey, 16),
385392
threadPSKc = _VoidPtrToByteArray(self.ThreadPSKc, 16),
@@ -393,13 +400,13 @@ def fromNetworkInfo(cls, networkInfo):
393400
networkInfoStruct = cls()
394401
networkInfoStruct.NetworkType = networkInfo.NetworkType if networkInfo.NetworkType != None else -1
395402
networkInfoStruct.NetworkId = networkInfo.NetworkId if networkInfo.NetworkId != None else -1
396-
networkInfoStruct.WiFiSSID = networkInfo.WiFiSSID
403+
networkInfoStruct.WiFiSSID = _StringToCString(networkInfo.WiFiSSID)
397404
networkInfoStruct.WiFiMode = networkInfo.WiFiMode if networkInfo.WiFiMode != None else -1
398405
networkInfoStruct.WiFiRole = networkInfo.WiFiRole if networkInfo.WiFiRole != None else -1
399406
networkInfoStruct.WiFiSecurityType = networkInfo.WiFiSecurityType if networkInfo.WiFiSecurityType != None else -1
400407
networkInfoStruct.WiFiKey = _ByteArrayToVoidPtr(networkInfo.WiFiKey)
401408
networkInfoStruct.WiFiKeyLen = len(networkInfo.WiFiKey) if (networkInfo.WiFiKey != None) else 0
402-
networkInfoStruct.ThreadNetworkName = networkInfo.ThreadNetworkName
409+
networkInfoStruct.ThreadNetworkName = _StringToCString(networkInfo.ThreadNetworkName)
403410
networkInfoStruct.ThreadExtendedPANId = _ByteArrayToVoidPtr(networkInfo.ThreadExtendedPANId)
404411
networkInfoStruct.ThreadNetworkKey = _ByteArrayToVoidPtr(networkInfo.ThreadNetworkKey)
405412
networkInfoStruct.ThreadPSKc = _ByteArrayToVoidPtr(networkInfo.ThreadPSKc)
@@ -442,10 +449,10 @@ def toDeviceDescriptor(self):
442449
manufacturingDay = self.ManufacturingDay if self.ManufacturingDay != 0 else None,
443450
primary802154MACAddress = bytearray(self.Primary802154MACAddress) if not _IsByteArrayAllZeros(self.Primary802154MACAddress) else None,
444451
primaryWiFiMACAddress = bytearray(self.PrimaryWiFiMACAddress) if not _IsByteArrayAllZeros(self.PrimaryWiFiMACAddress) else None,
445-
serialNumber = self.SerialNumber if len(self.SerialNumber) != 0 else None,
446-
softwareVersion = self.SoftwareVersion if len(self.SoftwareVersion) != 0 else None,
447-
rendezvousWiFiESSID = self.RendezvousWiFiESSID if len(self.RendezvousWiFiESSID) != 0 else None,
448-
pairingCode = self.PairingCode if len(self.PairingCode) != 0 else None,
452+
serialNumber = _CStringToString(self.SerialNumber) if len(self.SerialNumber) != 0 else None,
453+
softwareVersion = _CStringToString(self.SoftwareVersion) if len(self.SoftwareVersion) != 0 else None,
454+
rendezvousWiFiESSID = _CStringToString(self.RendezvousWiFiESSID) if len(self.RendezvousWiFiESSID) != 0 else None,
455+
pairingCode = _CStringToString(self.PairingCode) if len(self.PairingCode) != 0 else None,
449456
pairingCompatibilityVersionMajor = self.PairingCompatibilityVersionMajor,
450457
pairingCompatibilityVersionMinor = self.PairingCompatibilityVersionMinor,
451458
deviceFeatures = self.DeviceFeatures,
@@ -473,9 +480,14 @@ def toDeviceDescriptor(self):
473480
# This is a fix for WEAV-429. Jay Logue recommends revisiting this at a later
474481
# date to allow for truely multiple instances so this is temporary.
475482
def _singleton(cls):
476-
instance = cls()
477-
instance.__call__ = lambda: instance
478-
return instance
483+
instance = [None]
484+
485+
def wrapper(*args, **kwargs):
486+
if instance[0] is None:
487+
instance[0] = cls(*args, **kwargs)
488+
return instance[0]
489+
490+
return wrapper
479491

480492
@_singleton
481493
class WeaveDeviceManager(object):
@@ -506,7 +518,7 @@ def HandleError(devMgr, reqState, err, devStatusPtr):
506518
self.completeEvent.set()
507519

508520
def HandleDeviceEnumerationResponse(devMgr, deviceDescPtr, deviceAddrStr):
509-
print(" Enumerated device IP: %s" % (deviceAddrStr))
521+
print(" Enumerated device IP: %s" % (_CStringToString(deviceAddrStr)))
510522
deviceDescPtr.contents.toDeviceDescriptor().Print(" ")
511523

512524
self.cbHandleComplete = _CompleteFunct(HandleComplete)
@@ -587,15 +599,15 @@ def DeviceId(self):
587599

588600
def DeviceAddress(self):
589601
return self._CallDevMgr(
590-
lambda: _dmLib.nl_Weave_DeviceManager_DeviceAddress(self.devMgr)
602+
lambda: _CStringToString(_dmLib.nl_Weave_DeviceManager_DeviceAddress(self.devMgr))
591603
)
592604

593605
def SetRendezvousAddress(self, addr, intf = None):
594606
if addr is not None and "\x00" in addr:
595607
raise ValueError("Unexpected NUL character in addr");
596608

597609
res = self._CallDevMgr(
598-
lambda: _dmLib.nl_Weave_DeviceManager_SetRendezvousAddress(self.devMgr, addr, intf)
610+
lambda: _dmLib.nl_Weave_DeviceManager_SetRendezvousAddress(self.devMgr, _StringToCString(addr), _StringToCString(intf))
599611
)
600612
if (res != 0):
601613
raise self._ErrorToException(res)
@@ -659,15 +671,15 @@ def ConnectDevice(self, deviceId, deviceAddr=None,
659671

660672
if (pairingCode == None and accessToken == None):
661673
self._CallDevMgrAsync(
662-
lambda: _dmLib.nl_Weave_DeviceManager_ConnectDevice_NoAuth(self.devMgr, deviceId, deviceAddr, self.cbHandleComplete, self.cbHandleError)
674+
lambda: _dmLib.nl_Weave_DeviceManager_ConnectDevice_NoAuth(self.devMgr, deviceId, _StringToCString(deviceAddr), self.cbHandleComplete, self.cbHandleError)
663675
)
664676
elif (pairingCode != None):
665677
self._CallDevMgrAsync(
666-
lambda: _dmLib.nl_Weave_DeviceManager_ConnectDevice_PairingCode(self.devMgr, deviceId, deviceAddr, pairingCode, self.cbHandleComplete, self.cbHandleError)
678+
lambda: _dmLib.nl_Weave_DeviceManager_ConnectDevice_PairingCode(self.devMgr, deviceId, _StringToCString(deviceAddr), _StringToCString(pairingCode), self.cbHandleComplete, self.cbHandleError)
667679
)
668680
else:
669681
self._CallDevMgrAsync(
670-
lambda: _dmLib.nl_Weave_DeviceManager_ConnectDevice_AccessToken(self.devMgr, deviceId, deviceAddr, _ByteArrayToVoidPtr(accessToken), len(accessToken), self.cbHandleComplete, self.cbHandleError)
682+
lambda: _dmLib.nl_Weave_DeviceManager_ConnectDevice_AccessToken(self.devMgr, deviceId, _StringToCString(deviceAddr), _ByteArrayToVoidPtr(accessToken), len(accessToken), self.cbHandleComplete, self.cbHandleError)
671683
)
672684

673685
def RendezvousDevice(self, pairingCode=None, accessToken=None,
@@ -696,7 +708,7 @@ def RendezvousDevice(self, pairingCode=None, accessToken=None,
696708
)
697709
elif (pairingCode != None):
698710
self._CallDevMgrAsync(
699-
lambda: _dmLib.nl_Weave_DeviceManager_RendezvousDevice_PairingCode(self.devMgr, pairingCode, deviceCriteria, self.cbHandleComplete, self.cbHandleError)
711+
lambda: _dmLib.nl_Weave_DeviceManager_RendezvousDevice_PairingCode(self.devMgr, _StringToCString(pairingCode), deviceCriteria, self.cbHandleComplete, self.cbHandleError)
700712
)
701713
else:
702714
self._CallDevMgrAsync(
@@ -747,7 +759,7 @@ def ConnectBle(self, bleConnection, pairingCode=None, accessToken=None):
747759
)
748760
elif (pairingCode != None):
749761
self._CallDevMgrAsync(
750-
lambda: _dmLib.nl_Weave_DeviceManager_ConnectBle_PairingCode(self.devMgr, bleConnection, pairingCode, self.cbHandleComplete, self.cbHandleError)
762+
lambda: _dmLib.nl_Weave_DeviceManager_ConnectBle_PairingCode(self.devMgr, bleConnection, _StringToCString(pairingCode), self.cbHandleComplete, self.cbHandleError)
751763
)
752764
else:
753765
self._CallDevMgrAsync(
@@ -767,7 +779,7 @@ def PassiveRendezvousDevice(self, pairingCode=None, accessToken=None):
767779
)
768780
elif (pairingCode != None):
769781
self._CallDevMgrAsync(
770-
lambda: _dmLib.nl_Weave_DeviceManager_PassiveRendezvousDevice_PairingCode(self.devMgr, pairingCode, self.cbHandleComplete, self.cbHandleError)
782+
lambda: _dmLib.nl_Weave_DeviceManager_PassiveRendezvousDevice_PairingCode(self.devMgr, _StringToCString(pairingCode), self.cbHandleComplete, self.cbHandleError)
771783
)
772784
else:
773785
self._CallDevMgrAsync(
@@ -786,15 +798,15 @@ def RemotePassiveRendezvous(self, rendezvousDeviceAddr=None, pairingCode=None, a
786798

787799
if (pairingCode == None and accessToken == None):
788800
self._CallDevMgrAsync(
789-
lambda: _dmLib.nl_Weave_DeviceManager_RemotePassiveRendezvous_NoAuth(self.devMgr, rendezvousDeviceAddr, rendezvousTimeout, inactivityTimeout, self.cbHandleComplete, self.cbHandleError)
801+
lambda: _dmLib.nl_Weave_DeviceManager_RemotePassiveRendezvous_NoAuth(self.devMgr, _StringToCString(rendezvousDeviceAddr), rendezvousTimeout, inactivityTimeout, self.cbHandleComplete, self.cbHandleError)
790802
)
791803
elif (pairingCode != None):
792804
self._CallDevMgrAsync(
793-
lambda: _dmLib.nl_Weave_DeviceManager_RemotePassiveRendezvous_PASEAuth(self.devMgr, rendezvousDeviceAddr, pairingCode, rendezvousTimeout, inactivityTimeout, self.cbHandleComplete, self.cbHandleError)
805+
lambda: _dmLib.nl_Weave_DeviceManager_RemotePassiveRendezvous_PASEAuth(self.devMgr, _StringToCString(rendezvousDeviceAddr), _StringToCString(pairingCode), rendezvousTimeout, inactivityTimeout, self.cbHandleComplete, self.cbHandleError)
794806
)
795807
else:
796808
self._CallDevMgrAsync(
797-
lambda: _dmLib.nl_Weave_DeviceManager_RemotePassiveRendezvous_CASEAuth(self.devMgr, rendezvousDeviceAddr, _ByteArrayToVoidPtr(accessToken), len(accessToken), rendezvousTimeout, inactivityTimeout, self.cbHandleComplete, self.cbHandleError)
809+
lambda: _dmLib.nl_Weave_DeviceManager_RemotePassiveRendezvous_CASEAuth(self.devMgr, _StringToCString(rendezvousDeviceAddr), _ByteArrayToVoidPtr(accessToken), len(accessToken), rendezvousTimeout, inactivityTimeout, self.cbHandleComplete, self.cbHandleError)
798810
)
799811

800812
def ReconnectDevice(self):
@@ -883,13 +895,13 @@ def GetCameraAuthData(self, nonce):
883895
raise ValueError("Unexpected NUL character in nonce")
884896

885897
def HandleGetCameraAuthDataComplete(devMgr, reqState, macAddress, signedCameraPayload):
886-
self.callbackRes = [ macAddress, signedCameraPayload ]
898+
self.callbackRes = [ _CStringToString(macAddress), _CStringToString(signedCameraPayload) ]
887899
self.completeEvent.set()
888900

889901
cbHandleGetCameraAuthDataComplete = _GetCameraAuthDataCompleteFunct(HandleGetCameraAuthDataComplete)
890902

891903
return self._CallDevMgrAsync(
892-
lambda: _dmLib.nl_Weave_DeviceManager_GetCameraAuthData(self.devMgr, nonce, cbHandleGetCameraAuthDataComplete, self.cbHandleError)
904+
lambda: _dmLib.nl_Weave_DeviceManager_GetCameraAuthData(self.devMgr, _StringToCString(nonce), cbHandleGetCameraAuthDataComplete, self.cbHandleError)
893905
)
894906

895907
def AddNetwork(self, networkInfo):
@@ -1006,7 +1018,7 @@ def RegisterServicePairAccount(self, serviceId, accountId, serviceConfig, pairin
10061018
raise ValueError("Unexpected NUL character in accountId")
10071019

10081020
self._CallDevMgrAsync(
1009-
lambda: _dmLib.nl_Weave_DeviceManager_RegisterServicePairAccount(self.devMgr, serviceId, accountId,
1021+
lambda: _dmLib.nl_Weave_DeviceManager_RegisterServicePairAccount(self.devMgr, serviceId, _StringToCString(accountId),
10101022
_ByteArrayToVoidPtr(serviceConfig), len(serviceConfig),
10111023
_ByteArrayToVoidPtr(pairingToken), len(pairingToken),
10121024
_ByteArrayToVoidPtr(pairingInitData), len(pairingInitData),
@@ -1351,13 +1363,13 @@ def _CallDevMgrAsync(self, callFunct):
13511363
def _ErrorToException(self, err, devStatusPtr=None):
13521364
if (err == 4044 and devStatusPtr):
13531365
devStatus = devStatusPtr.contents
1354-
msg = _dmLib.nl_Weave_DeviceManager_StatusReportToString(devStatus.ProfileId, devStatus.StatusCode)
1366+
msg = _CStringToString(_dmLib.nl_Weave_DeviceManager_StatusReportToString(devStatus.ProfileId, devStatus.StatusCode))
13551367
sysErrorCode = devStatus.SysErrorCode if (devStatus.SysErrorCode != 0) else None
13561368
if (sysErrorCode != None):
13571369
msg = msg + " (system err %d)" % (sysErrorCode)
13581370
return DeviceError(devStatus.ProfileId, devStatus.StatusCode, sysErrorCode, msg)
13591371
else:
1360-
return DeviceManagerError(err, _dmLib.nl_Weave_DeviceManager_ErrorToString(err))
1372+
return DeviceManagerError(err, _CStringToString(_dmLib.nl_Weave_DeviceManager_ErrorToString(err)))
13611373

13621374

13631375
def NetworkTypeToString(val):

0 commit comments

Comments
 (0)