Problem with registering a device to the Network Server Registry with HTTP API v3

Hi everyone,

I am trying to register a device using the HTTP API and it works well for the end device registry, join server registry, and application server registry. However, when the PUT request is done to the network server registry, it fails with a 400 error. stating that the “frequency_plan_id” field is missing. However, the POST data has the frequency_plan_id field.

(Note: I am following the order stated, I tested for the application server by skipping the network server once.)

The complete PUT data is as follows;

{
  "end_device": {
    "multicast": false,
    "supports_join": true,
    "lorawan_version": "1.0.3",
    "ids": {
      "device_id": "elsys-co2-043abc",
      "dev_eui": "A81758FFFE044BAB",
      "join_eui": "000ABDE000001232"
    },
    "mac_settings": {
      "supports_32_bit_f_cnt": true
    },
    "supports_class_c": false,
    "supports_class_b": false,
    "lorawan_phy_version": "1.0.3-a",
    "frequency_plan_id": "EU_863_870_TTN"
  }
}

The failure message I get is as follows;

{
  "code": 3,
  "message": "error:pkg/networkserver:field_mask (invalid field mask)",
  "details": [
    {
      "@type": "type.googleapis.com/ttn.lorawan.v3.ErrorDetails",
      "namespace": "pkg/networkserver",
      "name": "field_mask",
      "message_format": "invalid field mask",
      "correlation_id": "24c0694175004aa58e116f97ff943b4a",
      "cause": {
        "namespace": "pkg/ttnpb",
        "name": "missing_field",
        "message_format": "field `{field}` is missing",
        "attributes": {
          "field": "frequency_plan_id"
        },
        "code": 2
      },
      "code": 3
    }
  ]
}

Any help regarding this would be appreciated.

I played a bit with the API this weekend, as a “consumer” of the API, I was not involved in the design.

As far as I can tell, it’s not telling you that frequency_plan_id is missing, it’s telling you that you need to set a field mask.

I think you need to tell in the URL which fields you want to update/create exactly, as a command separated list of fields. Then make sure that these fields and their contents are present in the body of the PUT data.

This should in the query part of the URL that you’re PUTing to, like https://xxxxx?field_mask=aaa,bbb,ccc where aaa,bbb,ccc is something like
multicast,ids,supports_join,lorawan_version,ids,mac_settings,supports_class_c,supports_class_b,lorawan_phy_version,frequency_plan_id

See also: Fields and Field Masks | The Things Stack for LoRaWAN

Thanks for the response @bertrik, I did try the option of adding the field mask in the PUT request URL itself, but that too gave the same error. So, I don’t think that should be the case. Given the fact that other registries do not require any field mask query parameter and work fine, I believe the field mask parameter is required for updates for existing devices when you only need certain fields to be updated.

I checked the browser developer console while adding a device through the TTN v3 console, and the PUT request to NS was of the form https://eu1.cloud.thethings.network/api/v3/ns/applications/appid/devices/test-device-1 and the data was of the form

{
   "end_device":{
      "multicast":false,
      "supports_join":true,
      "lorawan_version":"1.0.3",
      "ids":{
         "device_id":"test-device-1",
         "dev_eui":"A81758FFFE044BAB",
         "join_eui":"70B3D57ED0035800"
      },
      "mac_settings":{
         "supports_32_bit_f_cnt":true
      },
      "supports_class_c":false,
      "supports_class_b":false,
      "lorawan_phy_version":"1.0.3-a",
      "frequency_plan_id":"EU_863_870_TTN"
   },
   "field_mask":{
      "paths":[
         "multicast",
         "supports_join",
         "lorawan_version",
         "ids.device_id",
         "ids.dev_eui",
         "ids.join_eui",
         "mac_settings.supports_32_bit_f_cnt",
         "supports_class_c",
         "supports_class_b",
         "lorawan_phy_version",
         "frequency_plan_id"
      ]
   }
}

Following this I added the field_mask field to the POST data too, but that too gave the same error. (Note that this field_mask entry was also included for the other three registries too as observed in the developer console, but no error occured for those registries in my code without this field.)

I checked the lorawan-stack codebase and if I understood correctly, the set call for the network server is checking for the required fields “supports_join, lorawan_version, lorawan_phy_version, frequency_plan_id” and in case of an a missing field raises a errInvalidFieldMask error.

Adding field mask to the POST data worked finally. The data should be of the form,

{
  "end_device": {
    "frequency_plan_id": "EU_863_870_TTN",
    "supports_join": true,
    "lorawan_version": "1.0.3",
    "lorawan_phy_version": "1.0.3-a",
    "ids": {
      "device_id": "elsys-co2-043abc",
      "dev_eui": "A81758FFFE044BAB",
      "join_eui": "70B3D57ED00358FF"
    },
    "mac_settings": {
      "rx1_delay": {
        "value": 1
      },
      "supports_32_bit_f_cnt": true
    },
    "supports_class_c": false,
    "supports_class_b": false,
    "multicast": false
  },
   "field_mask":{
      "paths":[
         "multicast",
         "supports_join",
         "lorawan_version",
         "ids.device_id",
         "ids.dev_eui",
         "ids.join_eui",
         "mac_settings.supports_32_bit_f_cnt",
         "supports_class_c",
         "supports_class_b",
         "lorawan_phy_version",
         "frequency_plan_id"
      ]
   }
}

However, the other registries work fine without this field in the POST data.

1 Like