Protocol Converter Nbiot
The protocol converter consumes NBIOT messages from ENCO, and sends them towards IOT hub
Overview
The protocol converter for NBIOT consists of:
- protocol-converter-nbiot, which consumes incoming messages, decodes their payload according to the correct decoder and forwards them to IoT Hub using the correct device credentials.
Message flow
message body example:
{
"payload": "08677870501818944500008000332e35392b31372e30",
"msisdn": "327700013187272",
"networkData": {
"ip": "10.32.0.7"
}
}
Messages will come in from ENCO via https endpoint secured by mutual TLS and ip whitelisting. Device will be identified via backoffice-backend (retrieval of device info and product). The device payload will be decoded according to the corresponing product.
The protocol converter will retrieve device details from IoT hub via the service API, based on the clientId of the device that sent the message. It will then act as that device and send the decoded payload to IoT Hub.
protocol-forwarder-nbiot
This application is very straightforward:
- It receives messages over HTTP using expressJS
- It retrieves device configuration from IoT Hub using
azure-iothub - It retrieves device information from backoffice-backend (identifier and product)
- It decodes the received nbiot payload accoring to the recieved product (thing-type)
- It sends the decoded messages to IoT Hub using
azure-iot-devicewith HTTP transport (azure-iot-device-http)
Decoding
Adding a decoder can be done by simply adding a new decode file to the folder src/decoding/decoders. Copy any decode file as a baseline and alter according to vendor specs. Make sure the decode file name is exacly the same as the decode type that will be defined on Product level!! This is an absolute requirement as the decode file will be accessed via this name.
Incomming payload:
080123018819550864431044995670047b02a36a0084ff8409000a6428460a6428460a6228460a6228460a6228460a6228460a6228460a6428460a6428460a6428460a6428460a6428460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6428460000000000000000000000000000000052e8
Output of the decoder:
DecodeRequest {
payload: '080123018819550864431044995670047b02a36a0084ff8409000a6428460a6428460a6228460a6228460a6228460a6228460a6228460a6428460a6428460a6428460a6428460a6428460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6428460000000000000000000000000000000052e8',
deviceInfo: {
id: '327700013187272',
deviceId: 'tekelek_nbiot-7536c8e4-2b7e-42f3-ac5b-6c10aa5d2e1e',
decodeType: 'TEKELEK_LPGTANKFILLLEVELNBIOTJG_V1'
},
containers: [
Container {
containerName: 'Product Type', postfix: '', value: 'TEK 822'
},
Container { containerName: 'ReBoot', postfix: '', value: '0' },
Container { containerName: 'Manual', postfix: '', value: '0' },
Container { containerName: 'Alarm', postfix: '', value: '0' },
Container { containerName: 'Scheduled', postfix: '', value: '1' },
Container { containerName: 'Active', postfix: '', value: '1' },
Container { containerName: 'Limit 3', postfix: '', value: '0' },
Container { containerName: 'Limit 2', postfix: '', value: '0' },
Container { containerName: 'Limit 1', postfix: '', value: '0' },
Container { containerName: 'CSQ', postfix: '', value: '25' },
.....
]
}
Live testing
execute command:
curl \
--location 'https://prod-16.northeurope.logic.azure.com:443/workflows/613600c507d1483391e293d5a0ac2acc/triggers/When_a_HTTP_request_is_received/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2FWhen_a_HTTP_request_is_received%2Frun&sv=1.0&sig=et9iZAB74f2Lg7nkOnpZ1l-tSL_-oBN9cb5ButLSo6g' \
--header 'Content-Type: application/json' \
--data \
'{"payload": "080123018819550864431044995670047b02a36a0084ff8409000a6428460a6428460a6228460a6228460a6228460a6228460a6228460a6428460a6428460a6428460a6428460a6428460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6628460a6428460000000000000000000000000000000052e8",
"identifier": "327700011056233", \
"environment" : "sbx", \
"token":"syukyks4654-s589sdfs6655-fggnio895soi"}'
This call will send a request to a logic app running in the SBX environment:
Resource-group: rg-gerdy-do-not-delete
logic app: SendTestMessageToIoTHub
This logic app has access to the protocol-converter-nbiot through ip white-listing configuered via pulumi.
https://portal.azure.com/#@ProximusCorp.onmicrosoft.com/resource/subscriptions/84f5ee7f-ee87-4518-bfa9-65a42b169881/resourceGroups/rg-gerdy-do-not-delete/providers/Microsoft.Logic/workflows/SendTestMessageToIoTHub/logicApp
Code:
```json
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"staticResults": {
"HTTP0": {
"status": "Succeeded"
}
},
"triggers": {
"When_a_HTTP_request_is_received": {
"type": "Request",
"kind": "Http",
"inputs": {
"method": "POST",
"schema": {
"type": "object",
"properties": {
"identifier": {
"type": "string"
},
"payload": {
"type": "string"
},
"token": {
"type": "string"
},
"environment": {
"type": "string"
}
}
}
}
}
},
"actions": {
"HTTP": {
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Http",
"inputs": {
"uri": "https://app-protocol-converter-nbiot-5d1d2a18.azurewebsites.net/nbiot/test",
"method": "POST",
"headers": {
"Authorization": "Bearer @{body('Parse_JSON')?['token']}"
},
"body": {
"msisdn": "@{body('Parse_JSON')?['identifier']}",
"payload": "@{body('Parse_JSON')?['payload']}"
}
},
"runtimeConfiguration": {
"contentTransfer": {
"transferMode": "Chunked"
},
"staticResult": {
"staticResultOptions": "Disabled",
"name": "HTTP0"
}
}
},
"Parse_JSON": {
"runAfter": {},
"type": "ParseJson",
"inputs": {
"content": "@triggerBody()",
"schema": {
"type": "object",
"properties": {
"identifier": {
"type": "string"
},
"payload": {
"type": "string"
},
"token": {
"type": "string"
},
"environment": {
"type": "string"
}
}
}
}
}
},
"outputs": {},
"parameters": {
"$connections": {
"type": "Object",
"defaultValue": {}
}
}
},
"parameters": {
"$connections": {
"value": {}
}
}
}
```