int ipc_pwr_phone_state(struct ipc_message *message) { struct ipc_pwr_phone_state_response_data *data; if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_pwr_phone_state_response_data)) return -1; if (!ipc_seq_valid(message->aseq)) return 0; data = (struct ipc_pwr_phone_state_response_data *) message->data; switch (data->state) { case IPC_PWR_PHONE_STATE_RESPONSE_LPM: RIL_LOGD("Power state is low power mode"); ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, NULL, 0); ril_radio_state_update(RADIO_STATE_OFF); break; case IPC_PWR_PHONE_STATE_RESPONSE_NORMAL: RIL_LOGD("Power state is normal"); ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, NULL, 0); ril_radio_state_update(RADIO_STATE_SIM_NOT_READY); break; } return 0; }
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; }
int ril_sms_send(char *number, char *message) { char *pdu; size_t length; int rc; pdu = pdu_create(number, message); if (pdu == NULL) return -1; length = strlen(pdu); if (length == 0) return -1; ril_data.state.ril_sms_tpid = RIL_SMS_TPID; if (ril_data.state.sms_incoming_msg_tpid != 0) { RIL_LOGD("Another message is waiting ACK, queuing"); rc = ipc_sms_incoming_msg_register(pdu, length, IPC_SMS_TYPE_POINT_TO_POINT, ril_data.state.ril_sms_tpid); if (rc < 0) { RIL_LOGE("Unable to register incoming msg"); return -1; } return 0; } ipc_sms_incoming_msg_complete(pdu, length, IPC_SMS_TYPE_POINT_TO_POINT, ril_data.state.ril_sms_tpid); return 0; }
void ipc_sms_send_msg(struct ipc_message_info *info) { struct ipc_sms_send_msg_response *report_msg; RIL_SMS_Response response; RIL_Errno e; if (info->data == NULL || info->length < sizeof(struct ipc_sms_send_msg_response)) goto error; report_msg = (struct ipc_sms_send_msg_response *) info->data; RIL_LOGD("Got ACK for msg_tpid #%d\n", report_msg->msg_tpid); memset(&response, 0, sizeof(response)); response.messageRef = report_msg->msg_tpid; response.ackPDU = NULL; e = ipc2ril_sms_ack_error(report_msg->error, &response.errorCode); ril_request_complete(ril_request_get_token(info->aseq), e, (void *) &response, sizeof(response)); // Send the next SMS in the list ril_request_send_sms_next(); return; error: ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); }
int ipc_rfs_destroy(struct ril_client *client) { struct ipc_client *ipc_client; int rc; if (client == NULL || client->data == NULL) { RIL_LOGE("Client was already destroyed"); return 0; } ipc_client = (struct ipc_client *) client->data; RIL_LOGD("Destroying ipc rfs client"); if (ipc_client != NULL) { ipc_client_close(ipc_client); ipc_client_data_destroy(ipc_client); ipc_client_destroy(ipc_client); } client->data = NULL; return 0; }
int ril_request_radio_power(void *data, size_t size, RIL_Token token) { struct ipc_pwr_phone_state_request_data request_data; struct ril_request *request; int power_state; int rc; if (data == NULL || size < sizeof(power_state)) goto error; request = ril_request_find_request_status(RIL_REQUEST_RADIO_POWER, RIL_REQUEST_HANDLED); if (request != NULL) return RIL_REQUEST_UNHANDLED; power_state = *((int *)data); memset(&request_data, 0, sizeof(request_data)); if (power_state > 0) { RIL_LOGD("Requesting normal power state"); request_data.state = IPC_PWR_PHONE_STATE_REQUEST_NORMAL; } else { RIL_LOGD("Requesting low power mode power state"); request_data.state = IPC_PWR_PHONE_STATE_REQUEST_LPM; } rc = ipc_gen_phone_res_expect_abort(ipc_fmt_request_seq(token), IPC_PWR_PHONE_STATE); if (rc < 0) goto error; rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &request_data, sizeof(request_data)); if (rc < 0) goto error; rc = RIL_REQUEST_HANDLED; goto complete; error: ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); rc = RIL_REQUEST_COMPLETED; complete: return rc; }
void ril_request_send_sms_next(void) { struct ril_request_send_sms_info *send_sms; RIL_Token t; char *pdu; int pdu_length; unsigned char *smsc; int smsc_length; int rc; ril_data.tokens.outgoing_sms = RIL_TOKEN_NULL; send_sms = ril_request_send_sms_info_find(); if (send_sms == NULL) return; t = send_sms->token; pdu = send_sms->pdu; pdu_length = send_sms->pdu_length; smsc = send_sms->smsc; smsc_length = send_sms->smsc_length; ril_request_send_sms_unregister(send_sms); if (pdu == NULL) { RIL_LOGE("SMS send request has no valid PDU"); if (smsc != NULL) free(smsc); return; } ril_data.tokens.outgoing_sms = t; if (smsc == NULL) { // We first need to get SMS SVC before sending the message RIL_LOGD("We have no SMSC, let's ask one"); rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t); if (rc < 0) { RIL_LOGE("Unable to add the request to the list"); ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); if (pdu != NULL) free(pdu); // Send the next SMS in the list ril_request_send_sms_next(); } ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t)); } else { ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length); if (pdu != NULL) free(pdu); if (smsc != NULL) free(smsc); } }
void ipc_sms_svc_center_addr(struct ipc_message_info *info) { struct ril_request_send_sms_info *send_sms; RIL_Token t; char *pdu; int pdu_length; unsigned char *smsc; int smsc_length; int rc; if (info->data == NULL || info->length < sizeof(unsigned char)) goto error; send_sms = ril_request_send_sms_info_find_token(ril_request_get_token(info->aseq)); if (send_sms == NULL || send_sms->pdu == NULL || send_sms->pdu_length <= 0) { RIL_LOGE("The request wasn't queued, reporting generic error!"); ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); ril_request_send_sms_info_clear(send_sms); ril_request_send_sms_unregister(send_sms); // Send the next SMS in the list ril_request_send_sms_next(); return; } t = send_sms->token; pdu = send_sms->pdu; pdu_length = send_sms->pdu_length; smsc = (unsigned char *) info->data + sizeof(unsigned char); smsc_length = (int) ((unsigned char *) info->data)[0]; RIL_LOGD("Got SMSC, completing the request"); ril_request_send_sms_unregister(send_sms); ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length); if (pdu != NULL) free(pdu); return; error: ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); }
void ipc_sms_incoming_msg(struct ipc_message_info *info) { struct ipc_sms_incoming_msg *msg; unsigned char *pdu_hex; char *pdu; int length; int rc; if (info->data == NULL || info->length < sizeof(struct ipc_sms_incoming_msg)) goto error; msg = (struct ipc_sms_incoming_msg *) info->data; pdu_hex = ((unsigned char *) info->data + sizeof(struct ipc_sms_incoming_msg)); length = msg->length * 2 + 1; pdu = (char *) calloc(1, length); bin2hex(pdu_hex, msg->length, pdu); if (ril_data.state.sms_incoming_msg_tpid != 0) { RIL_LOGD("Another message is waiting ACK, queuing"); rc = ipc_sms_incoming_msg_register(pdu, length, msg->type, msg->msg_tpid); if (rc < 0) RIL_LOGE("Unable to register incoming msg"); return; } ipc_sms_incoming_msg_complete(pdu, length, msg->type, msg->msg_tpid); return; error: if (info != NULL) ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); }
RIL_RadioState ipc2ril_sec_pin_status_response(struct ipc_sec_pin_status_response_data *data, RIL_CardStatus *card_status) #endif { RIL_AppStatus app_statuses[] = { // Absent { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN }, // Not ready { RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN }, // Ready { RIL_APPTYPE_SIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY, NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN }, // PIN lock { RIL_APPTYPE_SIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN }, // PUK lock { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN }, // PUK locked { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN, NULL, NULL, 0, RIL_PINSTATE_ENABLED_PERM_BLOCKED, RIL_PINSTATE_UNKNOWN }, // Perso network { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK, NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN }, // Perso network subset { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET, NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN }, // Perso corporate { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_CORPORATE, NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN }, // Perso service provider { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER, NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN }, }; RIL_RadioState radio_state; unsigned int index; unsigned int count; unsigned int i; if (data == NULL || card_status == NULL) return 0; count = sizeof(app_statuses) / sizeof(RIL_AppStatus); switch (data->status) { case IPC_SEC_PIN_STATUS_LOCK_SC: switch (data->facility_lock) { case IPC_SEC_FACILITY_LOCK_TYPE_SC_UNLOCKED: index = 2; break; case IPC_SEC_FACILITY_LOCK_TYPE_SC_PIN1_REQ: index = 3; break; case IPC_SEC_FACILITY_LOCK_TYPE_SC_PUK_REQ: index = 4; break; case IPC_SEC_FACILITY_LOCK_TYPE_SC_CARD_BLOCKED: index = 5; break; default: index = 0; break; } break; case IPC_SEC_PIN_STATUS_LOCK_FD: index = 0; break; case IPC_SEC_PIN_STATUS_LOCK_PN: index = 6; break; case IPC_SEC_PIN_STATUS_LOCK_PU: index = 7; break; case IPC_SEC_PIN_STATUS_LOCK_PP: index = 9; break; case IPC_SEC_PIN_STATUS_LOCK_PC: index = 8; break; case IPC_SEC_PIN_STATUS_READY: case IPC_SEC_PIN_STATUS_INIT_COMPLETE: case IPC_SEC_PIN_STATUS_PB_INIT_COMPLETE: index = 2; break; case IPC_SEC_PIN_STATUS_SIM_LOCK_REQUIRED: case IPC_SEC_PIN_STATUS_INSIDE_PF_ERROR: case IPC_SEC_PIN_STATUS_CARD_NOT_PRESENT: case IPC_SEC_PIN_STATUS_CARD_ERROR: default: index = 0; break; } switch (index) { case 1: radio_state = RADIO_STATE_SIM_NOT_READY; break; case 2: radio_state = RADIO_STATE_SIM_READY; break; default: radio_state = RADIO_STATE_SIM_LOCKED_OR_ABSENT; } #if RIL_VERSION >= 6 memset(card_status, 0, sizeof(RIL_CardStatus_v6)); #else memset(card_status, 0, sizeof(RIL_CardStatus)); #endif if (index == 0) card_status->card_state = RIL_CARDSTATE_ABSENT; else card_status->card_state = RIL_CARDSTATE_PRESENT; card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN; card_status->cdma_subscription_app_index = -1; #if RIL_VERSION >= 7 card_status->ims_subscription_app_index = -1; #endif memcpy((void *) &card_status->applications[0], (void *) &app_statuses[index], sizeof(RIL_AppStatus)); card_status->gsm_umts_subscription_app_index = 0; card_status->num_applications = 1; RIL_LOGD("%s: Selecting status application %d on %d", __func__, index, count); return radio_state; }
void ril_request_send_sms(RIL_Token t, void *data, size_t length) { char *pdu = NULL; int pdu_length; unsigned char *smsc = NULL; int smsc_length; int rc; if (data == NULL || length < (int) (2 * sizeof(char *))) goto error; if (ril_radio_state_complete(RADIO_STATE_OFF, t)) return; pdu = ((char **) data)[1]; smsc = ((unsigned char **) data)[0]; pdu_length = 0; smsc_length = 0; if (pdu != NULL) { pdu_length = strlen(pdu) + 1; pdu = strdup(pdu); } if (smsc != NULL) { smsc_length = strlen((char *) smsc); smsc = (unsigned char *) strdup((char *) smsc); } if (ril_data.tokens.outgoing_sms != RIL_TOKEN_NULL) { RIL_LOGD("Another outgoing SMS is being processed, adding to the list"); rc = ril_request_send_sms_register(pdu, pdu_length, smsc, smsc_length, t); if (rc < 0) { RIL_LOGE("Unable to add the request to the list"); goto error; } return; } ril_data.tokens.outgoing_sms = t; if (smsc == NULL) { // We first need to get SMS SVC before sending the message RIL_LOGD("We have no SMSC, let's ask one"); rc = ril_request_send_sms_register(pdu, pdu_length, NULL, 0, t); if (rc < 0) { RIL_LOGE("Unable to add the request to the list"); goto error; } ipc_fmt_send_get(IPC_SMS_SVC_CENTER_ADDR, ril_request_get_id(t)); } else { ril_request_send_sms_complete(t, pdu, pdu_length, smsc, smsc_length); if (pdu != NULL) free(pdu); if (smsc != NULL) free(smsc); } return; error: ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); if (pdu != NULL) free(pdu); if (smsc != NULL) free(smsc); // Send the next SMS in the list ril_request_send_sms_next(); }
void ril_request_send_sms_complete(RIL_Token t, char *pdu, int pdu_length, unsigned char *smsc, int smsc_length) { struct ipc_sms_send_msg_request send_msg; unsigned char send_msg_type; unsigned char *pdu_hex; int pdu_hex_length; void *data; int length; unsigned char *p; if (pdu == NULL || pdu_length <= 0 || smsc == NULL || smsc_length <= 0) goto error; if ((pdu_length / 2 + smsc_length) > 0xfe) { RIL_LOGE("PDU or SMSC too large, aborting"); goto error; } pdu_hex_length = pdu_length % 2 == 0 ? pdu_length / 2 : (pdu_length ^ 1) / 2; // Length of the final message length = sizeof(send_msg) + pdu_hex_length + smsc_length; RIL_LOGD("Sending SMS message (length: 0x%x)!", length); pdu_hex = calloc(1, pdu_hex_length); hex2bin(pdu, pdu_length, pdu_hex); send_msg_type = IPC_SMS_MSG_SINGLE; /* PDU operations */ int pdu_tp_da_index = 2; unsigned char pdu_tp_da_len = pdu_hex[pdu_tp_da_index]; if (pdu_tp_da_len > 0xff / 2) { RIL_LOGE("PDU TP-DA Len failed (0x%x)\n", pdu_tp_da_len); goto pdu_end; } RIL_LOGD("PDU TP-DA Len is 0x%x\n", pdu_tp_da_len); int pdu_tp_udh_index = pdu_tp_da_index + pdu_tp_da_len; unsigned char pdu_tp_udh_len = pdu_hex[pdu_tp_udh_index]; if (pdu_tp_udh_len > 0xff / 2 || pdu_tp_udh_len < 5) { RIL_LOGE("PDU TP-UDH Len failed (0x%x)\n", pdu_tp_udh_len); goto pdu_end; } RIL_LOGD("PDU TP-UDH Len is 0x%x\n", pdu_tp_udh_len); int pdu_tp_udh_num_index = pdu_tp_udh_index + 4; unsigned char pdu_tp_udh_num = pdu_hex[pdu_tp_udh_num_index]; if (pdu_tp_udh_num > 0xf) { RIL_LOGE("PDU TP-UDH Num failed (0x%x)\n", pdu_tp_udh_num); goto pdu_end; } int pdu_tp_udh_seq_index = pdu_tp_udh_index + 5; unsigned char pdu_tp_udh_seq = pdu_hex[pdu_tp_udh_seq_index]; if (pdu_tp_udh_seq > 0xf || pdu_tp_udh_seq > pdu_tp_udh_num) { RIL_LOGE("PDU TP-UDH Seq failed (0x%x)\n", pdu_tp_udh_seq); goto pdu_end; } RIL_LOGD("We are sending message %d on %d\n", pdu_tp_udh_seq, pdu_tp_udh_num); if (pdu_tp_udh_num > 1) { RIL_LOGD("We are sending a multi-part message!"); send_msg_type = IPC_SMS_MSG_MULTIPLE; } pdu_end: // Alloc memory for the final message data = calloc(1, length); // Clear and fill the IPC structure part of the message memset(&send_msg, 0, sizeof(struct ipc_sms_send_msg_request)); send_msg.type = IPC_SMS_TYPE_OUTGOING; send_msg.msg_type = send_msg_type; send_msg.length = (unsigned char) (pdu_hex_length + smsc_length + 1); send_msg.smsc_len = smsc_length; // Copy the parts of the message p = data; memcpy(p, &send_msg, sizeof(send_msg)); p += sizeof(send_msg); memcpy(p, smsc, smsc_length); p += smsc_length; memcpy(p, pdu_hex, pdu_hex_length); ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_SMS_SEND_MSG, ipc_sms_send_msg_complete); ipc_fmt_send(IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, length, ril_request_get_id(t)); free(pdu_hex); free(data); return; error: ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0); // Send the next SMS in the list ril_request_send_sms_next(); }
int ipc_fmt_create(struct ril_client *client) { struct ipc_client *ipc_client; int rc; if (client == NULL) return -EINVAL; RIL_LOGD("Creating new FMT client"); ipc_client = ipc_client_create(IPC_CLIENT_TYPE_FMT); if (ipc_client == NULL) { RIL_LOGE("FMT client creation failed"); goto error_client_create; } client->data = (void *) ipc_client; RIL_LOGD("Setting log handler"); rc = ipc_client_set_log_callback(ipc_client, ipc_log_handler, NULL); if (rc < 0) { RIL_LOGE("Setting log handler failed"); goto error_log_callback; } RIL_LOGD("Creating data"); rc = ipc_client_data_create(ipc_client); if (rc < 0) { RIL_LOGE("Creating data failed"); goto error_data_create; } RIL_LOGD("Starting bootstrap"); rc = ipc_client_bootstrap(ipc_client); if (rc < 0) { RIL_LOGE("Modem bootstrap failed"); goto error_bootstrap; } RIL_LOGD("Client power on..."); rc = ipc_client_power_on(ipc_client); if (rc < 0) { RIL_LOGE("%s: failed to power on ipc client", __func__); goto error_power_on; } RIL_LOGD("Client open..."); rc = ipc_client_open(ipc_client); if (rc < 0) { RIL_LOGE("%s: failed to open ipc client", __func__); goto error_open; } RIL_LOGD("IPC FMT client done"); return 0; error: ipc_client_power_off(ipc_client); error_power_on: error_get_fd: ipc_client_close(ipc_client); error_open: error_bootstrap: ipc_client_data_destroy(ipc_client); error_data_create: error_log_callback: ipc_client_destroy(ipc_client); error_client_create: client->data = NULL; return -1; }
void ipc_log_handler(void *log_data, const char *message) { RIL_LOGD("ipc: %s", message); }
int ipc_rfs_create(struct ril_client *client) { struct ipc_client *ipc_client; int rc; if (client == NULL) return -EINVAL; RIL_LOGD("Creating new RFS client"); ipc_client = ipc_client_create(IPC_CLIENT_TYPE_RFS); if (ipc_client == NULL) { RIL_LOGE("RFS client creation failed"); goto error_client_create; } client->data = (void *) ipc_client; RIL_LOGD("Setting log handler"); rc = ipc_client_set_log_callback(ipc_client, ipc_log_handler, NULL); if (rc < 0) { RIL_LOGE("Setting log handler failed"); goto error_log_callback; } RIL_LOGD("Creating data"); rc = ipc_client_data_create(ipc_client); if (rc < 0) { RIL_LOGE("Creating data failed"); goto error_data_create; } RIL_LOGD("Client open..."); rc = ipc_client_open(ipc_client); if (rc < 0) { RIL_LOGE("%s: failed to open ipc client", __func__); goto error_open; } RIL_LOGD("IPC RFS client done"); return 0; error: error_get_fd: ipc_client_close(ipc_client); error_open: ipc_client_data_destroy(ipc_client); error_data_create: error_log_callback: ipc_client_destroy(ipc_client); error_client_create: client->data = NULL; return -1; }