int _mosquitto_handle_pubrel(struct mosquitto *mosq) { uint16_t mid; struct mosquitto_message_all *message = NULL; 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 PUBREL (Mid: %d)", mid); if(!_mosquitto_message_remove(mosq, mid, mosq_md_in, &message)){ /* Only pass the message on if we have removed it from the queue - this * prevents multiple callbacks for the same message. */ if(mosq->on_message){ mosq->on_message(mosq->obj, &message->msg); }else{ _mosquitto_message_cleanup(&message); } } rc = _mosquitto_send_pubcomp(mosq, mid); if(rc) return rc; return MOSQ_ERR_SUCCESS; }
int _mosquitto_handle_pubrel(struct mosquitto_db *db, struct mosquitto *mosq) { uint16_t mid; #ifndef WITH_BROKER struct mosquitto_message_all *message = NULL; #endif int rc; assert(mosq); if(mosq->protocol == mosq_p_mqtt311){ if((mosq->in_packet.command&0x0F) != 0x02){ return MOSQ_ERR_PROTOCOL; } } rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); if(rc) return rc; #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREL from %s (Mid: %d)", mosq->id, mid); if(mqtt3_db_message_release(db, mosq, mid, mosq_md_in)){ /* Message not found. Still send a PUBCOMP anyway because this could be * due to a repeated PUBREL after a client has reconnected. */ } #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREL (Mid: %d)", mosq->id, mid); if(!_mosquitto_message_remove(mosq, mid, mosq_md_in, &message)){ /* Only pass the message on if we have removed it from the queue - this * prevents multiple callbacks for the same message. */ pthread_mutex_lock(&mosq->callback_mutex); if(mosq->on_message){ mosq->in_callback = true; mosq->on_message(mosq, mosq->userdata, &message->msg); mosq->in_callback = false; } pthread_mutex_unlock(&mosq->callback_mutex); _mosquitto_message_cleanup(&message); } #endif rc = _mosquitto_send_pubcomp(mosq, mid); if(rc) return rc; return MOSQ_ERR_SUCCESS; }
int _mosquitto_handle_pubrel(struct mosquitto_db *db, struct mosquitto *mosq) { uint16_t mid; #ifndef WITH_BROKER struct mosquitto_message_all *message = NULL; #endif 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 PUBREL from %s (Mid: %d)", mosq->id, mid); if(mqtt3_db_message_release(db, mosq, mid, mosq_md_in)){ /* Message not found. */ return MOSQ_ERR_SUCCESS; } #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREL (Mid: %d)", mosq->id, mid); if(!_mosquitto_message_remove(mosq, mid, mosq_md_in, &message)){ /* Only pass the message on if we have removed it from the queue - this * prevents multiple callbacks for the same message. */ pthread_mutex_lock(&mosq->callback_mutex); if(mosq->on_message){ mosq->in_callback = true; mosq->on_message(mosq, mosq->userdata, &message->msg); mosq->in_callback = false; } pthread_mutex_unlock(&mosq->callback_mutex); _mosquitto_message_cleanup(&message); } #endif rc = _mosquitto_send_pubcomp(mosq, mid); 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; }