This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF5 Mesh SDK Serial Example Interactive PyACI Provisioning problem

Hello,

I am new to nrf5 mesh. I have setup my system based on Nordic's documentation and was evaluating Serial Example with Interactive Py script.

My setup consists of: 2 no. PCA10028 V 1.0.0 dev boards, Windows 7 PC, with Python 3.6.4 (32-bit) installed. I have generated "serial_nrf51422_xxAC_s130_2_0_1.emProject" with CMake and flashed both the boards with its HEX files via SES IDE.

I am running the interactive_pyaci.py script am trying to do Provisioning as per the doc. But I am getting the following error: ERROR - COM5: OobUse: ERROR_INVALID_LENGTH

Please see the log messages below:

$ python interactive_pyaci.py -d COM5 COM6 -b 115200 --no-logfile

    To control your device, use d[x], where x is the device index.
    Devices are indexed based on the order of the COM ports specified by the -d option.
    The first device, d[0], can also be accessed using device.

    Type d[x]. and hit tab to see the available methods.

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)]
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: p = Provisioner(d[0])

In [2]: 2018-02-28 10:13:44,035 - INFO - COM5: Success
2018-02-28 10:13:44,038 - INFO - COM5: Success
2018-02-28 10:13:44,046 - INFO - COM5: SubnetAdd: {'subnet_handle': 0}
a = Provisionee(d[1])

In [3]: 2018-02-28 10:13:52,684 - INFO - COM6: Success
2018-02-28 10:13:52,688 - INFO - COM6: Success


In [3]: p.scan_start()

In [4]: 2018-02-28 10:14:12,202 - INFO - COM5: Success


In [4]: a.listen()

In [5]: 2018-02-28 10:14:22,778 - INFO - COM6: Success
2018-02-28 10:14:22,915 - INFO - COM5: Received UUID BA95A3713305A75BA838872DABA62B92 with RSSI: -208 dB


In [5]: p.provision()

In [6]: 2018-02-28 10:14:57,995 - INFO - COM5: Provision: {'context': 0}
2018-02-28 10:14:58,011 - INFO - COM6: Link established
2018-02-28 10:14:58,026 - INFO - COM5: Link established
2018-02-28 10:14:58,081 - INFO - COM5: Received capabilities
2018-02-28 10:14:58,082 - INFO - COM5: Number of elements: 2
2018-02-28 10:14:58,085 - ERROR - COM5: OobUse: ERROR_INVALID_LENGTH

I am following the Interactive PyACI documentation present in the SDK. Please let me know where am I going wrong.

Thanks

Parents
  • Hi rohandey87,

    It seems that there is an issue in the release where some of the provisioning APIs has been changed, but the provisioning python script was not updated for this. It is fixed internally and will be a part of the next release. I've attached a diff that should fix your problem.

    diff --git a/scripts/interactive_pyaci/aci/aci_cmd.py b/scripts/interactive_pyaci/aci/aci_cmd.py
    index 82b32b7..5cf991d 100644
    --- a/scripts/interactive_pyaci/aci/aci_cmd.py
    +++ b/scripts/interactive_pyaci/aci/aci_cmd.py
    @@ -27,7 +27,7 @@
     # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     # POSSIBILITY OF SUCH DAMAGE.
     
    -# This file was autogenerated by serial_doc_gen_pyaci.py at 2017-08-04 18:04:07.
    +# This file was autogenerated by serial_doc_gen_pyaci.py at 2018-02-22 19:45:14.
     from aci.aci_utils import CommandPacket, ResponsePacket, value_to_barray, iterable_to_barray, barray_pop
     from aci.aci_evt import CmdRsp
     
    @@ -224,7 +224,7 @@ class TxPowerSet(CommandPacket):
         Parameters
         ----------
             tx_power : uint8_t
    -            Transmit power of radio, @see serial_cmd_tx_power_value_t.
    +            Transmit power of radio, see @ref serial_cmd_tx_power_value_t for accepted values.
         """
         def __init__(self, tx_power):
             __data = bytearray()
    @@ -324,14 +324,18 @@ class OobUse(CommandPacket):
             context_id : uint8_t
                 ID of context to set the oob method for.
             oob_method : uint8_t
    -            OOB method to use, see @ref nrf_mesh_prov_oob_method_t for values.
    +            OOB method to use, see @ref nrf_mesh_prov_oob_method_t for accepted values.
    +        oob_action : uint8_t
    +            OOB action to use, see @ref nrf_mesh_prov_input_action_t or @ref
    +                nrf_mesh_prov_output_action_t for values.
             size : uint8_t
                 Size of the OOB data.
         """
    -    def __init__(self, context_id, oob_method, size):
    +    def __init__(self, context_id, oob_method, oob_action, size):
             __data = bytearray()
             __data += value_to_barray(context_id, 1)
             __data += value_to_barray(oob_method, 1)
    +        __data += value_to_barray(oob_action, 1)
             __data += value_to_barray(size, 1)
             super(OobUse, self).__init__(0x66, __data)
     
    @@ -480,12 +484,12 @@ class DfuData(CommandPacket):
     
         Parameters
         ----------
    -        dfu_packet : nrf_mesh_dfu_packet_t
    +        dfu_packet : uint8_t[31]
                 DFU packet data.
         """
         def __init__(self, dfu_packet):
             __data = bytearray()
    -        __data += value_to_barray(dfu_packet, 24)
    +        __data += iterable_to_barray(dfu_packet)
             super(DfuData, self).__init__(0x78, __data)
     
     
    @@ -1023,7 +1027,7 @@ class ModelPubPeriodSet(CommandPacket):
             model_handle : access_model_handle_t
                 Handle of the model that the access module should operate on.
             resolution : uint8_t
    -            @see access_publish_resolution_t
    +            see @ref access_publish_resolution_t for accepted values.
             step_number : uint8_t
                 Must not be larger than @ref ACCESS_PUBLISH_PERIOD_STEP_MAX.
         """
    @@ -1184,6 +1188,7 @@ class ModelPubTtlSet(CommandPacket):
             model_handle : access_model_handle_t
                 Handle of the model that the access module should operate on.
             ttl : uint8_t
    +            TTL
         """
         def __init__(self, model_handle, ttl):
             __data = bytearray()
    @@ -1229,6 +1234,7 @@ class ElemLocGet(CommandPacket):
         Parameters
         ----------
             element_index : uint16_t
    +            Element Index
         """
         def __init__(self, element_index):
             __data = bytearray()
    @@ -1242,6 +1248,7 @@ class ElemSigModelCountGet(CommandPacket):
         Parameters
         ----------
             element_index : uint16_t
    +            Element Index
         """
         def __init__(self, element_index):
             __data = bytearray()
    @@ -1255,6 +1262,7 @@ class ElemVendorModelCountGet(CommandPacket):
         Parameters
         ----------
             element_index : uint16_t
    +            Element Index
         """
         def __init__(self, element_index):
             __data = bytearray()
    @@ -1283,8 +1291,9 @@ class HandleGet(CommandPacket):
         Parameters
         ----------
             element_index : uint16_t
    -
    +            Element Index
             model_id : access_model_id_t
    +            Model ID
         """
         def __init__(self, element_index, model_id):
             __data = bytearray()
    @@ -1299,6 +1308,7 @@ class ElemModelsGet(CommandPacket):
         Parameters
         ----------
             element_index : uint16_t
    +            Element Index
         """
         def __init__(self, element_index):
             __data = bytearray()
    @@ -1406,6 +1416,15 @@ class AdvAddrGetRsp(ResponsePacket):
             super(AdvAddrGetRsp, self).__init__("AdvAddrGet", 0x41, __data)
     
     
    +class TxPowerGetRsp(ResponsePacket):
    +    """Response to a(n) TxPowerGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["tx_power"] = barray_pop(raw_data, 1)
    +        assert(len(raw_data) == 0)
    +        super(TxPowerGetRsp, self).__init__("TxPowerGet", 0x45, __data)
    +
    +
     class UuidGetRsp(ResponsePacket):
         """Response to a(n) UuidGet command."""
         def __init__(self, raw_data):
    @@ -1706,12 +1725,159 @@ class StateGetRsp(ResponsePacket):
             super(StateGetRsp, self).__init__("StateGet", 0xD6, __data)
     
     
    +class ModelPubAddrGetRsp(ResponsePacket):
    +    """Response to a(n) ModelPubAddrGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["addr_handle"] = barray_pop(raw_data, 2)
    +        assert(len(raw_data) == 0)
    +        super(ModelPubAddrGetRsp, self).__init__("ModelPubAddrGet", 0xE1, __data)
    +
    +
    +class ModelPubPeriodGetRsp(ResponsePacket):
    +    """Response to a(n) ModelPubPeriodGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["resolution"] = barray_pop(raw_data, 1)
    +        __data["step_number"] = barray_pop(raw_data, 1)
    +        assert(len(raw_data) == 0)
    +        super(ModelPubPeriodGetRsp, self).__init__("ModelPubPeriodGet", 0xE3, __data)
    +
    +
    +class ModelSubsGetRsp(ResponsePacket):
    +    """Response to a(n) ModelSubsGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["count"] = barray_pop(raw_data, 2)
    +        __data["address_handles"] = raw_data[:92]
    +        raw_data = raw_data[92:]
    +        assert(len(raw_data) == 0)
    +        super(ModelSubsGetRsp, self).__init__("ModelSubsGet", 0xE6, __data)
    +
    +
    +class ModelAppGetRsp(ResponsePacket):
    +    """Response to a(n) ModelAppGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["count"] = barray_pop(raw_data, 2)
    +        __data["appkey_handles"] = raw_data[:92]
    +        raw_data = raw_data[92:]
    +        assert(len(raw_data) == 0)
    +        super(ModelAppGetRsp, self).__init__("ModelAppGet", 0xE9, __data)
    +
    +
    +class ModelPubAppGetRsp(ResponsePacket):
    +    """Response to a(n) ModelPubAppGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["appkey_handle"] = barray_pop(raw_data, 2)
    +        assert(len(raw_data) == 0)
    +        super(ModelPubAppGetRsp, self).__init__("ModelPubAppGet", 0xEB, __data)
    +
    +
    +class ModelPubTtlGetRsp(ResponsePacket):
    +    """Response to a(n) ModelPubTtlGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["ttl"] = barray_pop(raw_data, 1)
    +        assert(len(raw_data) == 0)
    +        super(ModelPubTtlGetRsp, self).__init__("ModelPubTtlGet", 0xED, __data)
    +
    +
    +class ElemLocGetRsp(ResponsePacket):
    +    """Response to a(n) ElemLocGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["location"] = barray_pop(raw_data, 2)
    +        assert(len(raw_data) == 0)
    +        super(ElemLocGetRsp, self).__init__("ElemLocGet", 0xEF, __data)
    +
    +
    +class ElemSigModelCountGetRsp(ResponsePacket):
    +    """Response to a(n) ElemSigModelCountGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["model_count"] = barray_pop(raw_data, 1)
    +        assert(len(raw_data) == 0)
    +        super(ElemSigModelCountGetRsp, self).__init__("ElemSigModelCountGet", 0xF0, __data)
    +
    +
    +class ElemVendorModelCountGetRsp(ResponsePacket):
    +    """Response to a(n) ElemVendorModelCountGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["model_count"] = barray_pop(raw_data, 1)
    +        assert(len(raw_data) == 0)
    +        super(ElemVendorModelCountGetRsp, self).__init__("ElemVendorModelCountGet", 0xF1, __data)
    +
    +
    +class ModelIdGetRsp(ResponsePacket):
    +    """Response to a(n) ModelIdGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["model_id"] = barray_pop(raw_data, 4)
    +        assert(len(raw_data) == 0)
    +        super(ModelIdGetRsp, self).__init__("ModelIdGet", 0xF2, __data)
    +
    +
    +class HandleGetRsp(ResponsePacket):
    +    """Response to a(n) HandleGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["model_handle"] = barray_pop(raw_data, 2)
    +        assert(len(raw_data) == 0)
    +        super(HandleGetRsp, self).__init__("HandleGet", 0xF3, __data)
    +
    +
    +class ElemModelsGetRsp(ResponsePacket):
    +    """Response to a(n) ElemModelsGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["count"] = barray_pop(raw_data, 2)
    +        __data["model_handles"] = raw_data[:92]
    +        raw_data = raw_data[92:]
    +        assert(len(raw_data) == 0)
    +        super(ElemModelsGetRsp, self).__init__("ElemModelsGet", 0xF4, __data)
    +
    +
    +class ModelsGetRsp(ResponsePacket):
    +    """Response to a(n) ModelsGet command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["count"] = barray_pop(raw_data, 2)
    +        __data["model_ids"] = raw_data[:92]
    +        raw_data = raw_data[92:]
    +        assert(len(raw_data) == 0)
    +        super(ModelsGetRsp, self).__init__("ModelsGet", 0xFC, __data)
    +
    +
    +class InitRsp(ResponsePacket):
    +    """Response to a(n) Init command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["model_handle"] = barray_pop(raw_data, 2)
    +        assert(len(raw_data) == 0)
    +        super(InitRsp, self).__init__("Init", 0xFD, __data)
    +
    +
    +class CommandRsp(ResponsePacket):
    +    """Response to a(n) Command command."""
    +    def __init__(self, raw_data):
    +        __data = {}
    +        __data["data_len"] = barray_pop(raw_data, 1)
    +        __data["data"] = raw_data[:len(raw_data)]
    +        raw_data = raw_data[len(raw_data):]
    +        assert(len(raw_data) == 0)
    +        super(CommandRsp, self).__init__("Command", 0xFE, __data)
    +
    +
     RESPONSE_LUT = {
         0x02: {"object": EchoRsp, "name": "Echo"},
         0x09: {"object": SerialVersionGetRsp, "name": "SerialVersionGet"},
         0x0A: {"object": FwInfoGetRsp, "name": "FwInfoGet"},
         0x13: {"object": BeaconParamsGetRsp, "name": "BeaconParamsGet"},
         0x41: {"object": AdvAddrGetRsp, "name": "AdvAddrGet"},
    +    0x45: {"object": TxPowerGetRsp, "name": "TxPowerGet"},
         0x54: {"object": UuidGetRsp, "name": "UuidGet"},
         0x63: {"object": ProvisionRsp, "name": "Provision"},
         0x66: {"object": OobUseRsp, "name": "OobUse"},
    @@ -1742,7 +1908,22 @@ RESPONSE_LUT = {
         0xA5: {"object": AddrPublicationAddVirtualRsp, "name": "AddrPublicationAddVirtual"},
         0xA6: {"object": AddrPublicationRemoveRsp, "name": "AddrPublicationRemove"},
         0xD4: {"object": BankInfoGetRsp, "name": "BankInfoGet"},
    -    0xD6: {"object": StateGetRsp, "name": "StateGet"}
    +    0xD6: {"object": StateGetRsp, "name": "StateGet"},
    +    0xE1: {"object": ModelPubAddrGetRsp, "name": "ModelPubAddrGet"},
    +    0xE3: {"object": ModelPubPeriodGetRsp, "name": "ModelPubPeriodGet"},
    +    0xE6: {"object": ModelSubsGetRsp, "name": "ModelSubsGet"},
    +    0xE9: {"object": ModelAppGetRsp, "name": "ModelAppGet"},
    +    0xEB: {"object": ModelPubAppGetRsp, "name": "ModelPubAppGet"},
    +    0xED: {"object": ModelPubTtlGetRsp, "name": "ModelPubTtlGet"},
    +    0xEF: {"object": ElemLocGetRsp, "name": "ElemLocGet"},
    +    0xF0: {"object": ElemSigModelCountGetRsp, "name": "ElemSigModelCountGet"},
    +    0xF1: {"object": ElemVendorModelCountGetRsp, "name": "ElemVendorModelCountGet"},
    +    0xF2: {"object": ModelIdGetRsp, "name": "ModelIdGet"},
    +    0xF3: {"object": HandleGetRsp, "name": "HandleGet"},
    +    0xF4: {"object": ElemModelsGetRsp, "name": "ElemModelsGet"},
    +    0xFC: {"object": ModelsGetRsp, "name": "ModelsGet"},
    +    0xFD: {"object": InitRsp, "name": "Init"},
    +    0xFE: {"object": CommandRsp, "name": "Command"}
     }
     
     
    diff --git a/scripts/interactive_pyaci/aci/aci_evt.py b/scripts/interactive_pyaci/aci/aci_evt.py
    index f406a32..b655545 100644
    --- a/scripts/interactive_pyaci/aci/aci_evt.py
    +++ b/scripts/interactive_pyaci/aci/aci_evt.py
    @@ -27,7 +27,7 @@
     # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     # POSSIBILITY OF SUCH DAMAGE.
     
    -# This file was autogenerated by serial_doc_gen_pyaci.py at 2017-08-04 18:04:07.
    +# This file was autogenerated by serial_doc_gen_pyaci.py at 2018-02-22 19:45:14.
     from aci.aci_utils import EventPacket, barray_pop
     
     
    @@ -59,7 +59,8 @@ class DeviceStarted(EventPacket):
         Parameters
         ----------
             operating_mode : uint8_t
    -            Operating mode of the device. @see serial_device_operating_mode_t.
    +            Operating mode of the device. see @ref serial_device_operating_mode_t for accepted
    +                values.
             hw_error : uint8_t
                 Hardware error code, or 0 if no error occured.
             data_credit_available : uint8_t
    @@ -96,7 +97,7 @@ class DeviceInternalEvent(EventPacket):
         Parameters
         ----------
             event_type : uint8_t
    -            Reported event. See @ref internal_event_type_t for values.
    +            Reported event. See @ref internal_event_type_t for accepted values.
             state : uint8_t
                 State information about the event type reported.
             packet_size : uint8_t
    @@ -671,18 +672,22 @@ class MeshIvUpdateNotification(EventPacket):
             super(MeshIvUpdateNotification, self).__init__("MeshIvUpdateNotification", 0xD3, __data)
     
     
    -class MeshKeyRefreshStart(EventPacket):
    -    """The key refresh procedure has been started for the network with the given index."""
    -    def __init__(self, raw_data):
    -        __data = {}
    -        super(MeshKeyRefreshStart, self).__init__("MeshKeyRefreshStart", 0xD5, __data)
    +class MeshKeyRefreshNotification(EventPacket):
    +    """A network has entered a new phase in the key refresh procedure.
     
    -
    -class MeshKeyRefreshEnd(EventPacket):
    -    """The key refresh procedure has ended for the network with the given index."""
    +    Parameters
    +    ----------
    +        netkey_index : uint16_t
    +            Network key index of the network key being updated.
    +        phase : uint8_t
    +            Current key refresh phase for the network key being updated.
    +    """
         def __init__(self, raw_data):
             __data = {}
    -        super(MeshKeyRefreshEnd, self).__init__("MeshKeyRefreshEnd", 0xD6, __data)
    +        __data["netkey_index"] = barray_pop(raw_data, 2)
    +        __data["phase"] = barray_pop(raw_data, 1)
    +        assert(len(raw_data) == 0)
    +        super(MeshKeyRefreshNotification, self).__init__("MeshKeyRefreshNotification", 0xD4, __data)
     
     
     class MeshSarFailed(EventPacket):
    @@ -726,8 +731,7 @@ class Event(object):
         DFU_REQ_SOURCE = 0xA1
         DFU_START = 0xA2
         MESH_IV_UPDATE_NOTIFICATION = 0xD3
    -    MESH_KEY_REFRESH_END = 0xD6
    -    MESH_KEY_REFRESH_START = 0xD5
    +    MESH_KEY_REFRESH_NOTIFICATION = 0xD4
         MESH_MESSAGE_RECEIVED_SUBSCRIPTION = 0xD1
         MESH_MESSAGE_RECEIVED_UNICAST = 0xD0
         MESH_SAR_FAILED = 0xD7
    @@ -764,8 +768,7 @@ EVENT_LUT = {
         Event.DFU_REQ_SOURCE: DfuReqSource,
         Event.DFU_START: DfuStart,
         Event.MESH_IV_UPDATE_NOTIFICATION: MeshIvUpdateNotification,
    -    Event.MESH_KEY_REFRESH_END: MeshKeyRefreshEnd,
    -    Event.MESH_KEY_REFRESH_START: MeshKeyRefreshStart,
    +    Event.MESH_KEY_REFRESH_NOTIFICATION: MeshKeyRefreshNotification,
         Event.MESH_MESSAGE_RECEIVED_SUBSCRIPTION: MeshMessageReceivedSubscription,
         Event.MESH_MESSAGE_RECEIVED_UNICAST: MeshMessageReceivedUnicast,
         Event.MESH_SAR_FAILED: MeshSarFailed,
    diff --git a/scripts/interactive_pyaci/provisioning.py b/scripts/interactive_pyaci/provisioning.py
    index da4fc27..ec4c5f0 100644
    --- a/scripts/interactive_pyaci/provisioning.py
    +++ b/scripts/interactive_pyaci/provisioning.py
    @@ -102,6 +102,21 @@ class OOBMethod(object):
         INPUT = 0x03
     
     
    +class OOBOutputAction(object):
    +    BLINK = 0x00
    +    BEEP = 0x01
    +    VIBRATE = 0x02
    +    DISPLAY_NUMERIC = 0x03
    +    ALPHANUMERIC = 0x04
    +
    +
    +class OOBInputAction(object):
    +    PUSH = 0x00
    +    TWIST = 0x01
    +    ENTER_NUMBER = 0x02
    +    ENTER_STRING = 0x03
    +
    +
     class ProvisioneeList(object):
         def __init__(self):
             self.__list = []
    @@ -271,7 +286,9 @@ class Provisioner(ProvDevice):
                     str(event._data["num_elements"])))
                 self.__caps[event._data["context_id"]] = event._data
                 self.iaci.send(cmd.OobUse(event._data["context_id"],
    -                                      OOBMethod.NONE, 0))
    +                                      OOBMethod.NONE,
    +                                      0,
    +                                      0))
     
             elif event._opcode == Event.PROV_COMPLETE:
                 caps = self.__caps[event._data["context_id"]]
    

    NOTE: You actually only have to apply the last part of the diff, related to `provisioning.py`. The rest, you can do with `ninja serial_pyaci` or `make serial_pyaci` to re-generate the (de-)serialization code.

    Hope this helps,
    Thomas

  • Hi Thomas,

    I tried the steps you provided and am able to run the provisioning successfully.

    Thanks a lot.

Reply Children
No Data
Related