赞
踩
阿里云:一机一密、一型一密、CA证书、证书获取、证书烧录
公钥、私钥、数字签名和数字证书的概念及解密(数字证书:CA用自己的私钥,对需要认证的公钥及相关的信息进行加密) (CA也有自己的公钥和私钥,CA的公钥就是默认放在操作系统或浏览器中)SSL数字证书(一)CA、根证书与数字证书:根证书是CA认证中心给自己颁发的证书,是信任链的起始点
公钥、私钥、证书、加密、解密、加签(数字签名)、验签
公钥、私钥、hash、数字签名、CA以及验证过程:证书的格式一般为X.509或者Base64编码
s3预签名url(presign)
AWS IOT Device C SDK交叉编译(嵌入式linux)
亚马逊云物联网AWS IoT初体验( MQTT.fx的配置)
AWS Client端SDK授权方案(Amazon Cognito 身份池、token及IdentityId)
重点关注main函数里4个重要API函数:
1、jsonStruct_t
2、aws_iot_shadow_register_delta
3、aws_iot_shadow_get
4、aws_iot_shadow_update
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <unistd.h> #include <string.h> #include <limits.h> #include <cJSON.h> #include "aws_iot_config.h" #include "aws_iot_log.h" #include "aws_iot_version.h" #include "aws_iot_mqtt_client_interface.h" #include "aws_iot_shadow_interface.h" #define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 400 static char certDirectory[PATH_MAX + 1] = "./certs"; #define HOST_ADDRESS_SIZE 255 static char HostAddress[HOST_ADDRESS_SIZE] = AWS_IOT_MQTT_HOST; static uint32_t port = AWS_IOT_MQTT_PORT; static uint8_t numPubs = 5; typedef struct cameras{ int power; int stream; }cameraState; cameraState camera; //照相机的物模型 int reporetedFlag = 0; void ShadowUpdateStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, const char *pReceivedJsonDocument, void *pContextData) { //device 发起update请求,收到server accpected消息时会触发这个回调,用于判断update状态是否成功 if(SHADOW_ACK_TIMEOUT == status) { IOT_INFO("Update Timeout--"); } else if(SHADOW_ACK_REJECTED == status) { IOT_INFO("Update RejectedXX"); } else if(SHADOW_ACK_ACCEPTED == status) { IOT_INFO("Update Accepted !!"); } } //***************CJSON*********************// parseCMDJSON create_monitor_with_helpers用于解析或构造state内容 int parseCMDJSON(const char * const monitor){//使用CJSON解析get shadow返回的消息 const cJSON *state = NULL; const cJSON *desired = NULL; const cJSON *reported = NULL; const cJSON *power = NULL; const cJSON *stream = NULL; int status = 0; cJSON *monitor_json = cJSON_Parse(monitor);//它将解析JSON并分配cJSON表示它的项目树。 if (monitor_json == NULL) { const char *error_ptr = cJSON_GetErrorPtr(); if (error_ptr != NULL) { fprintf(stderr, "Error before: %s\n", error_ptr); } status = 0; goto end; } state = cJSON_GetObjectItemCaseSensitive(monitor_json, "state"); //得到state内容 if (cJSON_IsString(state) && (state->valuestring != NULL)) { printf("Checking monitor \"%s\"\n", state->valuestring); } desired = cJSON_GetObjectItemCaseSensitive(state, "desired"); //从stated尝试解析desired reported = cJSON_GetObjectItemCaseSensitive(state, "reported"); //从stated尝试解析reported if(!cJSON_IsNull(reported))//如果reported不为空 { power = cJSON_GetObjectItemCaseSensitive(reported, "power"); stream = cJSON_GetObjectItemCaseSensitive(reported, "stream"); if (cJSON_IsNumber(power)){ camera.power = power->valueint; //使用云上状态同步本地状态 IOT_INFO("reported power:%d", camera.power ); } if (cJSON_IsNumber(stream)){ camera.stream = stream->valueint; //使用云上状态同步本地状态 IOT_INFO("reported stream:%d", camera.stream); } status = 1; } if (!cJSON_IsNull(desired))//如果desired不为空,所以应该用desired状态同步本状态。上面reported同步的状态将被覆盖 { power = cJSON_GetObjectItemCaseSensitive(desired, "power"); stream = cJSON_GetObjectItemCaseSensitive(desired, "stream"); if (cJSON_IsNumber(power)){ camera.power = power->valueint; IOT_INFO("desired power:%d", camera.power ); } if (cJSON_IsNumber(stream)){ camera.stream = stream->valueint; IOT_INFO("desired stream:%d", camera.stream); } reporetedFlag = 1;//更新状态 status = 1; } end: cJSON_Delete(monitor_json); return status; } char *create_monitor_with_helpers(void)//构造reported update 的state内容 { char *string = NULL; cJSON *monitor = cJSON_CreateObject(); cJSON *state = cJSON_CreateObject(); cJSON *reporteds = cJSON_CreateObject(); cJSON *desired = cJSON_CreateObject(); cJSON *reported = cJSON_CreateObject(); if (cJSON_AddNumberToObject(reported, "power", camera.power) == NULL) //构造power属性到reported中 goto end; if (cJSON_AddNumberToObject(reported, "stream", camera.stream) == NULL) //构造stream属性到reported中 goto end; cJSON_AddItemToObject(state, "reported", reported); cJSON_AddItemToObject(state, "desired", desired); //将reported和desired添加到state cJSON_AddItemToObject(monitor, "state", state); //将state添加到返回的主json中 char tempClientTokenBuffer[MAX_SIZE_CLIENT_TOKEN_CLIENT_SEQUENCE]; if(aws_iot_fill_with_client_token(tempClientTokenBuffer, MAX_SIZE_CLIENT_TOKEN_CLIENT_SEQUENCE) != SUCCESS){ return false; } cJSON_AddStringToObject(monitor, "clientToken", tempClientTokenBuffer);//将clientToken标识添加到主JSON中 string = cJSON_PrintUnformatted(monitor);//生成JSON PrintUnformatted函数为不格式化生成,生成一个紧凑的json字串 if (string == NULL) { fprintf(stderr, "Failed to print monitor.\n"); } end: cJSON_Delete(monitor); return string; } // get shadow API的回调 当得到server返回时会触发这个函数 //收到的回复的名称 操作的反应 通知操作是接受/拒绝/超时 static void ShadowGetStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, const char *pReceivedJsonDocument, void *pContextData) { //收到json文档 动作调用期间传入的void *数据(更新,获取或删除) IOT_INFO("get shadow json:\n%s",pReceivedJsonDocument); parseCMDJSON(pReceivedJsonDocument);//解析出reported desired if(SHADOW_ACK_TIMEOUT == status) { IOT_INFO("get Timeout--"); } else if(SHADOW_ACK_REJECTED == status) { IOT_INFO("get RejectedXX"); } else if(SHADOW_ACK_ACCEPTED == status) { IOT_INFO("get Accepted !!"); } } //************************************************************************// //当收到delta消息中<disired>中含有该属性时 会触发该回调函数 //json数据内容 json数据长度 void power_Callback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext) { char res[10]; strncpy(res, pJsonString, JsonStringDataLen); camera.power = atoi(res);//得到delta消息中power的值 if(camera.power == 1){ IOT_INFO("power on"); } else{ IOT_INFO("power off"); } reporetedFlag = 1; } //当收到delta消息中<disired>中含有该属性时 会触发该回到函数 void stream_Callback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext) { char res[10]; strncpy(res, pJsonString, JsonStringDataLen); camera.stream = atoi(res);//得到delta消息中stream的值 if(camera.stream == 0){ IOT_INFO("stream off"); } else{ IOT_INFO("stream open"); } reporetedFlag = 1; } //************************************************************************// void iot_reporte(AWS_IoT_Client *mqttClient, jsonStruct_t JsonHander[2]){ IoT_Error_t rc = FAILURE; char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER]; size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]); char test[300]; strcpy(test, create_monitor_with_helpers()); IOT_INFO("Update Shadow: %s", test); rc = aws_iot_shadow_update(mqttClient, AWS_IOT_MY_THING_NAME, test,ShadowUpdateStatusCallback, NULL, 10, true);//数字为超时时间 调用aws_iot_shadow_update } int main(int argc, char **argv) { IoT_Error_t rc = FAILURE; int32_t i = 0; char *pJsonStringToUpdate; jsonStruct_t powerHandler; //1、jsonStruct_t state中某个属性 有4个成员 powerHandler.cb = power_Callback; //当接受delta消息有该参数时触发的回调函数地址 powerHandler.pKey = "power"; //属性名称 powerHandler.pData = &(camera.power); //属性值地址 powerHandler.dataLength = sizeof(int);//属性大小 powerHandler.type = SHADOW_JSON_INT32;//属性类型 jsonStruct_t streamHandler; //1、jsonStruct_t state中某个属性 有4个成员 streamHandler.cb = stream_Callback; streamHandler.pKey = "stream"; streamHandler.pData = &(camera.stream); streamHandler.dataLength = sizeof(int); streamHandler.type = SHADOW_JSON_INT32; jsonStruct_t HandlerArray[2] = {powerHandler, streamHandler}; //******************完成client为接入 iot server 不用更改*************// char rootCA[PATH_MAX + 1]; char clientCRT[PATH_MAX + 1]; char clientKey[PATH_MAX + 1]; char CurrentWD[PATH_MAX + 1]; IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); getcwd(CurrentWD, sizeof(CurrentWD)); snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME); snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME); snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME); AWS_IoT_Client mqttClient; ShadowInitParameters_t sp = ShadowInitParametersDefault; sp.pHost = AWS_IOT_MQTT_HOST; sp.port = AWS_IOT_MQTT_PORT; sp.pClientCRT = clientCRT; sp.pClientKey = clientKey; sp.pRootCA = rootCA; sp.enableAutoReconnect = false; sp.disconnectHandler = NULL; IOT_INFO("Shadow Init"); rc = aws_iot_shadow_init(&mqttClient, &sp); if(SUCCESS != rc) { IOT_ERROR("Shadow Connection Error"); return rc; } ShadowConnectParameters_t scp = ShadowConnectParametersDefault; scp.pMyThingName = AWS_IOT_MY_THING_NAME; scp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID; scp.mqttClientIdLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID); IOT_INFO("Shadow Connect"); rc = aws_iot_shadow_connect(&mqttClient, &scp); if(SUCCESS != rc) { IOT_ERROR("Shadow Connection Error"); return rc; } rc = aws_iot_shadow_set_autoreconnect_status(&mqttClient, true); if(SUCCESS != rc) { IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); return rc; } //*******************************// rc = aws_iot_shadow_register_delta(&mqttClient, &streamHandler); //2、aws_iot_shadow_register_delta(收到增量消息触发1中回调函数) rc = aws_iot_shadow_register_delta(&mqttClient, &powerHandler); if(SUCCESS != rc) { IOT_ERROR("Shadow Register Delta Error"); } else{ IOT_INFO("Shadow Register Success"); camera.power = 1; camera.stream = 0; 数字为超时时间 aws_iot_shadow_get(&mqttClient, AWS_IOT_MY_THING_NAME, ShadowGetStatusCallback, NULL, 2, true); //3、aws_iot_shadow_get(一般启动时获取设备配置) // while(updateFlag==0){ // shadow_get的结果将在callback中传递给程序 // sleep(1); // } // iot_reporte(&mqttClient, HandlerArray); //4、aws_iot_shadow_update // 上线自检 更新状态 } while(NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) { rc = aws_iot_shadow_yield(&mqttClient, 200);//此函数可以在单独的线程中使用,等待传入消息,确保使用AWS服务保持连接。它还确保清除Shadow操作的过期请求并执行Timeout回调。 if(NETWORK_ATTEMPTING_RECONNECT == rc) { continue; } if(reporetedFlag == 1){ //检测状态改变标志位 进行reported当前状态 IOT_INFO("stream and power handle function"); iot_reporte(&mqttClient, HandlerArray); //4、aws_iot_shadow_update(向云端更新设备影子,只更新不跟踪) reporetedFlag = 0; } sleep(1); } if(SUCCESS != rc) { IOT_ERROR("An error occurred in the loop %d", rc); } IOT_INFO("Disconnecting"); rc = aws_iot_shadow_disconnect(&mqttClient); if(SUCCESS != rc) { IOT_ERROR("Disconnect error %d", rc); } return rc; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。