void cfw_dump_message(struct cfw_message * msg) { #if 1 pr_debug(LOG_MODULE_CFW, "%p id: %x src: %d[cpu:%d] dst: %d[cpu:%d] type: %s", msg, CFW_MESSAGE_ID(msg), CFW_MESSAGE_SRC(msg), port_get_cpu_id(CFW_MESSAGE_SRC(msg)), CFW_MESSAGE_DST(msg), port_get_cpu_id(CFW_MESSAGE_DST(msg)), cfw_get_msg_type_str(msg)); #else pr_debug(LOG_MODULE_CFW, "id: %x src: %d dst: %d type: %s", msg->id, msg->src, msg->dst, cfw_get_msg_type_str(msg)); #endif }
struct cfw_rsp_message * cfw_alloc_rsp_msg(const struct cfw_message *req, int msg_id, int size) { struct cfw_rsp_message * rsp = (struct cfw_rsp_message *) cfw_alloc_message(size, NULL); CFW_MESSAGE_TYPE(&rsp->header) = TYPE_RSP; CFW_MESSAGE_ID(&rsp->header) = msg_id; CFW_MESSAGE_LEN(&rsp->header) = size; CFW_MESSAGE_DST(&rsp->header) = CFW_MESSAGE_SRC(req); CFW_MESSAGE_SRC(&rsp->header) = CFW_MESSAGE_DST(req); rsp->header.priv = req->priv; /* Substitute server-side with client-side conn */ if (req->conn != NULL) rsp->header.conn = ((conn_handle_t*)req->conn)->client_handle; else rsp->header.conn = NULL; return rsp; }
struct cfw_message * cfw_alloc_evt_msg(service_t *svc, int msg_id, int size) { struct cfw_message * evt = (struct cfw_message *) cfw_alloc_message(size, NULL); CFW_MESSAGE_TYPE(evt) = TYPE_EVT; CFW_MESSAGE_ID(evt) = msg_id; CFW_MESSAGE_LEN(evt) = size; CFW_MESSAGE_SRC(evt) = svc->port_id; /* 3 fields below whould be filed by send_event method*/ CFW_MESSAGE_DST(evt) = 0; evt->priv = NULL; evt->conn = NULL; return evt; }
struct cfw_message * cfw_alloc_internal_msg(int msg_id, int size, void * priv) { struct cfw_message * evt = (struct cfw_message *) cfw_alloc_message(size, NULL); CFW_MESSAGE_TYPE(evt) = TYPE_INT; CFW_MESSAGE_ID(evt) = msg_id; CFW_MESSAGE_LEN(evt) = size; CFW_MESSAGE_SRC(evt) = 0; /* 3 fields below whould be filed by send_event method*/ CFW_MESSAGE_DST(evt) = 0; evt->priv = priv; evt->conn = NULL; return evt; }
fsm_state_t act_start_done(struct fsm_event_message * evt) { pr_info(LOG_MODULE_NFC, "NFC RF active!"); { struct cfw_message evt; CFW_MESSAGE_ID(&evt) = MSG_ID_NFC_RF_EVT; CFW_MESSAGE_TYPE(&evt) = TYPE_EVT; CFW_MESSAGE_LEN(&evt) = sizeof(evt); CFW_MESSAGE_SRC(&evt) = _cfw_get_service_port(NFC_SERVICE_ID); cfw_send_event(&evt); } process_pending_msg_cb(NFC_STATUS_SUCCESS); return ST_ACTIVE; }
static void circular_storage_shutdown(service_t *svc, struct cfw_message *msg) { struct cfw_message *sm = (struct cfw_message *)message_alloc( sizeof(*sm), NULL); /* In order to ensure that any pending requests are processed prior to the * service shutdown, send a message to self so it will be processed after * all other pending requests. */ CFW_MESSAGE_ID(sm) = MSG_ID_LL_CIRCULAR_STORAGE_SHUTDOWN_REQ; CFW_MESSAGE_DST(sm) = circular_storage_service.port_id; CFW_MESSAGE_SRC(sm) = circular_storage_service.port_id; CFW_MESSAGE_PRIV(sm) = msg; cfw_send_message(sm); }
static void send_service_avail_evt(int service_id, uint16_t port_id, void *param) { cfw_svc_available_evt_msg_t * evt = (cfw_svc_available_evt_msg_t*) balloc(sizeof(*evt), NULL); evt->service_id = service_id; CFW_MESSAGE_LEN(&evt->header) = sizeof(*evt); CFW_MESSAGE_ID(&evt->header) = MSG_ID_CFW_SVC_AVAIL_EVT; CFW_MESSAGE_SRC(&evt->header) = service_mgr_port_id; CFW_MESSAGE_DST(&evt->header) = port_id; CFW_MESSAGE_TYPE(&evt->header) = TYPE_EVT; evt->header.priv = param; pr_debug(LOG_MODULE_MAIN, "Notify : %d to %d", service_id, port_id); cfw_send_message(evt); }
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; } } }
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); }