std::shared_ptr<T> allocate_observer(Args&&... args) { void* ptr = allocate_observer(); if (ptr == nullptr) return std::shared_ptr<T>(); auto deleter = [this](observer* o) { o->~observer(); free_observer(o); }; return std::shared_ptr<T>(new (ptr) T(std::forward<Args>(args)...), deleter); }
smcp_status_t smcp_observable_update(smcp_observable_t context, uint8_t key) { smcp_status_t ret = SMCP_STATUS_OK; smcp_t const interface = smcp_get_current_instance(); int8_t i; #if !SMCP_EMBEDDED context->interface = interface; #endif if(interface->inbound.is_fake || interface->inbound.is_dupe) { goto bail; } for(i = context->first_observer-1; i >= 0; i = observer_table[i].next - 1) { if(observer_table[i].key != key) continue; if(smcp_inbound_is_related_to_async_response(&observer_table[i].async_response)) break; } if(interface->inbound.has_observe_option) { if(i == -1) { i = get_unused_observer_index(); if(i == -1) goto bail; if(context->last_observer == 0) { context->first_observer = context->last_observer = i + 1; } else { observer_table[context->last_observer-1].next = i +1; context->last_observer = i + 1; } observer_table[i].key = key; observer_table[i].seq = 0; observer_table[i].observable = context; } smcp_start_async_response(&observer_table[i].async_response,SMCP_ASYNC_RESPONSE_FLAG_DONT_ACK); ret = smcp_outbound_add_option_uint(COAP_OPTION_OBSERVE,observer_table[i].seq); } else if(i != -1) { free_observer(&observer_table[i]); } bail: return ret; }
static smcp_status_t event_response_handler(int statuscode, struct smcp_observer_s* observer) { if(statuscode==SMCP_STATUS_TIMEOUT) { if(SHOULD_CONFIRM_EVENT_FOR_OBSERVER(observer)) { statuscode = SMCP_STATUS_RESET; } else { statuscode = SMCP_STATUS_OK; } } if(statuscode!=SMCP_STATUS_TRANSACTION_INVALIDATED) { if(statuscode && ((statuscode < COAP_RESULT_200) || (statuscode >= COAP_RESULT_400))) { statuscode = SMCP_STATUS_RESET; } } if(statuscode==SMCP_STATUS_RESET) { free_observer(observer); return SMCP_STATUS_RESET; } return SMCP_STATUS_OK; }