调试stm32f407通过以太网MQTT连接服务器,发现如果服务器不需要用户名和密码权限则可以正常连接MQTT服务器,并能够发布和订阅消息,但连接需要用户名和密码的服务器,则提示认证失败。分析这个函数,发现函数没有处理client结构体中的用户名和密码字段 mqtt_client_connect(client, &mqttServerIpAddr, 1883, mqtt_connection_cb, 0, &ci);
修改后的代码如下,可以正常连接了。
err_t
mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port, mqtt_connection_cb_t cb, void *arg,
const struct mqtt_connect_client_info_t *client_info)
{
err_t err;
size_t len;
u16_t client_id_length;
/* Length is the sum of 2+"MQTT", protocol level, flags and keep alive */
u16_t remaining_length = 2 + 4 + 1 + 1 + 2;
u8_t flags = 0, will_topic_len = 0, will_msg_len = 0;
LWIP_ASSERT("mqtt_client_connect: client != NULL", client != NULL);
LWIP_ASSERT("mqtt_client_connect: ip_addr != NULL", ip_addr != NULL);
LWIP_ASSERT("mqtt_client_connect: client_info != NULL", client_info != NULL);
LWIP_ASSERT("mqtt_client_connect: client_info->client_id != NULL", client_info->client_id != NULL);
if (client->conn_state != TCP_DISCONNECTED) {
LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_client_connect: Already connected\n"));
return ERR_ISCONN;
}
/* Wipe clean */
memset(client, 0, sizeof(mqtt_client_t));
client->connect_arg = arg;
client->connect_cb = cb;
client->keep_alive = client_info->keep_alive;
mqtt_init_requests(client->req_list);
/* Build connect message */
if (client_info->will_topic != NULL && client_info->will_msg != NULL) {
flags |= MQTT_CONNECT_FLAG_WILL;
flags |= (client_info->will_qos & 3) << 3;
if (client_info->will_retain) {
flags |= MQTT_CONNECT_FLAG_WILL_RETAIN;
}
len = strlen(client_info->will_topic);
LWIP_ERROR("mqtt_client_connect: client_info->will_topic length overflow", len <= 0xFF, return ERR_VAL);
LWIP_ERROR("mqtt_client_connect: client_info->will_topic length must be > 0", len > 0, return ERR_VAL);
will_topic_len = (u8_t)len;
len = strlen(client_info->will_msg);
LWIP_ERROR("mqtt_client_connect: client_info->will_msg length overflow", len <= 0xFF, return ERR_VAL);
will_msg_len = (u8_t)len;
len = remaining_length + 2 + will_topic_len + 2 + will_msg_len;
LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);
remaining_length = (u16_t)len;
}
/* Don't complicate things, always connect using clean session */
flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;
len = strlen(client_info->client_id);
LWIP_ERROR("mqtt_client_connect: client_info->client_id length overflow", len <= 0xFFFF, return ERR_VAL);
client_id_length = (u16_t)len;
len = remaining_length + 2 + client_id_length;
LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);
if(client_info->client_user!=0)
{
flags |= MQTT_CONNECT_FLAG_USERNAME;
len+=2;
len+=strlen(client_info->client_user);
}
if(client_info->client_pass!=0)
{
flags |= MQTT_CONNECT_FLAG_PASSWORD;
len+=2;
len+=strlen(client_info->client_pass);
}
remaining_length = (u16_t)len;
if (mqtt_output_check_space(&client->output, remaining_length) == 0) {
return ERR_MEM;
}
client->conn = tcp_new();
if (client->conn == NULL) {
return ERR_MEM;
}
/* Set arg pointer for callbacks */
tcp_arg(client->conn, client);
/* Any local address, pick random local port number */
err = tcp_bind(client->conn, IP_ADDR_ANY, 0);
if (err != ERR_OK) {
LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_client_connect: Error binding to local ip/port, %d\n", err));
goto tcp_fail;
}
LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_client_connect: Connecting to host: %s at port:%"U16_F"\n", ipaddr_ntoa(ip_addr), port));
/* Connect to server */
err = tcp_connect(client->conn, ip_addr, port, mqtt_tcp_connect_cb);
if (err != ERR_OK) {
LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_client_connect: Error connecting to remote ip/port, %d\n", err));
goto tcp_fail;
}
/* Set error callback */
tcp_err(client->conn, mqtt_tcp_err_cb);
client->conn_state = TCP_CONNECTING;
/* Append fixed header */
mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_CONNECT, 0, 0, 0, remaining_length);
/* Append Protocol string */
mqtt_output_append_string(&client->output, "MQTT", 4);
/* Append Protocol level */
mqtt_output_append_u8(&client->output, 4);
/* Append connect flags */
mqtt_output_append_u8(&client->output, flags);
/* Append keep-alive */
mqtt_output_append_u16(&client->output, client_info->keep_alive);
/* Append client id */
mqtt_output_append_string(&client->output, client_info->client_id, client_id_length);
/* Append will message if used */
if ((flags & MQTT_CONNECT_FLAG_WILL) != 0) {
mqtt_output_append_string(&client->output, client_info->will_topic, will_topic_len);
mqtt_output_append_string(&client->output, client_info->will_msg, will_msg_len);
}
if((flags & MQTT_CONNECT_FLAG_USERNAME) != 0)
{
mqtt_output_append_string(&client->output, client_info->client_user, strlen(client_info->client_user));
}
if((flags & MQTT_CONNECT_FLAG_PASSWORD) != 0)
{
mqtt_output_append_string(&client->output, client_info->client_pass, strlen(client_info->client_pass));
}
return ERR_OK;
tcp_fail:
tcp_abort(client->conn);
client->conn = NULL;
return err;
}