static void _handle_client_message(struct cfw_message *msg, void *data) { (void)data; switch (CFW_MESSAGE_ID(msg)) { case MSG_ID_CFW_OPEN_SERVICE: { /* We have passed the allocated cnx as an opaque data */ struct _svc_cnx *cnx = CFW_MESSAGE_PRIV(msg); /* Get the service parameters from the message and store them locally */ cfw_open_conn_rsp_msg_t *con_msg = (cfw_open_conn_rsp_msg_t *)msg; cnx->sh = (svc_client_handle_t *)(con_msg->client_handle); cnx->src_port = con_msg->port; cfw_msg_free(msg); list_add(&_services, (list_t *)cnx); break; } case MSG_ID_CFW_CLOSE_SERVICE: { struct _svc_cnx *cnx = CFW_MESSAGE_PRIV(msg); list_remove(&_services, (list_t *)cnx); bfree(cnx); cfw_msg_free(msg); break; } case MSG_ID_CFW_SVC_AVAIL_EVT: { struct _svc_cnx *cnx = CFW_MESSAGE_PRIV(msg); if (((cfw_svc_available_evt_msg_t*)msg)->service_id == cnx->service_id) { cfw_open_service(_proxy_handle, cnx->service_id, cnx); } cfw_msg_free(msg); break; } default: { /* Find the service connection based on the message source port */ struct _svc_cnx *cnx = (struct _svc_cnx*) list_find_first(&_services, _cmp_port, &(CFW_MESSAGE_SRC(msg))); if (cnx) { cnx->cb(msg, cnx->data); } else { cfw_msg_free(msg); } break; } } }
BleStatus ble_client_init(ble_client_gap_event_cb_t gap_event_cb, void *gap_event_param, ble_client_gatts_event_cb_t gatts_event_cb, void *gatts_event_param) { BleStatus status; uint32_t delay_until; cfw_platform_nordic_init(); client_handle = cfw_init(cfw_get_service_queue(), ble_core_client_handle_message, NULL); sync.response = 0; if (cfw_register_svc_available(client_handle, BLE_CORE_SERVICE_ID, NULL)) return BLE_STATUS_ERROR; /* Wait for response messages */ wait_for_condition(sync.response, status); if (status != BLE_STATUS_SUCCESS) return status; /* We need to wait for ~1 ms before continuing */ delay_until = get_uptime_32k() + TIMEOUT_TICKS_1MS; while (get_uptime_32k() < delay_until); sync.response = 0; cfw_open_service(client_handle, BLE_CORE_SERVICE_ID, NULL); /* Wait for response messages */ wait_for_condition(sync.response, status); if (status != BLE_STATUS_SUCCESS) return status; ble_client_gap_event_cb = gap_event_cb; ble_client_gap_event_param = gap_event_param; ble_client_gatts_event_cb = gatts_event_cb; ble_client_gatts_event_param = gatts_event_param; return sync.status; }