diff options
Diffstat (limited to 'ucs2-afb/ucs_binding.c')
-rw-r--r-- | ucs2-afb/ucs_binding.c | 101 |
1 files changed, 97 insertions, 4 deletions
diff --git a/ucs2-afb/ucs_binding.c b/ucs2-afb/ucs_binding.c index b72aca9..553ed36 100644 --- a/ucs2-afb/ucs_binding.c +++ b/ucs2-afb/ucs_binding.c @@ -68,11 +68,15 @@ typedef struct { typedef struct { struct afb_event node_event; - } EventData_t; +typedef struct { + struct afb_event rx_event; +} EventDataRx_t; + static ucsContextT *ucsContextS = NULL; static EventData_t *eventData = NULL; +static EventDataRx_t *eventDataRx = NULL; PUBLIC void UcsXml_CB_OnError(const char format[], uint16_t vargsCnt, ...) { /*AFB_DEBUG (afbIface, format, args); */ @@ -208,12 +212,74 @@ void UCSI_CB_OnStop(void *pTag) { sd_event_add_time(afb_daemon_get_event_loop(), NULL, CLOCK_MONOTONIC, 0, 0, OnStopCB, pTag); } +/* helper function: wraps Rx message in json and triggers notification */ +STATIC void NotifyEventRxMsg(uint16_t src_addr, uint16_t msg_id, uint8_t *data_ptr, uint32_t data_sz) { + + if (!eventDataRx) + return; + + if (data_sz > CTRL_MAX_DATA_SZ) { + AFB_NOTICE("RX-MSG: discarded, payload exceeds %d bytes", CTRL_MAX_DATA_SZ); + return; + } + + json_object *j_event_info = json_object_new_object(); + json_object *j_array = json_object_new_array(); + + if (!j_event_info || !j_array) { + if (j_event_info) { + json_object_put(j_event_info); + } + if (j_array) { + json_object_put(j_array); + } + AFB_ERROR("Failed to create json objects"); + return; + } + + uint32_t cnt = 0U; + for (cnt = 0U; cnt < data_sz; cnt++) { + json_object_array_add(j_array, json_object_new_int(data_ptr[cnt])); + } + + json_object_object_add(j_event_info, "node", json_object_new_int(src_addr)); + json_object_object_add(j_event_info, "msgid", json_object_new_int(msg_id)); + json_object_object_add(j_event_info, "data", j_array); + + afb_event_push(eventDataRx->rx_event, j_event_info); +} + +/** Asynchronous processing of Rx messages in mainloop is recommended */ +STATIC int OnAmsMessageReceivedCB (sd_event_source *source, void *pTag) { + ucsContextT *ucsContext = (ucsContextT*) pTag; + uint32_t data_sz = 0U; + uint8_t *data_ptr = NULL; + uint16_t msg_id = 0U; + uint16_t src_addr = 0U; + + while (UCSI_GetAmsMessage(&ucsContext->ucsiData, &msg_id, &src_addr, &data_ptr, &data_sz)) { + NotifyEventRxMsg(src_addr, msg_id, data_ptr, data_sz); + AFB_DEBUG("RX-MSG: src=0x%04X, msg_id=0x%04X, size=%d", src_addr, msg_id, data_sz); + UCSI_ReleaseAmsMessage(&ucsContext->ucsiData); + } + + return 0; +} + /** This callback will be raised, when ever an applicative message on the control channel arrived */ void UCSI_CB_OnAmsMessageReceived(void *pTag) { - /* If not interested, just ignore this event. - Otherwise UCSI_GetAmsMessage may now be called asynchronous (mainloop) to get the content. - Don't forget to call UCSI_ReleaseAmsMessage after that */ + static sd_event_source *src_ptr = NULL; + + if (!src_ptr) + { + /* first time usage: create and trigger event source */ + sd_event_add_defer(afb_daemon_get_event_loop(), &src_ptr, &OnAmsMessageReceivedCB, pTag); + } + else + { + sd_event_source_set_enabled(src_ptr, SD_EVENT_ONESHOT); + } } void UCSI_CB_OnRouteResult(void *pTag, uint16_t routeId, bool isActive, uint16_t connectionLabel) @@ -511,6 +577,33 @@ OnExitError: return; } +PUBLIC void ucs2_subscriberx (struct afb_req request) { + + if (!eventDataRx) { + + eventDataRx = malloc(sizeof(EventDataRx_t)); + if (eventDataRx) { + eventDataRx->rx_event = afb_daemon_make_event("rx-message"); + } + + if (!eventDataRx || !afb_event_is_valid(eventDataRx->rx_event)) { + afb_req_fail_f(request, "create-event", "Cannot create or register event"); + goto OnExitError; + } + } + + if (afb_req_subscribe(request, eventDataRx->rx_event) != 0) { + + afb_req_fail_f (request, "subscribe-event", "Cannot subscribe to event"); + goto OnExitError; + } + + afb_req_success(request,NULL,"event subscription successful"); + +OnExitError: + return; +} + static json_object * ucs2_validate_command (struct afb_req request, const char* func_name) { |