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); } }
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_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_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message) { struct mosquitto_message_all *cur, *prev = NULL; bool found = false; int rc; assert(mosq); assert(message); if(dir == mosq_md_out){ pthread_mutex_lock(&mosq->out_message_mutex); cur = mosq->out_messages; while(cur){ if(cur->msg.mid == mid){ if(prev){ prev->next = cur->next; }else{ mosq->out_messages = cur->next; } *message = cur; 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--; } found = true; break; } prev = cur; cur = cur->next; } if(found){ cur = mosq->out_messages; while(cur){ if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){ if(cur->msg.qos > 0 && cur->state == mosq_ms_invalid){ mosq->inflight_messages++; if(cur->msg.qos == 1){ cur->state = mosq_ms_wait_for_puback; }else if(cur->msg.qos == 2){ cur->state = mosq_ms_wait_for_pubrec; } rc = _mosquitto_send_publish(mosq, cur->msg.mid, cur->msg.topic, cur->msg.payloadlen, cur->msg.payload, cur->msg.qos, cur->msg.retain, cur->dup); if(rc){ pthread_mutex_unlock(&mosq->out_message_mutex); return rc; } } }else{ pthread_mutex_unlock(&mosq->out_message_mutex); return MOSQ_ERR_SUCCESS; } cur = cur->next; } pthread_mutex_unlock(&mosq->out_message_mutex); return MOSQ_ERR_SUCCESS; }else{ pthread_mutex_unlock(&mosq->out_message_mutex); return MOSQ_ERR_NOT_FOUND; } }else{ pthread_mutex_lock(&mosq->in_message_mutex); cur = mosq->in_messages; while(cur){ if(cur->msg.mid == mid){ if(prev){ prev->next = cur->next; }else{ mosq->in_messages = cur->next; } *message = cur; mosq->in_queue_len--; if(cur->next == NULL){ mosq->in_messages_last = prev; }else if(!mosq->in_messages){ mosq->in_messages_last = NULL; } found = true; break; } prev = cur; cur = cur->next; } pthread_mutex_unlock(&mosq->in_message_mutex); if(found){ return MOSQ_ERR_SUCCESS; }else{ return MOSQ_ERR_NOT_FOUND; } } }
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; }
int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message) { struct mosquitto_message_all *cur, *prev = NULL; bool found = false; int rc; assert(mosq); assert(message); if(dir == mosq_md_out){ pthread_mutex_lock(&mosq->out_message_mutex); cur = mosq->out_messages; while(cur){ if(cur->msg.mid == mid){ if(prev){ prev->next = cur->next; }else{ mosq->out_messages = cur->next; } *message = cur; 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--; } found = true; break; } prev = cur; cur = cur->next; } if(found){ //add by lanhuaiyu for log // char *buf = (char*) malloc((*message)->msg.payloadlen+1); // memset(buf, 0, (*message)->msg.payloadlen+1); // memcpy(buf, (*message)->msg.payload, (*message)->msg.payloadlen); // // _mosquitto_log_printf(mosq, MOSQ_LOG_PUBLISH, // "mid:%ld\tSEND\tOK\t%s\t%s", (*message)->msg.mid,mosq->id,buf); // free(buf); cur = mosq->out_messages; while(cur){ if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){ if(cur->msg.qos > 0 && cur->state == mosq_ms_invalid){ mosq->inflight_messages++; if(cur->msg.qos == 1){ cur->state = mosq_ms_wait_for_puback; }else if(cur->msg.qos == 2){ cur->state = mosq_ms_wait_for_pubrec; } rc = _mosquitto_send_publish(mosq, cur->msg.mid, cur->msg.topic, cur->msg.payloadlen, cur->msg.payload, cur->msg.qos, cur->msg.retain, cur->dup); if(rc){ pthread_mutex_unlock(&mosq->out_message_mutex); return rc; } } }else{ pthread_mutex_unlock(&mosq->out_message_mutex); return MOSQ_ERR_SUCCESS; } cur = cur->next; } pthread_mutex_unlock(&mosq->out_message_mutex); return MOSQ_ERR_SUCCESS; }else{ pthread_mutex_unlock(&mosq->out_message_mutex); //modify by lanhuaiyu,重启后接收到上次未完成消息将导致重连;所以注释掉,始终返回MOSQ_ERR_SUCCESS return MOSQ_ERR_NOT_FOUND; // return MOSQ_ERR_SUCCESS; } }else{ pthread_mutex_lock(&mosq->in_message_mutex); cur = mosq->in_messages; while(cur){ if(cur->msg.mid == mid){ if(prev){ prev->next = cur->next; }else{ mosq->in_messages = cur->next; } *message = cur; mosq->in_queue_len--; if(cur->next == NULL){ mosq->in_messages_last = prev; }else if(!mosq->in_messages){ mosq->in_messages_last = NULL; } found = true; break; } prev = cur; cur = cur->next; } pthread_mutex_unlock(&mosq->in_message_mutex); if(found){ return MOSQ_ERR_SUCCESS; }else{ //modify by lanhuaiyu,重启后接收到上次未完成消息将导致重连;所以注释掉,始终返回MOSQ_ERR_SUCCESS return MOSQ_ERR_NOT_FOUND; // return MOSQ_ERR_SUCCESS; } } }