#include #include #include #include #include #include #include #include "dbus_suspend_api.h" #define SENSSION_REGISTER_DIR "/var/run/pm_dbus_services"/*注册后,在此目录创建同名文件,bus_name*/ #define OBJECT_PATH "/" #define SUSPEND_INTERFACE "local.interface" #define SUSPEND_FUNCTION "suspend" #define RESUME_FUNCTION "resume" typedef enum __bool { false = 0, true =1, }bool; typedef struct __listener { char bus_name[64]; CALLBACK suspend_callback; CALLBACK resume_callback; }suspend_listener; void reply_to_method_call(suspend_listener *listener, DBusMessage * msg, DBusConnection * conn, bool suspend) { DBusMessage * reply; DBusMessageIter arg; char *param = NULL; dbus_bool_t stat = TRUE; dbus_uint32_t level = 2010; dbus_uint32_t serial = 0; if(!dbus_message_iter_init(msg,&arg)) printf("Message has noargs\n"); else if(dbus_message_iter_get_arg_type(&arg)!= DBUS_TYPE_STRING) printf("Arg is notstring!\n"); else dbus_message_iter_get_basic(&arg, ¶m); if(param == NULL && !suspend) return; if (suspend) { listener->suspend_callback(NULL); } else { printf("resume irq: %s\n", param); listener->resume_callback(param); } //创建返回消息reply reply = dbus_message_new_method_return(msg); //在返回消息中填入两个参数,和信号加入参数的方式是一样的。这次我们将加入两个参数。 dbus_message_iter_init_append(reply,&arg); if(!dbus_message_iter_append_basic(&arg,DBUS_TYPE_BOOLEAN,&stat)){ printf("Out ofMemory!\n"); exit(1); } if(!dbus_message_iter_append_basic(&arg,DBUS_TYPE_UINT32,&level)){ printf("Out ofMemory!\n"); exit(1); } //发送返回消息 if( !dbus_connection_send(conn, reply,&serial)){ printf("Out of Memory\n"); exit(1); } dbus_connection_flush (conn); dbus_message_unref (reply); } void listen_dbus(suspend_listener *listener) { DBusMessage * msg; DBusMessageIter arg; DBusConnection * connection; DBusError err; int ret; char * sigvalue; dbus_error_init(&err); //创建于session D-Bus的连接 connection =dbus_bus_get(DBUS_BUS_SYSTEM, &err); if(dbus_error_is_set(&err)){ fprintf(stderr,"ConnectionError %s\n",err.message); dbus_error_free(&err); } if(connection == NULL) return; ret =dbus_bus_request_name(connection, listener->bus_name, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); if(dbus_error_is_set(&err)) { fprintf(stderr,"Name Error%s\n",err.message); dbus_error_free(&err); } if(ret !=DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) return; /*注册到目录,记录*/ char cmd[128] = {0}; sprintf(cmd, "mkdir -p %s && touch %s/%s", SENSSION_REGISTER_DIR, SENSSION_REGISTER_DIR, listener->bus_name); system(cmd); while(true) { dbus_connection_read_write(connection,100); msg =dbus_connection_pop_message (connection); if(msg == NULL){ usleep(1000); continue; } if(dbus_message_is_method_call(msg, SUSPEND_INTERFACE, SUSPEND_FUNCTION)){ if(strcmp(dbus_message_get_path(msg),OBJECT_PATH) == NULL) reply_to_method_call(listener, msg, connection, true); } else if(dbus_message_is_method_call(msg, SUSPEND_INTERFACE, RESUME_FUNCTION)){ if(strcmp(dbus_message_get_path(msg),OBJECT_PATH) == NULL) reply_to_method_call(listener, msg, connection, false); } dbus_message_unref(msg); } } void *dbus_service_thread(void *data) { suspend_listener *listener = (suspend_listener *)data; listen_dbus(listener); pthread_exit(NULL); } SUSPEND_API int request_system_suspend(void) { system("pm-suspend"); return 0; } SUSPEND_API int register_suspend_listener(char *bus_name, CALLBACK suspend_callback, CALLBACK resume_callback ) { int rc; pthread_t thread_id; suspend_listener *listener; listener = malloc(sizeof(suspend_listener)); assert(listener); strncpy(listener->bus_name, bus_name, 64); listener->bus_name[64] = '\0'; listener->suspend_callback = suspend_callback; listener->resume_callback = resume_callback; rc=pthread_create(thread_id, NULL, (void *)dbus_service_thread, (void *)listener); if(rc!=0){ printf("error. return code is %d\n", rc); return -1; } return 0; }