* Copyright (C) 2023 Xiaomi Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Included Files
****************************************************************************/
#include <stdio.h>
#include "tapi_internal.h"
#include "tapi_phonebook.h"
* Private Type Declarations
****************************************************************************/
typedef struct {
int fdn_idx;
char* tag;
char* number;
char* pin2;
} fdn_record_param;
* Private Function Prototypes
****************************************************************************/
static void phonebook_event_data_free(void* user_data);
static void load_adn_entries_cb(DBusMessage* message, void* user_data);
static void load_fdn_entries_cb(DBusMessage* message, void* user_data);
static void insert_fdn_record_append(DBusMessageIter* iter, void* user_data);
static void insert_fdn_record_cb(DBusMessage* message, void* user_data);
static void delete_fdn_record_append(DBusMessageIter* iter, void* user_data);
static void update_fdn_record_append(DBusMessageIter* iter, void* user_data);
* Private Functions
****************************************************************************/
static void phonebook_event_data_free(void* user_data)
{
tapi_async_handler* handler = user_data;
tapi_async_result* ar;
void* data;
if (handler != NULL) {
ar = handler->result;
if (ar != NULL) {
data = ar->data;
if (data != NULL)
free(data);
free(ar);
}
free(handler);
}
}
static void load_adn_entries_cb(DBusMessage* message, void* user_data)
{
DBusMessageIter iter;
tapi_async_handler* handler;
tapi_async_result* ar;
tapi_async_function cb;
DBusError err;
char* entries;
handler = user_data;
if (handler == NULL) {
tapi_log_error("handler in %s is null", __func__);
return;
}
if ((ar = handler->result) == NULL) {
tapi_log_error("async result in %s is null", __func__);
return;
}
if ((cb = handler->cb_function) == NULL) {
tapi_log_error("callback in %s is null", __func__);
return;
}
dbus_error_init(&err);
if (dbus_set_error_from_message(&err, message) == true) {
tapi_log_error("error from message in %s, %s: %s", __func__, err.name, err.message);
dbus_error_free(&err);
ar->status = ERROR;
goto done;
}
if (dbus_message_iter_init(message, &iter) == false) {
tapi_log_error("message iter init failed in %s", __func__);
ar->status = ERROR;
goto done;
}
dbus_message_iter_get_basic(&iter, &entries);
ar->data = entries;
ar->status = OK;
done:
cb(ar);
}
static void load_fdn_entries_cb(DBusMessage* message, void* user_data)
{
fdn_entry entries[MAX_FDN_RECORD_LENGTH];
DBusMessageIter iter, arr, entry;
tapi_async_handler* handler;
tapi_async_result* ar;
tapi_async_function cb;
DBusError err;
int index;
handler = user_data;
if (handler == NULL) {
tapi_log_error("handler in %s is null", __func__);
return;
}
if ((ar = handler->result) == NULL) {
tapi_log_error("async result in %s is null", __func__);
return;
}
if ((cb = handler->cb_function) == NULL) {
tapi_log_error("callback in %s is null", __func__);
return;
}
dbus_error_init(&err);
if (dbus_set_error_from_message(&err, message) == true) {
tapi_log_error("error from message in %s, %s: %s", __func__, err.name, err.message);
dbus_error_free(&err);
ar->status = ERROR;
goto done;
}
if (dbus_message_iter_init(message, &iter) == false) {
tapi_log_error("message iter init failed in %s", __func__);
ar->status = ERROR;
goto done;
}
dbus_message_iter_recurse(&iter, &arr);
if (dbus_message_iter_get_arg_type(&arr) == DBUS_TYPE_ARRAY) {
dbus_message_iter_recurse(&arr, &entry);
index = 0;
while (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_INVALID) {
if (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRUCT) {
dbus_message_iter_get_basic(&entry, &entries[index].fdn_idx);
dbus_message_iter_next(&entry);
dbus_message_iter_get_basic(&entry, &entries[index].tag);
dbus_message_iter_next(&entry);
dbus_message_iter_get_basic(&entry, &entries[index].number);
index++;
}
if (index >= MAX_FDN_RECORD_LENGTH)
break;
dbus_message_iter_next(&arr);
dbus_message_iter_recurse(&arr, &entry);
}
ar->arg2 = index;
}
ar->data = entries;
ar->status = OK;
done:
cb(ar);
}
static void insert_fdn_record_append(DBusMessageIter* iter, void* user_data)
{
tapi_async_handler* param = user_data;
fdn_record_param* insert_fdn_record;
char* name;
char* number;
char* pin2;
if (param == NULL) {
tapi_log_error("param in %s is null", __func__);
return;
}
if (param->result == NULL) {
tapi_log_error("invalid pin argument in %s!", __func__);
return;
}
insert_fdn_record = param->result->data;
name = insert_fdn_record->tag;
number = insert_fdn_record->number;
pin2 = insert_fdn_record->pin2;
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &name);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &number);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &pin2);
}
static void insert_fdn_record_cb(DBusMessage* message, void* user_data)
{
DBusMessageIter iter;
tapi_async_handler* handler;
tapi_async_result* ar;
tapi_async_function cb;
DBusError err;
handler = user_data;
if (handler == NULL) {
tapi_log_error("handler in %s is null", __func__);
return;
}
if ((ar = handler->result) == NULL) {
tapi_log_error("async result in %s is null", __func__);
return;
}
if ((cb = handler->cb_function) == NULL) {
tapi_log_error("callback in %s is null", __func__);
return;
}
dbus_error_init(&err);
if (dbus_set_error_from_message(&err, message) == true) {
tapi_log_error("error from message in %s, %s: %s", __func__, err.name, err.message);
dbus_error_free(&err);
ar->status = ERROR;
goto done;
}
if (dbus_message_iter_init(message, &iter) == false) {
tapi_log_error("message iter init failed in %s", __func__);
ar->status = ERROR;
goto done;
}
dbus_message_iter_get_basic(&iter, &ar->arg2);
ar->status = OK;
done:
cb(ar);
}
static void delete_fdn_record_append(DBusMessageIter* iter, void* user_data)
{
tapi_async_handler* param = user_data;
fdn_record_param* delete_fdn_record;
int fdn_idx;
char* pin2;
if (param == NULL) {
tapi_log_error("param in %s is null", __func__);
return;
}
if (param->result == NULL) {
tapi_log_error("invalid pin argument in %s!", __func__);
return;
}
delete_fdn_record = param->result->data;
pin2 = delete_fdn_record->pin2;
fdn_idx = delete_fdn_record->fdn_idx;
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &pin2);
dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &fdn_idx);
}
static void update_fdn_record_append(DBusMessageIter* iter, void* user_data)
{
tapi_async_handler* param = user_data;
fdn_record_param* update_fdn_record;
char* new_number;
char* new_name;
int fdn_idx;
char* pin2;
if (param == NULL) {
tapi_log_error("param in %s is null", __func__);
return;
}
if (param->result == NULL) {
tapi_log_error("invalid pin argument in %s!", __func__);
return;
}
update_fdn_record = param->result->data;
new_name = update_fdn_record->tag;
new_number = update_fdn_record->number;
pin2 = update_fdn_record->pin2;
fdn_idx = update_fdn_record->fdn_idx;
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &new_name);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &new_number);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &pin2);
dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &fdn_idx);
}
* Public Functions
****************************************************************************/
int tapi_phonebook_load_adn_entries(tapi_context context,
int slot_id, int event_id, tapi_async_function p_handle)
{
tapi_async_handler* user_data;
dbus_context* ctx = context;
tapi_async_result* ar;
GDBusProxy* proxy;
if (ctx == NULL) {
tapi_log_error("context in %s is null", __func__);
return -EINVAL;
}
if (!tapi_is_valid_slotid(slot_id)) {
tapi_log_error("invalid slot id in %s", __func__);
return -EINVAL;
}
proxy = get_dbus_proxy_by_type(ctx, slot_id, DBUS_PROXY_PHONEBOOK);
if (proxy == NULL) {
tapi_log_error("no available proxy in %s", __func__);
return -EIO;
}
ar = calloc(1, sizeof(tapi_async_result));
if (ar == NULL) {
tapi_log_error("async result in %s is null", __func__);
return -ENOMEM;
}
ar->msg_id = event_id;
ar->arg1 = slot_id;
user_data = calloc(1, sizeof(tapi_async_handler));
if (user_data == NULL) {
tapi_log_error("user data in %s is null", __func__);
free(ar);
return -ENOMEM;
}
user_data->cb_function = p_handle;
user_data->result = ar;
if (!g_dbus_proxy_method_call(proxy, "Import", NULL,
load_adn_entries_cb, user_data, handler_free)) {
tapi_log_error("method call failed in %s", __func__);
handler_free(user_data);
return -EINVAL;
}
return OK;
}
int tapi_phonebook_load_fdn_entries(tapi_context context,
int slot_id, int event_id, tapi_async_function p_handle)
{
tapi_async_handler* user_data;
dbus_context* ctx = context;
tapi_async_result* ar;
GDBusProxy* proxy;
if (ctx == NULL) {
tapi_log_error("context in %s is null", __func__);
return -EINVAL;
}
if (!tapi_is_valid_slotid(slot_id)) {
tapi_log_error("invalid slot id in %s", __func__);
return -EINVAL;
}
proxy = get_dbus_proxy_by_type(ctx, slot_id, DBUS_PROXY_PHONEBOOK);
if (proxy == NULL) {
tapi_log_error("no available proxy in %s", __func__);
return -EIO;
}
ar = calloc(1, sizeof(tapi_async_result));
if (ar == NULL) {
tapi_log_error("async result in %s is null", __func__);
return -ENOMEM;
}
ar->msg_id = event_id;
ar->arg1 = slot_id;
ar->arg2 = 0;
ar->data = NULL;
user_data = calloc(1, sizeof(tapi_async_handler));
if (user_data == NULL) {
tapi_log_error("user data in %s is null", __func__);
free(ar);
return -ENOMEM;
}
user_data->cb_function = p_handle;
user_data->result = ar;
if (!g_dbus_proxy_method_call(proxy, "ImportFdn", NULL,
load_fdn_entries_cb, user_data, handler_free)) {
tapi_log_error("method call failed in %s", __func__);
handler_free(user_data);
return -EINVAL;
}
return OK;
}
int tapi_phonebook_insert_fdn_entry(tapi_context context, int slot_id,
int event_id, char* name, char* number, char* pin2, tapi_async_function p_handle)
{
fdn_record_param* fdn_record;
tapi_async_handler* user_data;
dbus_context* ctx = context;
tapi_async_result* ar;
GDBusProxy* proxy;
if (ctx == NULL) {
tapi_log_error("context in %s is null", __func__);
return -EINVAL;
}
if (!tapi_is_valid_slotid(slot_id)) {
tapi_log_error("invalid slot id in %s", __func__);
return -EINVAL;
}
if (name == NULL) {
tapi_log_error("name in %s is null", __func__);
return -EINVAL;
}
if (number == NULL) {
tapi_log_error("number in %s is null", __func__);
return -EINVAL;
}
if (pin2 == NULL) {
tapi_log_error("pin2 in %s is null", __func__);
return -EINVAL;
}
proxy = get_dbus_proxy_by_type(ctx, slot_id, DBUS_PROXY_PHONEBOOK);
if (proxy == NULL) {
tapi_log_error("no available proxy in %s", __func__);
return -EIO;
}
fdn_record = calloc(1, sizeof(fdn_record_param));
if (fdn_record == NULL) {
tapi_log_error("fdn record in %s is null", __func__);
return -ENOMEM;
}
fdn_record->tag = name;
fdn_record->number = number;
fdn_record->pin2 = pin2;
ar = calloc(1, sizeof(tapi_async_result));
if (ar == NULL) {
tapi_log_error("async result in %s is null", __func__);
free(fdn_record);
return -ENOMEM;
}
ar->msg_id = event_id;
ar->arg1 = slot_id;
ar->data = fdn_record;
user_data = calloc(1, sizeof(tapi_async_handler));
if (user_data == NULL) {
tapi_log_error("user data in %s is null", __func__);
free(fdn_record);
free(ar);
return -ENOMEM;
}
user_data->cb_function = p_handle;
user_data->result = ar;
if (!g_dbus_proxy_method_call(proxy, "InsertFdn", insert_fdn_record_append,
insert_fdn_record_cb, user_data, phonebook_event_data_free)) {
phonebook_event_data_free(user_data);
tapi_log_error("method call failed in %s", __func__);
return -EINVAL;
}
return OK;
}
int tapi_phonebook_delete_fdn_entry(tapi_context context, int slot_id,
int event_id, int fdn_idx, char* pin2, tapi_async_function p_handle)
{
fdn_record_param* fdn_record;
tapi_async_handler* user_data;
dbus_context* ctx = context;
tapi_async_result* ar;
GDBusProxy* proxy;
if (ctx == NULL) {
tapi_log_error("context in %s is null", __func__);
return -EINVAL;
}
if (!tapi_is_valid_slotid(slot_id)) {
tapi_log_error("invalid slot id in %s", __func__);
return -EINVAL;
}
if (fdn_idx < 1) {
tapi_log_error("invalid fdn idx in %s", __func__);
return -EINVAL;
}
if (pin2 == NULL) {
tapi_log_error("pin2 in %s is null", __func__);
return -EINVAL;
}
proxy = get_dbus_proxy_by_type(ctx, slot_id, DBUS_PROXY_PHONEBOOK);
if (proxy == NULL) {
tapi_log_error("no available proxy in %s", __func__);
return -EIO;
}
fdn_record = calloc(1, sizeof(fdn_record_param));
if (fdn_record == NULL) {
tapi_log_error("fdn record in %s is null", __func__);
return -ENOMEM;
}
fdn_record->fdn_idx = fdn_idx;
fdn_record->pin2 = pin2;
ar = calloc(1, sizeof(tapi_async_result));
if (ar == NULL) {
tapi_log_error("async result in %s is null", __func__);
free(fdn_record);
return -ENOMEM;
}
ar->msg_id = event_id;
ar->arg1 = slot_id;
ar->data = fdn_record;
user_data = calloc(1, sizeof(tapi_async_handler));
if (user_data == NULL) {
tapi_log_error("user data in %s is null", __func__);
free(fdn_record);
free(ar);
return -ENOMEM;
}
user_data->cb_function = p_handle;
user_data->result = ar;
if (!g_dbus_proxy_method_call(proxy, "DeleteFdn", delete_fdn_record_append,
method_call_complete, user_data, phonebook_event_data_free)) {
tapi_log_error("method call failed in %s", __func__);
phonebook_event_data_free(user_data);
return -EINVAL;
}
return OK;
}
int tapi_phonebook_update_fdn_entry(tapi_context context, int slot_id, int event_id,
int fdn_idx, char* new_name, char* new_number, char* pin2, tapi_async_function p_handle)
{
tapi_async_handler* user_data;
dbus_context* ctx = context;
fdn_record_param* fdn_record;
tapi_async_result* ar;
GDBusProxy* proxy;
if (ctx == NULL) {
tapi_log_error("context in %s is null", __func__);
return -EINVAL;
}
if (!tapi_is_valid_slotid(slot_id)) {
tapi_log_error("invalid slot id in %s", __func__);
return -EINVAL;
}
if (fdn_idx < 1) {
tapi_log_error("invalid fdn idx in %s", __func__);
return -EINVAL;
}
if (new_name == NULL) {
tapi_log_error("new name in %s is null", __func__);
return -EINVAL;
}
if (new_number == NULL) {
tapi_log_error("new number in %s is null", __func__);
return -EINVAL;
}
if (pin2 == NULL) {
tapi_log_error("pin2 in %s is null", __func__);
return -EINVAL;
}
proxy = get_dbus_proxy_by_type(ctx, slot_id, DBUS_PROXY_PHONEBOOK);
if (proxy == NULL) {
tapi_log_error("no available proxy in %s", __func__);
return -EIO;
}
fdn_record = calloc(1, sizeof(fdn_record_param));
if (fdn_record == NULL) {
tapi_log_error("fdn record in %s is null", __func__);
return -ENOMEM;
}
fdn_record->fdn_idx = fdn_idx;
fdn_record->tag = new_name;
fdn_record->number = new_number;
fdn_record->pin2 = pin2;
ar = calloc(1, sizeof(tapi_async_result));
if (ar == NULL) {
tapi_log_error("async result in %s is null", __func__);
free(fdn_record);
return -ENOMEM;
}
ar->msg_id = event_id;
ar->arg1 = slot_id;
ar->data = fdn_record;
user_data = calloc(1, sizeof(tapi_async_handler));
if (user_data == NULL) {
tapi_log_error("user data in %s is null", __func__);
free(fdn_record);
free(ar);
return -ENOMEM;
}
user_data->cb_function = p_handle;
user_data->result = ar;
if (!g_dbus_proxy_method_call(proxy, "UpdateFdn", update_fdn_record_append,
method_call_complete, user_data, phonebook_event_data_free)) {
phonebook_event_data_free(user_data);
tapi_log_error("method call failed in %s", __func__);
return -EINVAL;
}
return OK;
}