summaryrefslogtreecommitdiff
path: root/src/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.cpp')
-rwxr-xr-xsrc/client.cpp2366
1 files changed, 2366 insertions, 0 deletions
diff --git a/src/client.cpp b/src/client.cpp
new file mode 100755
index 0000000..f3fc816
--- /dev/null
+++ b/src/client.cpp
@@ -0,0 +1,2366 @@
+/*
+ * libslp-sensor
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: JuHyun Kim <jh8212.kim@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <math.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include <cobject_type.h>
+
+#include <csync.h>
+#include <cmutex.h>
+#include <clist.h>
+#include <cworker.h>
+#include <csock.h>
+
+#include <cpacket.h>
+
+#include <common.h>
+#include <sf_common.h>
+
+#include <vconf.h>
+#include <glib.h>
+#include <sensor.h>
+#include <errno.h>
+
+extern int errno;
+
+#ifndef EXTAPI
+#define EXTAPI __attribute__((visibility("default")))
+#endif
+
+#define MAX_BIND_SLOT 16
+#define MAX_CB_SLOT_PER_BIND 16
+#define MAX_CB_BIND_SLOT 64
+#define MAX_EVENT_LIST 19
+
+#define PITCH_MIN 35
+#define PITCH_MAX 145
+
+#define MAX_CHANNEL_NAME_LEN 50
+#define BASE_GATHERING_INTERVAL 100
+
+#define ACCEL_SENSOR_BASE_CHANNEL_NAME "accel_datastream"
+#define GEOMAG_SENSOR_BASE_CHANNEL_NAME "geomag_datastream"
+#define LIGHT_SENSOR_BASE_CHANNEL_NAME "lumin_datastream"
+#define PROXI_SENSOR_BASE_CHANNEL_NAME "proxi_datastream"
+#define MOTION_ENGINE_BASE_CHANNEL_NAME "motion_datastream"
+#define GYRO_SENSOR_BASE_CHANNEL_NAME "gyro_datastream"
+#define BAROMETER_SENSOR_BASE_CHANNEL_NAME "barometer_datastream"
+#define FUSION_SENSOR_BASE_CHANNEL_NAME "fusion_datastream"
+
+#define ROTATION_0 0
+#define ROTATION_90 90
+#define ROTATION_180 180
+#define ROTATION_270 270
+#define ROTATION_360 360
+#define ROTATION_THD 45
+
+#define RADIAN_VALUE (57.2957)
+#define XY_POSITIVE_THD 2.0
+#define XY_NEGATIVE_THD -2.0
+
+#define ON_TIME_REQUEST_COUNTER 1
+
+#define VCONF_SF_SERVER_POWER_OFF "memory/private/sensor/poweroff"
+
+const char *STR_SF_CLIENT_IPC_SOCKET = "/tmp/sf_socket";
+
+static cmutex _lock;
+static int g_system_off_cb_ct = 0;
+
+enum _sensor_current_state {
+ SENSOR_STATE_UNKNOWN = -1,
+ SENSOR_STATE_STOPPED = 0,
+ SENSOR_STATE_STARTED = 1,
+ SENSOR_STATE_PAUSED = 2
+};
+
+enum _sensor_wakeup_state {
+ SENSOR_WAKEUP_UNKNOWN = -1,
+ SENSOR_WAKEUP_UNSETTED = 0,
+ SENSOR_WAKEUP_SETTED = 1,
+};
+
+enum _sensor_poweroff_state {
+ SENSOR_POWEROFF_UNKNOWN = -1,
+ SENSOR_POWEROFF_AWAKEN = 1,
+};
+
+struct sf_bind_table_t {
+ csock *ipc;
+ sensor_type_t sensor_type;
+ int cb_event_max_num; /*limit by MAX_BIND_PER_CB_SLOT*/
+ int cb_slot_num[MAX_CB_SLOT_PER_BIND];
+ int my_handle;
+ int sensor_state;
+ int wakeup_state;
+ int sensor_option;
+};
+
+struct cb_bind_table_t {
+ char call_back_key[MAX_KEY_LEN];
+ void *client_data;
+ void (*sensor_callback_func_t)(unsigned int, sensor_event_data_t *, void *);
+ unsigned int cb_event_type;
+ int my_cb_handle;
+ int my_sf_handle;
+
+ unsigned int request_count;
+ unsigned int request_data_id;
+ void *collected_data;
+ unsigned int current_collected_idx;
+
+ GSource *source;
+ guint gsource_interval;
+ guint gID;
+};
+
+static struct rotation_event rotation_mode[] =
+{
+ { ROTATION_UNKNOWN, { ROTATION_UNKNOWN, ROTATION_UNKNOWN }},
+ { ROTATION_EVENT_90, { ROTATION_LANDSCAPE_LEFT, ROTATION_PORTRAIT_BTM }},
+ { ROTATION_EVENT_0, { ROTATION_PORTRAIT_TOP, ROTATION_LANDSCAPE_LEFT }},
+ { ROTATION_EVENT_180, { ROTATION_PORTRAIT_BTM, ROTATION_LANDSCAPE_RIGHT }},
+ { ROTATION_EVENT_270, { ROTATION_LANDSCAPE_RIGHT, ROTATION_PORTRAIT_TOP }},
+};
+
+struct event_counter_t {
+ const unsigned int event_type;
+ unsigned int event_counter;
+ unsigned int cb_list[MAX_BIND_SLOT];
+};
+
+static event_counter_t g_event_list[MAX_EVENT_LIST] = {
+ { ACCELEROMETER_EVENT_ROTATION_CHECK, 0, {0, }},
+ { ACCELEROMETER_EVENT_CALIBRATION_NEEDED, 0, {0, }},
+ { ACCELEROMETER_EVENT_SET_HORIZON, 0, {0, }},
+ { ACCELEROMETER_EVENT_SET_WAKEUP, 0, {0, }},
+ { GEOMAGNETIC_EVENT_CALIBRATION_NEEDED, 0, {0, }},
+ { PROXIMITY_EVENT_CHANGE_STATE, 0, {0, }},
+ { LIGHT_EVENT_CHANGE_LEVEL, 0, {0, }},
+ { MOTION_ENGINE_EVENT_SNAP, 0, {0, }},
+ { MOTION_ENGINE_EVENT_SHAKE, 0, {0, }},
+ { MOTION_ENGINE_EVENT_DOUBLETAP, 0, {0, }},
+ { MOTION_ENGINE_EVENT_PANNING, 0, {0, }},
+ { MOTION_ENGINE_EVENT_TOP_TO_BOTTOM, 0, {0, }},
+ { MOTION_ENGINE_EVENT_DIRECT_CALL, 0, {0, }},
+ { MOTION_ENGINE_EVENT_TILT_TO_UNLOCK, 0, {0, }},
+ { MOTION_ENGINE_EVENT_LOCK_EXECUTE_CAMERA, 0, {0, }},
+ { MOTION_ENGINE_EVENT_SMART_ALERT , 0, {0, }},
+ { MOTION_ENGINE_EVENT_TILT , 0, {0, }},
+ { MOTION_ENGINE_EVENT_PANNING_BROWSE , 0, {0, }},
+ { MOTION_ENGINE_EVENT_NO_MOVE , 0, {0, }},
+};
+
+static sf_bind_table_t g_bind_table[MAX_BIND_SLOT];
+
+static cb_bind_table_t g_cb_table[MAX_CB_BIND_SLOT];
+
+static gboolean sensor_timeout_handler(gpointer data);
+
+inline static void add_cb_number(int list_slot, unsigned int cb_number)
+{
+ if(list_slot < 0 || list_slot > MAX_EVENT_LIST - 1)
+ return;
+
+ unsigned int i = 0;
+ const unsigned int EVENT_COUNTER = g_event_list[list_slot].event_counter;
+
+ for(i = 0 ; i < EVENT_COUNTER ; i++) {
+ if(g_event_list[list_slot].cb_list[i] == cb_number){
+ return;
+ }
+ }
+
+ if(EVENT_COUNTER < MAX_BIND_SLOT) {
+ g_event_list[list_slot].event_counter++;
+ g_event_list[list_slot].cb_list[EVENT_COUNTER] = cb_number;
+ } else {
+ return ;
+ }
+}
+
+
+inline static void del_cb_number(int list_slot, unsigned int cb_number)
+{
+ if(list_slot < 0 || list_slot > MAX_EVENT_LIST - 1)
+ return;
+
+ unsigned int i = 0, j = 0;
+ const unsigned int EVENT_COUNTER = g_event_list[list_slot].event_counter;
+
+ for(i = 0 ; i < EVENT_COUNTER ; i++){
+ if(g_event_list[list_slot].cb_list[i] == cb_number){
+ for(j = i ; j < EVENT_COUNTER - 1; j++){
+ g_event_list[list_slot].cb_list[j] = g_event_list[list_slot].cb_list[j+1];
+ }
+ g_event_list[list_slot].cb_list[EVENT_COUNTER - 1] = 0;
+ g_event_list[list_slot].event_counter--;
+ return ;
+ }
+ }
+
+ DBG("cb number [%d] is not registered\n", cb_number);
+}
+
+
+inline static void del_cb_by_event_type(unsigned int event_type, unsigned int cb_number)
+{
+ int list_slot = 0;
+
+ for(list_slot = 0 ; list_slot < MAX_EVENT_LIST ; list_slot++)
+ if(g_event_list[list_slot].event_type == event_type)
+ break;
+
+ del_cb_number(list_slot, cb_number);
+}
+
+
+inline static int acquire_handle(void)
+{
+ register int i;
+ _lock.lock();
+ for (i = 0; i < MAX_BIND_SLOT; i ++) {
+ if (g_bind_table[i].ipc == NULL) break;
+ }
+ _lock.unlock();
+
+ return i;
+}
+
+
+inline static int cb_acquire_handle(void)
+{
+ register int i;
+ _lock.lock();
+ for (i = 0; i < MAX_CB_BIND_SLOT; i ++) {
+ if (g_cb_table[i].sensor_callback_func_t == NULL) break;
+ }
+ _lock.unlock();
+
+ return i;
+}
+
+
+inline static void release_handle(int i)
+{
+ register int j;
+
+ _lock.lock();
+ delete g_bind_table[i].ipc;
+ g_bind_table[i].ipc = NULL;
+ g_bind_table[i].sensor_type = UNKNOWN_SENSOR;
+
+ g_bind_table[i].my_handle = -1;
+ g_bind_table[i].sensor_state = SENSOR_STATE_UNKNOWN;
+ g_bind_table[i].wakeup_state = SENSOR_WAKEUP_UNKNOWN;
+ g_bind_table[i].sensor_option = SENSOR_OPTION_DEFAULT;
+
+ for (j=0; j<g_bind_table[i].cb_event_max_num; j++) {
+ if ( (j<MAX_CB_SLOT_PER_BIND) && (g_bind_table[i].cb_slot_num[j] > -1) ) {
+ del_cb_by_event_type(g_cb_table[g_bind_table[i].cb_slot_num[j]].cb_event_type, g_bind_table[i].cb_slot_num[j]);
+ g_cb_table[g_bind_table[i].cb_slot_num[j]].client_data= NULL;
+ g_cb_table[g_bind_table[i].cb_slot_num[j]].sensor_callback_func_t = NULL;
+ g_cb_table[g_bind_table[i].cb_slot_num[j]].cb_event_type = 0x00;
+ g_cb_table[g_bind_table[i].cb_slot_num[j]].my_cb_handle = -1;
+ g_bind_table[i].cb_slot_num[j] = -1;
+ }
+ }
+
+ g_bind_table[i].cb_event_max_num = 0;
+
+ _lock.unlock();
+}
+
+
+inline static void cb_release_handle(int i)
+{
+ _lock.lock();
+ g_cb_table[i].client_data= NULL;
+ g_cb_table[i].sensor_callback_func_t = NULL;
+ g_cb_table[i].cb_event_type = 0x00;
+ g_cb_table[i].my_cb_handle = -1;
+ g_cb_table[i].my_sf_handle = -1;
+
+ g_cb_table[i].request_count = 0;
+ g_cb_table[i].request_data_id = 0;
+
+ if ( g_cb_table[i].collected_data )
+ {
+ free (g_cb_table[i].collected_data);
+ g_cb_table[i].collected_data = NULL;
+ }
+
+ g_cb_table[i].collected_data = NULL;
+ g_cb_table[i].current_collected_idx = 0;
+
+ g_cb_table[i].source = NULL;
+ g_cb_table[i].gsource_interval = 0;
+ g_cb_table[i].gID = 0;
+ _lock.unlock();
+}
+
+
+void power_off_cb(keynode_t *node, void *data)
+{
+ int val = -1;
+ int handle = -1, j = -1;
+ int state = -1;
+
+ if(vconf_keynode_get_type(node) != VCONF_TYPE_INT)
+ {
+ ERR("Errer invailed keytype");
+ return;
+ }
+
+ val = vconf_keynode_get_int(node);
+
+ switch(val)
+ {
+ case SENSOR_POWEROFF_AWAKEN:
+ for(handle = 0 ; handle < MAX_BIND_SLOT ; handle++)
+ {
+ if(g_bind_table[handle].ipc != NULL)
+ {
+ state = sf_stop(handle);
+
+ if(state < 0)
+ {
+ ERR("Cannot stop handle [%d]",handle);
+ continue;
+ }
+ else
+ {
+ DBG("LCD OFF and sensor handle [%d] stopped",handle);
+ }
+
+ for(j = 0 ; j < g_bind_table[handle].cb_event_max_num ; j++)
+ {
+ if((j<MAX_CB_SLOT_PER_BIND) && (g_bind_table[handle].cb_slot_num[j] > -1))
+ {
+ state = sf_unregister_event(handle ,g_cb_table[g_bind_table[handle].cb_slot_num[j]].cb_event_type);
+
+ if(state < 0)
+ ERR("cannot unregster_event for event [%x], handle [%d]",g_cb_table[g_bind_table[handle].cb_slot_num[j]].cb_event_type, handle);
+ }
+ }
+
+ sf_disconnect(handle);
+ }
+ }
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+
+void lcd_off_cb(keynode_t *node, void *data)
+{
+ int val = -1;
+ int i = -1, j = -1;
+
+ if(vconf_keynode_get_type(node) != VCONF_TYPE_INT)
+ {
+ ERR("Errer invailed keytype");
+ return;
+ }
+
+ val = vconf_keynode_get_int(node);
+
+ switch(val)
+ {
+ case VCONFKEY_PM_STATE_LCDOFF: // LCD OFF
+ for(i = 0 ; i < MAX_BIND_SLOT ; i++)
+ {
+ if((g_bind_table[i].wakeup_state != SENSOR_WAKEUP_SETTED && g_bind_table[i].sensor_option != SENSOR_OPTION_ALWAYS_ON ) && g_bind_table[i].ipc != NULL)
+ {
+ if(g_bind_table[i].sensor_state == SENSOR_STATE_STARTED)
+ {
+ if(sf_stop(i) < 0)
+ {
+ ERR("Cannot stop handle [%d]",i);
+ }
+ else
+ {
+ g_bind_table[i].sensor_state = SENSOR_STATE_PAUSED;
+
+ for(j = 0; j < g_bind_table[i].cb_event_max_num; j++)
+ {
+ if(g_cb_table[g_bind_table[i].cb_slot_num[j]].cb_event_type != 0)
+ DBG("LCD OFF stopped event_type [%x]",g_cb_table[g_bind_table[i].cb_slot_num[j]].cb_event_type);
+ if(g_cb_table[g_bind_table[i].cb_slot_num[j]].collected_data != NULL)
+ {
+ g_source_destroy(g_cb_table[g_bind_table[i].cb_slot_num[j]].source);
+ g_source_unref(g_cb_table[g_bind_table[i].cb_slot_num[j]].source);
+ g_cb_table[g_bind_table[i].cb_slot_num[j]].source = NULL;
+ }
+ }
+
+ }
+ }
+ DBG("LCD OFF and sensor handle [%d] stopped",i);
+ }
+ }
+
+ break;
+ case VCONFKEY_PM_STATE_NORMAL: // LCD ON
+ for(i = 0 ; i < MAX_BIND_SLOT ; i++)
+ {
+ if(g_bind_table[i].sensor_state == SENSOR_STATE_PAUSED)
+ {
+ if(sf_start(i,g_bind_table[i].sensor_option) < 0)
+ {
+ ERR("Cannot start handle [%d]",i);
+ }
+ else
+ {
+ for(j = 0; j < g_bind_table[i].cb_event_max_num; j++)
+ {
+ if(g_cb_table[g_bind_table[i].cb_slot_num[j]].cb_event_type != 0)
+ DBG("LCD ON started event_type [%x]",g_cb_table[g_bind_table[i].cb_slot_num[j]].cb_event_type);
+ if(g_cb_table[g_bind_table[i].cb_slot_num[j]].collected_data != NULL)
+ {
+ g_cb_table[g_bind_table[i].cb_slot_num[j]].source = g_timeout_source_new(g_cb_table[g_bind_table[i].cb_slot_num[j]].gsource_interval);
+ g_source_set_callback(g_cb_table[g_bind_table[i].cb_slot_num[j]].source, sensor_timeout_handler, (gpointer)&g_cb_table[g_bind_table[i].cb_slot_num[j]].my_cb_handle,NULL);
+ g_cb_table[g_bind_table[i].cb_slot_num[j]].gID = g_source_attach(g_cb_table[g_bind_table[i].cb_slot_num[j]].source, NULL);
+ }
+ }
+ }
+ DBG("LCD ON and sensor handle [%d] started",i);
+ }
+ }
+
+ break;
+ default :
+ break ;
+ }
+}
+
+int system_off_set(void)
+{
+ int result = -1;
+ if(g_system_off_cb_ct == 0)
+ {
+ result = vconf_notify_key_changed(VCONFKEY_PM_STATE, lcd_off_cb, NULL);
+ if(result < 0)
+ {
+ ERR("cannot setting lcd_off_set_cb");
+ }
+
+ result = vconf_notify_key_changed(VCONF_SF_SERVER_POWER_OFF, power_off_cb, NULL);
+ if(result < 0)
+ {
+ ERR("cannot setting power_off_set_cb");
+ }
+
+ g_system_off_cb_ct++;
+ }
+ else if (g_system_off_cb_ct > 0)
+ {
+ g_system_off_cb_ct++;
+ }
+ else
+ {
+ ERR("g_system_off_cb_ct is negative");
+ return -1;
+ }
+
+ DBG("system_off_set success");
+ return 1;
+}
+
+int system_off_unset(void)
+{
+ int result = -1;
+ if(g_system_off_cb_ct == 1)
+ {
+ result = vconf_ignore_key_changed(VCONFKEY_PM_STATE, lcd_off_cb);
+ if(result < 0)
+ {
+ ERR("cannot setting lcd_off_set_cb");
+ }
+
+ result = vconf_ignore_key_changed(VCONF_SF_SERVER_POWER_OFF, power_off_cb);
+ if(result < 0)
+ {
+ ERR("cannot setting power_off_set_cb");
+ }
+
+ g_system_off_cb_ct = 0;
+ }
+ else if (g_system_off_cb_ct > 1)
+ {
+ g_system_off_cb_ct--;
+ }
+ else
+ {
+ ERR("g_system_off_cb_ct is negative");
+ return -1;
+ }
+ DBG("system_off_unset success");
+
+ return 1;
+}
+
+
+void lcd_off_set_wake_up(keynode_t *node, void *data)
+{
+ int state = 0;
+
+ state = sf_set_property(ACCELEROMETER_SENSOR, ACCELEROMETER_PROPERTY_SET_WAKEUP, WAKEUP_SET);
+
+ if(state < 0)
+ {
+ ERR("ACCELEROMETER_PROPERTY_SET_WAKEUP fail");
+ }
+}
+
+
+static void sensor_changed_cb(keynode_t *node, void *data)
+{
+ int event_number = (int)(data);
+ unsigned int i = 0;
+ int val;
+ int cb_number = 0;
+ sensor_event_data_t cb_data;
+ sensor_panning_data_t panning_data;
+
+ if(!node)
+ {
+ ERR("Node is NULL");
+ return;
+ }
+
+ if (vconf_keynode_get_type(node) != VCONF_TYPE_INT )
+ {
+ ERR("Err invaild key_type , incomming key_type : %d , key_name : %s , key_value : %d", vconf_keynode_get_type(node), vconf_keynode_get_name(node),vconf_keynode_get_int(node));
+ return;
+ }
+
+ val = vconf_keynode_get_int(node);
+
+ for( i = 0 ; i < g_event_list[event_number].event_counter ; i++)
+ {
+ cb_number = g_event_list[event_number].cb_list[i];
+
+ if(g_bind_table[g_cb_table[cb_number].my_sf_handle].sensor_state == SENSOR_STATE_STARTED)
+ {
+ if (g_cb_table[cb_number].sensor_callback_func_t)
+ {
+ if(g_cb_table[cb_number].cb_event_type == MOTION_ENGINE_EVENT_PANNING || g_cb_table[cb_number].cb_event_type == MOTION_ENGINE_EVENT_TILT || g_cb_table[cb_number].cb_event_type == MOTION_ENGINE_EVENT_PANNING_BROWSE)
+ {
+ if(val != 0)
+ {
+ panning_data.x = (short)(val >> 16);
+ panning_data.y = (short)(val & 0x0000FFFF);
+ cb_data.event_data_size = sizeof(sensor_panning_data_t);
+ cb_data.event_data = (void *)&panning_data;
+ g_cb_table[cb_number].sensor_callback_func_t(g_cb_table[cb_number].cb_event_type,&cb_data, g_cb_table[cb_number].client_data);
+ }
+ }
+ else
+ {
+ if ( val<0 )
+ {
+ ERR("vconf_keynode_get_int fail for key : %s , handle_num : %d ,get_value : %d\n",g_cb_table[cb_number].call_back_key,cb_number , val);
+ return ;
+ }
+
+ switch (g_cb_table[cb_number].cb_event_type) {
+ case ACCELEROMETER_EVENT_SET_WAKEUP :
+ /* fall through */
+ case ACCELEROMETER_EVENT_ROTATION_CHECK :
+ /* fall through */
+ case ACCELEROMETER_EVENT_SET_HORIZON :
+ /* fall through */
+ case GEOMAGNETIC_EVENT_CALIBRATION_NEEDED :
+ /* fall through */
+ case LIGHT_EVENT_CHANGE_LEVEL :
+ /* fall through */
+ case PROXIMITY_EVENT_CHANGE_STATE:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_SNAP:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_SHAKE:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_DOUBLETAP:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_TOP_TO_BOTTOM:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_DIRECT_CALL:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_TILT_TO_UNLOCK:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_LOCK_EXECUTE_CAMERA:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_SMART_ALERT:
+ /* fall through */
+ case MOTION_ENGINE_EVENT_NO_MOVE:
+ cb_data.event_data_size = sizeof(val);
+ cb_data.event_data = (void *)&val;
+ g_cb_table[cb_number].sensor_callback_func_t(g_cb_table[cb_number].cb_event_type, &cb_data , g_cb_table[cb_number].client_data);
+ break;
+ default :
+ ERR("Undefined cb_event_type");
+ return ;
+ break;
+ }
+ }
+ }
+ else
+ {
+ ERR("Empty Callback func in event : %x\n",g_cb_table[cb_number].cb_event_type);
+ }
+ }
+ else
+ {
+ ERR("Sensor doesn't start for event : %x",g_cb_table[cb_number].cb_event_type);
+ }
+ }
+}
+
+
+static gboolean sensor_timeout_handler(gpointer data)
+{
+ int *cb_handle = (int*)(data);
+ int state;
+ sensor_event_data_t cb_data;
+
+ if ( g_bind_table[g_cb_table[*cb_handle].my_sf_handle].sensor_state != SENSOR_STATE_STARTED ) {
+ return TRUE;
+ }
+
+ if (g_cb_table[*cb_handle].sensor_callback_func_t) {
+
+ if ( ((g_cb_table[*cb_handle].request_data_id & 0xFFFF) > 0) && ((g_cb_table[*cb_handle].request_data_id & 0xFFFF) < 10) ) {
+ sensor_data_t *base_data_values;
+ base_data_values =(sensor_data_t *)g_cb_table[*cb_handle].collected_data;
+
+ if ( !base_data_values ) {
+ ERR("ERR get saved_gather_data stuct fail in sensor_timeout_handler \n");
+ return FALSE;
+ }
+ state = sf_get_data(g_cb_table[*cb_handle].my_sf_handle, g_cb_table[*cb_handle].request_data_id, base_data_values);
+
+ if ( state < 0 ) {
+ ERR("ERR sensor_get_struct_data fail in sensor_timeout_handler : %d\n",state);
+ return TRUE;
+ }
+
+ cb_data.event_data_size = sizeof (sensor_data_t);
+ cb_data.event_data = g_cb_table[*cb_handle].collected_data;
+
+ g_cb_table[*cb_handle].sensor_callback_func_t( g_cb_table[*cb_handle].cb_event_type , &cb_data , g_cb_table[*cb_handle].client_data);
+
+
+ } else {
+ ERR("Does not support data_type");
+ return TRUE;
+ }
+
+
+ } else {
+ ERR("Empty Callback func in cb_handle : %d\n", *cb_handle);
+ }
+
+ return TRUE;
+}
+
+///////////////////////////////////for internal ///////////////////////////////////
+static int server_get_properties(int handle , unsigned int data_id, void *property_data)
+{
+ cpacket *packet;
+
+ try {
+ packet = new cpacket(sizeof(cmd_return_property_t) + sizeof(base_property_struct)+ 4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+
+ cmd_get_property_t *cmd_payload;
+
+ INFO("server_get_properties called with handle : %d \n", handle);
+ if (handle < 0) {
+ ERR("Invalid handle\n");
+ errno = EINVAL;
+ delete packet;
+ return -1;
+ }
+
+ cmd_payload = (cmd_get_property_t*)packet->data();
+ if (!cmd_payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_GET_PROPERTY);
+ packet->set_payload_size(sizeof(cmd_get_property_t));
+
+ if(data_id)
+ cmd_payload->get_level = data_id;
+ else
+ cmd_payload->get_level = ((unsigned int)g_bind_table[handle].sensor_type<<16) | 0x0001;
+
+
+
+ INFO("Send CMD_GET_PROPERTY command\n");
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Faield to send a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->cmd() == CMD_GET_PROPERTY) {
+ cmd_return_property_t *return_payload;
+ return_payload = (cmd_return_property_t*)packet->data();
+ if (return_payload->state < 0) {
+ ERR("sever get property fail , return state : %d\n",return_payload->state);
+ errno = EBADE;
+ delete packet;
+ return -2;
+ } else {
+ base_property_struct *base_return_property;
+ base_return_property = (base_property_struct *)return_payload->property_struct;
+
+ if(data_id)
+ {
+ sensor_data_properties_t *return_properties;
+ return_properties = (sensor_data_properties_t *)property_data;
+ return_properties->sensor_unit_idx = base_return_property->sensor_unit_idx ;
+ return_properties->sensor_min_range= base_return_property->sensor_min_range;
+ return_properties->sensor_max_range= base_return_property->sensor_max_range;
+ return_properties->sensor_resolution = base_return_property->sensor_resolution;
+ }
+ else
+ {
+ sensor_properties_t *return_properties;
+ return_properties = (sensor_properties_t *)property_data;
+ return_properties->sensor_unit_idx = base_return_property->sensor_unit_idx ;
+ return_properties->sensor_min_range= base_return_property->sensor_min_range;
+ return_properties->sensor_max_range= base_return_property->sensor_max_range;
+ return_properties->sensor_resolution = base_return_property->sensor_resolution;
+ memset(return_properties->sensor_name, '\0', sizeof(return_properties->sensor_name));
+ memset(return_properties->sensor_vendor, '\0', sizeof(return_properties->sensor_vendor));
+ strncpy(return_properties->sensor_name, base_return_property->sensor_name, strlen(base_return_property->sensor_name));
+ strncpy(return_properties->sensor_vendor, base_return_property->sensor_vendor, strlen(base_return_property->sensor_vendor));
+ }
+ }
+ } else {
+ ERR("unexpected server cmd\n");
+ errno = EBADE;
+ delete packet;
+ return -2;
+ }
+ }
+
+ delete packet;
+ return 0;
+}
+
+
+static int server_set_property(int handle , unsigned int property_id, long value )
+{
+ cpacket *packet;
+ try {
+ packet = new cpacket(sizeof(cmd_set_value_t) + 4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+ cmd_set_value_t *cmd_payload;
+ INFO("server_set_property called with handle : %d \n", handle);
+ if (handle < 0) {
+ ERR("Invalid handle\n");
+ errno = EINVAL;
+ delete packet;
+ return -1;
+ }
+
+ cmd_payload = (cmd_set_value_t*)packet->data();
+ if (!cmd_payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_SET_VALUE);
+ packet->set_payload_size(sizeof(cmd_set_value_t));
+
+ cmd_payload->sensor_type = g_bind_table[handle].sensor_type;
+ cmd_payload->property = property_id;
+ cmd_payload->value = value;
+
+
+ INFO("Send CMD_SET_VALUE command\n");
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Faield to send a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->cmd() == CMD_DONE) {
+ cmd_done_t *payload;
+ payload = (cmd_done_t*)packet->data();
+
+ if (payload->value == -1) {
+ ERR("cannot support input property\n");
+ errno = ENODEV;
+ delete packet;
+ return -1;
+ }
+ } else {
+ ERR("unexpected server cmd\n");
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ }
+
+ delete packet;
+ return 0;
+}
+
+///////////////////////////////////for external ///////////////////////////////////
+
+EXTAPI int sf_is_sensor_event_available ( sensor_type_t desired_sensor_type , unsigned int desired_event_type )
+{
+ int handle;
+ cpacket *packet;
+ try {
+ packet = new cpacket(sizeof(cmd_reg_t)+4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+ cmd_reg_t *payload;
+
+ handle = sf_connect(desired_sensor_type);
+ if ( handle < 0 ) {
+ errno = ENODEV;
+ delete packet;
+ return -2;
+ }
+
+ if ( desired_event_type != 0 ) {
+
+ payload = (cmd_reg_t*)packet->data();
+ if (!payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_REG);
+ packet->set_payload_size(sizeof(cmd_reg_t));
+ payload->type = REG_CHK;
+ payload->event_type = desired_event_type;
+
+ INFO("Send CMD_REG command\n");
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Faield to send a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->cmd() == CMD_DONE) {
+ cmd_done_t *payload;
+ payload = (cmd_done_t*)packet->data();
+ if (payload->value == -1) {
+ ERR("sever check fail\n");
+ errno = ENODEV;
+ delete packet;
+ return -2;
+ }
+ } else {
+ ERR("unexpected server cmd\n");
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ }
+
+ }
+
+ sf_disconnect(handle);
+ delete packet;
+
+ return 0;
+}
+
+EXTAPI int sf_get_data_properties(unsigned int data_id, sensor_data_properties_t *return_data_properties)
+{
+ int handle;
+ int state = -1;
+
+ retvm_if( (!return_data_properties ) , -1 , "Invalid return properties pointer : %p", return_data_properties);
+
+
+ handle = sf_connect((sensor_type_t)(data_id >> 16));
+ if ( handle < 0 ) {
+ ERR("Sensor connet fail !! for : %x \n", (data_id >> 16));
+ return -1;
+ } else {
+ state = server_get_properties( handle , data_id, return_data_properties );
+ if ( state < 0 ) {
+ ERR("server_get_properties fail , state : %d \n",state);
+ }
+ sf_disconnect(handle);
+ }
+
+ return state;
+}
+
+EXTAPI int sf_get_properties(sensor_type_t sensor_type, sensor_properties_t *return_properties)
+{
+ int handle;
+ int state = -1;
+
+ retvm_if( (!return_properties ) , -1 , "Invalid return properties pointer : %p", return_properties);
+
+ handle = sf_connect(sensor_type);
+ if ( handle < 0 ) {
+ ERR("Sensor connet fail !! for : %x \n", sensor_type);
+ return -1;
+ } else {
+ state = server_get_properties( handle , 0, return_properties );
+ if ( state < 0 ) {
+ ERR("server_get_properties fail , state : %d \n",state);
+ }
+ sf_disconnect(handle);
+ }
+
+ return state;
+}
+
+
+EXTAPI int sf_set_property(sensor_type_t sensor_type, unsigned int property_id, long value)
+{
+ int handle;
+ int state = -1;
+
+ handle = sf_connect(sensor_type);
+ if ( handle < 0 ) {
+ ERR("Sensor connet fail !! for : %x \n", sensor_type);
+ return -1;
+ } else {
+ state = server_set_property( handle , property_id, value );
+ if ( state < 0 ) {
+ ERR("server_set_property fail , state : %d \n",state);
+ }
+ sf_disconnect(handle);
+ }
+
+ return state;
+}
+
+
+EXTAPI int sf_connect(sensor_type_t sensor_type)
+{
+ register int i, j;
+ cpacket *packet;
+ try {
+ packet = new cpacket(sizeof(cmd_hello_t)+MAX_CHANNEL_NAME_LEN+4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+ cmd_hello_t *payload;
+ cmd_done_t *return_payload;
+
+ pid_t cpid;
+ size_t channel_name_length;
+
+ const char *sf_channel_name = NULL;
+
+ cpid = getpid();
+
+ INFO("Sensor_attach_channel from pid : %d , to sensor_type : %x",cpid ,sensor_type);
+
+ i = acquire_handle();
+ if (i == MAX_BIND_SLOT) {
+ ERR("MAX_BIND_SLOT, Too many slot required");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ INFO("Empty slot : %d\n", i);
+
+ switch (sensor_type) {
+ case ACCELEROMETER_SENSOR :
+ sf_channel_name = (char *)ACCEL_SENSOR_BASE_CHANNEL_NAME;
+ g_bind_table[i].cb_event_max_num = 8;
+ break;
+
+ case GEOMAGNETIC_SENSOR :
+ sf_channel_name = (char *)GEOMAG_SENSOR_BASE_CHANNEL_NAME;
+ g_bind_table[i].cb_event_max_num = 3;
+ break;
+
+ case LIGHT_SENSOR:
+ sf_channel_name = (char *)LIGHT_SENSOR_BASE_CHANNEL_NAME;
+ g_bind_table[i].cb_event_max_num = 3;
+ break;
+
+ case PROXIMITY_SENSOR:
+ sf_channel_name = (char *)PROXI_SENSOR_BASE_CHANNEL_NAME;
+ g_bind_table[i].cb_event_max_num = 3;
+ break;
+
+ case MOTION_SENSOR:
+ sf_channel_name = (char *)MOTION_ENGINE_BASE_CHANNEL_NAME;
+ g_bind_table[i].cb_event_max_num = 12;
+ break;
+
+ case GYROSCOPE_SENSOR:
+ sf_channel_name = (char *)GYRO_SENSOR_BASE_CHANNEL_NAME;
+ g_bind_table[i].cb_event_max_num = 1;
+ break;
+
+ case THERMOMETER_SENSOR:
+ break;
+ case BAROMETER_SENSOR:
+ sf_channel_name = (char *)BAROMETER_SENSOR_BASE_CHANNEL_NAME;
+ g_bind_table[i].cb_event_max_num = 3;
+ break;
+ case FUSION_SENSOR:
+ sf_channel_name = (char *)FUSION_SENSOR_BASE_CHANNEL_NAME;
+ g_bind_table[i].cb_event_max_num = 3;
+ break;
+
+ case UNKNOWN_SENSOR:
+ default :
+ ERR("Undefined sensor_type");
+ release_handle(i);
+ errno = ENODEV;
+ delete packet;
+ return -2;
+ break;
+ }
+
+ g_bind_table[i].sensor_type = sensor_type ;
+ g_bind_table[i].my_handle = i;
+ g_bind_table[i].sensor_state = SENSOR_STATE_STOPPED;
+ g_bind_table[i].wakeup_state = SENSOR_WAKEUP_UNSETTED;
+ g_bind_table[i].sensor_option = SENSOR_OPTION_DEFAULT;
+
+ for(j = 0 ; j < g_bind_table[i].cb_event_max_num ; j++)
+ g_bind_table[i].cb_slot_num[j] = -1;
+
+ try {
+ g_bind_table[i].ipc = new csock( (char *)STR_SF_CLIENT_IPC_SOCKET, csock::SOCK_TCP|csock::SOCK_IPC|csock::SOCK_WORKER, 0, 0);
+ } catch (...) {
+ release_handle(i);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (g_bind_table[i].ipc && g_bind_table[i].ipc->connect_to_server() == false) {
+ delete g_bind_table[i].ipc;
+ g_bind_table[i].ipc = NULL;
+ release_handle(i);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+
+ INFO("Connected to server\n");
+ payload = (cmd_hello_t*)packet->data();
+ if (!payload) {
+ ERR("cannot find memory for send packet->data");
+ release_handle(i);
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ if (!sf_channel_name ) {
+ ERR("cannot find matched-sensor name!!!");
+ release_handle(i);
+ errno = ENODEV;
+ delete packet;
+ return -2;
+ } else {
+ channel_name_length = strlen(sf_channel_name);
+ if ( channel_name_length > MAX_CHANNEL_NAME_LEN ) {
+ ERR("error, channel_name_length too long !!!");
+ release_handle(i);
+ errno = EINVAL;
+ delete packet;
+ return -1;
+ }
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_HELLO);
+ packet->set_payload_size(sizeof(cmd_hello_t) + channel_name_length);
+ strcpy(payload->name, sf_channel_name);
+
+ if (g_bind_table[i].ipc && g_bind_table[i].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Failed to send a hello packet\n");
+ release_handle(i);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ INFO("Wait for recv a reply packet\n");
+ if (g_bind_table[i].ipc && g_bind_table[i].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ release_handle(i);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[i].ipc && g_bind_table[i].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ release_handle(i);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ }
+
+ return_payload = (cmd_done_t*)packet->data();
+ if (!return_payload) {
+ ERR("cannot find memory for return packet->data");
+ release_handle(i);
+ delete packet;
+ return -1;
+ }
+
+ if ( return_payload->value < 0) {
+ ERR("There is no sensor \n");
+ release_handle(i);
+ delete packet;
+ return -1;
+ }
+
+ system_off_set();
+
+ INFO("Connected sensor type : %x , handle : %d \n", sensor_type , i);
+ delete packet;
+ return i;
+}
+
+EXTAPI int sf_disconnect(int handle)
+{
+ cpacket *packet;
+ cmd_byebye_t *payload;
+
+ retvm_if( handle > MAX_BIND_SLOT - 1 , -1 , "Incorrect handle");
+ retvm_if( (g_bind_table[handle].ipc == NULL) ||(handle < 0) , -1 , "sensor_detach_channel fail , invalid handle value : %d",handle);
+
+ try {
+ packet = new cpacket(sizeof(cmd_byebye_t)+4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+
+ INFO("Detach, so remove %d from the table\n", handle);
+
+ payload = (cmd_byebye_t*)packet->data();
+ if (!payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_BYEBYE);
+ packet->set_payload_size(sizeof(cmd_byebye_t));
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Failed to send, but delete handle\n");
+ errno = ECOMM;
+ goto out;
+ }
+
+ INFO("Recv a reply packet\n");
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ ERR("Send to reply packet fail\n");
+ errno = ECOMM;
+ goto out;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ ERR("Failed to recv packet\n");
+ errno = ECOMM;
+ }
+ }
+
+out:
+ release_handle(handle);
+ system_off_unset();
+ delete packet;
+ return 0;
+
+}
+
+EXTAPI int sf_start(int handle , int option)
+{
+ cpacket *packet;
+ cmd_start_t *payload;
+
+ int lcd_state = 0;
+
+ retvm_if( handle > MAX_BIND_SLOT - 1, -1 , "Incorrect handle");
+ retvm_if( (g_bind_table[handle].ipc == NULL) ||(handle < 0) , -1 , "sensor_start fail , invalid handle value : %d",handle);
+ retvm_if( option < 0 , -1 , "sensor_start fail , invalid option value : %d",option);
+ retvm_if( g_bind_table[handle].sensor_state == SENSOR_STATE_STARTED , 0 , "sensor already started");
+
+ try {
+ packet = new cpacket(sizeof(cmd_start_t)+4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+
+ if(option != SENSOR_OPTION_ALWAYS_ON)
+ {
+ if(vconf_get_int(VCONFKEY_PM_STATE, &lcd_state) == 0)
+ {
+ if(lcd_state == VCONFKEY_PM_STATE_LCDOFF)
+ {
+ g_bind_table[handle].sensor_state = SENSOR_STATE_PAUSED;
+ DBG("SENSOR_STATE_PAUSED(LCD OFF)");
+ delete packet;
+ return 0;
+ }
+ }
+ else
+ {
+ DBG("vconf_get_int Error lcd_state = [%d]",lcd_state);
+ }
+ }
+ else
+ {
+ DBG("sensor start (SENSOR_OPTION_ALWAYS_ON)");
+ }
+
+ INFO("Sensor S/F Started\n");
+
+ payload = (cmd_start_t*)packet->data();
+ if (!payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_START);
+ packet->set_payload_size(sizeof(cmd_start_t));
+ payload->option = option;
+
+ INFO("Send CMD_START command\n");
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Faield to send a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ INFO("Recv a reply packet\n");
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ ERR("Send to reply packet fail\n");
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ DBG("packet received\n");
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->cmd() == CMD_DONE) {
+ cmd_done_t *payload;
+ payload = (cmd_done_t*)packet->data();
+ if (payload->value < 0) {
+ ERR("Error from sensor server [-1 or -2 : socket error, -3 : stopped by sensor plugin] value = [%d]\n", payload->value);
+ errno = ECOMM;
+ delete packet;
+ return payload->value;
+ }
+ } else {
+ ERR("unexpected server cmd\n");
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ }
+
+ g_bind_table[handle].sensor_state = SENSOR_STATE_STARTED;
+ g_bind_table[handle].sensor_option = option;
+
+ delete packet;
+ return 0;
+
+}
+
+EXTAPI int sf_stop(int handle)
+{
+ cpacket *packet;
+ cmd_stop_t *payload;
+
+ retvm_if( handle > MAX_BIND_SLOT - 1, -1 , "Incorrect handle");
+ retvm_if( (g_bind_table[handle].ipc == NULL) ||(handle < 0) , -1 , "sensor_stop fail , invalid handle value : %d",handle);
+ retvm_if( (g_bind_table[handle].sensor_state == SENSOR_STATE_STOPPED) || (g_bind_table[handle].sensor_state == SENSOR_STATE_PAUSED) , 0 , "sensor already stopped");
+
+ try {
+ packet = new cpacket(sizeof(cmd_stop_t)+4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+
+ INFO("Sensor S/F Stopped handle = [%d]\n", handle);
+
+ payload = (cmd_stop_t*)packet->data();
+ if (!payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_STOP);
+ packet->set_payload_size(sizeof(cmd_stop_t));
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Failed to send a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ g_bind_table[handle].sensor_state = SENSOR_STATE_STOPPED;
+ delete packet;
+
+ return 0;
+
+}
+
+EXTAPI int sf_register_event(int handle , unsigned int event_type , event_condition_t *event_condition , sensor_callback_func_t cb , void *cb_data )
+{
+ cpacket *packet;
+ cmd_reg_t *payload;
+ int i = 0, j = 0;
+ int avail_cb_slot_idx = -1;
+
+ int collect_data_flag = 0;
+
+ retvm_if( handle > MAX_BIND_SLOT - 1 , -1 , "Incorrect handle");
+ retvm_if( (g_bind_table[handle].ipc == NULL) ||(handle < 0) , -1 , "sensor_register_cb fail , invalid handle value : %d",handle);
+
+ try {
+ packet = new cpacket(sizeof(cmd_reg_t)+4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+
+ payload = (cmd_reg_t*)packet->data();
+ if (!payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ DBG("Current handle's(%d) cb_event_max_num : %d\n", handle , g_bind_table[handle].cb_event_max_num);
+
+ for ( i=0 ; i<g_bind_table[handle].cb_event_max_num ; i++ ) {
+ if ( ((event_type&0xFFFF)>>i) == 0x0001) {
+ if ( (g_bind_table[handle].cb_slot_num[i] == -1) ||(!(g_cb_table[ g_bind_table[handle].cb_slot_num[i] ].sensor_callback_func_t)) ) {
+ DBG("Find available slot in g_bind_table for cb\n");
+ avail_cb_slot_idx = i;
+ break;
+ }
+ }
+ }
+
+ if (avail_cb_slot_idx < 0 ) {
+ ERR("Find cb_slot fail, There is already callback function!!\n");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ i = cb_acquire_handle();
+ if (i == MAX_CB_BIND_SLOT) {
+ ERR("MAX_BIND_SLOT, Too many slot required");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+ INFO("Empty cb_slot : %d\n", i);
+
+ g_cb_table[i].my_cb_handle = i;
+ g_cb_table[i].my_sf_handle = handle;
+
+ INFO("Sensor S/F register cb\n");
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_REG);
+ packet->set_payload_size(sizeof(cmd_reg_t));
+ payload->type = REG_ADD;
+ payload->event_type = event_type;
+
+ if(!event_condition)
+ payload->interval = BASE_GATHERING_INTERVAL;
+ else if((event_condition->cond_op == CONDITION_EQUAL) && (event_condition->cond_value1 > 0 ))
+ payload->interval = event_condition->cond_value1;
+ else
+ payload->interval = BASE_GATHERING_INTERVAL;
+
+
+ INFO("Send CMD_REG command with reg_type : %x , event_typ : %x\n",payload->type , payload->event_type );
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Faield to send a packet\n");
+ cb_release_handle(i);
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ cb_release_handle(i);
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ cb_release_handle(i);
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->cmd() == CMD_DONE) {
+ cmd_done_t *payload;
+ payload = (cmd_done_t*)packet->data();
+ if (payload->value == -1) {
+ ERR("server register fail\n");
+ cb_release_handle(i);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ } else {
+ ERR("unexpected server cmd\n");
+ cb_release_handle(i);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ }
+
+ memset(g_cb_table[i].call_back_key,'\0',MAX_KEY_LEN);
+ snprintf(g_cb_table[i].call_back_key,(MAX_KEY_LEN-1),"%s%x",DEFAULT_SENSOR_KEY_PREFIX, event_type);
+
+ g_cb_table[i].cb_event_type = event_type;
+ g_cb_table[i].client_data = cb_data;
+ g_cb_table[i].sensor_callback_func_t = cb;
+
+ switch (event_type ) {
+ case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case PROXIMITY_EVENT_STATE_REPORT_ON_TIME:
+ /* fall through */
+ case GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_SENSOR_EVENT_RAW_DATA_REPORT_ON_TIME:
+ collect_data_flag = 1;
+ g_cb_table[i].request_data_id = (event_type & (0xFFFF<<16)) |0x0001;
+ break;
+ case LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_TEMPERATURE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_ROTATION_VECTOR_EVENT_DATA_REPORT_ON_TIME:
+ collect_data_flag = 1;
+ g_cb_table[i].request_data_id = (event_type & (0xFFFF<<16)) |0x0002;
+ break;
+ case ACCELEROMETER_EVENT_LINEAR_ACCELERATION_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_ROTATION_MATRIX_EVENT_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_ALTITUDE_DATA_REPORT_ON_TIME:
+ collect_data_flag = 1;
+ g_cb_table[i].request_data_id = (event_type & (0xFFFF<<16)) |0x0004;
+ break;
+ case ACCELEROMETER_EVENT_GRAVITY_DATA_REPORT_ON_TIME:
+ collect_data_flag = 1;
+ g_cb_table[i].request_data_id = (event_type & (0xFFFF<<16)) |0x0008;
+ break;
+ default :
+ collect_data_flag = 0;
+ }
+
+ INFO("key : %s(p:%p), cb_handle value : %d\n", g_cb_table[i].call_back_key ,g_cb_table[i].call_back_key, i );
+
+ if ( collect_data_flag ) {
+ sensor_data_t *collected_data_set;
+
+ collected_data_set = new sensor_data_t [ON_TIME_REQUEST_COUNTER];
+ if ( !collected_data_set ) {
+ ERR("memory allocation fail for gathering datas\n");
+ cb_release_handle(i);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ g_cb_table[i].collected_data = (void *)collected_data_set;
+ g_cb_table[i].current_collected_idx = 0;
+
+ if (!event_condition) {
+ g_cb_table[i].gsource_interval = BASE_GATHERING_INTERVAL;
+ } else {
+ if ( (event_condition->cond_op == CONDITION_EQUAL) && (event_condition->cond_value1 > 0 ) ) {
+ g_cb_table[i].gsource_interval = (guint)event_condition->cond_value1;
+ } else {
+ ERR("Invaild input_condition interval , input_interval : %f\n", event_condition->cond_value1);
+ cb_release_handle(i);
+ errno = EINVAL;
+ delete packet;
+ return -1;
+ }
+ }
+
+
+ if ( g_cb_table[i].gsource_interval != 0 ) {
+ g_cb_table[i].source = g_timeout_source_new(g_cb_table[i].gsource_interval);
+ } else {
+ ERR("Error , gsource_interval value : %u",g_cb_table[i].gsource_interval);
+ cb_release_handle(i);
+ errno = EINVAL;
+ delete packet;
+ return -1;
+ }
+ g_source_set_callback (g_cb_table[i].source, sensor_timeout_handler, (gpointer)&g_cb_table[i].my_cb_handle,NULL);
+ g_cb_table[i].gID = g_source_attach (g_cb_table[i].source, NULL);
+
+ }else {
+ g_cb_table[i].request_count = 0;
+ g_cb_table[i].request_data_id = 0;
+ g_cb_table[i].collected_data = NULL;
+ g_cb_table[i].gsource_interval = BASE_GATHERING_INTERVAL;
+
+ for(j = 0 ; j < MAX_EVENT_LIST ; j++){
+ if(g_event_list[j].event_type == event_type) {
+ if(g_event_list[j].event_counter < 1){
+ if(vconf_notify_key_changed(g_cb_table[i].call_back_key,sensor_changed_cb,(void*)(j)) == 0 ) {
+ DBG("vconf_add_chaged_cb success for key : %s , my_cb_handle value : %d\n", g_cb_table[i].call_back_key, g_cb_table[i].my_cb_handle);
+ } else {
+ DBG("vconf_add_chaged_cb fail for key : %s , my_cb_handle value : %d\n", g_cb_table[i].call_back_key, g_cb_table[i].my_cb_handle);
+ cb_release_handle(i);
+ errno = ENODEV;
+ delete packet;
+ return -2;
+ }
+ }else {
+ DBG("vconf_add_changed_cb is already registered for key : %s, my_cb_handle value : %d\n", g_cb_table[i].call_back_key, g_cb_table[i].my_cb_handle);
+ }
+ add_cb_number(j, i);
+ }
+ }
+ }
+
+
+ g_bind_table[handle].cb_slot_num[avail_cb_slot_idx] = i;
+ delete packet;
+
+ return 0;
+}
+
+
+EXTAPI int sf_unregister_event(int handle, unsigned int event_type)
+{
+ int state = 0;
+ cpacket *packet;
+ cmd_reg_t *payload;
+ int find_cb_handle =-1;
+ int i = 0, j = 0;
+
+ int collect_data_flag = 0;
+
+ retvm_if( handle > MAX_BIND_SLOT - 1, -1 , "Incorrect handle");
+ retvm_if( (g_bind_table[handle].ipc == NULL) ||(handle < 0) , -1 , "sensor_unregister_cb fail , invalid handle value : %d",handle);
+
+ try {
+ packet = new cpacket(sizeof(cmd_reg_t)+4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+
+ payload = (cmd_reg_t*)packet->data();
+ if (!payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ for ( i=0 ; i<g_bind_table[handle].cb_event_max_num ; i++ ) {
+ if ( g_bind_table[handle].cb_slot_num[i] != -1 ) {
+
+ if ( event_type == g_cb_table[ g_bind_table[handle].cb_slot_num[i] ].cb_event_type) {
+ find_cb_handle = g_bind_table[handle].cb_slot_num[i];
+ break;
+ }
+ }
+ }
+
+ if (find_cb_handle < 0) {
+ ERR("Err , Cannot find cb_slot_num!! for event : %x\n", event_type );
+ errno = EINVAL;
+ delete packet;
+ return -1;
+ }
+
+
+ INFO("Sensor S/F unregister cb\n");
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_REG);
+ packet->set_payload_size(sizeof(cmd_reg_t));
+ payload->type = REG_DEL;
+ payload->event_type = event_type;
+ payload->interval = g_cb_table[find_cb_handle].gsource_interval;
+
+ switch (event_type ) {
+ case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case ACCELEROMETER_EVENT_LINEAR_ACCELERATION_DATA_REPORT_ON_TIME :
+ /* fall through */
+ case GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case PROXIMITY_EVENT_STATE_REPORT_ON_TIME:
+ /* fall through */
+ case GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_TEMPERATURE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_ALTITUDE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_SENSOR_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_ROTATION_VECTOR_EVENT_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_ROTATION_MATRIX_EVENT_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case ACCELEROMETER_EVENT_GRAVITY_DATA_REPORT_ON_TIME:
+ collect_data_flag = 1;
+ break;
+ }
+
+ INFO("Send CMD_REG command\n");
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Faield to send a packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ ERR("Failed to recv packet_header\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ ERR("Failed to recv packet\n");
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ }
+
+ if ( collect_data_flag ) {
+ if(g_cb_table[find_cb_handle].source)
+ {
+ g_source_destroy(g_cb_table[find_cb_handle].source);
+ g_source_unref(g_cb_table[find_cb_handle].source);
+ }
+ g_cb_table[find_cb_handle].request_count = 0;
+ g_cb_table[find_cb_handle].request_data_id = 0;
+ g_cb_table[find_cb_handle].gsource_interval = 0;
+ } else {
+ for(j = 0 ; j < MAX_EVENT_LIST ; j++){
+ if(g_event_list[j].event_type == event_type){
+ if(g_event_list[j].event_counter <= 1){
+ state = vconf_ignore_key_changed(g_cb_table[find_cb_handle].call_back_key, sensor_changed_cb);
+ if ( state < 0 ) {
+ ERR("Failed to del callback using by vconf_del_changed_cb for key : %s\n",g_cb_table[find_cb_handle].call_back_key);
+ errno = ENODEV;
+ state = -2;
+ }
+ else {
+ DBG("del callback using by vconf success [%s] handle = [%d]",g_cb_table[find_cb_handle].call_back_key, find_cb_handle);
+ }
+ } else {
+ DBG("fake remove");
+ }
+ del_cb_number(j,find_cb_handle);
+ }
+ }
+ }
+
+ cb_release_handle(find_cb_handle);
+ g_bind_table[handle].cb_slot_num[i] = -1;
+ delete packet;
+
+ return state;
+}
+
+
+EXTAPI int sf_get_data(int handle , unsigned int data_id , sensor_data_t* values)
+{
+ cpacket *packet;
+ cmd_get_data_t *payload;
+ cmd_get_struct_t *return_payload;
+ int i;
+ struct timeval sv;
+
+
+ retvm_if( (!values) , -1 , "sf_get_data fail , invalid get_values pointer %p", values);
+ retvm_if( ( (data_id & 0xFFFF) < 1) || ( (data_id & 0xFFFF) > 0xFFF), -1 , "sf_get_data fail , invalid data_id %d", data_id);
+ retvm_if( handle > MAX_BIND_SLOT - 1 , -1 , "Incorrect handle");
+ retvm_if( (g_bind_table[handle].ipc == NULL) ||(handle < 0) , -1 , "sf_get_data fail , invalid handle value : %d",handle);
+
+ try {
+ packet = new cpacket(sizeof(cmd_get_struct_t)+sizeof(base_data_struct)+4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+
+ if(g_bind_table[handle].sensor_state != SENSOR_STATE_STARTED)
+ {
+ ERR("sensor framewoker doesn't started");
+ values->data_accuracy = SENSOR_ACCURACY_UNDEFINED;
+ values->data_unit_idx = SENSOR_UNDEFINED_UNIT;
+ values->time_stamp = 0;
+ values->values_num = 0;
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ payload = (cmd_get_data_t*)packet->data();
+ if (!payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_GET_STRUCT);
+ packet->set_payload_size(sizeof(cmd_get_data_t));
+ payload->data_id = data_id;
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ release_handle(handle);
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+ }
+
+ return_payload = (cmd_get_struct_t*)packet->data();
+ if (!return_payload) {
+ ERR("cannot find memory for return packet->data");
+ errno = ENOMEM;
+ delete packet;
+ return -2;
+ }
+
+ if ( return_payload->state < 0 ) {
+ ERR("get values fail from server \n");
+ values->data_accuracy = SENSOR_ACCURACY_UNDEFINED;
+ values->data_unit_idx = SENSOR_UNDEFINED_UNIT;
+ values->time_stamp = 0;
+ values->values_num = 0;
+ errno = ECOMM;
+ delete packet;
+ return -2;
+ }
+
+ base_data_struct *base_return_data;
+ base_return_data = (base_data_struct *)return_payload->data_struct;
+
+ gettimeofday(&sv, NULL);
+ values->time_stamp = MICROSECONDS(sv);
+
+ values->data_accuracy = base_return_data->data_accuracy;
+ values->data_unit_idx = base_return_data->data_unit_idx;
+ values->values_num = base_return_data->values_num;
+ for ( i = 0 ; i < base_return_data->values_num ; i++ ) {
+ values->values[i] = base_return_data->values[i];
+// DBG("client , get_data_value , [%d] : %f \n", i , values->values[i]);
+ }
+
+ delete packet;
+ return 0;
+
+}
+
+EXTAPI int sf_check_rotation( unsigned long *curr_state)
+{
+ int state = -1;
+
+ double raw_z;
+ double atan_value = 0, norm_z = 0;
+ int acc_theta = 0 , acc_pitch = 0;
+ int handle = 0;
+ int lcd_type = 0;
+
+ sensor_data_t base_data_values;
+
+ retvm_if( curr_state==NULL , -1 , "sf_check_rotation fail , invalid curr_state");
+
+ *curr_state = ROTATION_UNKNOWN;
+
+ INFO("Sensor_attach_channel from pid : %d",getpid());
+
+ handle = sf_connect( ACCELEROMETER_SENSOR);
+ if (handle<0)
+ {
+ ERR("sensor attach fail\n");
+ return -1;
+ }
+
+ state = sf_start(handle, 0);
+ if(state < 0)
+ {
+ ERR("sf_start fail\n");
+ return -1;
+ }
+
+ state = sf_get_data(handle, ACCELEROMETER_BASE_DATA_SET, &base_data_values);
+ if(state < 0)
+ {
+ ERR("sf_get_data fail\n");
+ return -1;
+ }
+
+ state = sf_stop(handle);
+ if(state < 0)
+ {
+ ERR("sf_stop fail\n");
+ return -1;
+ }
+
+ state = sf_disconnect(handle);
+ if(state < 0)
+ {
+ ERR("sf_disconnect fail\n");
+ return -1;
+ }
+
+ if((base_data_values.values[0] > XY_POSITIVE_THD || base_data_values.values[0] < XY_NEGATIVE_THD) || (base_data_values.values[1] > XY_POSITIVE_THD || base_data_values.values[1] < XY_NEGATIVE_THD))
+ {
+ atan_value = atan2((base_data_values.values[0]),(base_data_values.values[1]));
+ acc_theta = ((int)(atan_value * (RADIAN_VALUE) + 360))%360;
+
+ raw_z = (double)(base_data_values.values[2]) / 9.8;
+
+ if ( raw_z > 1.0 ) {
+ norm_z = 1.0;
+ }
+ else if ( raw_z < -1.0 ) {
+ norm_z = -1.0;
+ }
+ else {
+ norm_z = raw_z;
+ }
+ acc_pitch = (int)( acos(norm_z) *(RADIAN_VALUE));
+ }
+
+ INFO( "cal value [acc_theta] : %d , [acc_pitch] : %d\n",acc_theta ,acc_pitch);
+
+ if( (acc_pitch>PITCH_MIN) && (acc_pitch<PITCH_MAX) ) {
+ if ((acc_theta >= ROTATION_360 - ROTATION_THD && acc_theta <= ROTATION_360 ) || (acc_theta >= ROTATION_0 && acc_theta < ROTATION_0 + ROTATION_THD))
+ {
+ *curr_state = rotation_mode[ROTATION_EVENT_0].rm[lcd_type];
+ }
+ else if(acc_theta >= ROTATION_90 - ROTATION_THD && acc_theta < ROTATION_90 + ROTATION_THD)
+ {
+ *curr_state = rotation_mode[ROTATION_EVENT_90].rm[lcd_type];
+ }
+ else if(acc_theta >= ROTATION_180 - ROTATION_THD && acc_theta < ROTATION_180 + ROTATION_THD)
+ {
+ *curr_state = rotation_mode[ROTATION_EVENT_180].rm[lcd_type];
+ }
+ else if(acc_theta >= ROTATION_270 - ROTATION_THD && acc_theta < ROTATION_270 + ROTATION_THD)
+ {
+ *curr_state = rotation_mode[ROTATION_EVENT_270].rm[lcd_type];
+ }
+ else {
+ ERR("Wrong acc_theta : %d , cannot detect current state of ACCEL_SENSOR",acc_theta);
+ *curr_state = rotation_mode[ROTATION_UNKNOWN].rm[lcd_type];
+ }
+ }else {
+ INFO("Cannot detect current state of ACCEL_SENSOR");
+ *curr_state = rotation_mode[ROTATION_UNKNOWN].rm[lcd_type];
+ }
+
+ return 0;
+
+}
+
+
+EXTAPI int sf_set_wakeup(sensor_type_t sensor_type)
+{
+ int i = 0;
+
+ if(sf_is_wakeup_supported(sensor_type) < 0)
+ {
+ ERR("Cannot support wake up");
+ return -1;
+ }
+
+ for(i = 0 ; i < MAX_BIND_SLOT ; i++)
+ {
+ if(g_bind_table[i].sensor_type == sensor_type)
+ {
+ g_bind_table[i].wakeup_state = SENSOR_WAKEUP_SETTED;
+ }
+ }
+
+ vconf_notify_key_changed(VCONFKEY_PM_STATE, lcd_off_set_wake_up, NULL);
+
+ return 0;
+}
+
+EXTAPI int sf_unset_wakeup(sensor_type_t sensor_type)
+{
+ int i = 0;
+ int state = -1;
+
+ if(sf_is_wakeup_supported(sensor_type) < 0)
+ {
+ ERR("Cannot support wake up");
+ return -1;
+ }
+
+ if(sensor_type == ACCELEROMETER_SENSOR)
+ {
+ state = sf_set_property(sensor_type, ACCELEROMETER_PROPERTY_SET_WAKEUP, WAKEUP_UNSET);
+ if(state != 0)
+ {
+ ERR("set wakeup fail");
+ return -1;
+ }
+ }
+ else
+ {
+ ERR("Cannot support wakeup");
+ return -1;
+ }
+
+ for(i = 0 ; i < MAX_BIND_SLOT ; i++)
+ {
+ if(g_bind_table[i].sensor_type == sensor_type)
+ {
+ g_bind_table[i].wakeup_state = SENSOR_WAKEUP_UNSETTED;
+ }
+ }
+
+ vconf_ignore_key_changed(VCONFKEY_PM_STATE, lcd_off_set_wake_up);
+
+ return state;
+}
+
+EXTAPI int sf_is_wakeup_supported(sensor_type_t sensor_type)
+{
+ if(sensor_type == ACCELEROMETER_SENSOR)
+ return sf_set_property(sensor_type, ACCELEROMETER_PROPERTY_CHECK_WAKEUP_SUPPORTED, WAKEUP_SET);
+ else
+ {
+ ERR("Cannot support wakeup");
+ return -1;
+ }
+}
+
+EXTAPI int sf_is_wakeup_enabled(sensor_type_t sensor_type)
+{
+ if(sensor_type == ACCELEROMETER_SENSOR)
+ return sf_set_property(sensor_type,ACCELEROMETER_PROPERTY_CHECK_WAKEUP_STATUS,0);
+ else
+ {
+ ERR("Cannot support wakeup");
+ return -1;
+ }
+}
+
+EXTAPI int sf_change_event_condition(int handle, unsigned int event_type, event_condition_t *event_condition)
+{
+ cpacket *packet;
+ cmd_reg_t *payload;
+ int sensor_state = SENSOR_STATE_UNKNOWN;
+
+ int i = 0;
+
+ retvm_if( handle > MAX_BIND_SLOT - 1 , -1 , "Incorrect handle");
+ retvm_if( (g_bind_table[handle].ipc == NULL) ||(handle < 0) , -1 , "sf_change_event_condition fail , invalid handle value : %d",handle);
+
+ try {
+ packet = new cpacket(sizeof(cmd_reg_t) + 4);
+ } catch (int ErrNo) {
+ ERR("packet creation fail , errno : %d , errstr : %s\n",ErrNo, strerror(ErrNo));
+ return -1;
+ }
+
+ switch (event_type ) {
+ case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case ACCELEROMETER_EVENT_LINEAR_ACCELERATION_DATA_REPORT_ON_TIME :
+ /* fall through */
+ case GEOMAGNETIC_EVENT_ATTITUDE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case PROXIMITY_EVENT_STATE_REPORT_ON_TIME:
+ /* fall through */
+ case GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_TEMPERATURE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case BAROMETER_EVENT_ALTITUDE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case LIGHT_EVENT_LEVEL_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_SENSOR_EVENT_RAW_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_ROTATION_VECTOR_EVENT_DATA_REPORT_ON_TIME:
+ /* fall through */
+ case FUSION_ROTATION_MATRIX_EVENT_DATA_REPORT_ON_TIME:
+ break;
+ default :
+ ERR("Cannot support this API");
+ delete packet;
+ return -1;
+ }
+
+ for(i = 0 ; i < MAX_CB_SLOT_PER_BIND ; i++)
+ {
+ if(g_cb_table[g_bind_table[handle].cb_slot_num[i]].cb_event_type == event_type)
+ {
+ if(!event_condition)
+ {
+ if(g_cb_table[g_bind_table[handle].cb_slot_num[i]].gsource_interval == (guint)BASE_GATHERING_INTERVAL)
+ {
+ ERR("same interval");
+ delete packet;
+ return -1;
+ }
+ }
+ else
+ {
+ if(g_cb_table[g_bind_table[handle].cb_slot_num[i]].gsource_interval == (guint)event_condition->cond_value1)
+ {
+ ERR("same interval");
+ delete packet;
+ return -1;
+ }
+ }
+
+ DBG("find callback number [%d]",i);
+ break;
+ }
+ }
+
+ if(i == MAX_CB_SLOT_PER_BIND)
+ {
+ ERR("cannot find event_type [%x] in handle [%d]", event_type, handle);
+ delete packet;
+ return -1;
+ }
+
+ sensor_state = g_bind_table[handle].sensor_state;
+ g_bind_table[handle].sensor_state = SENSOR_STATE_STOPPED;
+
+ payload = (cmd_reg_t*)packet->data();
+ if(!payload) {
+ ERR("cannot find memory for send packet->data");
+ errno = ENOMEM;
+ g_bind_table[handle].sensor_state = SENSOR_STATE_STARTED;
+ delete packet;
+ return -2;
+ }
+
+ packet->set_version(PROTOCOL_VERSION);
+ packet->set_cmd(CMD_REG);
+ packet->set_payload_size(sizeof(cmd_reg_t));
+ payload->type = REG_ADD;
+ payload->event_type = event_type;
+
+ if(!event_condition)
+ payload->interval = BASE_GATHERING_INTERVAL;
+ else if((event_condition->cond_op == CONDITION_EQUAL) && (event_condition->cond_value1 > 0 ))
+ payload->interval = event_condition->cond_value1;
+ else
+ payload->interval = BASE_GATHERING_INTERVAL;
+
+
+ INFO("Send CMD_REG command with reg_type : %x , event_type : %x\n",payload->type , payload->event_type );
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->send(packet->packet(), packet->size()) == false) {
+ ERR("Faield to send a packet\n");
+ errno = ECOMM;
+ g_bind_table[handle].sensor_state = sensor_state;
+ delete packet;
+ return -2;
+ }
+
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv(packet->packet(), packet->header_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ errno = ECOMM;
+ g_bind_table[handle].sensor_state = sensor_state;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->payload_size()) {
+ if (g_bind_table[handle].ipc && g_bind_table[handle].ipc->recv((char*)packet->packet() + packet->header_size(), packet->payload_size()) == false) {
+ ERR("Faield to receive a packet\n");
+ errno = ECOMM;
+ g_bind_table[handle].sensor_state = sensor_state;
+ delete packet;
+ return -2;
+ }
+
+ if (packet->cmd() == CMD_DONE) {
+ cmd_done_t *payload;
+ payload = (cmd_done_t*)packet->data();
+ if (payload->value == -1) {
+ ERR("server register fail\n");
+ errno = ECOMM;
+ g_bind_table[handle].sensor_state = sensor_state;
+ delete packet;
+ return -2;
+ }
+ } else {
+ ERR("unexpected server cmd\n");
+ errno = ECOMM;
+ g_bind_table[handle].sensor_state = sensor_state;
+ delete packet;
+ return -2;
+ }
+ }
+
+ if(g_cb_table[i].source != NULL)
+ {
+ g_source_destroy(g_cb_table[i].source);
+ g_source_unref(g_cb_table[i].source);
+ }
+
+ g_cb_table[i].gsource_interval = (guint)payload->interval;
+ g_cb_table[i].source = g_timeout_source_new(g_cb_table[i].gsource_interval);
+ g_source_set_callback (g_cb_table[i].source, sensor_timeout_handler, (gpointer)&g_cb_table[i].my_cb_handle,NULL);
+ g_cb_table[i].gID = g_source_attach (g_cb_table[i].source, NULL);
+
+ g_bind_table[handle].sensor_state = sensor_state;
+ delete packet;
+
+ return 0;
+}
+
+int sf_change_sensor_option(int handle, int option)
+{
+ retvm_if( handle > MAX_BIND_SLOT - 1 , -1 , "Incorrect handle");
+ retvm_if( (g_bind_table[handle].ipc == NULL) ||(handle < 0) , -1 , "sensor_start fail , invalid handle value : %d",handle);
+ retvm_if( option < 0 || option > 1, -1 , "sensor_start fail , invalid option value : %d",option);
+
+ g_bind_table[handle].sensor_option = option;
+
+ if(g_bind_table[handle].sensor_state == SENSOR_STATE_PAUSED)
+ {
+ if( sf_start(handle, option) < 0)
+ {
+ ERR("sensor start fail");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+//! End of a file