Skip to main content

Amazon Web Services

The example below connects to AWS IoT Core over MQTT — the standard transport for device-to-cloud messaging on AWS. You'll need an active network connection (see WiFi, Ethernet, or cellular via PPP) before the code runs.

NuGet package: GHIElectronics.TinyCLR.Networking.Mqtt.

AWS IoT Core authenticates devices with X.509 client certificates — not username/password — so MQTT username and password are both null in the connection settings.

What you'll need from AWS

Create these in the AWS IoT Core console before flashing:

  1. A policy that grants the device the IoT actions it needs (iot:Connect, iot:Publish, iot:Subscribe, iot:Receive). Scope the Resource to your thing ARN rather than "*" for production.
  2. A "Thing" — your device's registered identity. The thing name becomes your deviceId.
  3. A client certificate and private key generated for the thing. Download both — AWS shows them only once.
  4. The Amazon Root CA 1 certificate (RSA 2048). Download from Amazon Trust Services.
  5. Your account's endpoint{prefix}-ats.iot.{region}.amazonaws.com. Find it in the IoT Core console under Settings → Device data endpoint.

Embed all three certificates (Amazon Root CA, client certificate, private key) as resources in your TinyCLR project.

For a current console walkthrough, see Amazon's Getting Started with AWS IoT Core.

Example minimal policy (replace <your-region> and <your-account> and the thing ARN with real values):

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect",
"iot:Publish",
"iot:Subscribe",
"iot:Receive"
],
"Resource": [
"arn:aws:iot:<your-region>:<your-account>:client/MyDevice",
"arn:aws:iot:<your-region>:<your-account>:topic/$aws/things/MyDevice/shadow/*",
"arn:aws:iot:<your-region>:<your-account>:topicfilter/$aws/things/MyDevice/shadow/*"
]
}
]
}

Connecting and publishing a shadow update

using System.Diagnostics;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using GHIElectronics.TinyCLR.Networking.Mqtt;

// Replace with your account's endpoint, region, and device name.
var iotEndPoint = "a13gxtasnslh-ats.iot.us-west-2.amazonaws.com";
var iotPort = 8883;
var deviceId = "MyDevice";

// Device-shadow MQTT topics.
var topicShadowUpdate = "$aws/things/" + deviceId + "/shadow/update";
var topicShadowGet = "$aws/things/" + deviceId + "/shadow/get";

// JSON payload for a shadow update.
var message = "{\"state\":{\"desired\":{\"message\":\"Hello World\"}}}";

// Load the three certificates from project resources.
var caCertSource = Resources.GetBytes(Resources.BinaryResources.AmazonRootCA1);
var clientCertSource = Resources.GetBytes(Resources.BinaryResources.DeviceCertificate);
var privateKeyData = Resources.GetBytes(Resources.BinaryResources.DevicePrivateKey);

var caCert = new X509Certificate(caCertSource);
var clientCert = new X509Certificate(clientCertSource);
clientCert.PrivateKey = privateKeyData;

var clientSetting = new MqttClientSetting{
BrokerName = iotEndPoint,
BrokerPort = iotPort,
CaCertificate = caCert,
ClientCertificate = clientCert,
SslProtocol = SslProtocols.Tls12,
};

var iotClient = new Mqtt(clientSetting);

iotClient.PublishReceivedChanged += (sender, topic, data, duplicate, qos, retain) => {
Debug.WriteLine("Received on " + topic + ": " + Encoding.UTF8.GetString(data));
};

iotClient.SubscribedChanged += (sender, packetId, qos) => Debug.WriteLine("Subscribed");

Debug.WriteLine("Connecting...");

// AWS IoT uses X.509 client cert auth — leave username and password null.
var connectSetting = new MqttConnectionSetting{
ClientId = deviceId,
UserName = null,
Password = null,
};

var connectCode = iotClient.Connect(connectSetting);

if (connectCode != ConnectReturnCode.ConnectionAccepted){
Debug.WriteLine("Connect failed: " + connectCode);
return;
}

ushort packetId = 1;

// Subscribe to shadow get responses.
iotClient.Subscribe(new[] { topicShadowGet }, new[] { QoSLevel.AtLeastOnce }, packetId++);

// Publish a shadow update.
iotClient.Publish(topicShadowUpdate, Encoding.UTF8.GetBytes(message), QoSLevel.AtMostOnce, retain: false, packetId++);

Verify the connection in the AWS IoT console — under your thing, you'll see the connection status, and any shadow updates will appear on the Device Shadow tab.

Notes

  • Scope your policies"Resource": ["*"] gives any client connected with these credentials full IoT permissions on your account. For shipped products, scope Resource to specific thing/topic ARNs as shown in the policy example above.
  • -ats endpoint — always use the Amazon Trust Services (-ats) endpoint suffix. The older non--ats endpoint uses an outdated root CA chain.
  • Time sync — TLS validates certificate dates against the device clock. Make sure the clock is reasonably correct (within a few hours of real UTC) or the TLS handshake will fail.
  • Certificate rotation — AWS IoT supports rotating client certificates. Plan an OTA update path so you can refresh the device certificate before it expires (default validity is configurable but finite).

API reference

NamespaceDescription
GHIElectronics.TinyCLR.Networking.MqttMQTT client classes