阅读Sofia-SIP源码 - su模块 - su.c

现在进入到su.c文件内看看具体如何做到跨平台效果的。在su.h头文件内为了跨平台目的而重新定义了一套api,通用的socket描述符类,以及相应的结构体。


su_init/su_deinit

int su_init(void)
{
#if HAVE_OPEN_C
  char apname[60];
  su_socket_t s;
#endif

  su_home_threadsafe(NULL);

#if HAVE_SIGPIPE
  signal(SIGPIPE, SIG_IGN);	/* we want to get EPIPE instead */
#endif

#if HAVE_OPEN_C
  /* This code takes care of enabling an access point (interface) */
  aConnection = su_localinfo_ap_set(su_ap, &ifindex);
  su_localinfo_ap_name_to_index(ifindex);
#endif

  su_log_init(su_log_default);
  su_log_init(su_log_global);

  return 0;
}

void su_deinit(void)
{
#if HAVE_OPEN_C
	su_localinfo_ap_deinit(aConnection);
#endif
}
int su_init(void)
{
  WORD wVersionRequested;
  WSADATA wsaData;
  GUID const disconnectExGuid = WSAID_DISCONNECTEX;

  wVersionRequested = MAKEWORD(2, 0);

  if (WSAStartup(wVersionRequested, &wsaData) !=0) {
    return -1;
  }

  su_log_init(su_log_default);

  su_log_init(su_log_global);

  if (get_extension_function_pointer(&disconnectExGuid,
				     (void **)&_DisconnectEx) == -1)
    su_log("DisconnectEx: cannot load (%d): %s",
	   su_errno(), su_strerror(su_errno()));

  return 0;
}
void su_deinit(void)
{
  WSACleanup();
}

前两个是非windows平台下的初始化和退出清理函数,后两个是windows平台下的初始化和退出清理函数。widnows平台下的初始化和退出清理与通常使用没什么特殊之处,只不过多了一步获取DisconnectorEx函数。非windows平台下的初始化与windows平台下的初始化唯一相同之处是初始化两个日志对象。这两个日志对象是在su_log.h头文件中定义的。虽然su.h头文件说明中指出它本身是有关网络相关接口,但初始化和退出清理函数却是有关整个su模块的处理。因此,su_init函数里才会初始化两个全局su_log_t结构体变量。之前在分析su_log.c文件时就已经提到过并没有看到任何有关向这两个全局变量赋上日志输出函数和流对象的代码。同样,我们在这里也看到只是调用了su_log_init函数,也没有赋上日志输出函数和流对象。非windows平台下除了那些HAVE_OPEN_C条件宏控制的处理外,还有一个函数su_home_threadsafe。查看这个函数说明是将su_home_t结构体变量转换成线程安全模式,但竟然没找到函数定义。而且这里调用时传入了null,估计是和log一样,有一个全局su_home_t变量,针对它做的操作。

初始化其他部分都是针对HAVE_OPEN_C和HAVE_SIGPIPE两个宏做出的特殊处理。在linux下写socket的程序的时候,如果尝试在一个已经disconnected socket上调用send,就会让底层抛出一个SIGPIPE信号。这个信号的缺省处理方法是退出进程,大多数时候这都不是我们期望的。因此我们需要重载这个信号的处理方法。调用signal(SIGPIPE, SIG_IGN)即可安全屏蔽SIGPIPE。目前还不得而知HAVE_OPEN_C条件下处理的具体含义,在windows工程下也没法找到HAVE_OPEN_C的宏定义。


为了实现跨平台效果,su模块内定义了一套完整的新的API接口。API接口分两类。一类是所有平台的实现都一致,那么就只有一个唯一的实现。另一类是针对不同平台将会有特殊实现,会使用条件宏方式定义不同的函数实现。同时也注意到,只是定义了API接口,并没有与特定平台相关的运作细节。例如,没有平台相关的获取网络事件的特定处理细节。


你可能感兴趣的:(sofia,sip,sip,voip,sofia,源码,su)