Disable Auto-provisioning of Devices in Fiware MQTT JSON IoT Agent - fiware

We are using FIWARE Orion NGSI V2 version and MQTT JSON IoT Agent. We have attached the version of Context Broker and IoT Agent we are using below.
By default, whenever we send telemetry data through MQTT broker, for a device which does not exist in Fiware, the IoT Agent is automatically provisioning/creating the device in IoT Agent and corresponding entity in Context Broker.
We want to restrict this behavior and do not want the IoT Agent to auto-provision devices, but to only accept telemetry data for already registered devices.
We have already tried to set the IOTA_APPEND_MODE environment variable to false, also tried to set the autoprovision flag to false when creating the service group. None of these options are working and autoprovisioning is still happening.
Need your help and guidance on how do we disable the auto-provisioning IoT Agent.
IoT Agent version:
{"libVersion":"2.12.0-next","port":"4041","baseRoot":"/","version":"1.14.0-next"}
Context Broker Version:
{
"orion" : {
"version" : "2.3.0",
"uptime" : "12 d, 18 h, 50 m, 12 s",
"git_hash" : "764f44bff1e73f819d4e0ac52e878272c375d322",
"compile_time" : "Tue Nov 5 09:16:27 UTC 2019",
"compiled_by" : "root",
"compiled_in" : "cfe8becf7aae",
"release_date" : "Tue Nov 5 09:16:27 UTC 2019",
"doc" : "https://fiware-orion.rtfd.io/en/2.3.0/"
}
}

Have you tried to deactivate the autoprovision flag for a given iotagent device group?
https://github.com/telefonicaid/iotagent-node-lib/blob/f2e0305ca13a181140ee1fd1df8debb5a0838bee/doc/advanced-topics.md#autoprovision-configuration-autoprovision
Best

Version 1.18.0 seems it fix some issues related with autoprovision flag. As #fgalan mentioned, the version you are running is quite old, so probably you need to upgrade at least to 1.18.0. I really encourage you to upgrade since it is backward compatible.

Related

AASA - Apple App Site Association - Not working

I have been having a long and frustrating experience trying to get AASA to work for webcredentials. My goal here is to allow usernames and passwords to be stored in the iOS keychain.
I did have this working on a root domain the other week but it is not sufficient for my scenario as I will explain. It didn't work for me straight away I have to say but it eventually started working after a clean build so I thought this was the issue then but now I am not so sure.
I am using Expo with EAS build. We have a multi-tenant application. From a single codebase we deploy to multiple apps in the store. All are on the same team ID but they are separate applications and use separate credentials, nothing is shared.
I am confident my apps textContentType of username and password on my TextFields is correct as this has not changed from when I managed to get it working originally and I have checked it countless times.
Expectation
For the "Save Password" prompt to be displayed after login. What I have noticed however is when going to store a password manually using "add password" via iCloudKeychain from the keyboard accessory this does accurately show the correct "TENANT_SUBDOMAIN.example.com". I find this confusing.
Goal Scenario
I am hosting a site on Netlify. I have it setup to support wildcard subdomains with a LetsEncrypt provisioned wildcard SSL certificate. I then have edge functions which change the content of my index.html and apple-app-site-association file dynamically based on the requested subdomain.
I have added the Associated Domains capability to my provisioning profile.
I am using the latest Expo 47 and EAS build. I have added in the appropriate associated domains configuration and I can see this when introspecting my entitlements under com.apple.developer.associated-domains and it is correct.
I am using TestFlight for testing. I am doing a --clean-build on EAS every time and I also increase the runtime version. I have also tried manually refreshing credentials outside of the build process which does this automatically. This must be using the correct provisioning profile otherwise I would get a build failure as the requested entitlements wouldn't match.
The AASA file is currently hosted just in the .well-known directory. I have tried using the root and also tried using both. There are no redirects taking place.
I am aware the AASA file is pulled on application installation and update. I repeatedly remove the apps and then reboot my phone in an attempt to reset any device caches.
The content-type of the file is application/json and I have confirmed this using developer tools in the browser.
There is no robots.txt or anything blocking the request from an infrastructure perspective. There are no additional firewalls or geo restricted access as I am just using plain Netlify to host this, nothing fancy.
I am confident the Team ID and bundle IDs are correct in the AASA file.
I remove the content-length header in the Edge function so it is correctly calculated by the network instead and I have confirmed this using curl.
When I check the file using https://app-site-association.cdn-apple.com/a/v1/site.example.com Apple has the correct file cached on it's CDN so I would expect it to work.
I added in an applinks section so I could use the Apple App Search API validation tool and the Branch.io AASA verification tool to verify correctness. Branch.io says the file is fine and Apple says it's fine also but because the App has not been deployed to the store yet I see Error no apps with domain entitlements. From what I can tell this is normal in development and makes sense as it uses the current released version of the app to verify the deep link configuration. So to me this means Apple can parse the file correctly.
When I stream my device console logs; on install I can see the AASA requesting the correct domains. I see no errors on swcd I just see the Beginning data task AASA-XXXX with the correct domains.
When I run Charles proxy on my phone with a verified SSL installation (also reinstalled a few times now) I do not see quite what I would expect - but the device logs seem to imply it is doing the correct thing. When I view the app-site-association... URL requests in Charles there is one per application install which is correct. The request is marked as Unknown and when I look at the request the host is shown but as you would expect from SSL I see no path. The info says METHOD: CONNECT with Error - Input Error: EOF. This is the only error I see, I am not sure if it is a red herring and something to do with Charles. Given the error as you expect there is no body in the request or response. It is worth noting in general testing I have no VPN enabled and I have do not have Private Relay enabled in my iOS settings.
When I perform a sysdiagnose I see the following at the timestamp in my console log in the swcutil_show.txt device log. This looks correct in comparison to other apps webcredentials and applinks services I see there and I see no errors:
Service: webcredentials
App ID: MYTEAMID.com.cf.example.b2c.ios
App Version: 1.0
App PI: <LSPersistentIdentifier 0x141816200> { v = 0, t = 0x8, u = 0x1e7c, db = 0094F7C4-3078-41A2-A33E-79D5A62C80A6, {length = 8, bytes = 0x7c1e000000000000} }
Domain: CORRECT_SUBDOMAIN.example.app
User Approval: unspecified
Site/Fmwk Approval: approved
Flags:
Last Checked: 2022-12-09 14:14:32 +0000
Next Check: 2022-12-14 14:03:00 +0000
Service: applinks
App ID: MYTEAMID.com.cf.example.b2c.ios
App Version: 1.0
App PI: <LSPersistentIdentifier 0x13fd38d00> { v = 0, t = 0x8, u = 0x219c, db = 0094F7C4-3078-41A2-A33E-79D5A62C80A6, {length = 8, bytes = 0x9c21000000000000} }
Domain: CORRECT_SUBDOMAIN.example.app
Patterns: {"/":"*"}
User Approval: unspecified
Site/Fmwk Approval: approved
Flags:
Last Checked: 2022-12-13 13:13:23 +0000
Next Check: 2022-12-18 13:01:51 + 0000
At end of file:
MYTEAMID.com.cf.example.b2c.ios: 8 bytes
(This seems correct for all apps)
Other Scenario
I have tried setting this up using an apex on another domain which hasn't been seen before by Apple. I have tried using a subdomain with a root domain serving the same content and I have tried the subdomain and root domain on their own. I have also tried not using the Edge functions and having static files but to no avail.
When I do this I ensure I wait for the Apple CDN to catch up and remove/add entries prior to deleting the apps, rebooting my device, and reinstalling to test.
AASA File
AASA content comes back with the correct payload and Content-Type: application/json and Content-Length headers, both from Apples CDN and the origin. When I had this somehow working in my initial test it was on a root domain and I did not have an applinks section, this was only added so I could use the verification tools for universal links.
I am not sending back different content or duplicated content and I block the www subdomain - I have also tried it with a www subdomain for the record.
{
"applinks": {
"details": [
{
"appIDs": [
"MYTEAMID.com.cf.example.b2c.ios"
],
"components": [
{
"#": "no_universal_links",
"exclude": true,
"comment": "Matches any URL with a fragment that equals no_universal_links and instructs the system not to open it as a universal link."
}
]
}
]
},
"webcredentials": {
"apps": [
"MYTEAMID.com.cf.example.b2c.ios"
]
}
}
I have also tried this with the older format:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "MYTEAMID.com.cf.example.b2c.ios",
"paths": [
"*"
]
}
]
},
"webcredentials": {
"apps": [
"MYTEAMID.com.cf.example.b2c.ios"
]
}
}
associatedDomains iOS. expo config
associatedDomains: [
`webcredentials:${SUBDOMAIN}.example.app`,
`applinks:${SUBDOMAIN}.example.app`,
],
Help :)
I have been trying to get this to work for a long time now and I am completely out of ideas. If anybody has any suggestions I would really appreciate it. I am very confused how the devices request seems correct and the CDN content is correct but it is still not working. It's worth also reiterating that I need to have different subdomains for each tenant as the credentials must not be shared across apps so the keychain->domain association store must be different.
I am wondering if it's the LetsEncrypt wildcard SSL certificate but I wouldn't expect it to verify and for Apple to cache the file if this was the case. It seems very unlikely to me but it is the only thing I haven't tried at this point.
Many Thanks,
Mark

IoT-AgentUL how to get data

Currently I've got my own LoRaWAN network, with around 45 devices sending data with this payload: ID=D0001&T=23&H=60 where ID is the sensorId; T-Temperature; H - Humidity.
What steps do I have to make next to get context from my devices?
These are the steps that I've made:
1 - Installed IoT-Agent Ultralight
2 - Configured MQTT on the config.js file with my MQTT data
config.mqtt = {
host: 'HOST_NAME',
port: 1883,
protocol : mqtt,
username: 'USERNAME',
password: 'PASSWORD',
retain: false,
retries: 5,
retryTime: 5,
keepalive: 0,
avoidLeadingSlash: false
};
3 - IoTAgent-ul (node bin/iot-agentul), getting this message: time=2020-12-01T10:44:48.197Z | lvl=INFO | corr=526cdc56-62b8-4791-b95d-f5110ca18b7e | trans=526cdc56-62b8-4791-b95d-f5110ca18b7e | op=IOTAUL.MQTT.Binding | from=n/a | srv=n/a | subsrv=n/a | msg=connected | comp=IoTAgent
It is unclear whether you need the IoT Agent for Ultralight or the IoT Agent for LoRaWAN. Ultralight is a payload syntax, the Ultralight IoT Agent supports HTTP, MQTT and AMPQ transports. LoRaWAN is a transport, it supports a couple of COAP protocols.
If you are really sending LoRa COAP messages then you'll need the LoRaWAN agent.
If you are using Ultralight over MQTT, then your message payload should look like this
ID|D0001|T|23|H|60
An Ultralight over MQTT Tutorial exists within the Step-by-Step Guide.
If you are using COAP over LoRaWAN, then your message payload would be a stream of base64 bytes coming from the LoRa gateway. The Things network tutorial describes the set-up.
If your payload literally is: ID=D0001&T=23&H=60, you're going to need to create your own parser like the Custom IoT Agent Tutorial and follow the steps in altering the IoT Agent codebase.
Specifically, the flow of control with the HTTPBindings parseData() function. The ulParser would need to be re-written to accept your alternate syntax. It looks similar enough that all you'd need to do is:
if (payload) {
data = ulParser.parse(payload.replace(/&/g, "|").replace(/=/g, "|"));
}
(Even better if that could be done prior to sending to the Ultralight IoT Agent)
The advantage of re-using an existing IoT Agent (or writing a new one using the IoT Agent Node lib) is that functions such as the creation of entities and mapping of attributes is achieved using the existing code.

Can IoT device with different protocols use IoT Agents to "talk" with each other?

I'm playing around with FIWARE Orion, IoT Agent JSON, and IoT Agent OPC UA. I'm wondering that since all the IoT Agents connect with Orion and map different IoT protocols into NGSI, is it possible for devices using different protocols to communicate with each other without adding any additional application logic?
Let's consider a MQTT device A and an OPC UA server B, For example, is it possible for:
B reports its measurements to the Orion Context Broker, A subscribe to that attribute. Some thing like
B-->IoT Agent OPC UA-->Orion-->IoT Agent JSON-->mosquitto-->A
(I tried to make a context provider registration. However, the url of the B entity attributes(orion:1026/v2/B/attrs/XXX) obviously doesn't work since Orion will send POST to an orion:1026/v2/B/attrs/XXX/op/query which doesn't exist), and the provided attribute is not provisioned at IoT Agent JSON...I feel like I'm taking the totally wrong direction)
A and B access the same entity and report their measurements to that entity in the Orion. Since A and B both need their own IoT Agents, and the same entity can not be provisioned at each agent due to duplicated...
Is it a super bad idea that trying to mess up one entity with several protocols' devices...Thank you so much for answering my doubts in advance!!!
Each NGSI entity should map to something that has state in the real world. In your case your data models should be based on Device and you should have a separate OPC-UA-based Device entity and a second separate JSON Device entity. These are the low level entities within your system, which would hold readings from the IoT Devices and would also hold additional data (such as battery-level or a link to the documentation or whatever).
If you want to model the state of a second aggregated entity then you can do that as well - just subscribe to changes in context in the device and Upsert the values and metadata over to the other entity.
curl --location --request POST 'http://localhost:1027/v2/subscriptions/' \
--header 'Content-Type: application/json' \
--header 'fiware-service: openiot' \
--data-raw '{
"description": "Notify Subscription Listener of Lamp context changes",
"subject": {
"entities": [
{
"idPattern": "Lamp.*"
}
],
"condition": {
"attrs": ["luminosity"]
}
},
"notification": {
"http": {
"url": "http://tutorial:3000/device/subscription/luminosity"
},
"attrs": ["luminosity", "controlledAsset", "supportedUnits"]
},
"throttling": 5
}'
Sample code to do the work from the listening endpoint ( /device/subscription/luminosity ) can be found here - it is a tutorial which is still a work-in-progress, so the full documentation is currently missing.
function shadowDeviceMeasures(req, res) {
const attrib = req.params.attrib;
async function copyAttributeData(device, index) {
await upsertDeviceEntityAsLD(device);
if (device[attrib]) {
await upsertLinkedAttributeDataAsLD(device, 'controlledAsset', attrib);
}
}
req.body.data.forEach(copyAttributeData);
res.status(204).send();
}
The point here is that you can (and should) think of data entities at different levels -
I have a thermometer Device - it is sending temperature readings. It has a temperature attribute
I have a Building - it has a thermometer in it - the Building has a temperature attribute and metadata.providedBy linking back to the Device
Depending on your use case you may only need to consider entities at one layer or you may need to use both.

Modify device - IoTAgentUL

I need to modify a registered device in IoTAgent UltraLight. With modify I mean add some attributes and delete others.
I also want to update the entity in Orion CB.
Is it possible to do that? How can I do that?
IoTAs (and the IoTA library in general), expose a north provisioning interface for device creation. The core idea is when you provision a device in the IoTA (directly, or through the IoTA Manager), an entity is automatically created in Context Broker. Such nothr provisioning interface allows for retrieval, removal and update, too.
Being said that, the south interface of the IoTAs is designed to only accept measures and command execution results from the devices. Thus, if a new attribute comes into play, and you provide values for that new attribute via an IoTA, a new attribute will not be appended at Context Broker; simply, this information will be droped.
In order to accept data regarding new attributes, first you'll have to use the above mentioned provisioning interface of the IoTAs, in particular the update device operation, in order to provision such new attribute; that will automatically append a new attribute to the entity at Context Broker level. From here on, values for the new attribute sent to the IoTA will be updated in Context Broker.
Such an update request looks like:
PUT http://iota_host:iota_port/iot/devices/<dev_id>?protocol=<protocol_type>
Fiware-Service: <service>
Fiware-ServicePath: <subservice>
{
"entity_type": <entity_type>,
"attributes": [ <new_active_attrs_if_any> ],
"lazy": [ <new_lazy_attrs_if_any> ],
"commands": [ <new_commands_if_any> ],
"statis_attributes": [ <new_static_attrs_if_any> ]
}
Sadly, already existent attributes cannot be removed, for the time being.

Orion Context Broker v2 subscription issue

We're trying to implement subscriptions with Orion Context Broker v2, but when we create a new subscription it's returning a '405 Method Not Allowed' response.
We're following the documentation (http://telefonicaid.github.io/fiware-orion/api/v2/), I've attached an image with the request sent with Postman:
Postman subscription request
The Orion Context Broker version we are using is:
{
"orion": {
"version": "0.25.0",
"uptime": "16 d, 23 h, 49 m, 31 s",
"git_hash": "a8cf800d4e9fdd7b4293a886490c40309a5bb58c",
"compile_time": "Mon Nov 2 09:13:05 CET 2015",
"compiled_by": "fermin",
"compiled_in": "centollo"
}
}
Are we doing something bad related with the request?
Thanks in advance.
NGSIv2 operations to create/update/delete subscriptions have not been yet implememented in Orion 0.26.1 (the last version at the moment of writting this). The NGSIv2 operations related with subscriptions available in that version are:
GET /v2/subscriptions, to get all subscriptions
GET /v2/subscripstions/<id>, to get a given subscription (by id).
Note that NGSIv2 is yet in beta status, so sometimes the specification goes ahead of Orion implementation. Please, have a look to the following table in order to know the current implementation status of the different operations described at the NGSIv2 draft specification. This table is updated in a monthly basics.
EDIT: NGSIv2 operations to create/update/delete subscription are available from Orion 0.27.0.