int mosquitto_sub_topic_tokens_free(char ***topics, int count) { int i; if(!topics || !(*topics) || count<1) return MOSQ_ERR_INVAL; for(i=0; i<count; i++){ if((*topics)[i]) _mosquitto_free((*topics)[i]); } _mosquitto_free(*topics); return MOSQ_ERR_SUCCESS; }
static int _subs_clean_session(struct mosquitto_db *db, struct mosquitto *context, struct _mosquitto_subhier *root) { int rc = 0; struct _mosquitto_subhier *child, *last = NULL; struct _mosquitto_subleaf *leaf, *next; if(!root) return MOSQ_ERR_SUCCESS; leaf = root->subs; while(leaf){ if(leaf->context == context){ db->subscription_count--; if(leaf->prev){ leaf->prev->next = leaf->next; }else{ root->subs = leaf->next; } if(leaf->next){ leaf->next->prev = leaf->prev; } next = leaf->next; _mosquitto_free(leaf); leaf = next; }else{ leaf = leaf->next; } } child = root->children; while(child){ _subs_clean_session(db, context, child); if(!child->children && !child->subs && !child->retained){ if(last){ last->next = child->next; }else{ root->children = child->next; } _mosquitto_free(child->topic); _mosquitto_free(child); if(last){ child = last->next; }else{ child = root->children; } }else{ last = child; child = child->next; } } return rc; }
static void _free_acl(struct _mosquitto_acl *acl) { if(!acl) return; if(acl->child){ _free_acl(acl->child); } if(acl->next){ _free_acl(acl->next); } if(acl->topic){ _mosquitto_free(acl->topic); } _mosquitto_free(acl); }
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char **argv; int argc = 1; char *token; char *saveptr = NULL; int rc; argv = _mosquitto_malloc(sizeof(char *)*1); argv[0] = "mosquitto"; token = strtok_r(lpCmdLine, " ", &saveptr); while(token){ argc++; argv = _mosquitto_realloc(argv, sizeof(char *)*argc); if(!argv){ fprintf(stderr, "Error: Out of memory.\n"); return MOSQ_ERR_NOMEM; } argv[argc-1] = token; token = strtok_r(NULL, " ", &saveptr); } rc = main(argc, argv); _mosquitto_free(argv); return rc; }
int mosquitto_unpwd_cleanup(struct _mosquitto_db *db) { struct _mosquitto_unpwd *tail; if(!db) return MOSQ_ERR_INVAL; while(db->unpwd){ tail = db->unpwd->next; if(db->unpwd->password) _mosquitto_free(db->unpwd->password); if(db->unpwd->username) _mosquitto_free(db->unpwd->username); _mosquitto_free(db->unpwd); db->unpwd = tail; } return MOSQ_ERR_SUCCESS; }
static int _sub_add(struct mosquitto_db *db, struct mosquitto *context, int qos, struct _mosquitto_subhier *subhier, struct _sub_token *tokens) { struct _mosquitto_subhier *branch, *last = NULL; struct _mosquitto_subleaf *leaf, *last_leaf; if(!tokens){ if(context){ leaf = subhier->subs; last_leaf = NULL; while(leaf){ if(!strcmp(leaf->context->id, context->id)){ /* Client making a second subscription to same topic. Only * need to update QoS. Return -1 to indicate this to the * calling function. */ leaf->qos = qos; return -1; } last_leaf = leaf; leaf = leaf->next; } leaf = _mosquitto_malloc(sizeof(struct _mosquitto_subleaf)); if(!leaf) return MOSQ_ERR_NOMEM; leaf->next = NULL; leaf->context = context; leaf->qos = qos; if(last_leaf){ last_leaf->next = leaf; leaf->prev = last_leaf; }else{ subhier->subs = leaf; leaf->prev = NULL; } db->subscription_count++; } return MOSQ_ERR_SUCCESS; } branch = subhier->children; while(branch){ if(!strcmp(branch->topic, tokens->topic)){ return _sub_add(db, context, qos, branch, tokens->next); } last = branch; branch = branch->next; } /* Not found */ branch = _mosquitto_calloc(1, sizeof(struct _mosquitto_subhier)); if(!branch) return MOSQ_ERR_NOMEM; branch->topic = _mosquitto_strdup(tokens->topic); if(!branch->topic){ _mosquitto_free(branch); return MOSQ_ERR_NOMEM; } if(!last){ subhier->children = branch; }else{ last->next = branch; } return _sub_add(db, context, qos, branch, tokens->next); }
int _mosquitto_send_connack(struct mosquitto *context, int result) {//发送一个带2个数字的CONNACK回包给客户端,告诉他连接成功 struct _mosquitto_packet *packet = NULL; int rc; if(context){ if(context->id){ _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending CONNACK to %s (%d)", context->id, result); }else{ _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending CONNACK to %s (%d)", context->address, result); } } packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); if(!packet) return MOSQ_ERR_NOMEM; packet->command = CONNACK; packet->remaining_length = 2; rc = _mosquitto_packet_alloc(packet); if(rc){ _mosquitto_free(packet); return rc; } packet->payload[packet->pos+0] = 0; packet->payload[packet->pos+1] = result; return _mosquitto_packet_queue(context, packet); }
int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers) { #ifdef REAL_WITH_TLS_PSK if(!mosq || !psk || !identity) return MOSQ_ERR_INVAL; /* Check for hex only digits */ if(strspn(psk, "0123456789abcdefABCDEF") < strlen(psk)){ return MOSQ_ERR_INVAL; } mosq->tls_psk = _mosquitto_strdup(psk); if(!mosq->tls_psk) return MOSQ_ERR_NOMEM; mosq->tls_psk_identity = _mosquitto_strdup(identity); if(!mosq->tls_psk_identity){ _mosquitto_free(mosq->tls_psk); return MOSQ_ERR_NOMEM; } if(ciphers){ mosq->tls_ciphers = _mosquitto_strdup(ciphers); if(!mosq->tls_ciphers) return MOSQ_ERR_NOMEM; }else{ mosq->tls_ciphers = NULL; } return MOSQ_ERR_SUCCESS; #else return MOSQ_ERR_NOT_SUPPORTED; #endif }
int _mosquitto_send_real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup) { struct _mosquitto_packet *packet = NULL; int packetlen; int rc; assert(mosq); assert(topic); packetlen = 2+strlen(topic) + payloadlen; if(qos > 0) packetlen += 2; /* For message id */ packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); if(!packet) return MOSQ_ERR_NOMEM; packet->mid = mid; packet->command = PUBLISH | ((dup&0x1)<<3) | (qos<<1) | retain; packet->remaining_length = packetlen; rc = _mosquitto_packet_alloc(packet); if(rc){ _mosquitto_free(packet); return rc; } /* Variable header (topic string) */ _mosquitto_write_string(packet, topic, strlen(topic)); if(qos > 0){ _mosquitto_write_uint16(packet, mid); } /* Payload */ if(payloadlen){ _mosquitto_write_bytes(packet, payload, payloadlen); } return _mosquitto_packet_queue(mosq, packet); }
int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...) { va_list va; char *s; int len; assert(mosq); assert(fmt); pthread_mutex_lock(&mosq->log_callback_mutex); if(mosq->on_log){ len = (int)strlen(fmt) + 500; s = _mosquitto_malloc(len*sizeof(char)); if(!s){ pthread_mutex_unlock(&mosq->log_callback_mutex); return MOSQ_ERR_NOMEM; } va_start(va, fmt); vsnprintf(s, len, fmt, va); va_end(va); s[len-1] = '\0'; /* Ensure string is null terminated. */ mosq->on_log(mosq, mosq->userdata, priority, s); _mosquitto_free(s); } pthread_mutex_unlock(&mosq->log_callback_mutex); return MOSQ_ERR_SUCCESS; }
/* For PUBACK, PUBCOMP, PUBREC, and PUBREL */ int _mosquitto_send_command_with_mid(struct mosquitto *mosq, uint8_t command, uint16_t mid, bool dup) { struct _mosquitto_packet *packet = NULL; int rc; assert(mosq); packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); if(!packet) return MOSQ_ERR_NOMEM; packet->command = command; if(dup){ packet->command |= 8; } packet->remaining_length = 2; rc = _mosquitto_packet_alloc(packet); if(rc){ _mosquitto_free(packet); return rc; } packet->payload[packet->pos+0] = MOSQ_MSB(mid); packet->payload[packet->pos+1] = MOSQ_LSB(mid); //add by lanhuaiyu for log packet->mid = mid; return _mosquitto_packet_queue(mosq, packet); }
/* Convert ////some////over/slashed///topic/etc/etc// * into some/over/slashed/topic/etc/etc */ int _mosquitto_fix_sub_topic(char **subtopic) { char *fixed = NULL; char *token; char *saveptr = NULL; assert(subtopic); assert(*subtopic); if(strlen(*subtopic) == 0) return MOSQ_ERR_SUCCESS; /* size of fixed here is +1 for the terminating 0 and +1 for the spurious / * that gets appended. */ fixed = _mosquitto_calloc(strlen(*subtopic)+2, 1); if(!fixed) return MOSQ_ERR_NOMEM; if((*subtopic)[0] == '/'){ fixed[0] = '/'; } token = strtok_r(*subtopic, "/", &saveptr); while(token){ strcat(fixed, token); strcat(fixed, "/"); token = strtok_r(NULL, "/", &saveptr); } fixed[strlen(fixed)-1] = '\0'; _mosquitto_free(*subtopic); *subtopic = fixed; return MOSQ_ERR_SUCCESS; }
int mqtt3_handle_unsubscribe(struct mosquitto_db *db, struct mosquitto *context) { uint16_t mid; char *sub; if(!context) return MOSQ_ERR_INVAL; _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBSCRIBE from %s", context->id); if(_mosquitto_read_uint16(&context->in_packet, &mid)) return 1; while(context->in_packet.pos < context->in_packet.remaining_length){ sub = NULL; if(_mosquitto_read_string(&context->in_packet, &sub)){ return 1; } if(sub){ _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "\t%s", sub); mqtt3_sub_remove(db, context, sub, &db->subs); _mosquitto_log_printf(NULL, MOSQ_LOG_UNSUBSCRIBE, "%s %s", context->id, sub); _mosquitto_free(sub); } } #ifdef WITH_PERSISTENCE db->persistence_changes++; #endif return _mosquitto_send_command_with_mid(context, UNSUBACK, mid, false); }
void mosquitto_destroy(struct mosquitto *mosq) { if(!mosq) return; _mosquitto_destroy(mosq); _mosquitto_free(mosq); }
static void _message_remove(struct mosquitto *context, struct mosquitto_client_msg **msg, struct mosquitto_client_msg *last) { if(!context || !msg || !(*msg)){ return; } /* FIXME - it would be nice to be able to remove the stored message here if ref_count==0 */ (*msg)->store->ref_count--; if(last){ last->next = (*msg)->next; if(!last->next){ context->last_msg = last; } }else{ context->msgs = (*msg)->next; if(!context->msgs){ context->last_msg = NULL; } } context->msg_count--; if((*msg)->qos > 0){ context->msg_count12--; } _mosquitto_free(*msg); if(last){ *msg = last->next; }else{ *msg = context->msgs; } }
/* For PUBACK, PUBCOMP, PUBREC, and PUBREL */ int _mosquitto_send_command_with_mid(struct _mosquitto_core *core, uint8_t command, uint16_t mid, bool dup) { struct _mosquitto_packet *packet = NULL; int rc; assert(core); packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); if(!packet) return MOSQ_ERR_NOMEM; packet->command = command; if(dup) { packet->command |= 8; } packet->remaining_length = 2; rc = _mosquitto_packet_alloc(packet); if(rc) { _mosquitto_free(packet); return rc; } packet->payload[packet->pos+0] = MOSQ_MSB(mid); packet->payload[packet->pos+1] = MOSQ_LSB(mid); _mosquitto_packet_queue(core, packet); return MOSQ_ERR_SUCCESS; }
int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...) { va_list va; char *s; int len; assert(mosq); assert(fmt); if((mosq->log_priorities & priority) && mosq->log_destinations != MOSQ_LOG_NONE){ len = strlen(fmt) + 500; s = _mosquitto_malloc(len*sizeof(char)); if(!s) return MOSQ_ERR_NOMEM; va_start(va, fmt); vsnprintf(s, len, fmt, va); va_end(va); s[len-1] = '\0'; /* Ensure string is null terminated. */ if(mosq->log_destinations & MOSQ_LOG_STDOUT){ fprintf(stdout, "%s\n", s); fflush(stdout); } if(mosq->log_destinations & MOSQ_LOG_STDERR){ fprintf(stderr, "%s\n", s); fflush(stderr); } _mosquitto_free(s); } return MOSQ_ERR_SUCCESS; }
int mqtt3_handle_unsubscribe(struct mosquitto_db *db, struct mosquitto *context) { uint16_t mid; char *sub; if(!context) return MOSQ_ERR_INVAL; _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBSCRIBE from %s", context->id); if(context->protocol == mosq_p_mqtt311){ if((context->in_packet.command&0x0F) != 0x02){ return MOSQ_ERR_PROTOCOL; } } if(_mosquitto_read_uint16(&context->in_packet, &mid)) return 1; g_epoll_unsubscribe_num++; while(context->in_packet.pos < context->in_packet.remaining_length){ sub = NULL; if(_mosquitto_read_string(&context->in_packet, &sub)){ return 1; } if(sub){ if(!strlen(sub)){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Empty unsubscription string from %s, disconnecting.", context->id); _mosquitto_free(sub); return 1; } if(mosquitto_sub_topic_check(sub)){ _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Invalid unsubscription string from %s, disconnecting.", context->id); _mosquitto_free(sub); return 1; } _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "\t%s", sub); mqtt3_sub_remove(db, context, sub, &db->subs); _mosquitto_log_printf(NULL, MOSQ_LOG_UNSUBSCRIBE, "%s %s", context->id, sub); _mosquitto_free(sub); } } #ifdef WITH_PERSISTENCE db->persistence_changes++; #endif return _mosquitto_send_command_with_mid(context, UNSUBACK, mid, false); }
int _mosquitto_will_clear(struct mosquitto *mosq) { if(!mosq->will) return MOSQ_ERR_SUCCESS; if(mosq->will->topic){ _mosquitto_free(mosq->will->topic); mosq->will->topic = NULL; } if(mosq->will->payload){ _mosquitto_free(mosq->will->payload); mosq->will->payload = NULL; } _mosquitto_free(mosq->will); mosq->will = NULL; return MOSQ_ERR_SUCCESS; }
void mqtt3_context_disconnect(struct mosquitto_db *db, struct mosquitto *ctxt) { if(ctxt->state != mosq_cs_disconnecting && ctxt->will){ if(mosquitto_acl_check(db, ctxt, ctxt->will->topic, MOSQ_ACL_WRITE) == MOSQ_ERR_SUCCESS){ /* Unexpected disconnect, queue the client will. */ mqtt3_db_messages_easy_queue(db, ctxt, ctxt->will->topic, ctxt->will->qos, ctxt->will->payloadlen, ctxt->will->payload, ctxt->will->retain); } } if(ctxt->will){ if(ctxt->will->topic) _mosquitto_free(ctxt->will->topic); if(ctxt->will->payload) _mosquitto_free(ctxt->will->payload); _mosquitto_free(ctxt->will); ctxt->will = NULL; } ctxt->disconnect_t = time(NULL); _mosquitto_socket_close(db, ctxt); }
static int _sub_remove(struct mosquitto_db *db, struct mosquitto *context, struct _mosquitto_subhier *subhier, struct _sub_token *tokens) { struct _mosquitto_subhier *branch, *last = NULL; struct _mosquitto_subleaf *leaf; if(!tokens){ leaf = subhier->subs; while(leaf){ if(leaf->context==context){ db->subscription_count--; if(leaf->prev){ leaf->prev->next = leaf->next; }else{ subhier->subs = leaf->next; } if(leaf->next){ leaf->next->prev = leaf->prev; } _mosquitto_free(leaf); return MOSQ_ERR_SUCCESS; } leaf = leaf->next; } return MOSQ_ERR_SUCCESS; } branch = subhier->children; while(branch){ if(!strcmp(branch->topic, tokens->topic)){ _sub_remove(db, context, branch, tokens->next); if(!branch->children && !branch->subs && !branch->retained){ if(last){ last->next = branch->next; }else{ subhier->children = branch->next; } _mosquitto_free(branch->topic); _mosquitto_free(branch); } return MOSQ_ERR_SUCCESS; } last = branch; branch = branch->next; } return MOSQ_ERR_SUCCESS; }
void mosquitto_destroy(struct mosquitto *mosq) { if(mosq->id) _mosquitto_free(mosq->id); _mosquitto_message_cleanup_all(mosq); if(mosq->will){ if(mosq->will->topic) _mosquitto_free(mosq->will->topic); if(mosq->will->payload) _mosquitto_free(mosq->will->payload); _mosquitto_free(mosq->will); } if(mosq->host){ _mosquitto_free(mosq->host); } #ifdef WITH_SSL if(mosq->ssl){ if(mosq->ssl->ssl){ SSL_free(mosq->ssl->ssl); } if(mosq->ssl->ssl_ctx){ SSL_CTX_free(mosq->ssl->ssl_ctx); } _mosquitto_free(mosq->ssl); } #endif _mosquitto_free(mosq); }
static int _db_client_msg_chunk_restore(mosquitto_db *db, FILE *db_fptr) { dbid_t i64temp, store_id; uint16_t i16temp, slen, mid; uint8_t qos, retain, direction, state, dup; char *client_id = NULL; int rc; read_e(db_fptr, &i16temp, sizeof(uint16_t)); slen = ntohs(i16temp); if(!slen){ _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Corrupt persistent database."); fclose(db_fptr); return 1; } client_id = _mosquitto_calloc(slen+1, sizeof(char)); if(!client_id){ fclose(db_fptr); _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; } read_e(db_fptr, client_id, slen); read_e(db_fptr, &i64temp, sizeof(dbid_t)); store_id = i64temp; read_e(db_fptr, &i16temp, sizeof(uint16_t)); mid = ntohs(i16temp); read_e(db_fptr, &qos, sizeof(uint8_t)); read_e(db_fptr, &retain, sizeof(uint8_t)); read_e(db_fptr, &direction, sizeof(uint8_t)); read_e(db_fptr, &state, sizeof(uint8_t)); read_e(db_fptr, &dup, sizeof(uint8_t)); rc = _db_client_msg_restore(db, client_id, mid, qos, retain, direction, state, dup, store_id); _mosquitto_free(client_id); return rc; error: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: %s.", strerror(errno)); if(db_fptr) fclose(db_fptr); if(client_id) _mosquitto_free(client_id); return 1; }
void mqtt3_db_store_clean(struct mosquitto_db *db) { /* FIXME - this may not be necessary if checks are made when messages are removed. */ struct mosquitto_msg_store *tail, *last = NULL; int i; assert(db); tail = db->msg_store; while(tail){ if(tail->ref_count == 0){ if(tail->source_id) _mosquitto_free(tail->source_id); if(tail->dest_ids){ for(i=0; i<tail->dest_id_count; i++){ if(tail->dest_ids[i]) _mosquitto_free(tail->dest_ids[i]); } _mosquitto_free(tail->dest_ids); } if(tail->msg.topic) _mosquitto_free(tail->msg.topic); if(tail->msg.payload) _mosquitto_free(tail->msg.payload); if(last){ last->next = tail->next; _mosquitto_free(tail); tail = last->next; }else{ db->msg_store = tail->next; _mosquitto_free(tail); tail = db->msg_store; } db->msg_store_count--; }else{ last = tail; tail = tail->next; } } }
int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password) { #ifdef WITH_SOCKS if(!mosq) return MOSQ_ERR_INVAL; if(!host || strlen(host) > 256) return MOSQ_ERR_INVAL; if(port < 1 || port > 65535) return MOSQ_ERR_INVAL; if(mosq->socks5_host){ _mosquitto_free(mosq->socks5_host); } mosq->socks5_host = _mosquitto_strdup(host); if(!mosq->socks5_host){ return MOSQ_ERR_NOMEM; } mosq->socks5_port = port; if(mosq->socks5_username){ _mosquitto_free(mosq->socks5_username); } if(mosq->socks5_password){ _mosquitto_free(mosq->socks5_password); } if(username){ mosq->socks5_username = _mosquitto_strdup(username); if(!mosq->socks5_username){ return MOSQ_ERR_NOMEM; } if(password){ mosq->socks5_password = _mosquitto_strdup(password); if(!mosq->socks5_password){ _mosquitto_free(mosq->socks5_username); return MOSQ_ERR_NOMEM; } } } return MOSQ_ERR_SUCCESS; #else return MOSQ_ERR_NOT_SUPPORTED; #endif }
struct mosquitto *mqtt3_context_init(struct mosquitto_db *db, mosq_sock_t sock) { struct mosquitto *context; char address[1024]; context = _mosquitto_calloc(1, sizeof(struct mosquitto)); if(!context) return NULL; context->state = mosq_cs_new; context->sock = sock; context->last_msg_in = mosquitto_time(); context->next_msg_out = mosquitto_time() + 60; context->keepalive = 60; /* Default to 60s */ context->clean_session = true; context->disconnect_t = 0; context->id = NULL; context->last_mid = 0; context->will = NULL; context->username = NULL; context->password = NULL; context->listener = NULL; context->acl_list = NULL; /* is_bridge records whether this client is a bridge or not. This could be * done by looking at context->bridge for bridges that we create ourself, * but incoming bridges need some other way of being recorded. */ context->is_bridge = false; context->in_packet.payload = NULL; _mosquitto_packet_cleanup(&context->in_packet); context->out_packet = NULL; context->current_out_packet = NULL; context->address = NULL; if((int)sock >= 0){ if(!_mosquitto_socket_get_address(sock, address, 1024)){ context->address = _mosquitto_strdup(address); } if(!context->address){ /* getpeername and inet_ntop failed and not a bridge */ _mosquitto_free(context); return NULL; } } context->bridge = NULL; context->msgs = NULL; context->last_msg = NULL; context->msg_count = 0; context->msg_count12 = 0; #ifdef WITH_TLS context->ssl = NULL; #endif if((int)context->sock >= 0){ HASH_ADD(hh_sock, db->contexts_by_sock, sock, sizeof(context->sock), context); } return context; }
int _mosquitto_packet_write(struct mosquitto *mosq) { ssize_t write_length; struct _mosquitto_packet *packet; if(!mosq) return MOSQ_ERR_INVAL; if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; while(mosq->out_packet){ packet = mosq->out_packet; while(packet->to_process > 0){ write_length = _mosquitto_net_write(mosq, &(packet->payload[packet->pos]), packet->to_process); if(write_length > 0){ #ifdef WITH_BROKER bytes_sent += write_length; #endif packet->to_process -= write_length; packet->pos += write_length; }else{ #ifdef WIN32 errno = WSAGetLastError(); #endif if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){ return MOSQ_ERR_SUCCESS; }else{ switch(errno){ case COMPAT_ECONNRESET: return MOSQ_ERR_CONN_LOST; default: return MOSQ_ERR_ERRNO; } } } } #ifdef WITH_BROKER msgs_sent++; #else if(((packet->command)&0xF6) == PUBLISH && mosq->on_publish){ /* This is a QoS=0 message */ mosq->in_callback = true; mosq->on_publish(mosq->obj, packet->mid); mosq->in_callback = false; } #endif /* Free data and reset values */ mosq->out_packet = packet->next; _mosquitto_packet_cleanup(packet); _mosquitto_free(packet); mosq->last_msg_out = time(NULL); } return MOSQ_ERR_SUCCESS; }
int _mosquitto_handle_suback(struct mosquitto *mosq) { uint16_t mid; uint8_t qos; int *granted_qos; int qos_count; int i = 0; int rc; assert(mosq); #ifdef WITH_BROKER _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received SUBACK from %s", mosq->id); #else _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received SUBACK1", mosq->id); #endif rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); if(rc) return rc; qos_count = mosq->in_packet.remaining_length - mosq->in_packet.pos; granted_qos = _mosquitto_malloc(qos_count*sizeof(int)); if(!granted_qos) return MOSQ_ERR_NOMEM; while(mosq->in_packet.pos < mosq->in_packet.remaining_length){ rc = _mosquitto_read_byte(&mosq->in_packet, &qos); if(rc){ _mosquitto_free(granted_qos); return rc; } granted_qos[i] = (int)qos; i++; } #ifndef WITH_BROKER pthread_mutex_lock(&mosq->callback_mutex); if(mosq->on_subscribe){ mosq->in_callback = true; mosq->on_subscribe(mosq, mosq->userdata, mid, qos_count, granted_qos); mosq->in_callback = false; } pthread_mutex_unlock(&mosq->callback_mutex); #endif _mosquitto_free(granted_qos); return MOSQ_ERR_SUCCESS; }
void mqtt3_context_disconnect(struct mosquitto_db *db, struct mosquitto *ctxt) { if(ctxt->state != mosq_cs_disconnecting && ctxt->will){ /* Unexpected disconnect, queue the client will. */ mqtt3_db_messages_easy_queue(db, ctxt, ctxt->will->topic, ctxt->will->qos, ctxt->will->payloadlen, ctxt->will->payload, ctxt->will->retain); } if(ctxt->will){ if(ctxt->will->topic) _mosquitto_free(ctxt->will->topic); if(ctxt->will->payload) _mosquitto_free(ctxt->will->payload); _mosquitto_free(ctxt->will); ctxt->will = NULL; } if(ctxt->listener){ ctxt->listener->client_count--; assert(ctxt->listener->client_count >= 0); ctxt->listener = NULL; } ctxt->disconnect_t = mosquitto_time(); _mosquitto_socket_close(ctxt); }
void mqtt3_bridge_packet_cleanup(struct mosquitto *context) { struct _mosquitto_packet *packet; if(!context) return; if(context->current_out_packet){ _mosquitto_packet_cleanup(context->current_out_packet); _mosquitto_free(context->current_out_packet); context->current_out_packet = NULL; } while(context->out_packet){ _mosquitto_packet_cleanup(context->out_packet); packet = context->out_packet; context->out_packet = context->out_packet->next; _mosquitto_free(packet); } context->out_packet = NULL; context->out_packet_last = NULL; _mosquitto_packet_cleanup(&(context->in_packet)); }