int crespo_ipc_fmt_client_recv(struct ipc_client *client, struct ipc_message_info *response) { struct modem_io modem_data; struct ipc_header *resphdr; int bread = 0; memset(&modem_data, 0, sizeof(struct modem_io)); modem_data.data = malloc(MAX_MODEM_DATA_SIZE); modem_data.size = MAX_MODEM_DATA_SIZE; memset(response, 0, sizeof(struct ipc_message_info)); wake_lock("secril_fmt-interface", 20); assert(client->handlers->read != NULL); bread = client->handlers->read((uint8_t*) &modem_data, sizeof(struct modem_io) + MAX_MODEM_DATA_SIZE, client->handlers->read_data); if (bread < 0) { ipc_client_log(client, "crespo_ipc_fmt_client_recv: can't receive enough bytes from modem to process incoming response!"); return -1; } if(modem_data.size <= 0 || modem_data.size >= MAX_MODEM_DATA_SIZE || modem_data.data == NULL) { ipc_client_log(client, "crespo_ipc_fmt_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!"); return -1; } resphdr = (struct ipc_header *) modem_data.data; response->mseq = resphdr->mseq; response->aseq = resphdr->aseq; response->group = resphdr->group; response->index = resphdr->index; response->type = resphdr->type; response->length = modem_data.size - sizeof(struct ipc_header); response->data = NULL; ipc_client_log(client, "crespo_ipc_fmt_client_recv: RECV FMT (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size); ipc_client_log(client, "crespo_ipc_fmt_client_recv: IPC response (aseq=0x%02x command=%s (0x%04x) type=%s)", response->aseq, ipc_command_to_str(IPC_COMMAND(response)), IPC_COMMAND(response), ipc_response_type_to_str(response->type)); if(response->length > 0) { #ifdef DEBUG ipc_client_log(client, "==== FMT DATA DUMP ===="); ipc_hex_dump(client, (void *) (modem_data.data + sizeof(struct ipc_header)), response->length); #endif response->data = malloc(response->length); memcpy(response->data, (uint8_t *) modem_data.data + sizeof(struct ipc_header), response->length); } free(modem_data.data); ipc_client_log(client, ""); wake_unlock("secril_fmt-interface", 20); return 0; }
int crespo_ipc_rfs_client_send(struct ipc_client *client, struct ipc_message_info *request) { struct modem_io modem_data; int rc = 0; memset(&modem_data, 0, sizeof(struct modem_io)); modem_data.id = request->mseq; modem_data.cmd = request->index; modem_data.size = request->length; modem_data.data = malloc(request->length); memcpy(modem_data.data, request->data, request->length); assert(client->handlers->write != NULL); ipc_client_log(client, "crespo_ipc_rfs_client_send: SEND RFS (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size); ipc_client_log(client, "crespo_ipc_rfs_client_send: IPC request (mseq=0x%02x command=%s (0x%04x))", request->mseq, ipc_command_to_str(IPC_COMMAND(request)), IPC_COMMAND(request)); #ifdef DEBUG if(request->length > 0) { ipc_client_log(client, "==== RFS DATA DUMP ===="); ipc_hex_dump(client, (void *) request->data, request->length); } #endif ipc_client_log(client, ""); rc = client->handlers->write((uint8_t*) &modem_data, sizeof(struct modem_io), client->handlers->write_data); return rc; }
int ipc_gen_phone_res(struct ipc_message *message) { struct ipc_gen_phone_res_expect *expect; struct ipc_gen_phone_res_data *data; struct ril_client *client; RIL_Errno error; int rc; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gen_phone_res_data)) return -1; client = ril_client_find_id(RIL_CLIENT_IPC_FMT); if (client == NULL) return -1; data = (struct ipc_gen_phone_res_data *) message->data; expect = ipc_gen_phone_res_expect_find_aseq(client, message->aseq); if (expect == NULL) { RIL_LOGD("Ignoring generic response for command %s", ipc_command_string(IPC_COMMAND(data->group, data->index))); return 0; } if (IPC_COMMAND(data->group, data->index) != expect->command) { RIL_LOGE("Generic response commands mismatch: %s/%s", ipc_command_string(IPC_COMMAND(data->group, data->index)), ipc_command_string(expect->command)); goto error; } RIL_LOGD("Generic response was expected"); if (expect->callback != NULL) { rc = expect->callback(message); goto complete; } rc = ipc_gen_phone_res_check(data); if (rc < 0) error = RIL_E_GENERIC_FAILURE; else error = RIL_E_SUCCESS; if (expect->complete || (expect->abort && error == RIL_E_GENERIC_FAILURE)) ril_request_complete(ipc_fmt_request_token(message->aseq), error, NULL, 0); rc = 0; goto complete; error: rc = -1; complete: if (expect != NULL) ipc_gen_phone_res_expect_unregister(client, expect); return rc; }
static gboolean received_data(GIOChannel *channel, GIOCondition cond, gpointer user_data) { struct rfs_manager *mgr = user_data; struct ipc_message_info resp; struct ipc_message_info *resp_ptr; int ret; if (cond & G_IO_NVAL) return FALSE; ret = ipc_client_recv(mgr->client, &resp); if (ret < 0) { g_warning("Could not receive IPC message from modem"); return FALSE; } g_message("Received RFS message cmd=%i", resp.cmd); resp_ptr = &resp; switch (IPC_COMMAND(resp_ptr)) { case IPC_RFS_NV_READ_ITEM: g_message("Received IPC_RFS_NV_READ_ITEM request"); ipc_rfs_send_io_confirm_for_nv_read_item(mgr->client, &resp); break; case IPC_RFS_NV_WRITE_ITEM: g_message("Received IPC_RFS_NV_WRITE_ITEM request"); ipc_rfs_send_io_confirm_for_nv_write_item(mgr->client, &resp); break; } ipc_client_response_free(mgr->client, &resp); return TRUE; }
int crespo_ipc_fmt_client_send(struct ipc_client *client, struct ipc_message_info *request) { struct modem_io modem_data; struct ipc_header reqhdr; int rc = 0; memset(&modem_data, 0, sizeof(struct modem_io)); modem_data.size = request->length + sizeof(struct ipc_header); reqhdr.mseq = request->mseq; reqhdr.aseq = request->aseq; reqhdr.group = request->group; reqhdr.index = request->index; reqhdr.type = request->type; reqhdr.length = (uint16_t) (request->length + sizeof(struct ipc_header)); modem_data.data = malloc(reqhdr.length); memcpy(modem_data.data, &reqhdr, sizeof(struct ipc_header)); memcpy((unsigned char *) (modem_data.data + sizeof(struct ipc_header)), request->data, request->length); assert(client->handlers->write != NULL); ipc_client_log(client, "crespo_ipc_fmt_client_send: SEND FMT (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size); ipc_client_log(client, "crespo_ipc_fmt_client_send: IPC request (mseq=0x%02x command=%s (0x%04x) type=%s)", request->mseq, ipc_command_to_str(IPC_COMMAND(request)), IPC_COMMAND(request), ipc_request_type_to_str(request->type)); #ifdef DEBUG if(request->length > 0) { ipc_client_log(client, "==== FMT DATA DUMP ===="); ipc_hex_dump(client, (void *) request->data, request->length); } #endif ipc_client_log(client, ""); rc = client->handlers->write((uint8_t*) &modem_data, sizeof(struct modem_io), client->handlers->write_data); return rc; }
int aries_ipc_fmt_client_recv(struct ipc_client *client, struct ipc_message_info *response) { struct ipc_header *resphdr; void *data; int bread = 0; data = malloc(MAX_MODEM_DATA_SIZE); memset(data, 0, MAX_MODEM_DATA_SIZE); memset(response, 0, sizeof(struct ipc_message_info)); assert(client->handlers->read != NULL); bread = client->handlers->read((uint8_t*) data, MAX_MODEM_DATA_SIZE, client->handlers->read_data); if (bread < 0) { ipc_client_log(client, "aries_ipc_fmt_client_recv: can't receive enough bytes from modem to process incoming response!"); return -1; } if(data == NULL) { ipc_client_log(client, "aries_ipc_fmt_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!"); return -1; } resphdr = (struct ipc_header *) data; response->mseq = resphdr->mseq; response->aseq = resphdr->aseq; response->group = resphdr->group; response->index = resphdr->index; response->type = resphdr->type; response->cmd = IPC_COMMAND(response); response->length = resphdr->length - sizeof(struct ipc_header); response->data = NULL; if(response->length > 0) { response->data = malloc(response->length); memcpy(response->data, (uint8_t *) data + sizeof(struct ipc_header), response->length); } free(data); ipc_client_log_recv(client, response, __func__); return 0; }
/** * In: IPC_GEN_PHONE_RES * Check the ipc_gen_phone_res_expects queue and act accordingly */ void ipc_gen_phone_res(struct ipc_message_info *info) { struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data; int id = ipc_gen_phone_res_get_id(info->aseq); RIL_Errno e; int rc; // In this case, it can be a real error or we just didn't queue if(id < 0) { LOGD("aseq: 0x%x not found in the IPC_GEN_PHONE_RES queue", info->aseq); return; } LOGD("aseq: 0x%x found in the IPC_GEN_PHONE_RES queue!", info->aseq); if(ipc_gen_phone_res_expects[id].command != IPC_COMMAND(phone_res)) { LOGE("IPC_GEN_PHONE_RES aseq (0x%x) doesn't match the queued one with command (0x%x)", ipc_gen_phone_res_expects[id].aseq, ipc_gen_phone_res_expects[id].command); if(ipc_gen_phone_res_expects[id].func != NULL) { LOGE("Not safe to run the custom function, reporting generic failure"); RIL_onRequestComplete(reqGetToken(ipc_gen_phone_res_expects[id].aseq), RIL_E_GENERIC_FAILURE, NULL, 0); } } if(ipc_gen_phone_res_expects[id].func != NULL) { ipc_gen_phone_res_expects[id].func(info); ipc_gen_phone_res_clean_id(id); return; } rc = ipc_gen_phone_res_check(phone_res); if(rc < 0) e = RIL_E_GENERIC_FAILURE; else e = RIL_E_SUCCESS; if(ipc_gen_phone_res_expects[id].to_complete || (ipc_gen_phone_res_expects[id].to_abort && rc < 0)) { RIL_onRequestComplete(reqGetToken(ipc_gen_phone_res_expects[id].aseq), e, NULL, 0); ipc_gen_phone_res_clean_id(id); return; } ipc_gen_phone_res_clean_id(id); }
int h1_ipc_send(struct ipc_client *client, struct ipc_message_info *request) { struct hdlc_header *hdlc; unsigned char *frame; unsigned char *payload; int frame_length; /* Frame length: HDLC/IPC header + payload length + HDLC flags (2) */ frame_length = (sizeof(*hdlc) + request->length + 2); frame = (unsigned char*)malloc(frame_length); frame[0] = FRAME_START; frame[frame_length-1] = FRAME_END; /* Setup HDLC header */ hdlc = (struct hdlc_header*)(frame + 1); hdlc->length = (sizeof(*hdlc) + request->length); hdlc->unknown = 0; /* IPC header */ hdlc->ipc.length = (sizeof(hdlc->ipc) + request->length); hdlc->ipc.mseq = request->mseq; hdlc->ipc.aseq = request->aseq; hdlc->ipc.group = request->group; hdlc->ipc.index = request->index; hdlc->ipc.type = request->type; /* IPC payload */ payload = (frame + 1 + sizeof(*hdlc)); memcpy(payload, request->data, request->length); ipc_client_log(client, "sending %s %s\n", ipc_command_to_str(IPC_COMMAND(request)), ipc_response_type_to_str(request->type)); ipc_hex_dump(client, frame, frame_length); client->handlers->write(frame, frame_length, client->handlers->write_data); free(frame); return 0; }
int h1_ipc_recv(struct ipc_client *client, struct ipc_message_info *response) { unsigned char buf[4]; unsigned char *data; unsigned short *frame_length; struct ipc_header *ipc; int num_read; int left; num_read = client->handlers->read((void*)buf, sizeof(buf), client->handlers->read_data); if(num_read == sizeof(buf) && *buf == FRAME_START) { frame_length = (unsigned short*)&buf[1]; left = (*frame_length - 3 + 1); data = (unsigned char*)malloc(left); num_read = client->handlers->read((void*)data, left, client->handlers->read_data); if(num_read == left && data[left-1] == FRAME_END) { ipc = (struct ipc_header*)data; response->mseq = ipc->mseq; response->aseq = ipc->aseq; response->group = ipc->group; response->index = ipc->index; response->type = ipc->type; response->length = (ipc->length - sizeof(*ipc)); response->data = (unsigned char*)malloc(response->length); memcpy(response->data, (data + sizeof(*ipc)), response->length); ipc_client_log(client, "received %s %s\n", ipc_command_to_str(IPC_COMMAND(response)), ipc_response_type_to_str(response->type)); ipc_hex_dump(client, data, num_read-1); return 0; } } return 0; }