Example #1
0
int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos)
{
    if(!mosq) return MOSQ_ERR_INVAL;
    if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;

    return _mosquitto_send_subscribe(mosq, mid, false, sub, qos);
}
Example #2
0
int main(int argc, char *argv[])
{
	struct mosquitto *mosq;
	int fd;
	bool clean_session = true;
	int keepalive = 60;

	mosq = mosquitto_new("packetgen", NULL);
	if(!mosq){
		fprintf(stderr, "Error: Out of memory.\n");
		return 1;
	}

	/* CONNECT */
	fd = open("mqtt.connect", O_CREAT|O_WRONLY, 00644);
	if(fd<0){
		fprintf(stderr, "Error: Unable to open mqtt.connect for writing.\n");
		return 1;
	}
	mosq->core.sock = fd;
	printf("_mosquitto_send_connect(): %d\n", _mosquitto_send_connect(mosq, keepalive, clean_session));
	printf("loop: %d\n", mosquitto_loop_write(mosq));
	close(fd);

	/* SUBSCRIBE */
	fd = open("mqtt.subscribe", O_CREAT|O_WRONLY, 00644);
	if(fd<0){
		fprintf(stderr, "Error: Unable to open mqtt.subscribe for writing.\n");
		return 1;
	}
	mosq->core.sock = fd;
	printf("_mosquitto_send_subscribe(): %d\n", _mosquitto_send_subscribe(mosq, NULL, false, "subscribe/topic", 2));
	printf("loop: %d\n", mosquitto_loop_write(mosq));
	close(fd);

	mosquitto_destroy(mosq);

	return 0;
}
/* 整个.c文件就是处理客户端的连接请求,返回一个连接确认包 */
int mqtt3_handle_connack(struct mosquitto_db *db, struct mosquitto *context)
{
	uint8_t byte;
	uint8_t rc;
	int i;
	char *notification_topic;
	int notification_topic_len;
	char notification_payload;

	if(!context){
		return MOSQ_ERR_INVAL;
	}

#ifdef WITH_STRICT_PROTOCOL
	if(context->in_packet.remaining_length != 2){
		return MOSQ_ERR_PROTOCOL;
	}
#endif

	_mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received CONNACK on connection %s.", context->id);
	if(_mosquitto_read_byte(&context->in_packet, &byte)) return 1; // Reserved byte, not used
	if(_mosquitto_read_byte(&context->in_packet, &rc)) return 1;
	switch(rc){
    //
		case CONNACK_ACCEPTED:
      // 这是一个broker客户端
			if(context->bridge){
        // 提醒机制是怎么做的?
        if(context->bridge->notifications){
					notification_payload = '1';
					if(context->bridge->notification_topic){
						if(_mosquitto_send_real_publish(context, _mosquitto_mid_generate(context),
								context->bridge->notification_topic, 1, &notification_payload, 1, true, 0)){

							return 1;
						}
						mqtt3_db_messages_easy_queue(db, context, context->bridge->notification_topic, 1, 1, &notification_payload, 1);
					}else{
						notification_topic_len = strlen(context->id)+strlen("$SYS/broker/connection//state");
						notification_topic = _mosquitto_malloc(sizeof(char)*(notification_topic_len+1));
						if(!notification_topic) return MOSQ_ERR_NOMEM;

						snprintf(notification_topic, notification_topic_len+1, "$SYS/broker/connection/%s/state", context->id);
						notification_payload = '1';
						if(_mosquitto_send_real_publish(context, _mosquitto_mid_generate(context),
								notification_topic, 1, &notification_payload, 1, true, 0)){

							_mosquitto_free(notification_topic);
							return 1;
						}
						mqtt3_db_messages_easy_queue(db, context, notification_topic, 1, 1, &notification_payload, 1);
						_mosquitto_free(notification_topic);
					}
				}// end of bridge notifications

        // broker之间的订阅处理机制,画个图可能好理解点
				for(i=0; i<context->bridge->topic_count; i++){
					if(context->bridge->topics[i].direction == bd_in || context->bridge->topics[i].direction == bd_both){
						if(_mosquitto_send_subscribe(context, NULL, false, context->bridge->topics[i].remote_topic, context->bridge->topics[i].qos)){
							return 1;
						}
					}else{
						if(_mosquitto_send_unsubscribe(context, NULL, false, context->bridge->topics[i].remote_topic)){
							/* direction = inwards only. This means we should not be subscribed
			 				 * to the topic. It is possible that we used to be subscribed to
			 				 * this topic so unsubscribe. */
							return 1;
						}
					}
				}

			}
      // 原来更新的是客户端的额状态
			context->state = mosq_cs_connected;
			return MOSQ_ERR_SUCCESS;

      // 连接错误,版本问题
		case CONNACK_REFUSED_PROTOCOL_VERSION:
			if(context->bridge){
				context->bridge->try_private_accepted = false;
			}
			_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unacceptable protocol version");
			return 1;

      //
		case CONNACK_REFUSED_IDENTIFIER_REJECTED:
			_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: identifier rejected");
			return 1;

      //
		case CONNACK_REFUSED_SERVER_UNAVAILABLE:
			_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: broker unavailable");
			return 1;

      //
    case CONNACK_REFUSED_BAD_USERNAME_PASSWORD:
			_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: broker unavailable");
			return 1;
      //
		case CONNACK_REFUSED_NOT_AUTHORIZED:
			_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: not authorised");
			return 1;

      //
		default:
			_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unknown reason");
			return 1;
	}
	return 1;
}