*/
#include <stdlib.h>
-#include <tapi_common.h>
-#include <ITapiCall.h>
#include <json.h>
#include <context_mgr.h>
#include "social_status_types.h"
#include "call.h"
+#define TELEPHONY_NOTI_ID_CNT 8
GENERATE_PROVIDER_COMMON_IMPL(social_status_call);
static bool telephony_initialized = false;
-static TapiHandle* tapi_handle = NULL;
-
-static void call_status_cb(TelCallStatus_t *out, void *user_data)
+static telephony_noti_e call_noti_ids[] =
{
- //TODO: Can this be called multiple times?
-
- std::string *addr = static_cast<std::string*>(user_data);
- *addr = out->pNumber;
-}
+ TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE,
+ TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE,
+// TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD,
+// TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING,
+ TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING,
+ TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING,
+ TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE,
+ TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE,
+// TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING,
+ TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING,
+ TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING,
+};
+static ctx::json latest;
ctx::social_status_call::social_status_call()
{
- tapi_handle = NULL;
}
ctx::social_status_call::~social_status_call()
"\"Address\":{\"type\":\"string\"}"
"}",
NULL);
+ //TODO remove Connecting, Connected
}
void ctx::social_status_call::call_event_cb(telephony_h handle, telephony_noti_e noti_id, void *data, void *user_data)
{
social_status_call *instance = static_cast<social_status_call*>(user_data);
- instance->handle_call_event(handle, noti_id);
+ instance->handle_call_event(handle, noti_id, data);
}
-void ctx::social_status_call::handle_call_event(telephony_h handle, telephony_noti_e noti_id)
+void ctx::social_status_call::handle_call_event(telephony_h handle, telephony_noti_e noti_id, void* id)
{
- telephony_call_state_e call_state;
+
json data;
+ unsigned int count;
+ telephony_call_h *call_list;
+ // Call state
switch (noti_id) {
- case TELEPHONY_NOTI_VOICE_CALL_STATE:
- IF_FAIL_VOID(get_voice_call_state(call_state));
- data.set(NULL, SOCIAL_ST_MEDIUM, SOCIAL_ST_VOICE);
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE:
+ data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_IDLE);
break;
- case TELEPHONY_NOTI_VIDEO_CALL_STATE:
- IF_FAIL_VOID(get_video_call_state(call_state));
- data.set(NULL, SOCIAL_ST_MEDIUM, SOCIAL_ST_VIDEO);
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE:
+ data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_ACTIVE);
break;
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING:
+ data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_ALERTING);
+ break;
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING:
+ data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_INCOMING);
+ break;
+/* // Ignore below cases
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD:
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING:*/
default:
_E("Unkown noti id: %d", noti_id);
return;
}
- std::string addr;
-
- switch (call_state) {
- case TELEPHONY_CALL_STATE_CONNECTING:
- IF_FAIL_VOID(get_call_address(addr));
- data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_CONNECTING);
- data.set(NULL, SOCIAL_ST_ADDRESS, addr);
+ // Call type
+ switch (noti_id) {
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_IDLE:
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_ACTIVE:
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_ALERTING:
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_INCOMING:
+ data.set(NULL, SOCIAL_ST_TYPE, SOCIAL_ST_VOICE);
break;
- case TELEPHONY_CALL_STATE_CONNECTED:
- IF_FAIL_VOID(get_call_address(addr));
- data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_CONNECTED);
- data.set(NULL, SOCIAL_ST_ADDRESS, addr);
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_IDLE:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ACTIVE:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_ALERTING:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_INCOMING:
+ data.set(NULL, SOCIAL_ST_TYPE, SOCIAL_ST_VIDEO);
break;
+/* // Ignore below cases
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_HELD:
+ case TELEPHONY_NOTI_VOICE_CALL_STATUS_DIALING:
+ case TELEPHONY_NOTI_VIDEO_CALL_STATUS_DIALING:*/
default:
- data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_IDLE);
- break;
+ _E("Unkown noti id: %d", noti_id);
+ return;
}
- context_manager::publish(SOCIAL_ST_SUBJ_CALL, NULL, ERR_NONE, data);
+ int err = telephony_call_get_call_list(handle, &count, &call_list);
+ IF_FAIL_VOID_TAG(err == TELEPHONY_ERROR_NONE, _E, "Getting call list failed");
+
+ unsigned int call_id = *static_cast<unsigned int *>(id);
+ for (unsigned int i = 0; i < count; i++) {
+ unsigned int tmp_id;
+ // Handle id
+ if (!get_call_handle_id(call_list[i], tmp_id)) {
+ continue;
+ }
+
+ if (call_id != tmp_id) {
+ continue;
+ }
+
+ // Address
+ std::string address;
+ if (get_call_address(call_list[i], address)) {
+ data.set(NULL, SOCIAL_ST_ADDRESS, address);
+ break;
+ }
+ }
+
+ if (latest != data) {
+ context_manager::publish(SOCIAL_ST_SUBJ_CALL, NULL, ERR_NONE, data);
+ latest = data.str();
+ }
+ telephony_call_release_call_list(count, &call_list);
}
bool ctx::social_status_call::init_telephony()
int err = telephony_init(&handle_list);
IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Initialization failed");
- tapi_handle = tel_init(NULL);
- if (tapi_handle == NULL) {
- _E("Initialization failed");
- return false;
- }
-
telephony_initialized = true;
return true;
}
IF_FAIL_VOID(telephony_initialized);
telephony_deinit(&handle_list);
- tel_deinit(tapi_handle);
- tapi_handle = NULL;
telephony_initialized = false;
}
IF_FAIL_RETURN_TAG(init_telephony(), false, _E, "Initialization failed");
int err;
- err = telephony_set_noti_cb(handle_list.handle[0], TELEPHONY_NOTI_VOICE_CALL_STATE, call_event_cb, this);
- IF_FAIL_CATCH(err == TELEPHONY_ERROR_NONE);
- err = telephony_set_noti_cb(handle_list.handle[0], TELEPHONY_NOTI_VIDEO_CALL_STATE, call_event_cb, this);
- IF_FAIL_CATCH(err == TELEPHONY_ERROR_NONE);
+ for (unsigned int i = 0; i < handle_list.count; i++) {
+ for (unsigned int j = 0; j < TELEPHONY_NOTI_ID_CNT; j++) {
+ err = telephony_set_noti_cb(handle_list.handle[i], call_noti_ids[j], call_event_cb, this);
+ IF_FAIL_CATCH(err == TELEPHONY_ERROR_NONE);
+ }
+ }
return true;
void ctx::social_status_call::unset_callback()
{
- telephony_unset_noti_cb(handle_list.handle[0], TELEPHONY_NOTI_VOICE_CALL_STATE);
- telephony_unset_noti_cb(handle_list.handle[0], TELEPHONY_NOTI_VIDEO_CALL_STATE);
+ for (unsigned int i = 0; i < handle_list.count; i++) {
+ for (unsigned int j = 0; j < TELEPHONY_NOTI_ID_CNT; j++) {
+ telephony_unset_noti_cb(handle_list.handle[i], call_noti_ids[j]);
+ }
+ }
+
release_telephony();
}
-bool ctx::social_status_call::get_voice_call_state(telephony_call_state_e& state)
+bool ctx::social_status_call::get_call_state(telephony_call_h& handle, std::string& state)
{
- int ret = telephony_call_get_voice_call_state(handle_list.handle[0], &state);
- IF_FAIL_RETURN_TAG(ret == TELEPHONY_ERROR_NONE, false, _E, "Getting status failed");
+ state.clear();
+
+ telephony_call_status_e st;
+ int err = telephony_call_get_status(handle, &st);
+ IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting state failed");
+
+ switch (st) {
+ case TELEPHONY_CALL_STATUS_ACTIVE:
+ state = SOCIAL_ST_ACTIVE;
+ break;
+ case TELEPHONY_CALL_STATUS_HELD:
+ state = SOCIAL_ST_HELD;
+ break;
+ case TELEPHONY_CALL_STATUS_DIALING:
+ state = SOCIAL_ST_DIALING;
+ break;
+ case TELEPHONY_CALL_STATUS_ALERTING:
+ state = SOCIAL_ST_ALERTING;
+ break;
+ case TELEPHONY_CALL_STATUS_INCOMING:
+ state = SOCIAL_ST_INCOMING;
+ break;
+ default:
+ state = SOCIAL_ST_IDLE;
+ }
+
+ IF_FAIL_RETURN_TAG(!state.empty(), false, _W, "State is empty");
+
return true;
}
-bool ctx::social_status_call::get_video_call_state(telephony_call_state_e& state)
+bool ctx::social_status_call::get_call_type(telephony_call_h& handle, std::string& type)
{
- int ret = telephony_call_get_video_call_state(handle_list.handle[0], &state);
- IF_FAIL_RETURN_TAG(ret == TELEPHONY_ERROR_NONE, false, _E, "Getting status failed");
+ type.clear();
+
+ telephony_call_type_e t;
+ int err = telephony_call_get_type(handle, &t);
+ IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting type failed");
+
+ switch (t) {
+ case TELEPHONY_CALL_TYPE_VOICE:
+ type = SOCIAL_ST_VOICE;
+ break;
+ case TELEPHONY_CALL_TYPE_VIDEO:
+ type = SOCIAL_ST_VIDEO;
+ break;
+ default:
+ _E("Unknown type: %d", t);
+ return false;
+ }
+
+ IF_FAIL_RETURN_TAG(!type.empty(), false, _W, "Type is empty");
+
return true;
}
-bool ctx::social_status_call::get_call_address(std::string& address)
+bool ctx::social_status_call::get_call_address(telephony_call_h& handle, std::string& address)
{
address.clear();
- tel_get_call_status_all(tapi_handle, call_status_cb, &address);
- /* FIXME: 'address' should not be empty, if the telephony works properly */
- IF_FAIL_RETURN_TAG(!address.empty(), true, _W, "Getting address failed");
+
+ char* number = NULL;
+ int err = telephony_call_get_number(handle, &number);
+ IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting address failed");
+
+ if (number) {
+ address = number;
+ free(number);
+ number = NULL;
+ }
+
+ IF_FAIL_RETURN_TAG(!address.empty(), false, _W, "Address is empty");
+
+ return true;
+}
+
+bool ctx::social_status_call::get_call_handle_id(telephony_call_h& handle, unsigned int& id)
+{
+ int err = telephony_call_get_handle_id(handle, &id);
+ IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, false, _E, "Getting handle id failed");
+
return true;
}
return ERR_NONE;
}
-
int ctx::social_status_call::unsubscribe()
{
unset_callback();
return ERR_NONE;
}
-bool ctx::social_status_call::read_current_status(ctx::json& data)
+bool ctx::social_status_call::read_current_status(telephony_h& handle, ctx::json& data)
{
- telephony_call_state_e voice_state;
- telephony_call_state_e video_state;
-
- if (!get_voice_call_state(voice_state))
- voice_state = TELEPHONY_CALL_STATE_IDLE;
-
- if (!get_video_call_state(video_state))
- video_state = TELEPHONY_CALL_STATE_IDLE;
-
- if (voice_state == TELEPHONY_CALL_STATE_IDLE && video_state == TELEPHONY_CALL_STATE_IDLE) {
- // Both types of calls are idle
- data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_IDLE);
- return true;
- }
-
- std::string addr;
- IF_FAIL_RETURN(get_call_address(addr), false);
-
- data.set(NULL, SOCIAL_ST_ADDRESS, addr);
-
- if (voice_state == TELEPHONY_CALL_STATE_CONNECTED || video_state == TELEPHONY_CALL_STATE_CONNECTED) {
- data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_CONNECTED);
- } else {
- data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_CONNECTING);
+ unsigned int count = 0;
+ telephony_call_h *call_list = NULL;
+ telephony_call_get_call_list(handle, &count, &call_list);
+
+ // Default data
+ data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_IDLE);
+
+ // Held & Dialing are ignored
+ for (unsigned int i = 0; i < count; i++) {
+ // Call state
+ std::string state;
+ if (get_call_state(call_list[i], state)) {
+ // Skip Held & Dialing
+ if (state.compare(SOCIAL_ST_HELD) == 0 || state.compare(SOCIAL_ST_DIALING) == 0)
+ continue;
+
+ data.set(NULL, SOCIAL_ST_STATE, state);
+ }
+
+ // Call type
+ std::string type;
+ if (get_call_type(call_list[i], type)) {
+ data.set(NULL, SOCIAL_ST_MEDIUM, type);
+ }
+
+ // Address
+ std::string address;
+ if (get_call_address(call_list[i], address)) {
+ data.set(NULL, SOCIAL_ST_ADDRESS, address);
+ }
+
+ if (state == SOCIAL_ST_ACTIVE) {
+ break;
+ }
}
+ telephony_call_release_call_list(count, &call_list);
return true;
}
temporary_handle = true;
}
+ bool ret = true;
json data;
- bool ret = read_current_status(data);
+ data.set(NULL, SOCIAL_ST_STATE, SOCIAL_ST_IDLE);
+
+ for (unsigned int i = 0; i < handle_list.count; i++) {
+ telephony_sim_state_e state;
+ int err = telephony_sim_get_state(handle_list.handle[i], &state);
+ IF_FAIL_RETURN_TAG(err == TELEPHONY_ERROR_NONE, ERR_OPERATION_FAILED, _E, "Getting SIM status failed");
+
+ if (state != TELEPHONY_SIM_STATE_AVAILABLE)
+ continue;
+
+ ret = read_current_status(handle_list.handle[i], data);
+ break;
+ }
if (temporary_handle)
release_telephony();