Alibaba Cloud One TypeOneパスワード無料事前登録-シングルチップマイクロコンピューターC言語の実装
ワンタイプワンシークレット
1つのタイプと1つのパスワードを使用するには、次の2つの方法があります。
●1つのタイプと1つのパスワードの事前登録:
デバイスをインターネットに接続する前に、デバイスのDeviceNameをIoTプラットフォームに事前登録する必要があります。使用することをお勧めします。 DeviceNameとしてのデバイスのMACアドレス、IMEI、SNコードなど。IoTプラットフォームは、デバイスに対してDeviceSecretを発行します。
クラウド認証が成功すると、デバイスはデバイス証明書(ProductKey、DeviceName、およびDeviceSecret)を使用して、クラウドとの通信接続を確立します。
MQTTチャネルとHTTPチャネルを介したワンタイプワンキー事前登録認証をサポートします。
●ワンタイプワンシークレット事前登録不要:
IoTプラットフォームにデバイスDeviceNameを事前登録する必要がないため、IoTカード番号をDeviceNameとして使用すると便利です。
クラウド認証が成功すると、デバイスはProductKey、ProductSecret、ClientID、およびDeviceTokenを使用して、クラウドとの通信接続を確立します。
MQTTチャネルを介したワンタイプワンキー事前登録認証をサポートします。
ワンタイプワンシークレット免除事前登録
事前登録の免除に関するいくつかの重要なポイントは次のとおりです。
- TLSチャネルを確立しますが、TCPチャネルは機能しません。
- Pre-registration-freeはMQTTモードのみをサポートし、HTTPモードはサポートしません。
- 登録モードとMQTTは同じ一般的な接続方法ですが、接続要求に含まれる要素が異なります。
- instanceId、instance ID、Alibaba Cloudのマニュアルには、IoTプラットフォームコンソールのインスタンス管理ページに表示するように記載されています。実際、パブリックインスタンスのIDはないため、このパラメーターは必要ありません。パブリックインスタンスでこのパラメータを入力すると、接続時にエラー04が表示されます。これは、ユーザー名またはパスワードが正しくないように見えますが、実際にはこのパラメータが間違っています。
- 登録と接続が正常に完了すると、サーバーは自動的にパラメーターに応答します。
- 次に、アクティブに切断するか、15秒待って自動的に切断することができます。
コード
ここには、登録パラメータの初期化と接続、通常のパラメータ初期化接続、接続機能の3つの機能が掲載されています。
その中で、接続関数の固定ヘッダーは必ずしも2バイトである必要はありません。実際には、可変ヘッダー+ペイロードの長さに依存します。一部の自己コンパイル型接続関数の場合は、2バイトに固定されます。
//创建TLS通道,然后发起MQTT注册连接
void ali_register_connect(void)
{
char content[128] = {
0};
sprintf(content,"deviceName%sproductKey%srandom123",device_name,product_key);
char mqttPassword[64] = {
0};
utils_hmac_sha1((const char*)content,strlen((const char*)content),(char *)mqttPassword,product_secret,product_secret_len);
char mqttClientId[128] = {
0};
sprintf((char *)mqttClientId,"%s|securemode=-2,authType=regnwl,random=123,signmethod=hmacsha1|",device_name);
char mqttUserName[64]={
0};
sprintf((char *)mqttUserName,"%s&%s",device_name,product_key);
mqtt_connect((char *)mqttClientId,(char *)mqttUserName,(char *)mqttPassword);
//此处可延时,然后获取回复后进行解析
......
}
// 建立TCP连接,然后使用注册时返回的clientid和devicetoken,发起MQTT连接
int ali_normal_connect(void)
{
char clientID[64]={
0};
char deviceToken[64]={
0};
STMFLASH_Read(ALI_CLIENTID_ADDR,(uint16_t *)clientID,32);
STMFLASH_Read(ALI_DEVICETOKEN_ADDR,(uint16_t *)deviceToken,32);
strcat(clientID,"|securemode=-2,authType=connwl|");
char mqttUserName[64]={
0};
sprintf((char *)mqttUserName,"%s&%s",device_name,product_key);
mqtt_connect((char *)clientID,(char *)mqttUserName,(char *)deviceToken);
rt_thread_mdelay(100);
uint8_t buffer[10]={
0};
ring_buf_read(&g_uart_rx_buf,sizeof(buffer),buffer);
if(buffer[0]==0x20 && buffer[3]==0x00)
{
return SUCCESS;
}
return ERROR;
}
//连接函数,可以移植,也可以字节编写。以下是自编的。
void mqtt_connect(char *ClientId,char *Username,char *Password)
{
uint8_t buffer[256]={
0};
uint16_t num=0;
uint8_t Fixed_len = 2; //连接报文中,固定报头长度=2
uint8_t Variable_len = 10; //连接报文中,可变报头长度=10
uint16_t ClientId_len = strlen(ClientId);
uint16_t Username_len = strlen(Username);
uint16_t Password_len = strlen(Password);
uint16_t Payload_len = 2 + ClientId_len + 2 + Username_len + 2 + Password_len; //总报文长度
/************************** 报头 *************************/
buffer[num++]=0x10; //固定报头第1个字节:0x01
uint16_t length =Variable_len + Payload_len;
do
{
char d = length % 128;
length /= 128;
/* if there are more digits to encode, set the top bit of this digit */
if (length > 0)
d |= 0x80;
buffer[num++] = d; //固定报头 :可变报头+有效负荷的长度
} while (length > 0);
buffer[num++]=0x00; //可变报头 :固定0x00
buffer[num++]=0x04; //可变报头 :固定0x04
buffer[num++]='M'; //可变报头 :固定0x4D
buffer[num++]='Q';; //可变报头 :固定0x51
buffer[num++]='T'; //可变报头 :固定0x54
buffer[num++]='T'; //可变报头 :固定0x54
buffer[num++]=0x04; //可变报头 :固定0x04
buffer[num++]=0xC2; //可变报头 :使能用户名和密码校验,不使用遗嘱,不保留会话
buffer[num++]=0x00; //可变报头 :保活时间高字节 0x00
buffer[num++]=0x64; //可变报头 :保活时间高字节 0x64 100s
/************************** 有效载荷 Payload *************************/
/* CLIENT_ID */
buffer[num++] = ClientId_len/256; //客户端ID长度高字节
buffer[num++] = ClientId_len%256; //客户端ID长度低字节
memcpy(&buffer[num],ClientId,ClientId_len); //复制客户端ID字串
num = num + ClientId_len;
/* 用户名 */
buffer[num++] = Username_len/256; //用户名长度高字节
buffer[num++] = Username_len%256; //用户名长度低字节
memcpy(&buffer[num],Username,Username_len); //复制用户名字串
num = num + Username_len;
/* 密码 */
buffer[num++] = Password_len/256; //密码长度高字节
buffer[num++] = Password_len%256; //密码长度低字节
memcpy(&buffer[num],Password,Password_len); //复制密码字串
num = num + Password_len;
HAL_UART_Transmit(&huart1, buffer, num ,100);
}