c语言之esp32之mqtt编程开发

static esp_mqtt_client_handle_t mqtt_clients[2] = { NULL, NULL };
static esp_mqtt_client_config_t m_mqtt_cfg[2] = { 0 };



static void mqtt_event_handler_ex(void* handler_args, esp_event_base_t base, int32_t event_id, void* event_data)
{
	int link_id = 0;
	if (handler_args)
		link_id = *(int*)handler_args;
	if (!(link_id == 1 || link_id == 2)) {
		printf("link id error\r\n");
	}
	ESP_LOGD(TAG, "Event dispatched from event loop base=%s,event_id=%d,link_id:%d",
		base, event_id, link_id);
	esp_mqtt_event_handle_t event = event_data;
	esp_mqtt_client_handle_t client = event->client;
	uint8_t respBuf[64] = { 0 };
	int msg_id;
	switch ((esp_mqtt_event_id_t)event_id) {
	case MQTT_EVENT_CONNECTED:
	{
		free_mqtt_certificates();
		memset(respBuf, 0, sizeof(respBuf));
		snprintf((char*)respBuf, 64, "+MQTTCONNECTED:%d,%d,%d,\"%s\",%d,%d\r\n",
			link_id, 4,
			m_mqtt_cfg[link_id - 1].broker.address.transport, m_mqtt_cfg[link_id - 1].broker.address.hostname,
			m_mqtt_cfg[link_id - 1].broker.address.port, !m_mqtt_cfg[link_id - 1].network.disable_auto_reconnect);
		esp_at_port_write_data(respBuf, strlen((char*)respBuf));
	}
	break;
	case MQTT_EVENT_DISCONNECTED:
		free_mqtt_certificates();
		snprintf((char*)respBuf, sizeof(respBuf), "+MQTTDISCONNECT:%d\r\n", link_id);
		esp_at_port_write_data(respBuf, strlen((char*)respBuf));
		break;
	case MQTT_EVENT_SUBSCRIBED:
		ESP_LOGE(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
		break;
	case MQTT_EVENT_UNSUBSCRIBED:
		ESP_LOGE(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
		break;
	case MQTT_EVENT_PUBLISHED:
		ESP_LOGE(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
		break;
	case MQTT_EVENT_DATA:
		free_mqtt_certificates();
		int link_id = 1; // 根据实际情况修改
		// 计算需要的缓冲区大小(确保足够大)
		int buffer_size = 50 + event->topic_len + event->data_len; // 预留额外空间
		char* buffer = (char*)malloc(buffer_size);
		if (!buffer) {
			ESP_LOGE(TAG, "Failed to allocate buffer");
			break;
		}
		// 按照 AT 指令格式拼接字符串
		int len = snprintf(
			buffer,
			buffer_size,
			"+MQTTSUBRECV:%d,\"%.*s\",%d,%.*s\r\n",
			link_id,
			event->topic_len, event->topic,
			event->data_len,
			event->data_len, event->data
		);
		// 通过 AT 端口发送
		esp_at_port_write_data((uint8_t*)buffer, len);
		// 释放缓冲区
		free(buffer);
		ESP_LOGI(TAG, "MQTT_EVENT_DATA");
		printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
		printf("DATA=%.*s\r\n", event->data_len, event->data);
		break;
	case MQTT_EVENT_ERROR:
		ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
		if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
			log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
			log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
			log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
			ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
		}
		break;
	default:
		ESP_LOGI(TAG, "Other event id:%d", event->event_id);
		break;
	}
}

//AT+MQTTCONNEX=1,"clinetid","172.16.1.105",1883,0,120,1
static uint8_t at_mqtt_connect_ex(uint8_t para_num) {
	int32_t ret = ESP_AT_RESULT_CODE_ERROR;
	int32_t cnt = 0;
	static int32_t link_id = 0;
	printf("at_mqtt_connect_ex start\r\n");
	if (esp_at_get_para_as_digit(cnt++, &link_id) != ESP_AT_PARA_PARSE_RESULT_OK) {
		printf("link_id error\r\n");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(link_id == 1 || link_id == 2)) {
		printf("link_id error\r\n");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	uint8_t* clinetId = NULL;
	if (esp_at_get_para_as_str(cnt++, &clinetId) != ESP_AT_PARA_PARSE_RESULT_OK) {
		ESP_LOGE(TAG, "Failed to parse clinetId");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	uint8_t* host = NULL;
	if (esp_at_get_para_as_str(cnt++, &host) != ESP_AT_PARA_PARSE_RESULT_OK) {
		ESP_LOGE(TAG, "Failed to parse host");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t port = 0;
	if (esp_at_get_para_as_digit(cnt++, &port) != ESP_AT_PARA_PARSE_RESULT_OK) {
		ESP_LOGE(TAG, "Failed to parse port");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (port < 0 || port > 65535) {
		ESP_LOGE(TAG, "Port out of range: %d", port);
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t disable_clean_session = 0;
	if (esp_at_get_para_as_digit(cnt++, &disable_clean_session) != ESP_AT_PARA_PARSE_RESULT_OK) {

		ESP_LOGE(TAG, "Failed to parse disable_clean_session");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(disable_clean_session == 0 || disable_clean_session == 1)) {
		printf("disable_clean_session error\r\n");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t keepalive = 0;
	if (esp_at_get_para_as_digit(cnt++, &keepalive) != ESP_AT_PARA_PARSE_RESULT_OK) {
		printf("keepalive error\r\n");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (keepalive < 0 || keepalive >7200) {
		printf("keepalive error\r\n");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t use_tls = 0;
	if (esp_at_get_para_as_digit(cnt++, &use_tls) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (use_tls < 1 || use_tls > 5) {
		ESP_LOGE(TAG, "ERROR: Invalid auth mode. Use 1-5\r\n");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (cnt != para_num) {
		printf("para_num!=cnt %d,%d\r\n", cnt, para_num);
		return ESP_AT_RESULT_CODE_ERROR;
	}
	m_mqtt_cfg[link_id - 1].broker.address.hostname = (const char*)host;
	m_mqtt_cfg[link_id - 1].broker.address.port = port;
	m_mqtt_cfg[link_id - 1].credentials.client_id = (const char*)clinetId;
	m_mqtt_cfg[link_id - 1].session.disable_clean_session = disable_clean_session;
	m_mqtt_cfg[link_id - 1].session.keepalive = keepalive;
	m_mqtt_cfg[link_id - 1].session.keepalive = keepalive;
	m_mqtt_cfg[link_id - 1].broker.address.transport = use_tls;
	m_mqtt_cfg[link_id - 1].network.disable_auto_reconnect = 1;
	if (mqtt_clients[link_id - 1]) {
		esp_mqtt_client_destroy(mqtt_clients[link_id - 1]);
	}
	mqtt_clients[link_id - 1] = esp_mqtt_client_init(&m_mqtt_cfg[link_id - 1]);
	if (mqtt_clients[link_id - 1] == NULL) {
		printf("esp_mqtt_client_init failed\r\n");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	ret = esp_mqtt_client_register_event(mqtt_clients[link_id - 1], ESP_EVENT_ANY_ID, mqtt_event_handler_ex, &link_id);
	if (ret != ESP_OK)
		return ESP_AT_RESULT_CODE_ERROR;
	if (esp_mqtt_client_start(mqtt_clients[link_id - 1]) != ESP_AT_PARA_PARSE_RESULT_OK) {
		printf("mqtt id:%d connect fail\r\n", link_id);
		return ESP_AT_RESULT_CODE_ERROR;
	}
	else {
		printf("mqtt id:%d connect success\r\n", link_id);
	}
	return ESP_AT_RESULT_CODE_OK;
}


//AT+MQTTDISCONNEX=1
static uint8_t at_mqtt_disconnect_ex(uint8_t para_num)
{
	// 参数索引
	int32_t cnt = 0;
	uint8_t buffer[512] = { 0 };
	unsigned short port;
	int32_t raw_port;
	const int timeout_ms = 5000; // 5秒超时
	const int check_interval_ms = 100;
	int elapsed_ms = 0;
	int32_t link_id = 0;
	int ret = 0;
	if (esp_at_get_para_as_digit(cnt++, &link_id) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(link_id == 1 || link_id == 2)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (cnt != para_num) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (mqtt_clients[link_id - 1] == NULL)
		return ESP_AT_RESULT_CODE_ERROR;
	if (esp_mqtt_client_disconnect(mqtt_clients[link_id - 1]) != ESP_AT_PARA_PARSE_RESULT_OK) {
		printf("esp_mqtt_client_disconnect fail\r\n");
		ret = ESP_AT_RESULT_CODE_ERROR;
	}
	if (esp_mqtt_client_destroy(mqtt_clients[link_id - 1]) == 0) {
		printf("esp_mqtt_client_destroy success\r\n");
		mqtt_clients[link_id - 1] = NULL;
		return ESP_AT_RESULT_CODE_OK;
	}
	mqtt_clients[link_id - 1] = NULL;
	return ESP_AT_RESULT_CODE_ERROR;
}

//AT+MQTTSUBEX=1,"test",1
static uint8_t at_mqtt_subscribe_ex(uint8_t para_num)
{
	int32_t cnt = 0;
	uint8_t buffer[512] = { 0 };
	unsigned short port;
	int32_t raw_port;
	int32_t link_id = 0;
	if (esp_at_get_para_as_digit(cnt++, &link_id) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(link_id == 1 || link_id == 2)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	uint8_t* topic = NULL;
	if (esp_at_get_para_as_str(cnt++, &topic) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t qos = 0;
	if (esp_at_get_para_as_digit(cnt++, &qos) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(qos == 0 || qos == 1 || qos == 2)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (cnt != para_num) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (mqtt_clients[link_id - 1] == NULL)
		return ESP_AT_RESULT_CODE_ERROR;
	int msg_id = esp_mqtt_client_subscribe(
		mqtt_clients[link_id - 1],
		(const char*)topic,
		qos
	);
	if (msg_id < 0) {
		ESP_LOGE(TAG, "Publish failed");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	return ESP_AT_RESULT_CODE_OK;
}

//AT+MQTTPUBEX=0,"test","test",1,0
static uint8_t at_mqtt_publish_ex(uint8_t para_num)
{
	int32_t cnt = 0;
	uint8_t buffer[512] = { 0 };
	unsigned short port;
	int32_t raw_port;
	int32_t link_id = 0;
	if (esp_at_get_para_as_digit(cnt++, &link_id) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(link_id == 1 || link_id == 2)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	uint8_t* topic = NULL;
	if (esp_at_get_para_as_str(cnt++, &topic) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t qos = 0;
	if (esp_at_get_para_as_digit(cnt++, &qos) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(qos == 0 || qos == 1 || qos == 2)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t retain = 0;
	if (esp_at_get_para_as_digit(cnt++, &retain) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(retain == 0 || retain == 1)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	uint8_t* message = NULL;
	if (esp_at_get_para_as_str(cnt++, &message) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (cnt != para_num) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int msg_id = esp_mqtt_client_publish(
		mqtt_clients[link_id - 1],
		(const char*)topic,
		(const char*)message,
		0,
		qos,
		retain
	);

	if (msg_id < 0) {
		ESP_LOGE(TAG, "Publish failed");
		return ESP_AT_RESULT_CODE_ERROR;
	}
	return ESP_AT_RESULT_CODE_OK;
}

static uint8_t at_mqtt_setwill_ex(uint8_t para_num) {

	int32_t cnt = 0;
	uint8_t buffer[512] = { 0 };
	int32_t link_id = 0;
	if (esp_at_get_para_as_digit(cnt++, &link_id) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}

	if (!(link_id == 1 || link_id == 2)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	uint8_t* topic = NULL;
	if (esp_at_get_para_as_str(cnt++, &topic) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t qos = 0;
	if (esp_at_get_para_as_digit(cnt++, &qos) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(qos == 0 || qos == 1 || qos == 2)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	int32_t retain = 0;
	if (esp_at_get_para_as_digit(cnt++, &retain) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (!(retain == 0 || retain == 1)) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	uint8_t* message = NULL;
	if (esp_at_get_para_as_str(cnt++, &message) != ESP_AT_PARA_PARSE_RESULT_OK) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	if (cnt != para_num) {
		return ESP_AT_RESULT_CODE_ERROR;
	}
	m_mqtt_cfg[link_id].session.last_will.qos = qos;
	m_mqtt_cfg[link_id].session.last_will.retain = retain;
	m_mqtt_cfg[link_id].session.last_will.topic = (const char *)topic;
	m_mqtt_cfg[link_id].session.last_will.msg =(const char *) message;
	m_mqtt_cfg[link_id].session.last_will.msg_len = strlen((char *)message);
	return ESP_AT_RESULT_CODE_OK;
}

测试AT指令:

ATE0
AT+CWMODE=1
AT+CIPMUX=1
AT+CWJAP="sunyard_sz","syd802806"
AT+CWJAP?
AT+MQTTCONNEX=1,"clinetid","172.16.1.105",1883,0,120,1
AT+MQTTSUBEX=1,"test",1
AT+MQTTPUBEX=1,"test",1,0,"test"
AT+MQTTDISCONNEX=1

测试效果:
image

posted @ 2025-09-01 16:23  我不是萧海哇~~~  阅读(16)  评论(0)    收藏  举报