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; }
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); }
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; }
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; }