コード例 #1
0
void parseInputArgsForConnectParams(int argc, char** argv) {
	int opt;

	while (-1 != (opt = getopt(argc, argv, "h:p:c:"))) {
		switch (opt) {
		case 'h':
			strcpy(HostAddress, optarg);
			IOT_DEBUG("Host %s", optarg);
			break;
		case 'p':
			port = atoi(optarg);
			IOT_DEBUG("arg %s", optarg);
			break;
		case 'c':
			strcpy(certDirectory, optarg);
			IOT_DEBUG("cert root directory %s", optarg);
			break;
		case '?':
			if (optopt == 'c') {
				IOT_ERROR("Option -%c requires an argument.", optopt);
			} else if (isprint(optopt)) {
				IOT_WARN("Unknown option `-%c'.", optopt);
			} else {
				IOT_WARN("Unknown option character `\\x%x'.", optopt);
			}
			break;
		default:
			IOT_ERROR("ERROR in command line argument parsing");
			break;
		}
	}

}
コード例 #2
0
static void AckStatusCallback(AWS_IoT_Client *pClient, char *topicName, uint16_t topicNameLen,
							  IoT_Publish_Message_Params *params, void *pData) {
	int32_t tokenCount;
	uint8_t i;
	void *pJsonHandler = NULL;
	char temporaryClientToken[MAX_SIZE_CLIENT_TOKEN_CLIENT_SEQUENCE];

	IOT_UNUSED(pClient);
	IOT_UNUSED(topicNameLen);
	IOT_UNUSED(pData);

	if(params->payloadLen > SHADOW_MAX_SIZE_OF_RX_BUFFER) {
		IOT_WARN("Payload larger than RX Buffer");
		return;
	}

	memcpy(shadowRxBuf, params->payload, params->payloadLen);
	shadowRxBuf[params->payloadLen] = '\0';    // jsmn_parse relies on a string

	if(!isJsonValidAndParse(shadowRxBuf, pJsonHandler, &tokenCount)) {
		IOT_WARN("Received JSON is not valid");
		return;
	}

	if(isAckForMyThingName(topicName)) {
		uint32_t tempVersionNumber = 0;
		if(extractVersionNumber(shadowRxBuf, pJsonHandler, tokenCount, &tempVersionNumber)) {
			if(tempVersionNumber > shadowJsonVersionNum) {
				shadowJsonVersionNum = tempVersionNumber;
			}
		}
	}

	if(extractClientToken(shadowRxBuf, temporaryClientToken)) {
		for(i = 0; i < MAX_ACKS_TO_COMEIN_AT_ANY_GIVEN_TIME; i++) {
			if(!AckWaitList[i].isFree) {
				if(strcmp(AckWaitList[i].clientTokenID, temporaryClientToken) == 0) {
					Shadow_Ack_Status_t status;
					if(strstr(topicName, "accepted") != NULL) {
						status = SHADOW_ACK_ACCEPTED;
					} else if(strstr(topicName, "rejected") != NULL) {
						status = SHADOW_ACK_REJECTED;
					} else {
						continue;
					}
					/* status == SHADOW_ACK_ACCEPTED || status == SHADOW_ACK_REJECTED */
					if(AckWaitList[i].callback != NULL) {
						AckWaitList[i].callback(AckWaitList[i].thingName, AckWaitList[i].action, status,
												shadowRxBuf, AckWaitList[i].pCallbackContext);
					}
					unsubscribeFromAcceptedAndRejected(i);
					AckWaitList[i].isFree = true;
					return;
				}
			}
		}
	}
}
コード例 #3
0
static void shadow_delta_callback(AWS_IoT_Client *pClient, char *topicName,
								  uint16_t topicNameLen, IoT_Publish_Message_Params *params, void *pData) {
	int32_t tokenCount;
	uint32_t i = 0;
	void *pJsonHandler = NULL;
	int32_t DataPosition;
	uint32_t dataLength;
	uint32_t tempVersionNumber = 0;

	FUNC_ENTRY;

	IOT_UNUSED(pClient);
	IOT_UNUSED(topicName);
	IOT_UNUSED(topicNameLen);
	IOT_UNUSED(pData);

	if(params->payloadLen > SHADOW_MAX_SIZE_OF_RX_BUFFER) {
		IOT_WARN("Payload larger than RX Buffer");
		return;
	}

	memcpy(shadowRxBuf, params->payload, params->payloadLen);
	shadowRxBuf[params->payloadLen] = '\0';    // jsmn_parse relies on a string

	if(!isJsonValidAndParse(shadowRxBuf, pJsonHandler, &tokenCount)) {
		IOT_WARN("Received JSON is not valid");
		return;
	}

	if(shadowDiscardOldDeltaFlag) {
		if(extractVersionNumber(shadowRxBuf, pJsonHandler, tokenCount, &tempVersionNumber)) {
			if(tempVersionNumber > shadowJsonVersionNum) {
				shadowJsonVersionNum = tempVersionNumber;
			} else {
				IOT_WARN("Old Delta Message received - Ignoring rx: %d local: %d", tempVersionNumber,
						 shadowJsonVersionNum);
				return;
			}
		}
	}

	for(i = 0; i < tokenTableIndex; i++) {
		if(!tokenTable[i].isFree) {
			if(isJsonKeyMatchingAndUpdateValue(shadowRxBuf, pJsonHandler, tokenCount,
											   (jsonStruct_t *) tokenTable[i].pStruct, &dataLength, &DataPosition)) {
				if(tokenTable[i].callback != NULL) {
					tokenTable[i].callback(shadowRxBuf + DataPosition, dataLength,
										   (jsonStruct_t *) tokenTable[i].pStruct);
				}
			}
		}
	}
}
コード例 #4
0
IoT_Error_t parseUnsignedInteger16Value(uint16_t *i, const char *jsonString, jsmntok_t *token) {
	if(token->type != JSMN_PRIMITIVE) {
		IOT_WARN("Token was not an integer");
		return JSON_PARSE_ERROR;
	}

	if(('-' == (char) (jsonString[token->start])) || (1 != sscanf(jsonString + token->start, "%" SCNu16, i))) {
		IOT_WARN("Token was not an unsigned integer.");
		return JSON_PARSE_ERROR;
	}

	return SUCCESS;
}
コード例 #5
0
IoT_Error_t parseDoubleValue(double *d, const char *jsonString, jsmntok_t *token) {
	if(token->type != JSMN_PRIMITIVE) {
		IOT_WARN("Token was not a double.");
		return JSON_PARSE_ERROR;
	}

	if(1 != sscanf(jsonString + token->start, "%lf", d)) {
		IOT_WARN("Token was not a double.");
		return JSON_PARSE_ERROR;
	}

	return SUCCESS;
}
コード例 #6
0
IoT_Error_t parseFloatValue(float *f, const char *jsonString, jsmntok_t *token) {
	if(token->type != JSMN_PRIMITIVE) {
		IOT_WARN("Token was not a float.");
		return JSON_PARSE_ERROR;
	}

	if(1 != sscanf(jsonString + token->start, "%f", f)) {
		IOT_WARN("Token was not a float.");
		return JSON_PARSE_ERROR;
	}

	return SUCCESS;
}
コード例 #7
0
IoT_Error_t parseInteger32Value(int32_t *i, const char *jsonString, jsmntok_t *token) {
	if(token->type != JSMN_PRIMITIVE) {
		IOT_WARN("Token was not an integer");
		return JSON_PARSE_ERROR;
	}

	if(1 != sscanf(jsonString + token->start, "%" SCNi32, i)) {
		IOT_WARN("Token was not an integer.");
		return JSON_PARSE_ERROR;
	}

	return SUCCESS;
}
コード例 #8
0
bool extractClientToken(const char *pJsonDocument, char *pExtractedClientToken) {
	int32_t tokenCount, i;
	uint8_t length;
	jsmntok_t ClientJsonToken;
	jsmn_init(&shadowJsonParser);

	tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct,
							sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));

	if(tokenCount < 0) {
		IOT_WARN("Failed to parse JSON: %d\n", tokenCount);
		return false;
	}

	/* Assume the top-level element is an object */
	if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
		return false;
	}

	for(i = 1; i < tokenCount; i++) {
		if(jsoneq(pJsonDocument, &jsonTokenStruct[i], SHADOW_CLIENT_TOKEN_STRING) == 0) {
			ClientJsonToken = jsonTokenStruct[i + 1];
			length = (uint8_t) (ClientJsonToken.end - ClientJsonToken.start);
			strncpy(pExtractedClientToken, pJsonDocument + ClientJsonToken.start, length);
			pExtractedClientToken[length] = '\0';
			return true;
		}
	}

	return false;
}
コード例 #9
0
void parseInputArgsForConnectParams(int argc, char **argv) {
	int opt;

	while (-1 != (opt = getopt(argc, argv, "h:p:c:t:s:"))) {
		switch (opt) {
			case 'h':
				strcpy(HostAddress, optarg);
				IOT_DEBUG("host %s\n", optarg);
				break;
			case 'p':
				port = atoi(optarg);
				IOT_DEBUG("port %s\n", optarg);
				break;
			case 'c':
				strcpy(certDirectory, optarg);
				IOT_DEBUG("cert root directory %s\n", optarg);
				break;
			case 't':
				strcpy(publishTopicName, optarg);
				IOT_DEBUG("publish topic name: %s\n", optarg);
				break;
			case 'f':
				strcpy(filename, optarg);
				IOT_DEBUG("config file %s", optarg);
				break;
			case 's':
				strcpy(subscribeTopicName, optarg);
				IOT_DEBUG("subscribe topic name: %s\n", optarg);
				break;
			case '?':
				if (optopt == 'c') {
					IOT_ERROR("Option -%c requires an argument.", optopt);
				} else if (isprint(optopt)) {
					IOT_WARN("Unknown option `-%c'.", optopt);
				} else {
					IOT_WARN("Unknown option character `\\x%x'.", optopt);
				}
				break;
			default:
				IOT_ERROR("Error in command line argument parsing");
				break;
		}
	}

}
コード例 #10
0
bool aws_iot_is_autoreconnect_enabled(AWS_IoT_Client *pClient) {
	FUNC_ENTRY;
	if(NULL == pClient) {
		IOT_WARN(" Client is null! ");
		FUNC_EXIT_RC(false);
	}

	FUNC_EXIT_RC(pClient->clientStatus.isAutoReconnectEnabled);
}
コード例 #11
0
IoT_Error_t parseBooleanValue(bool *b, const char *jsonString, jsmntok_t *token) {
	if(token->type != JSMN_PRIMITIVE) {
		IOT_WARN("Token was not a primitive.");
		return JSON_PARSE_ERROR;
	}
	if(jsonString[token->start] == 't' && jsonString[token->start + 1] == 'r' && jsonString[token->start + 2] == 'u'
	   && jsonString[token->start + 3] == 'e') {
		*b = true;
	} else if(jsonString[token->start] == 'f' && jsonString[token->start + 1] == 'a'
			  && jsonString[token->start + 2] == 'l' && jsonString[token->start + 3] == 's'
			  && jsonString[token->start + 4] == 'e') {
		*b = false;
	} else {
		IOT_WARN("Token was not a bool.");
		return JSON_PARSE_ERROR;
	}
	return SUCCESS;
}
コード例 #12
0
IoT_Error_t parseUnsignedInteger8Value(uint8_t *i, const char *jsonString, jsmntok_t *token) {
	if(token->type != JSMN_PRIMITIVE) {
		IOT_WARN("Token was not an integer");
		return JSON_PARSE_ERROR;
	}

	uint32_t i_word;
	if(('-' == (char) (jsonString[token->start])) || (1 != sscanf(jsonString + token->start, "%" SCNu32, &i_word))) {
		IOT_WARN("Token was not an unsigned integer.");
		return JSON_PARSE_ERROR;
	}
	if (i_word > UINT8_MAX) {
		IOT_WARN("Token value %u exceeds 8 bits", i_word);
		return JSON_PARSE_ERROR;
	}
	*i = i_word;

	return SUCCESS;
}
コード例 #13
0
IoT_Error_t parseInteger8Value(int8_t *i, const char *jsonString, jsmntok_t *token) {
	if(token->type != JSMN_PRIMITIVE) {
		IOT_WARN("Token was not an integer");
		return JSON_PARSE_ERROR;
	}

	int32_t i_word;
	if(1 != sscanf(jsonString + token->start, "%" SCNi32, &i_word)) {
		IOT_WARN("Token was not an integer.");
		return JSON_PARSE_ERROR;
	}
	if(i_word < INT8_MIN || i_word > INT8_MAX) {
		IOT_WARN("Token value %d out of range for 8-bit int", i_word);
		return JSON_PARSE_ERROR;
	}
	*i = i_word;

	return SUCCESS;
}
コード例 #14
0
IoT_Error_t parseStringValue(char *buf, const char *jsonString, jsmntok_t *token) {
	uint16_t size = 0;
	if(token->type != JSMN_STRING) {
		IOT_WARN("Token was not a string.");
		return JSON_PARSE_ERROR;
	}
	size = (uint16_t) (token->end - token->start);
	memcpy(buf, jsonString + token->start, size);
	buf[size] = '\0';
	return SUCCESS;
}
コード例 #15
0
void disconnectCallbackHandler(AWS_IoT_Client *pClient, void *data) {
	IOT_WARN("MQTT Disconnect");
	IoT_Error_t rc = FAILURE;

	if (NULL == pClient) {
		return;
	}

	IOT_UNUSED(data);

	if (aws_iot_is_autoreconnect_enabled(pClient)) {
		IOT_INFO("Auto Reconnect is enabled, Reconnecting attempt will start now");
	} else {
		IOT_WARN("Auto Reconnect not enabled. Starting manual reconnect...");
		rc = aws_iot_mqtt_attempt_reconnect(pClient);
		if (NETWORK_RECONNECTED == rc) {
			IOT_WARN("Manual Reconnect Successful");
		} else {
			IOT_WARN("Manual Reconnect Failed - %d", rc);
		}
	}
}
コード例 #16
0
bool isJsonValidAndParse(const char *pJsonDocument, void *pJsonHandler, int32_t *pTokenCount) {
	int32_t tokenCount;

	jsmn_init(&shadowJsonParser);

	tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct,
							sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));

	if(tokenCount < 0) {
		IOT_WARN("Failed to parse JSON: %d\n", tokenCount);
		return false;
	}

	/* Assume the top-level element is an object */
	if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
		IOT_WARN("Top Level is not an object\n");
		return false;
	}

	pJsonHandler = (void *) jsonTokenStruct;
	*pTokenCount = tokenCount;

	return true;
}
コード例 #17
0
bool isReceivedJsonValid(const char *pJsonDocument) {
	int32_t tokenCount;

	jsmn_init(&shadowJsonParser);

	tokenCount = jsmn_parse(&shadowJsonParser, pJsonDocument, strlen(pJsonDocument), jsonTokenStruct,
							sizeof(jsonTokenStruct) / sizeof(jsonTokenStruct[0]));

	if(tokenCount < 0) {
		IOT_WARN("Failed to parse JSON: %d\n", tokenCount);
		return false;
	}

	/* Assume the top-level element is an object */
	if(tokenCount < 1 || jsonTokenStruct[0].type != JSMN_OBJECT) {
		return false;
	}

	return true;
}
コード例 #18
0
bool aws_iot_mqtt_is_client_connected(AWS_IoT_Client *pClient) {
	bool isConnected;

	FUNC_ENTRY;

	if(NULL == pClient) {
		IOT_WARN(" Client is null! ");
		FUNC_EXIT_RC(false);
	}

	switch(pClient->clientStatus.clientState) {
		case CLIENT_STATE_INVALID:
		case CLIENT_STATE_INITIALIZED:
		case CLIENT_STATE_CONNECTING:
			isConnected = false;
			break;
		case CLIENT_STATE_CONNECTED_IDLE:
		case CLIENT_STATE_CONNECTED_YIELD_IN_PROGRESS:
		case CLIENT_STATE_CONNECTED_PUBLISH_IN_PROGRESS:
		case CLIENT_STATE_CONNECTED_SUBSCRIBE_IN_PROGRESS:
		case CLIENT_STATE_CONNECTED_UNSUBSCRIBE_IN_PROGRESS:
		case CLIENT_STATE_CONNECTED_RESUBSCRIBE_IN_PROGRESS:
		case CLIENT_STATE_CONNECTED_WAIT_FOR_CB_RETURN:
			isConnected = true;
			break;
		case CLIENT_STATE_DISCONNECTING:
		case CLIENT_STATE_DISCONNECTED_ERROR:
		case CLIENT_STATE_DISCONNECTED_MANUALLY:
		case CLIENT_STATE_PENDING_RECONNECT:
		default:
			isConnected = false;
			break;
	}

	FUNC_EXIT_RC(isConnected);
}
コード例 #19
0
int main(int argc, char **argv) {
	bool infinitePublishFlag = true;

	char rootCA[PATH_MAX + 1];
	char clientCRT[PATH_MAX + 1];
	char clientKey[PATH_MAX + 1];
	char CurrentWD[PATH_MAX + 1];
	char cPayload[100];

	int32_t i = 0;

	IoT_Error_t rc = FAILURE;

	AWS_IoT_Client client;
	IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault;
	IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault;

	IoT_Publish_Message_Params paramsQOS0;
	IoT_Publish_Message_Params paramsQOS1;

	parseInputArgsForConnectParams(argc, argv);

	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);

	IOT_DEBUG("rootCA %s", rootCA);
	IOT_DEBUG("clientCRT %s", clientCRT);
	IOT_DEBUG("clientKey %s", clientKey);
	mqttInitParams.enableAutoReconnect = false; // We enable this later below
	mqttInitParams.pHostURL = HostAddress;
	mqttInitParams.port = port;
	mqttInitParams.pRootCALocation = rootCA;
	mqttInitParams.pDeviceCertLocation = clientCRT;
	mqttInitParams.pDevicePrivateKeyLocation = clientKey;
	mqttInitParams.mqttCommandTimeout_ms = 20000;
	mqttInitParams.tlsHandshakeTimeout_ms = 5000;
	mqttInitParams.isSSLHostnameVerify = true;
	mqttInitParams.disconnectHandler = disconnectCallbackHandler;
	mqttInitParams.disconnectHandlerData = NULL;

	rc = aws_iot_mqtt_init(&client, &mqttInitParams);
	if(SUCCESS != rc) {
		IOT_ERROR("aws_iot_mqtt_init returned error : %d ", rc);
		return rc;
	}

	connectParams.keepAliveIntervalInSec = 10;
	connectParams.isCleanSession = true;
	connectParams.MQTTVersion = MQTT_3_1_1;
	connectParams.pClientID = AWS_IOT_MQTT_CLIENT_ID;
	connectParams.clientIDLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID);
	connectParams.isWillMsgPresent = false;

	IOT_INFO("Connecting...");
	rc = aws_iot_mqtt_connect(&client, &connectParams);
	if(SUCCESS != rc) {
		IOT_ERROR("Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port);
		return rc;
	}
	/*
	 * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
	 *  #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
	 *  #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
	 */
	rc = aws_iot_mqtt_autoreconnect_set_status(&client, true);
	if(SUCCESS != rc) {
		IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc);
		return rc;
	}

	IOT_INFO("Subscribing...");
	rc = aws_iot_mqtt_subscribe(&client, "sdkTest/sub", 11, QOS0, iot_subscribe_callback_handler, NULL);
	if(SUCCESS != rc) {
		IOT_ERROR("Error subscribing : %d ", rc);
		return rc;
	}

	sprintf(cPayload, "%s : %d ", "hello from SDK", i);

	paramsQOS0.qos = QOS0;
	paramsQOS0.payload = (void *) cPayload;
	paramsQOS0.isRetained = 0;

	paramsQOS1.qos = QOS1;
	paramsQOS1.payload = (void *) cPayload;
	paramsQOS1.isRetained = 0;

	if(publishCount != 0) {
		infinitePublishFlag = false;
	}

	while((NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc)
		  && (publishCount > 0 || infinitePublishFlag)) {

		//Max time the yield function will wait for read messages
		rc = aws_iot_mqtt_yield(&client, 100);
		if(NETWORK_ATTEMPTING_RECONNECT == rc) {
			// If the client is attempting to reconnect we will skip the rest of the loop.
			continue;
		}

		IOT_INFO("-->sleep");
		sleep(1);
		sprintf(cPayload, "%s : %d ", "hello from SDK QOS0", i++);
		paramsQOS0.payloadLen = strlen(cPayload);
		rc = aws_iot_mqtt_publish(&client, "sdkTest/sub", 11, &paramsQOS0);
		if(publishCount > 0) {
			publishCount--;
		}

		sprintf(cPayload, "%s : %d ", "hello from SDK QOS1", i++);
		paramsQOS1.payloadLen = strlen(cPayload);
		rc = aws_iot_mqtt_publish(&client, "sdkTest/sub", 11, &paramsQOS1);
		if (rc == MQTT_REQUEST_TIMEOUT_ERROR) {
			IOT_WARN("QOS1 publish ack not received.\n");
			rc = SUCCESS;
		}
		if(publishCount > 0) {
			publishCount--;
		}
	}

	if(SUCCESS != rc) {
		IOT_ERROR("An error occurred in the loop.\n");
	} else {
		IOT_INFO("Publish done\n");
	}

	return rc;
}