iot lab work shop
This project is maintained by DanielYEHsieh
In this lab, we will create a demo to provision personal user credential and Wi-Fi credential to device by android app once the device is powered at first time.
The solution architect would be separated into two part: (1) Get User Credential by Android app. (2) Android app provision the user credential to device.
(1) Get User Credential by Android app:
(2) Android app provision the user credential to device.
Here’s the tutorial for setting up AWS Service including AWS Cognito, AWS API Gateway, Lambda, Dynamo DB.
copy the following code to replace the code, lambda_function.py
import boto3
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
iot = boto3.client('iot')
dynamodb = boto3.client('dynamodb')
table = 'DSN'
# Create a policy
policyDocument = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:*",
"Resource": "*"
}
]
}
def delete_cert_and_policy(deviceId, principals):
for principal in principals:
certificateId = principal.split('/')[-1]
policies = iot.list_attached_policies(target=principal)
for policy in policies['policies']:
iot.detach_policy(
policyName=policy['policyName'], target=principal
)
iot.delete_policy(policyName=policy['policyName'])
iot.update_certificate(
certificateId=certificateId, newStatus='INACTIVE'
)
# iot.detach_thing_principal(
# thingName=deviceId,
# principal=principal
# )
# wait_for_detach_finish(deviceID, principal)
# iot.delete_certificate(
# certificateId=certificateId, forceDelete=True
# )
def lambda_handler(event, context):
logger.info("request: " + json.dumps(event));
# check device serial number is valid
deviceId = event['params']['querystring']['SN']
deviceItem = dynamodb.get_item(TableName=table, Key={'sn': {'S': deviceId}})
if not deviceItem.get('Item'):
return {
'statusCode': 403,
'body': {'msg': 'Invalid device serial number'}
}
# create thing
try:
iot.describe_thing(
thingName=deviceId
)
except iot.exceptions.ResourceNotFoundException:
response = iot.create_thing(
thingName=deviceId
)
# delete certificates which are attached to this thing
response = iot.list_thing_principals(
thingName=deviceId
)
if response['principals']:
delete_cert_and_policy(deviceId, response['principals'])
# generate keys and certificate
response = iot.create_keys_and_certificate(setAsActive=True)
certificateArn = response['certificateArn']
certificatePem = response['certificatePem']
privateKey = response['keyPair']['PrivateKey']
# attach certificate to thing
iot.attach_thing_principal(
thingName=deviceId,
principal=certificateArn
)
# create a policy for thing
policyName = 'Policy_' + deviceId
iot.create_policy(
policyName=policyName,
policyDocument=json.dumps(policyDocument)
)
# attach policy to certificate
iot.attach_policy(
policyName=policyName,
target=certificateArn
)
return {
'statusCode': 200,
'body': {
'certificatePem': certificatePem,
'privateKey': privateKey
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "IoTProvisionInputModel",
"type": "object",
"properties": {
"certificatePem": { "type": "string" },
"privateKey": { "type": "string" }
}
}
application/json
#set($inputRoot = $input.path('$'))
{
"params": {
"querystring": {
"SN": "$input.params('sn')"
}
}
}
application/json
#set($inputRoot = $input.path('$'))
{
"certificatePem" : $input.json('$.body.certificatePem'),
"privateKey" : $input.json('$.body.privateKey')
}
Log in the App.
Go to “cert Provision” page and use the UID (Device ID) to get the user credential from AWS Service (push the RE-GENKEY).
Use the following button to reset the device.
Then it will start Soft AP mode with previous Soft AP setting in Step 3, use android default app to connect to it.
Use the button “CONNECT TO PROVISION” to connect to Soft AP, it will start provisioning once it connect to the Soft AP.
There will be a pop-up a message to show the provision result.
Notice: There is a timeout in device soft AP started after android app connecting to it. If time’s up with no provision, then you need to push the reset button to restart the soft AP process. You can configure this timeout here:
Resetting the device to let it connect to designated WiFi SSID and send publish message to IoT Core. You can check MQTT log in AWS IoT Core.