int _mosquitto_handle_pubrec(struct mosquitto *mosq)
{
	uint16_t mid;
	int rc;

	assert(mosq);
#ifdef WITH_STRICT_PROTOCOL
	if(mosq->in_packet.remaining_length != 2){
		return MOSQ_ERR_PROTOCOL;
	}
#endif
	rc = _mosquitto_read_uint16(&mosq->in_packet, &mid);
	if(rc) return rc;
#ifdef WITH_BROKER
	_mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREC from %s (Mid: %d)", mosq->id, mid);

	rc = mqtt3_db_message_update(mosq, mid, mosq_md_out, ms_wait_for_pubcomp);
#else
	_mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREC (Mid: %d)", mosq->id, mid);

	rc = _mosquitto_message_update(mosq, mid, mosq_md_out, mosq_ms_wait_pubcomp);
#endif
	if(rc) return rc;
	rc = _mosquitto_send_pubrel(mosq, mid, false);
	if(rc) return rc;

	return MOSQ_ERR_SUCCESS;
}
Beispiel #2
0
void _mosquitto_message_retry_check_actual(struct mosquitto *mosq, struct mosquitto_message_all *messages, pthread_mutex_t mutex)
{
    time_t now = mosquitto_time();
    assert(mosq);

    pthread_mutex_lock(&mutex);

    while(messages) {
        if(messages->timestamp + mosq->message_retry < now) {
            switch(messages->state) {
            case mosq_ms_wait_for_puback:
            case mosq_ms_wait_for_pubrec:
                messages->timestamp = now;
                messages->dup = true;
                _mosquitto_send_publish(mosq, messages->msg.mid, messages->msg.topic, messages->msg.payloadlen, messages->msg.payload, messages->msg.qos, messages->msg.retain, messages->dup);
                break;
            case mosq_ms_wait_for_pubrel:
                messages->timestamp = now;
                messages->dup = true;
                _mosquitto_send_pubrec(mosq, messages->msg.mid);
                break;
            case mosq_ms_wait_for_pubcomp:
                messages->timestamp = now;
                messages->dup = true;
                _mosquitto_send_pubrel(mosq, messages->msg.mid, true);
                break;
            default:
                break;
            }
        }
        messages = messages->next;
    }
    pthread_mutex_unlock(&mutex);
}
Beispiel #3
0
void _mosquitto_message_retry_check(struct mosquitto *mosq)
{
	struct mosquitto_message_all *message;
	time_t now = time(NULL);
	assert(mosq);

	message = mosq->messages;
	while(message){
		if(message->timestamp + mosq->message_retry < now){
			switch(message->state){
				case mosq_ms_wait_puback:
				case mosq_ms_wait_pubrec:
					message->timestamp = now;
					message->dup = true;
					_mosquitto_send_publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup);
					break;
				case mosq_ms_wait_pubrel:
					message->timestamp = now;
					_mosquitto_send_pubrec(mosq, message->msg.mid);
					break;
				case mosq_ms_wait_pubcomp:
					message->timestamp = now;
					_mosquitto_send_pubrel(mosq, message->msg.mid, true);
					break;
				default:
					break;
			}
		}
		message = message->next;
	}
}
int _mosquitto_handle_pubrec(struct mosquitto *mosq)
{
	uint16_t mid;
	int rc;

	assert(mosq);
	if(mosq->core.in_packet.remaining_length != 2){
		return MOSQ_ERR_PROTOCOL;
	}
	rc = _mosquitto_read_uint16(&mosq->core.in_packet, &mid);
	if(rc) return rc;
	_mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Received PUBREC (Mid: %d)", mid);

	rc = _mosquitto_message_update(mosq, mid, mosq_md_out, mosq_ms_wait_pubcomp);
	if(rc) return rc;
	rc = _mosquitto_send_pubrel(mosq, mid, false);
	if(rc) return rc;

	return MOSQ_ERR_SUCCESS;
}
Beispiel #5
0
int mqtt3_db_message_write(struct mosquitto *context)
{
	int rc;
	struct mosquitto_client_msg *tail, *last = NULL;
	uint16_t mid;
	int retries;
	int retain;
	const char *topic;
	int qos;
	uint32_t payloadlen;
	const void *payload;
	int msg_count = 0;

	if(!context || context->sock == -1
			|| (context->state == mosq_cs_connected && !context->id)){
		return MOSQ_ERR_INVAL;
	}

	tail = context->msgs;
	while(tail){
		if(tail->direction == mosq_md_in){
			msg_count++;
		}
		if(tail->state != mosq_ms_queued){
			mid = tail->mid;
			retries = tail->dup;
			retain = tail->retain;
			topic = tail->store->msg.topic;
			qos = tail->qos;
			payloadlen = tail->store->msg.payloadlen;
			payload = tail->store->msg.payload;

			switch(tail->state){
				case mosq_ms_publish_qos0:
					rc = _mosquitto_send_publish(context, mid, topic, payloadlen, payload, qos, retain, retries);
					if(!rc){
						_message_remove(context, &tail, last);
					}else{
						return rc;
					}
					break;

				case mosq_ms_publish_qos1:
					rc = _mosquitto_send_publish(context, mid, topic, payloadlen, payload, qos, retain, retries);
					if(!rc){
						tail->timestamp = mosquitto_time();
						tail->dup = 1; /* Any retry attempts are a duplicate. */
						tail->state = mosq_ms_wait_for_puback;
					}else{
						return rc;
					}
					last = tail;
					tail = tail->next;
					break;

				case mosq_ms_publish_qos2:
					rc = _mosquitto_send_publish(context, mid, topic, payloadlen, payload, qos, retain, retries);
					if(!rc){
						tail->timestamp = mosquitto_time();
						tail->dup = 1; /* Any retry attempts are a duplicate. */
						tail->state = mosq_ms_wait_for_pubrec;
					}else{
						return rc;
					}
					last = tail;
					tail = tail->next;
					break;
				
				case mosq_ms_send_pubrec:
					rc = _mosquitto_send_pubrec(context, mid);
					if(!rc){
						tail->state = mosq_ms_wait_for_pubrel;
					}else{
						return rc;
					}
					last = tail;
					tail = tail->next;
					break;

				case mosq_ms_resend_pubrel:
					rc = _mosquitto_send_pubrel(context, mid, true);
					if(!rc){
						tail->state = mosq_ms_wait_for_pubcomp;
					}else{
						return rc;
					}
					last = tail;
					tail = tail->next;
					break;

				case mosq_ms_resend_pubcomp:
					rc = _mosquitto_send_pubcomp(context, mid);
					if(!rc){
						tail->state = mosq_ms_wait_for_pubrel;
					}else{
						return rc;
					}
					last = tail;
					tail = tail->next;
					break;

				default:
					last = tail;
					tail = tail->next;
					break;
			}
		}else{
			/* state == mosq_ms_queued */
			if(tail->direction == mosq_md_in && (max_inflight == 0 || msg_count < max_inflight)){
				if(tail->qos == 2){
					tail->state = mosq_ms_send_pubrec;
				}
			}else{
				last = tail;
				tail = tail->next;
			}
		}
	}

	return MOSQ_ERR_SUCCESS;
}