Luup Secure Plugins
Overview
MiOS has a secure way of provisioning plugins, which will generally be done for non-free applications. This mechanism can be used equally well for paid-for external apps that communicate with Vera, like a cell phone control, by creating an associated plugin for the app, even if the plugin doesn't do anything. The process of creating the plugin is no different than normal.
A provisioned plugin contains 3 fields of data: 'from' and 'to' which are date/time's, and 'limits' which is a free form text field that can be used by the plugin or external app to determine what functionality can be provided. These 3 fields exist both for the plugin itself, and for devices that use the plugin. When registering your app with MiOS you specify what the default values are if a user first installs your plugin without paying for anything. For example, consider that you have a plugin that monitors traffic conditions and costs $3/year to monitor local traffic and $6/year to monitor nation traffic and each homeowner has a 14 day free trial of the plugin, and that the limit code for the trial period is "trial" and for the $3 app is "local" and for the $6 app is "national" or $20 for national lifetime. You would specify with your MiOS Market representative that the default time period is 14 days and the default limit code is "trial". When the user installs the app, the plugin will have provision data where 'from' is the date he installed the plugin, 'to' is 14 days later, and 'limit' is "trial". When the customer pays the $3 or $6 the 'to' field will change to 1 year and the 'limit' will change also, when he pays $20, the 'to' field will become empty.
Some plugins create devices which may require provisioning of each device in addition to or instead of the provisioning for the main plugin. For example, a cell phone app may have a price of $10 for the first cell phone and $2 for each additional one. In this case, unlike the traffic example which only created a plugin entry, a device entry will be created for each phone and provision from/to/limit fields will exist for each phone as well as each device. Again, there could be a free trial period which uses the 'limit' code, and the first phone could use the 'included' code, and the subsequent phones could have 'extra' limit code. The limit codes are entirely free-form and it's up to you to decide what they mean.
The provisioning process itself is done by automated systems, contact MiOS to setup an account for payment and establish the terms of provisioning.
To retrieve the provisioning status of your plugin request the provisioning info as an lu request, like: http://ip:3480/data_request?id=lu_provision&PluginNum=x&DeviceNum=y. Note DeviceNum is optional, and whether specified or not, you'll receive in json format the all the provisioning info for the plugin and any associated devices. If DeviceNum is specified the encryption key for the device will be used to encrypt the return value, rather than using the key for the plugin itself. Encryption is optional (see section below). The format of lu_provision is:
{ "AllowMultiple": 1, "Title": "Test Secure Plugin", "timestamp": 1270155180, "Provision": { "from": 1270155180, "to": 1272697200, "limits": "trial", "Devices": [ { "from": 1272697200, "to": 1272783600, "limits": "trial", "device_num": "2", "altid": "2135551212" }, { "limits": "", "device_num": "8", "altid": "3105001000" } ] }, "Version": "0.50", "id": 144, }
Note this means the plugin itself has a provision from 1270155180 to 1272697200 (unix timestamp) with limit "trial", and the 2 devices which are associated with the plugin have their own provision data.
Step by step process of provisioning an external app like a mobile phone
Plugins which are done in Luup are automatically handled by the MIOS engine and the user interface. Here is a step-by-step example showing how you might handle setup of a mobile phone app. This is just a sample showing one possible implementation.
1a. Assuming your software is running on the phone but knows nothing about the MIOS engine that it will connect to, and is connected to the same network as the MIOS engine (probably wi-fi) call http://xxx to get a list of the MIOS engines on the same local network as the phone.
or 1b. If the phone is not on the same network or 1a doesn't return any matches, ask the user for his myMiOS username and get a list of associated MiOS engines by calling http://xxx
2a. Assuming that your going to track individual phones, you'll want to create a device for this phone. So you'll need to come up with a unique ID for the phone. It can be whatever the phone provides, such as a mac address, phone number, etc., or, if the phone doesn't provide anything, generate a unique id on your own, perhaps a timestamp, which you should try to install in some persistent memory on the phone so that if your app is uninstalled and reinstalled it will retain the same ID and not get provisioned twice. The id must have normal characters only: A-Z a-z 0-9 space - _ : and to ensure it does not conflict with the ID of another developer's device, preface it with some unique characters for your app, like: ACME_PHONE_CO_2135551212. Then, to create the device, call: http://ip:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=CreateDevice&deviceType=anytype&internalID=ACME_PHONE_CO_2135551212&Description=phoneapp&PluginNum=144&Reload=1&NoDupId=1&AesKey=abc123. Note the deviceType is a UPnP device type, and you can simply make one up for your device however you should use the standard upnp naming convention for clarity, like: urn:schemas-acmephone-com:device:AndroidApp:1. The PluginNum is the id of the plugin which you created in the MiOS market, Reload=1 means the MiOS engine will reload after creating the device so it gets initialized, NoDup=1 means that if there's already a device with the ID ACME_PHONE_CO_2135551212 then CreateDevice will return the existing device id rather than create a new one. AesKey can be a Aes128 or Aes256 key which you generate at random and that you want the MiOS engine to use to encrypt communication with you to prevent man in the middle hacks to fake provisioning. If submitting an AesKey, you should use https:// to send this to the MiOS engine, which will store it in an encrypted state. There is no way to retrieve the AesKey again however you can change it by calling CreateDevice again with the same internalID, NoDup=1 and a new key. See the section on security below. This request will return the device id of the newly created device. When the MiOS engine reloads it will download the plugin information and the provision data, like this: http://findvera.com/get_plugin_json2.php?plugin=6&ap=60431 (ap is the serial number). This will have the default provisioning for now. An icon will appear in the toolbox that allows the user to purchase and configure the plugin. You can also make the request using the myMiOS server.
2b. If you did not want to get a device id for the phone, and just want to provision the plugin for this MiOS engine, meaning only the plugin is provisioned and you won't be tracking devices, then just use CreatePlugin instead of CreateDevice: http://ip:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=CreatePlugin&PluginNum=144&AesKey=abc123.
3. Wait until the engine finishing reloading and downloading the plugin and then retrieve the provision data with lu_provision. user_data will contain the timestamp for the plugin which will show when the plugin data last changed so you know when to retrieve lu_provision again if the plugin provisioning has changed.
Security
To prevent users from circumventing the provisioning process the MiOS engine retrieves the plugin data using https and verifies the public key of the mios server. Additionally your app can supply an AesKey which means that lu_provision will always return the provision data encrypted with your key to provide you assurance you're talking to the real MiOS engine. You can pass the AesKey through the mios server to ensure it's properly encrypted and can't be intercepted.