コード例 #1
0
/*******************************************************************************
 *********************** SERVICE IMPLEMENTATION ********************************
 ******************************************************************************/
void handle_get(struct cfw_message *msg)
{
	circular_storage_get_req_msg_t *req =
		(circular_storage_get_req_msg_t *)msg;
	circular_storage_service_get_rsp_msg_t *resp =
		(circular_storage_service_get_rsp_msg_t *)cfw_alloc_rsp_msg(
			msg,
			MSG_ID_CIRCULAR_STORAGE_SERVICE_GET_RSP,
			sizeof(*resp));
	DRIVER_API_RC ret = DRV_RC_FAIL;
	uint32_t i = 0;

	for (i = 0; i < cir_storage_config.cir_storage_count; i++) {
		if (cir_storage_config.cir_storage_list[i].key == req->key) {
			if (cir_storage_config.cir_storage_list[i].storage !=
			    NULL) {
				ret = DRV_RC_OK;
				resp->storage =
					cir_storage_config.cir_storage_list[i].
					storage;
			} else {
				pr_debug(
					LOG_MODULE_MAIN,
					"Circular storage init: Flash SPI init failed");
				ret = DRV_RC_FAIL;
			}
		}
	}

	resp->status = ret;
	cfw_send_message(resp);
}
コード例 #2
0
/**@brief Callback to manage results of requests of setting ADC measure interval
 * @param[in]  msg  Request message.
 */
static void handle_battery_set_measure_interval(struct cfw_message *msg)
{
	uint16_t new_period_ms = 0;
	battery_cfg_type_t cfg_period;

	struct cfw_message *resp;

	resp = cfw_alloc_rsp_msg(
		msg,
		MSG_ID_BATTERY_SERVICE_SET_MEASURE_INTERVAL_RSP,
		sizeof(*resp));
	new_period_ms =
		((battery_set_measure_interval_msg_t *)msg)->period_cfg.
		new_period_ms;
	cfg_period =
		((battery_set_measure_interval_msg_t *)msg)->period_cfg.
		cfg_type;
	if (cfg_period == CFG_TEMPERATURE) {
		fg_set_temp_interval(new_period_ms);
	} else if (cfg_period == CFG_VOLTAGE) {
		fg_set_voltage_interval(new_period_ms);
	}
	cfw_send_message(resp);

	return;
}
コード例 #3
0
/**@brief Callback to manage results of requests of setting the battery level alarm threshold.
 * @param[in]  msg    Request message.
 *             msg_id Type of level alarm threshold.
 */
static void handle_bs_set_level_alarm(struct cfw_message *msg, int msg_id)
{
	int rsp_id = 0;
	int level_alarm_threshold = 0;

	fg_status_t (*fg_set_alarm)(uint8_t) = NULL;
	battery_set_level_alarm_rsp_msg_t *resp;

	switch (msg_id) {
	case MSG_ID_BATTERY_SERVICE_SET_LOW_LEVEL_ALARM_REQ:
		rsp_id = MSG_ID_BATTERY_SERVICE_SET_LOW_LEVEL_ALARM_RSP;
		fg_set_alarm = &fg_set_low_level_alarm_threshold;
		break;
	case MSG_ID_BATTERY_SERVICE_SET_CRITICAL_LEVEL_ALARM_REQ:
		rsp_id = MSG_ID_BATTERY_SERVICE_SET_CRITICAL_LEVEL_ALARM_RSP;
		fg_set_alarm = &fg_set_critical_level_alarm_threshold;
		break;
	default:
		assert(0);
		break;
	}
	level_alarm_threshold =
		((battery_set_level_alarm_msg_t *)msg)->level_alarm;
	resp = (battery_set_level_alarm_rsp_msg_t *)cfw_alloc_rsp_msg(
		msg, rsp_id, sizeof(*resp));
	resp->status = BATTERY_STATUS_ERROR_FUEL_GAUGE;
	if (FG_STATUS_SUCCESS == fg_set_alarm(level_alarm_threshold))
		resp->status = BATTERY_STATUS_SUCCESS;
	cfw_send_message(resp);

	return;
}
コード例 #4
0
/**@brief Callback to manage results of requests for getting the battery information.
 * @param[in]  msg  Request message.
 */
static void handle_battery_service_get_info(struct cfw_message *msg)
{
	battery_service_info_request_rsp_msg_t *resp =
		(battery_service_info_request_rsp_msg_t *)cfw_alloc_rsp_msg(
			msg,
			MSG_ID_BATTERY_SERVICE_GET_BATTERY_INFO_RSP,
			sizeof(
				*resp));

	switch (((battery_status_msg_t *)msg)->batt_info_id) {
	case BATTERY_DATA_LEVEL:
		handle_bs_get_soc(&resp->battery_soc);
		resp->status = resp->battery_soc.status;
		break;
	case BATTERY_DATA_STATUS:
		resp->battery_charging.is_charging = charging_sm_is_charging();
		resp->status = resp->battery_charging.status =
				       BATTERY_STATUS_SUCCESS;
		break;
	case BATTERY_DATA_VBATT:
		handle_bs_get_voltage(&resp->battery_voltage);
		resp->status = resp->battery_voltage.status;
		break;
	case BATTERY_DATA_TEMPERATURE:
		handle_bs_get_temperature(&resp->battery_temperature);
		resp->status = resp->battery_temperature.status;
		break;
	case BATTERY_DATA_CHARGE_CYCLE:
		handle_bs_get_charge_cycle(&resp->battery_charge_cycle);
		resp->status = resp->battery_charge_cycle.status;
		break;
	case BATTERY_DATA_CHARGER_STATUS:
		resp->battery_charger_connected.is_charger_connected =
			charging_sm_is_charger_connected();
		resp->status = resp->battery_charger_connected.status =
				       BATTERY_STATUS_SUCCESS;
		break;
	case BATTERY_DATA_CHARGER_TYPE:
		resp->battery_charging_source.charging_source =
			charging_sm_get_source();
		resp->status = resp->battery_charging_source.status =
				       BATTERY_STATUS_SUCCESS;
		break;
	case BATTERY_DATA_LOW_LEVEL_ALARM:
		handle_bs_get_low_level_alarm(&resp->battery_low_level_alarm);
		resp->status = resp->battery_low_level_alarm.status;
		break;
	case BATTERY_DATA_CRITICAL_LEVEL_ALARM:
		handle_bs_get_critical_level_alarm(
			&resp->battery_critical_level_alarm);
		resp->status = resp->battery_critical_level_alarm.status;
		break;
	default:
		break;
	}

	resp->batt_info_id = ((battery_status_msg_t *)msg)->batt_info_id;
	cfw_send_message(resp);
	return;
}
コード例 #5
0
void handle_erase_block(struct cfw_message *msg)
{
    ll_storage_erase_block_req_msg_t * req = (ll_storage_erase_block_req_msg_t *) msg;
    ll_storage_erase_block_rsp_msg_t * resp = (ll_storage_erase_block_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
            MSG_ID_LL_ERASE_BLOCK_RSP, sizeof(*resp));

    flash_device_t flash;
    uint16_t flash_id = 0;
    int16_t partition_index = -1;
    uint32_t i = 0;
    DRIVER_API_RC ret = DRV_RC_FAIL;

    if (req->no_blks == 0) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Block: Invalid write size");
        ret = DRV_RC_INVALID_OPERATION;
        goto send;
    }

    for (i = 0; i < ll_storage_config.no_part; i++)
        if (ll_storage_config.partitions[i].partition_id == req->partition_id) {
            flash_id = ll_storage_config.partitions[i].flash_id;
            partition_index = i;
            break;
        }

    if (partition_index == -1) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Block: Invalid partition ID");
        ret = DRV_RC_FAIL;
        goto send;
    }

    uint16_t last_block = ll_storage_config.partitions[partition_index].start_block + req->st_blk + req->no_blks - 1;

    if (last_block > ll_storage_config.partitions[partition_index].end_block) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Block: Partition overflow");
        ret = DRV_RC_OUT_OF_MEM;
        goto send;
    }

    flash = flash_devices[flash_id];

    if (flash.flash_location == EMBEDDED_FLASH)
    {
        ret = soc_flash_block_erase(ll_storage_config.partitions[partition_index].start_block + req->st_blk, req->no_blks);
    }
#ifdef CONFIG_SPI_FLASH
    else
    {
        // SERIAL_FLASH
        ret = spi_flash_sector_erase((struct device *)&pf_sba_device_flash_spi0,
            ll_storage_config.partitions[partition_index].start_block + req->st_blk, req->no_blks);
    }
#endif

send:
    resp->rsp_header.status = ret;
    cfw_send_message(resp);
}
コード例 #6
0
ファイル: ble_service.c プロジェクト: CurieBSP/main
static void ble_is_not_enabled_rsp(struct cfw_message *msg, int status)
{
	struct ble_enable_rsp *resp =
	    (struct ble_enable_rsp *)cfw_alloc_rsp_msg(msg,
			    /* translate msg from req to rsp */
						(CFW_MESSAGE_ID(msg) ^ MSG_ID_BLE_SERVICE_BASE)
						| MSG_ID_BLE_SERVICE_RSP,
						sizeof(*resp));
	resp->status = status;
	cfw_send_message(resp);
}
コード例 #7
0
ファイル: ble_service.c プロジェクト: CurieBSP/main
static void handle_msg_id_ble_dbg(struct cfw_message *msg)
{
	struct nble_debug_params params;
	struct ble_dbg_req_rsp *resp = (void *)
		cfw_alloc_rsp_msg(msg, MSG_ID_BLE_DBG_RSP, sizeof(*resp));
	struct ble_dbg_req_rsp *req = (struct ble_dbg_req_rsp *) msg;

	params.u0 = req->u0;
	params.u1 = req->u1;

	nble_gap_dbg_req(&params, resp);
}
コード例 #8
0
void handle_clear(struct cfw_message *msg)
{
	ll_storage_clear_req_msg_t * req = (ll_storage_clear_req_msg_t *) msg;
	ll_storage_clear_rsp_msg_t * resp =
		(ll_storage_clear_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
		MSG_ID_LL_CLEAR_RSP, sizeof(*resp));

	if (cir_storage_clear((cir_storage_t *)req->storage, req->size) == CBUFFER_STORAGE_SUCCESS)
		resp->rsp_header.status = DRV_RC_OK;
	else
		resp->rsp_header.status = DRV_RC_FAIL;

	cfw_send_message(resp);
}
コード例 #9
0
/**@brief Function to handle terminated audio streams.
 *
 * @details In this function played stream is freed. A new stream is
 *          initialized if necessary. Once all streams have been
 *          played, response message is built and sent.
 * @param[in]  msg  Request message.
 * @return   none
 */
static void ui_handle_as_stream_end(message_t * msg)
{
    rsp_message_t *resp;
    uint16_t resp_id;

    audio_stream_mgr_evt_msg *evt = (audio_stream_mgr_evt_msg *) msg;

    /* Need to filter MSG_ID_AS_STREAM_XX messages, as the UI SVC is not */
    /* the only one listening to them.                                   */
    if ((evt->sHandle != tone_stream) && (evt->sHandle != sps_stream))
        return;

    pr_debug(LOG_MODULE_UI_SVC,
        "Audio stream 0x%08x ended - reason %d",
        evt->sHandle,
        evt->sHandle->reason);

    if (tone_stream) {
        as_stream_destroy(tone_stream);
        tone_stream = NULL;
    }

    /* Check if more data to play. */
    if (sps_stream) {
        /* Play done. */
        as_stream_destroy(sps_stream);
        sps_stream = NULL;
        sps_id_stream_pending = 0;
    } else if (sps_id_stream_pending) {
        /* Play speech sequence. */
        ui_sps_play_init(sps_id_stream_pending, as_stream_priv);
    }

    if (!tone_stream && !sps_stream) {
        /* Request completed. */
        if (ui_audio_req->id == MSG_ID_UI_LPAL_REQ)
            resp_id = MSG_ID_UI_LPAL_RSP;
        else
            resp_id = MSG_ID_UI_ASR_RSP;

        resp = cfw_alloc_rsp_msg(ui_audio_req, resp_id, sizeof(*resp));
        if (resp == NULL) force_panic();

        resp->status = evt->sHandle->reason;
        cfw_send_message(resp);

        cfw_msg_free(ui_audio_req);
        ui_audio_req = NULL;
    }
}
コード例 #10
0
ファイル: ble_service.c プロジェクト: CurieBSP/main
static void handle_ble_disable(struct ble_enable_req *req, struct _ble_service_cb *p_cb)
{
	struct ble_enable_rsp *resp;

	pr_debug(LOG_MODULE_BLE, "ble_disable");
	p_cb->ble_state = BLE_ST_DISABLED;

	bt_le_adv_stop();

	resp = (void *)cfw_alloc_rsp_msg(&req->header,
				MSG_ID_BLE_ENABLE_RSP,
				sizeof(*resp));
	cfw_send_message(resp);

}
コード例 #11
0
void handle_push(struct cfw_message *msg)
{
	ll_storage_push_req_msg_t * req = (ll_storage_push_req_msg_t *) msg;
	ll_storage_push_rsp_msg_t * resp =
		(ll_storage_push_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
		MSG_ID_LL_PUSH_RSP, sizeof(*resp));
	DRIVER_API_RC ret = DRV_RC_FAIL;

	if (cir_storage_push((cir_storage_t *)req->storage, req->buffer, req->size) ==
			CBUFFER_STORAGE_SUCCESS) {
			ret = DRV_RC_OK;
	}

	resp->rsp_header.status = ret;
	cfw_send_message(resp);
}
コード例 #12
0
void handle_cir_stor_init(struct cfw_message *msg)
{
	ll_storage_cir_stor_init_req_msg_t * req = (ll_storage_cir_stor_init_req_msg_t *) msg;
	ll_storage_cir_stor_init_rsp_msg_t * resp =
		(ll_storage_cir_stor_init_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
		MSG_ID_LL_CIR_STOR_INIT_RSP, sizeof(*resp));
	DRIVER_API_RC ret = DRV_RC_FAIL;
	uint16_t flash_id = 0;
	int16_t partition_index = -1;
	uint32_t i = 0;
	flash_device_t flash;

	if (req->size == 0) {
		pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Cir stor init: Invalid size");
		ret = DRV_RC_FAIL;
		goto send;
	}

	for (i = 0; i < ll_storage_config.no_part; i++) {
		if (ll_storage_config.partitions[i].partition_id == req->partition_id) {
			flash_id = ll_storage_config.partitions[i].flash_id;
			partition_index = i;
			break;
		}
	}

	if (partition_index == -1) {
		pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Cir stor init: Invalid partition ID");
		ret = DRV_RC_FAIL;
		goto send;
	}
	flash = flash_devices[flash_id];

	if (flash.flash_location == SERIAL_FLASH) {
		resp->storage = (void *)cir_storage_flash_spi_init(req->size, req->block_start);
		if (resp->storage != NULL) {
			ret = DRV_RC_OK;
		} else {
			pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Cir stor init: Flash SPI init failed");
			ret = DRV_RC_FAIL;
		}
	}

send:
	resp->rsp_header.status = ret;
	cfw_send_message(resp);
}
コード例 #13
0
ファイル: ble_service.c プロジェクト: CurieBSP/main
static void ble_service_message_handler(struct cfw_message *msg, void *param)
{
	bool free_msg = true;
	struct _ble_service_cb *p_cb = param;
	uint16_t msg_id = CFW_MESSAGE_ID(msg);

	if (p_cb->ble_state < BLE_ST_ENABLED &&
		msg_id != MSG_ID_BLE_ENABLE_REQ) {
		ble_is_not_enabled_rsp(msg, -ENODEV);
		goto out;
	}

	switch (msg_id) {
	case MSG_ID_BLE_ENABLE_REQ: {
		struct ble_enable_req *req =
			container_of(msg, struct ble_enable_req, header);
		if (p_cb->ble_state) {
			if (req->enable) {
				handle_ble_enable(req, p_cb);
				free_msg = false;
			} else
				handle_ble_disable(req, p_cb);
		} else {
			pr_debug(LOG_MODULE_BLE, "ble_hdl_msg: core service not opened!");
			/* core service is not yet up */
			struct ble_enable_rsp *resp = (void *)cfw_alloc_rsp_msg(msg,
				MSG_ID_BLE_ENABLE_RSP, sizeof(*resp));
			resp->status = -EINPROGRESS;
			resp->enable = 0;
			cfw_send_message(resp);
		}
	}
		break;
#ifdef CONFIG_TCMD_BLE_DEBUG
	case MSG_ID_BLE_DBG_REQ:
		handle_msg_id_ble_dbg(msg);
		break;
#endif
	default:
		pr_warning(LOG_MODULE_BLE, "unsupported %d", msg_id);
		break;
	}
out:
	if (free_msg)
		cfw_msg_free(msg);
}
コード例 #14
0
void handle_clear(struct cfw_message *msg)
{
	circular_storage_clear_req_msg_t *req =
		(circular_storage_clear_req_msg_t *)msg;
	circular_storage_service_clear_rsp_msg_t *resp =
		(circular_storage_service_clear_rsp_msg_t *)cfw_alloc_rsp_msg(
			msg,
			MSG_ID_CIRCULAR_STORAGE_SERVICE_CLEAR_RSP,
			sizeof(*resp));

	if (cir_storage_clear((cir_storage_t *)req->storage,
			      req->elt_count) == CBUFFER_STORAGE_SUCCESS)
		resp->status = DRV_RC_OK;
	else
		resp->status = DRV_RC_FAIL;

	cfw_send_message(resp);
}
コード例 #15
0
void handle_push(struct cfw_message *msg)
{
	circular_storage_push_req_msg_t *req =
		(circular_storage_push_req_msg_t *)msg;
	circular_storage_service_push_rsp_msg_t *resp =
		(circular_storage_service_push_rsp_msg_t *)cfw_alloc_rsp_msg(
			msg,
			MSG_ID_CIRCULAR_STORAGE_SERVICE_PUSH_RSP,
			sizeof(*resp));
	DRIVER_API_RC ret = DRV_RC_FAIL;

	if (cir_storage_push((cir_storage_t *)req->storage, req->buffer) ==
	    CBUFFER_STORAGE_SUCCESS) {
		ret = DRV_RC_OK;
	}

	resp->status = ret;
	cfw_send_message(resp);
}
コード例 #16
0
void handle_peek(struct cfw_message *msg)
{
	ll_storage_peek_req_msg_t * req = (ll_storage_peek_req_msg_t *) msg;
	ll_storage_peek_rsp_msg_t * resp =
		(ll_storage_peek_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
		MSG_ID_LL_PEEK_RSP, sizeof(*resp));
	DRIVER_API_RC ret = DRV_RC_FAIL;
	int err;

	resp->buffer = balloc(req->size, NULL);
	err = cir_storage_peek((cir_storage_t *)req->storage, req->offset, resp->buffer, req->size);
	if (err == CBUFFER_STORAGE_SUCCESS) {
		ret = DRV_RC_OK;
	} else if (err == CBUFFER_STORAGE_EMPTY_ERROR) {
		ret = DRV_RC_OUT_OF_MEM;
	}

	resp->rsp_header.status = ret;
	cfw_send_message(resp);
}
コード例 #17
0
ファイル: ble_service.c プロジェクト: CurieBSP/main
static void ble_set_bda_cb(int status, void *user_data)
{
	struct ble_enable_req *req = user_data;

	if (!req)
		return;

	struct ble_enable_rsp *resp = (void *)cfw_alloc_rsp_msg(&req->header,
			    MSG_ID_BLE_ENABLE_RSP, sizeof(*resp));
	resp->status = status;

	if (status == 0) {
		resp->enable = 1;

		nble_gap_read_bda_req(resp);
	} else {
		/* error case */
		resp->enable = 0;
		cfw_send_message(resp);
	}
	bfree(req);
}
コード例 #18
0
void handle_peek(struct cfw_message *msg)
{
	circular_storage_peek_req_msg_t *req =
		(circular_storage_peek_req_msg_t *)msg;
	circular_storage_service_peek_rsp_msg_t *resp =
		(circular_storage_service_peek_rsp_msg_t *)cfw_alloc_rsp_msg(
			msg,
			MSG_ID_CIRCULAR_STORAGE_SERVICE_PEEK_RSP,
			sizeof(*resp));
	DRIVER_API_RC ret = DRV_RC_FAIL;
	int err;

	resp->buffer = balloc(((cir_storage_t *)req->storage)->elt_size, NULL);
	err = cir_storage_peek((cir_storage_t *)req->storage, resp->buffer);
	if (err == CBUFFER_STORAGE_SUCCESS) {
		ret = DRV_RC_OK;
	} else if (err == CBUFFER_STORAGE_EMPTY_ERROR) {
		ret = DRV_RC_OUT_OF_MEM;
	}

	resp->status = ret;
	cfw_send_message(resp);
}
コード例 #19
0
void handle_read_partition(struct cfw_message *msg)
{
    ll_storage_read_partition_req_msg_t * req = (ll_storage_read_partition_req_msg_t *) msg;
    ll_storage_read_partition_rsp_msg_t * resp = (ll_storage_read_partition_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
            MSG_ID_LL_READ_PARTITION_RSP, sizeof(*resp));

    flash_device_t flash;
    uint16_t flash_id = 0;
    int16_t partition_index = -1;
    uint32_t i = 0;
    uint32_t size = 0;
    unsigned int retlen = 0;
    DRIVER_API_RC ret = DRV_RC_FAIL;

    if (req->size == 0) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Read Data: Invalid size");
        ret = DRV_RC_INVALID_OPERATION;
        goto send;
    }

    for (i = 0; i < ll_storage_config.no_part; i++)
        if (ll_storage_config.partitions[i].partition_id == req->partition_id) {
            flash_id = ll_storage_config.partitions[i].flash_id;
            partition_index = i;
            break;
        }

    if (partition_index == -1) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Read Data: Invalid partition ID");
        ret = DRV_RC_FAIL;
        goto send;
    }

    flash = flash_devices[flash_id];

    if (((ll_storage_config.partitions[partition_index].start_block * flash.block_size) + (req->st_offset + req->size))
            > (ll_storage_config.partitions[partition_index].end_block * flash.block_size)) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Read Data: Partition overflow");
        ret = DRV_RC_OUT_OF_MEM;
        goto send;
    }

    size = (req->size / sizeof (uint32_t)) + !!(req->size % sizeof (uint32_t));

    uint32_t address = ((ll_storage_config.partitions[partition_index].start_block * flash.block_size) + req->st_offset);
    resp->buffer = balloc(size * sizeof(uint32_t), NULL);

    if (flash.flash_location == EMBEDDED_FLASH) {
        ret = soc_flash_read(address, size, &retlen, resp->buffer);
#ifdef CONFIG_SPI_FLASH
    } else {// SERIAL_FLASH
        ret = spi_flash_read((struct device *)&pf_sba_device_flash_spi0,
                             address, size, &retlen, resp->buffer);
#endif
    }

    resp->actual_read_size = (retlen * sizeof(uint32_t)) - (((req->size % sizeof(uint32_t)))
            ? (4 - (req->size % sizeof(uint32_t))):0);

send:
    resp->rsp_header.status = ret;
    cfw_send_message(resp);
}
コード例 #20
0
void internal_handle_message(struct cfw_message * msg, void * param)
{
    int free_msg = 1; /* by default free message */
    switch (CFW_MESSAGE_ID(msg))
        {
    case MSG_ID_CFW_ALLOC_PORT:
        {
            //TODO: Enable this, currently relies on sync IPC API.
            //_port_t * port = cfw_port_alloc(NULL);
            //cfw_port_set_handler(port, send_message_ipc, NULL);
            break;
        }

    case MSG_ID_CFW_OPEN_SERVICE:
        {
            cfw_open_conn_req_msg_t * req = (cfw_open_conn_req_msg_t *) msg;
            service_t * svc = cfw_get_service(req->service_id);
            if (svc == NULL) {
                pr_error(LOG_MODULE_MAIN, "try to open non registered service %d", req->service_id);
                cfw_open_conn_rsp_msg_t * resp =
                        (cfw_open_conn_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                                MSG_ID_CFW_OPEN_SERVICE, sizeof(*resp));
                resp->rsp_header.status = E_OS_ERR_UNKNOWN;
                cfw_send_message(resp);
                break;
            }
            uint8_t svc_cpu_id = port_get_cpu_id(svc->port_id);
            if (svc_cpu_id != get_cpu_id()) {
#ifdef INFRA_MULTI_CPU_SUPPORT
                pr_debug(LOG_MODULE_MAIN, "forward open service to proxy");
                CFW_MESSAGE_DST(msg) = proxies[svc_cpu_id].port_id;
                cfw_send_message(msg);
                free_msg = 0; /* the lower layers will free it! */
#else
                pr_error(LOG_MODULE_MAIN, "incorrect cpu_id settings, single cpu!");
#endif
            } else {
                conn_handle_t * conn_handle;

                conn_handle = (conn_handle_t *) balloc(sizeof(*conn_handle),
                        NULL );
                conn_handle->client_port = CFW_MESSAGE_SRC(msg);
                conn_handle->priv_data = NULL;
                conn_handle->svc = svc;
                conn_handle->client_handle = req->client_handle;
                /* For OPEN_SERVICE, conn is not know yet, it is just alloc'ed.
                 * set it here.*/
                req->header.conn = conn_handle;
                if (svc->client_connected != NULL &&
                        svc_cpu_id == get_cpu_id())
                    svc->client_connected(conn_handle);
                cfw_open_conn_rsp_msg_t * resp =
                        (cfw_open_conn_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                                MSG_ID_CFW_OPEN_SERVICE, sizeof(*resp));
                resp->port = svc->port_id;
                resp->cpu_id = svc_cpu_id;
#ifdef SVC_MANAGER_DEBUG
                pr_debug(LOG_MODULE_CFW, "OPEN_SERVICE: %d, svc:%p port:%d", req->service_id,
                        svc, svc->port_id);
#endif
                resp->svc_server_handle = conn_handle;
                resp->client_handle = req->client_handle;
                cfw_send_message(resp);
            }
            break;
        }

    case MSG_ID_CFW_CLOSE_SERVICE:
        {
            cfw_close_conn_req_msg_t * req = (cfw_close_conn_req_msg_t*) msg;
            service_t * svc = cfw_get_service(req->service_id);
            if (svc == NULL) {
                pr_debug(LOG_MODULE_MAIN, "try close unregistered service %d",
                         req->service_id);
                cfw_close_conn_rsp_msg_t * resp =
                        (cfw_close_conn_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                                MSG_ID_CFW_CLOSE_SERVICE, sizeof(*resp));
                resp->rsp_header.status = E_OS_ERR_UNKNOWN;
                cfw_send_message(resp);
                break;
            }
            uint8_t svc_cpu_id = port_get_cpu_id(svc->port_id);
            if (svc_cpu_id != get_cpu_id()) {
#ifdef INFRA_MULTI_CPU_SUPPORT
                CFW_MESSAGE_DST(msg) = proxies[svc_cpu_id].port_id;
                cfw_send_message(msg);
                free_msg=0;
#else
                pr_error(LOG_MODULE_MAIN, "incorrect cpu_id!");
#endif
            } else {
                cfw_close_conn_rsp_msg_t * resp =
                            (cfw_close_conn_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                                    MSG_ID_CFW_CLOSE_SERVICE, sizeof(*resp));
                conn_handle_t * conn = (conn_handle_t*) msg->conn;
                if (conn != NULL && conn->svc != NULL
                        && conn->svc->client_disconnected != NULL )
                    conn->svc->client_disconnected(conn);
                cfw_send_message(resp);
                /* Free server-side conn */
                bfree(conn);
            }
            break;
        }

    case MSG_ID_CFW_REGISTER_EVT:
        {
            int * params = (int *) &msg[1];
            int i;
            for (i = 0; i < params[0]; i++) {
                _cfw_register_event((conn_handle_t*) msg->conn, params[i + 1]);
            }
            cfw_register_evt_rsp_msg_t * resp =
                    (cfw_register_evt_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                            MSG_ID_CFW_REGISTER_EVT, (sizeof(*resp)));
            conn_handle_t * conn = (conn_handle_t*) msg->conn;
            if (conn != NULL && conn->svc != NULL
                    && conn->svc->registered_events_changed != NULL )
                conn->svc->registered_events_changed(conn);

            cfw_send_message(resp);
            break;
        }

    case MSG_ID_CFW_REGISTER_SVC_AVAIL:
        {
            bool already_avail = true;
            cfw_register_svc_avail_req_msg_t * req =
                    (cfw_register_svc_avail_req_msg_t *) msg;
            int flags = interrupt_lock();
            if (_find_service(req->service_id) == -1) {
                add_service_avail_listener(CFW_MESSAGE_SRC(msg),
                        req->service_id, msg->priv);
                already_avail = false;
            }
            interrupt_unlock(flags);
            cfw_register_svc_avail_rsp_msg_t * resp =
                (cfw_register_svc_avail_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                        MSG_ID_CFW_REGISTER_SVC_AVAIL, (sizeof(*resp)));
            cfw_send_message(resp);
            if (already_avail) {
                send_service_avail_evt(req->service_id, CFW_MESSAGE_SRC(msg), msg->priv);
            }
            break;
        }

    default:
        pr_warning(LOG_MODULE_CFW, "%s: unhandled message id: %x", __func__, CFW_MESSAGE_ID(msg));
        break;
        }
    if (free_msg)
        cfw_msg_free(msg);
}