lwip自带mqtt用户名和密码登陆失败问题分析

调试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;
}

你可能感兴趣的:(物联网)