void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq) { struct mosquitto_message_all *message; struct mosquitto_message_all *prev = NULL; assert(mosq); mosq->queue_len = 0; message = mosq->messages; while(message){ message->timestamp = 0; if(message->direction == mosq_md_out){ if(message->msg.qos == 1){ message->state = mosq_ms_wait_puback; }else if(message->msg.qos == 2){ message->state = mosq_ms_wait_pubrec; } mosq->queue_len++; }else{ if(prev){ prev->next = message->next; _mosquitto_message_cleanup(&message); message = prev; }else{ mosq->messages = message->next; _mosquitto_message_cleanup(&message); message = mosq->messages; } } prev = message; message = message->next; } }
void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq) { struct mosquitto_message_all *message; struct mosquitto_message_all *prev = NULL; assert(mosq); pthread_mutex_lock(&mosq->in_message_mutex); message = mosq->in_messages; mosq->in_queue_len = 0; while(message){ mosq->in_queue_len++; message->timestamp = 0; if(message->msg.qos != 2){ if(prev){ prev->next = message->next; _mosquitto_message_cleanup(&message); message = prev; }else{ mosq->in_messages = message->next; _mosquitto_message_cleanup(&message); message = mosq->in_messages; } }else{ /* Message state can be preserved here because it should match * whatever the client has got. */ } prev = message; message = message->next; } mosq->in_messages_last = prev; pthread_mutex_unlock(&mosq->in_message_mutex); pthread_mutex_lock(&mosq->out_message_mutex); mosq->inflight_messages = 0; message = mosq->out_messages; mosq->out_queue_len = 0; while(message){ mosq->out_queue_len++; message->timestamp = 0; if(message->msg.qos > 0){ mosq->inflight_messages++; } if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){ if(message->msg.qos == 1){ message->state = mosq_ms_wait_for_puback; }else if(message->msg.qos == 2){ /* Should be able to preserve state. */ } }else{ message->state = mosq_ms_invalid; } prev = message; message = message->next; } mosq->out_messages_last = prev; pthread_mutex_unlock(&mosq->out_message_mutex); }
int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain) { struct mosquitto_message_all *message; uint16_t local_mid; if(!mosq || !topic || qos<0 || qos>2) return MOSQ_ERR_INVAL; if(strlen(topic) == 0) return MOSQ_ERR_INVAL; if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE; if(_mosquitto_topic_wildcard_len_check(topic) != MOSQ_ERR_SUCCESS) { return MOSQ_ERR_INVAL; } //获取总共发送信息数,并加1返回 local_mid = _mosquitto_mid_generate(mosq); if(mid) { *mid = local_mid; } if(qos == 0) { return _mosquitto_send_publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false); } else { message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all)); if(!message) return MOSQ_ERR_NOMEM; message->next = NULL; message->timestamp = time(NULL); message->direction = mosq_md_out; if(qos == 1) { message->state = mosq_ms_wait_puback; } else if(qos == 2) { message->state = mosq_ms_wait_pubrec; } message->msg.mid = local_mid; message->msg.topic = _mosquitto_strdup(topic); if(!message->msg.topic) { _mosquitto_message_cleanup(&message); return MOSQ_ERR_NOMEM; } if(payloadlen) { message->msg.payloadlen = payloadlen; message->msg.payload = _mosquitto_malloc(payloadlen*sizeof(uint8_t)); if(!message->msg.payload) { _mosquitto_message_cleanup(&message); return MOSQ_ERR_NOMEM; } memcpy(message->msg.payload, payload, payloadlen*sizeof(uint8_t)); } else { message->msg.payloadlen = 0; message->msg.payload = NULL; } message->msg.qos = qos; message->msg.retain = retain; message->dup = false; _mosquitto_message_queue(mosq, message); return _mosquitto_send_publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup); } }
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; }
void _mosquitto_message_cleanup_all(struct mosquitto *mosq) { struct mosquitto_message_all *tmp; assert(mosq); while(mosq->in_messages){ tmp = mosq->in_messages->next; _mosquitto_message_cleanup(&mosq->in_messages); mosq->in_messages = tmp; } while(mosq->out_messages){ tmp = mosq->out_messages->next; _mosquitto_message_cleanup(&mosq->out_messages); mosq->out_messages = tmp; } }
int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir) { struct mosquitto_message_all *message; int rc; assert(mosq); rc = _mosquitto_message_remove(mosq, mid, dir, &message); if(rc == MOSQ_ERR_SUCCESS){ _mosquitto_message_cleanup(&message); } return rc; }
//超过重发限,需要移除消息,返回失败信息,add by lanhuaiyu@20150508 void _mos_message_retry_check_timeout(struct mosquitto *mosq) { time_t now = mosquitto_time(); assert(mosq); struct mosquitto_message_all *cur, *prev = NULL; pthread_mutex_lock(&mosq->out_message_mutex); cur = mosq->out_messages; while(cur){ if (cur->timestamp > 0 && cur->state != mosq_ms_invalid && (now - cur->timestamp) > mosq->max_message_retry) { _mosquitto_log_printf(mosq, MOSQ_LOG_NOTICE, "Message timeout %d will give up;now:%ld timestamp:%ld ", cur->msg.mid,now, cur->timestamp, mosq->max_message_retry); if(prev){ prev->next = cur->next; }else{ mosq->out_messages = cur->next; } mosq->out_queue_len--; if(cur->next == NULL){ mosq->out_messages_last = prev; }else if(!mosq->out_messages){ mosq->out_messages_last = NULL; } if(cur->msg.qos > 0){ mosq->inflight_messages--; } if (mosq->on_publish != NULL) { mosq->on_publish(mosq, mosq->userdata,cur->msg.mid, MOSQ_ERR_MSG_FAILED); } struct mosquitto_message_all* temp_del = cur; cur = cur->next; //need release memory _mosquitto_message_cleanup(&temp_del); } else{ prev = cur; cur = cur->next; } } pthread_mutex_unlock(&mosq->out_message_mutex); }
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 mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain) { struct mosquitto_message_all *message; uint16_t local_mid; int queue_status; if(!mosq || !topic || qos<0 || qos>2) return MOSQ_ERR_INVAL; if(STREMPTY(topic)) return MOSQ_ERR_INVAL; if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE; if(mosquitto_pub_topic_check(topic) != MOSQ_ERR_SUCCESS){ return MOSQ_ERR_INVAL; } local_mid = _mosquitto_mid_generate(mosq); if(mid){ *mid = local_mid; } if(qos == 0){ return _mosquitto_send_publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false); }else{ message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all)); if(!message) return MOSQ_ERR_NOMEM; message->next = NULL; message->timestamp = mosquitto_time(); message->msg.mid = local_mid; message->msg.topic = _mosquitto_strdup(topic); if(!message->msg.topic){ _mosquitto_message_cleanup(&message); return MOSQ_ERR_NOMEM; } if(payloadlen){ message->msg.payloadlen = payloadlen; message->msg.payload = _mosquitto_malloc(payloadlen*sizeof(uint8_t)); if(!message->msg.payload){ _mosquitto_message_cleanup(&message); return MOSQ_ERR_NOMEM; } memcpy(message->msg.payload, payload, payloadlen*sizeof(uint8_t)); }else{ message->msg.payloadlen = 0; message->msg.payload = NULL; } message->msg.qos = qos; message->msg.retain = retain; message->dup = false; pthread_mutex_lock(&mosq->out_message_mutex); printf("================ mosquitto.c ================\n"); printf("#mosq->inflight_messages : %s\n", mosq->inflight_messages); queue_status = _mosquitto_message_queue(mosq, message, mosq_md_out); if(queue_status == 0){ if(qos == 1){ message->state = mosq_ms_wait_for_puback; }else if(qos == 2){ message->state = mosq_ms_wait_for_pubrec; } pthread_mutex_unlock(&mosq->out_message_mutex); return _mosquitto_send_publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup); }else{ message->state = mosq_ms_invalid; pthread_mutex_unlock(&mosq->out_message_mutex); return MOSQ_ERR_SUCCESS; } } }
int _mosquitto_handle_publish(struct mosquitto *mosq) { uint8_t header; struct mosquitto_message_all *message; int rc = 0; uint16_t mid; assert(mosq); message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all)); if(!message) return MOSQ_ERR_NOMEM; header = mosq->in_packet.command; message->direction = mosq_md_in; message->dup = (header & 0x08)>>3; message->msg.qos = (header & 0x06)>>1; message->msg.retain = (header & 0x01); rc = _mosquitto_read_string(&mosq->in_packet, &message->msg.topic); if(rc){ _mosquitto_message_cleanup(&message); return rc; } rc = _mosquitto_fix_sub_topic(&message->msg.topic); if(rc){ _mosquitto_message_cleanup(&message); return rc; } if(!strlen(message->msg.topic)){ _mosquitto_message_cleanup(&message); return MOSQ_ERR_PROTOCOL; } if(message->msg.qos > 0){ rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); if(rc){ _mosquitto_message_cleanup(&message); return rc; } message->msg.mid = (int)mid; } message->msg.payloadlen = mosq->in_packet.remaining_length - mosq->in_packet.pos; if(message->msg.payloadlen){ message->msg.payload = _mosquitto_calloc(message->msg.payloadlen+1, sizeof(uint8_t)); rc = _mosquitto_read_bytes(&mosq->in_packet, message->msg.payload, message->msg.payloadlen); if(rc){ _mosquitto_message_cleanup(&message); return rc; } } _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBLISH (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, message->dup, message->msg.qos, message->msg.retain, message->msg.mid, message->msg.topic, (long)message->msg.payloadlen); message->timestamp = mosquitto_time(); switch(message->msg.qos){ case 0: 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); return MOSQ_ERR_SUCCESS; case 1: rc = _mosquitto_send_puback(mosq, message->msg.mid); 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); return rc; case 2: rc = _mosquitto_send_pubrec(mosq, message->msg.mid); message->state = mosq_ms_wait_for_pubrel; pthread_mutex_lock(&mosq->message_mutex); _mosquitto_message_queue(mosq, message, true); pthread_mutex_unlock(&mosq->message_mutex); return rc; default: return MOSQ_ERR_PROTOCOL; } }