Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1057525
  • 博文数量: 166
  • 博客积分: 10217
  • 博客等级: 上将
  • 技术积分: 2133
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-09 19:45
文章分类

全部博文(166)

文章存档

2012年(3)

2011年(7)

2010年(18)

2009年(59)

2008年(79)

我的朋友

分类: LINUX

2008-06-25 20:12:36

phoneserver模块:
#define PHONE_SERVER_SERVICE "lips.phone.server"
#define PHONE_SERVER_OBJECT "/phone/server/general"
#define PHONE_SERVER_INTERFACE "phone.server.general"


#define PHONE_SERVER_VOICE_OBJECT     "/phone/server/voice"
#define PHONE_SERVER_VOICE_INTERFACE      "phone.server.voice"
#define PHONE_SERVER_VOICE_METHOD_DIAL      "dial"
#define PHONE_SERVER_VOICE_METHOD_HOLD    "onhold"

int main()
{
........................................
 bus = dbus_init (); //其定义想见后面的dbus-if.c文件,主要是注册一个DBUS_BUS_SESSION总线类型的连接,以及dbus请求的监听,把dbus的监听放一个全局里,经于glib邦定后,glib层一监听到有请求到本模块的,会遍历链表,匹配到对应的inerface和method后,会执行本进程注册进去的回调函数,链表所放节点的数据结构如下:
typedef struct
{
  gchar *interface;
  gchar *method;
  void (*callback) ();
} t_listener;

if (!bus)
    return -1;

  dbus_error_init (&error);
  dbus_bus_request_name (bus, PHONE_SERVER_SERVICE, 0, &error);//注册一个服务器,PHONE_SERVER_SERVICE也即本进程的标志,表明本进程是phoneserver模块

/*一下都是把结构体
t_listene(接口,方法,回调函数)放进本进程的链表中,
一检测到有相应的求情后(服务器,接口,方法要匹配),马上会执行后面的回调函数,如
dial_cb
*/
 dbus_add_msg_listener_mc (PHONE_SERVER_VOICE_INTERFACE,
                            PHONE_SERVER_VOICE_METHOD_DIAL, dial_cb);
  dbus_add_msg_listener_mc (PHONE_SERVER_VOICE_INTERFACE,
                            PHONE_SERVER_VOICE_METHOD_HOLD, voc_mc_cb);
...........................................
dbus_add_msg_listener_mc (PHONE_SERVER_SMS_INTERFACE,
                            PHONE_SERVER_SMS_METHOD_SEND, send_sms_handler);
..............................................
dbus_add_msg_listener_mc (PHONE_SERVER_PBK_INTERFACE,
                            PHONE_SERVER_PBK_METHOD_ADD,
                            phonebook_add_entry_handler);
.................................

 ch_modem = g_io_channel_unix_new (g_fd);//g_fd为串口句柄
    result = g_io_add_watch (ch_modem, G_IO_IN, tapi_input_handler, NULL);//监听modem发给串口的数据,主要是未知事件,发AT后modem返回的数据。有数据进来会执行
tapi_input_handler函数。该函数一般会根据数据头判断是未知事件(一般以类似+clip: 的开头如来短信,来电),还是我们发at给modem然后modem返回的操作结果。前者优先解析。


  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);

}
注:监听到打电话请求后,执行dial_cb函数
dial_cb (DBusMessage *message)
{
  DBusError error;

  dbus_error_init (&error);
  DBusMessage *reply;

  UInt32 event_dbus;
  UInt32 sid_dbus;
  UInt32 lid_dbus;

  //voc_cid_t cid_dbus;
  Int8 *peer_number;
  char *pmethod;

  //voc_evt_t*evt;



  if (dbus_message_get_args (message, &error,
                             DBUS_TYPE_UINT32, &event_dbus,
                             DBUS_TYPE_UINT32, &sid_dbus,
                             DBUS_TYPE_UINT32, &lid_dbus,
                             DBUS_TYPE_STRING, &peer_number, DBUS_TYPE_INVALID))
  {
....................................
  }
tel_asyn_call_action (sid_dbus, &rid, tel_cb_dial, TEL_MAKE_CALL, call_id,
                          (Int8 *) peer_number);//该函数主要是够造AT,并发AT给modem,modem返回会执行传进去的回调函数
tel_cb_dial,tel_cb_dial只要是通过一下给voicecall模块发dbus请求,通知请求的结果,最终voicecall模块会执行发请求时时传进去的回调函数,见voicecall模块请求成功后注册的voc_call_evt_register (appsid, cid, VOC_EVT_CALL_STATUS, NULL, voc_cb_dial, g_strdup (rnum));  ,最终执行voc_cb_dial函数。注:voicecall调用libvocenbler封了一层,用libvocenbler跟phoneserver模块直接交互
 DBusMessage *message;
  DBusError error;

  dbus_error_init (&error);

  message = dbus_message_new_method_call (PHONE_VOICE_SERVICE,  //":1.56",//DBUS_SERVICE_DBUS,//
                                          PHONE_VOICE_OBJECT,
                                          PHONE_VOICE_INTERFACE,
                                          PHONE_VOICE_DELIVER_EVENT);

  if (message == NULL)
  {
    printf ("Failed to contruct message\n");
    dbus_error_free (&error);
    return FALSE;
  }

  /* Append the event to the signal */



  dbus_message_append_args (message, DBUS_TYPE_UINT32, &evt,
                            DBUS_TYPE_UINT32, &sid,
                            DBUS_TYPE_UINT32, &lcid, DBUS_TYPE_STRING, &remote,
                            //DBUS_TYPE_STRING, &pmethod,
                            DBUS_TYPE_INVALID);
  dbus_message_set_no_reply (message, TRUE);

  /* Send the signal */
  dbus_connection_send (bus, message, NULL);

  /* Free the signal now we have finished with it */
  dbus_message_unref (message);

另附
dbus-if.c文件
#include
#include
#include
#include

#include

#include
#include
#include
#include
#include "dbus-if.h"

#define _(x) gettext(x)

typedef struct
{
  gchar *interface;
  gchar *method;
  void (*callback) ();
} t_listener;

static GList *listeners = NULL;
static DBusConnection *bus = NULL;



static DBusHandlerResult
msg_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
{
  GMainLoop *mainloop = (GMainLoop *) user_data;
  GList *iter;

  for (iter = listeners; iter; iter = iter->next)
  {
    t_listener *li = (t_listener *) iter->data;

    if (dbus_message_is_signal (message, li->interface, li->method))
    {
      li->callback (message);
      return DBUS_HANDLER_RESULT_HANDLED;
    }
    else if (dbus_message_is_method_call (message, li->interface, li->method))
    {
      li->callback (message);
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  }

  /* A signal from the bus saying we are about to be disconnected */
  if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
  {
    g_main_loop_quit (mainloop);
    return DBUS_HANDLER_RESULT_HANDLED;
  }
  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}


void
dbus_add_msg_listener_mc (const gchar *interface, const gchar *method,
                          void (*callback) ())
{
//fix me, using hash table may be better.

  t_listener *new_listener = g_malloc0 (sizeof (t_listener));
  gchar *filterstr =
    g_strdup_printf ("type='method_call',interface='%s'", interface);

  new_listener->interface = g_strdup (interface);
  new_listener->method = g_strdup (method);
  new_listener->callback = callback;

  listeners = g_list_append (listeners, (gpointer) new_listener);

  dbus_bus_add_match (bus, filterstr, NULL);
  g_free (filterstr);

}

void
dbus_add_msg_listener (const gchar *interface, const gchar *method,
                       void (*callback) ())
{
//fix me, using hash table may be better.

  t_listener *new_listener = g_malloc0 (sizeof (t_listener));
  gchar *filterstr =
    g_strdup_printf ("type='signal',interface='%s'", interface);

  new_listener->interface = g_strdup (interface);
  new_listener->method = g_strdup (method);
  new_listener->callback = callback;

  listeners = g_list_append (listeners, (gpointer) new_listener);

  dbus_bus_add_match (bus, filterstr, NULL);
  g_free (filterstr);
}

DBusConnection *
dbus_init (void)
{
  DBusError error;

  //GMainLoop *mainloop;

  //mainloop = g_main_loop_new(NULL, TRUE);
  dbus_error_init (&error);

  bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
  if (!bus)
  {
    g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
    dbus_error_free (&error);
    return NULL;
  }

  dbus_connection_setup_with_g_main (bus, NULL);

  /* we do not request a namespace to support multiple listeners to these signals */

  dbus_connection_add_filter (bus, msg_filter, loop, NULL);

  //g_main_loop_unref(mainloop);
  return bus;
}

阅读(1456) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~