一个简单的eXosip的register注册例子

2024-02-22 02:38

本文主要是介绍一个简单的eXosip的register注册例子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个测试程序是从eXosip原有的测试程序改造的。原程序是tools 目录下的 sip_reg.c

 

本程序主要改造了这几个地方:

1) eXosip_event_wait() 函数的超时时间,从原来的1ms 修改为50ms

2) 对于初次注册时,服务器返回401的情况。  调用函数 eXosip_add_authentication_info()发送鉴权信息。

其余的内容基本没改,在我们的sipserver 上面注册成功了。

 

从这个例程中 我们可以看出sip鉴权的基本流程

从sip角度看, 注册过程是这样的:

        客户端                        server  

          |   --------regester --->      |

          |   <----------401------       |

          |   ---regester + nonce -》    |

          |  《----------200--------     |

其中 nonce中带有鉴权信息。形如:

Authorization: Digest username="buxiangyi", realm="Yate",  nonce="143e882c902a9c38a3286e9043c35d40.1366083396", uri="sip:172.16.50.189:5060", response="8119330abd3ff5e4e26d2fa87b563b39", algorithm=MD5

 

 

对于 eXosip, 其处理过程如下:

1)eXosip_init                            (初始化)

     |     

     v     

2)eXosip_listen_addr                     (监听sip端口)

     |     

     v     

3)eXosip_register_build_initial_register (构建一个register)

     |     

     v     

4)eXosip_register_send_register          (发送register)

     |     

     v     

5)eXosip_event_wait                      (等待对端事件)

     |     

     v     

6)eXosip_execute                         (处理事件,调整内部状态)

     |     

     v     

7)eXosip_automatic_action                (根据当前状况,发出响应消息)

之后应循环执行 5)-》 7)

 

 

主程序如下: 

#if defined(__arc__)

#define LOG_PERROR 1

#include <includes_api.h>

#include <os_cfg_pub.h>

#endif

 

#if !defined(WIN32) && !defined(_WIN32_WCE)

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <syslog.h>

#ifdef OSIP_MT

#include <pthread.h>

#endif

#endif

 

#ifdef _WIN32_WCE

#include <winsock2.h>

#endif

 

#include <osip2/osip_mt.h>

#include <eXosip2/eXosip.h>

 

#if !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__arc__)

#define _GNU_SOURCE

#include <getopt.h>

#endif

 

#define PROG_NAME "sipreg"

#define PROG_VER  "1.0"

#define UA_STRING "SipReg v" PROG_VER

#define SYSLOG_FACILITY LOG_DAEMON

 

#ifdef ANDROID

#include <android/log.h>

#define LOGI(format,...)  //__android_log_print(ANDROID_LOG_INFO ,"hello_hl","file[%s] line[%d] "format"",__FILE__, __LINE__ ,##__VA_ARGS__)

#define LOGE(format,...)  __android_log_print(ANDROID_LOG_ERROR,"hello_hl","file[%s] line[%d] "format"",__FILE__, __LINE__ ,##__VA_ARGS__)

#else

#include <stdio.h>

#define LOGI(format,...)  // printf("file[%s] line[%d] "format"\n",__FILE__, __LINE__ ,##__VA_ARGS__)

#define LOGE(format,...)  printf("file[%s] line[%d] "format"\n",__FILE__, __LINE__ ,##__VA_ARGS__)

#endif

 

 

#if defined(WIN32) || defined(_WIN32_WCE)

static void syslog_wrapper(int a, const char *fmt, ...)

{

  va_list args;

  va_start (args, fmt);

  vfprintf (stdout, fmt, args);

  va_end (args);

}

#define LOG_INFO 0

#define LOG_ERR 0

#define LOG_WARNING 0

#define LOG_DEBUG 0

 

#elif defined(LOG_PERROR)

#define syslog_wrapper    syslog

#else

#define syslog_wrapper(a,b...) fprintf(stderr,b);fprintf(stderr,"\n")

#endif

 

 

static void usage (void);

#ifdef OSIP_MT

static void *register_proc (void *arg);

#endif

 

static void

usage (void)

{

  printf ("Usage: " PROG_NAME " [required_options] [optional_options]\n"

          "\n\t[required_options]\n"

          "\t-r --proxy\tsip:proxyhost[:port]\n"

          "\t-u --from\tsip:user@host[:port]\n"

          "\n\t[optional_options]\n"

          "\t-c --contact\tsip:user@host[:port]\n"

          "\t-d --debug (log to stderr and do not fork)\n"

          "\t-e --expiry\tnumber (default 3600)\n"

          "\t-f --firewallip\tN.N.N.N\n"

          "\t-h --help\n"

          "\t-l --localip\tN.N.N.N (force local IP address)\n"

          "\t-p --port\tnumber (default 5060)\n"

          "\t-U --username\tauthentication username\n"

          "\t-P --password\tauthentication password\n");

}

 

typedef struct regparam_t

{

  int regid;

  int expiry;

  int auth;

} regparam_t;

 

#ifdef OSIP_MT

static void *

register_proc (void *arg)

{

  struct regparam_t *regparam = arg;

  int reg;

 

  for (;;)

    {

#ifdef _WIN32_WCE

      Sleep ((regparam->expiry / 2)*1000);

#else

      sleep (regparam->expiry / 2);

#endif

      eXosip_lock ();

      reg = eXosip_register_send_register (regparam->regid, NULL);

      if (0 > reg)

        {

#ifdef _WIN32_WCE

          fprintf(stdout, "eXosip_register: error while registring");

#else

          perror ("eXosip_register");

#endif

          exit (1);

 }

      regparam->auth = 0;

      eXosip_unlock ();

    }

  return NULL;

}

#endif

 

#ifdef _WIN32_WCE

int WINAPI WinMain( HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPTSTR    lpCmdLine,

int       nCmdShow)

#else

int main (int argc, char *argv[])

#endif

{

  int c;

  int port = 5060;

  char *contact = NULL;

  char *fromuser = NULL;

  const char *localip = NULL;

  const char *firewallip = NULL;

  char *proxy = NULL;

#if !defined(__arc__)

  struct servent *service;

#endif

  char *username = NULL;

  char *password = NULL;

  struct regparam_t regparam = { 0, 3600, 0 };

#ifdef OSIP_MT

  struct osip_thread *register_thread;

#endif

  int debug = 0;

  int nofork = 0;

 

#ifdef _WIN32_WCE

  proxy = osip_strdup("sip:sip.antisip.com");

  fromuser = osip_strdup("sip:jack@sip.antisip.com");

 

#else

  for (;;)

    {

#define short_options "c??f:hl:p:r:u:U:P:"

#ifdef _GNU_SOURCE

      int option_index = 0;

      static struct option long_options[] = {

        {"contact", required_argument, NULL, 'c'},

        {"debug", no_argument, NULL, 'd'},

        {"expiry", required_argument, NULL, 'e'},

        {"firewallip", required_argument, NULL, 'f'},

        {"from", required_argument, NULL, 'u'},

        {"help", no_argument, NULL, 'h'},

        {"localip", required_argument, NULL, 'l'},

        {"port", required_argument, NULL, 'p'},

        {"proxy", required_argument, NULL, 'r'},

        {"username", required_argument, NULL, 'U'},

        {"password", required_argument, NULL, 'P'},

        {NULL, 0, NULL, 0}

      };

 

      c = getopt_long (argc, argv, short_options, long_options, &option_index);

#else

      c = getopt (argc, argv, short_options);

#endif

      if (c == -1)

        break;

 

      switch (c)

        {

          case 'c':

            contact = optarg;

            break;

          case 'd':

            nofork = 1;

#ifdef LOG_PERROR

            debug = LOG_PERROR;

#endif

            break;

          case 'e':

            regparam.expiry = atoi (optarg);

            break;

          case 'f':

            firewallip = optarg;

            break;

          case 'h':

            usage ();

            exit (0);

          case 'l':

            localip = optarg;

            break;

          case 'p':

#if !defined(__arc__)

            service = getservbyname (optarg, "udp");

            if (service)

              port = ntohs(service->s_port);

            else

              port = atoi (optarg);

#else

   port = atoi (optarg);

#endif

            break;

          case 'r':

            proxy = optarg;

            break;

          case 'u':

            fromuser = optarg;

            break;

          case 'U':

   username = optarg;

            break;

          case 'P':

   password = optarg;

            break;

          default:

            break;

        }

    }

#endif

 

  LOGE("111111");

  if (!proxy || !fromuser)

    {

      usage ();

      exit (1);

    }

 

#ifndef _WIN32_WCE

  if (!nofork)

    {

      int cpid = fork ();

 

      if (cpid)                

        exit (0);

     

      LOGE("22222");

      close (0);

      close (1);

      close (2);

 

    }

#endif

 

#if 0

  openlog (PROG_NAME, LOG_PID | debug, SYSLOG_FACILITY);

#endif

 

  LOGE(" up and running");

  LOGE( "proxy: %s", proxy);

  LOGE( "fromuser: %s", fromuser);

  LOGE( "contact: %s", contact);

  LOGE( "expiry: %d", regparam.expiry);

  LOGE( "local port: %d", port);

  LOGE( "passwd :%s",password );

 

  if (debug>0)

    TRACE_INITIALIZE (6, NULL);

 

  if (eXosip_init ())

    {

      syslog_wrapper (LOG_ERR, "eXosip_init failed");

      exit (1);

    }

  if (eXosip_listen_addr (IPPROTO_UDP, NULL, port, AF_INET, 0))

    {

      syslog_wrapper (LOG_ERR, "eXosip_listen_addr failed");

      exit (1);

    }

 

  if (localip)

    {

      syslog_wrapper (LOG_INFO, "local address: %s", localip);

      eXosip_masquerade_contact (localip, port);

    }

 

  if (firewallip)

    {

      syslog_wrapper (LOG_INFO, "firewall address: %s:%i", firewallip, port);

      eXosip_masquerade_contact (firewallip, port);

    }

 

  eXosip_set_user_agent (UA_STRING);

 

  if (username && password)

    {

      syslog_wrapper (LOG_INFO, "username: %s", username);

      syslog_wrapper (LOG_INFO, "password: [removed]");

      if (eXosip_add_authentication_info

          (username, username, password, NULL, NULL))

        {

          syslog_wrapper (LOG_ERR, "eXosip_add_authentication_info failed");

          exit (1);

        }

    }

 

{

osip_message_t *reg = NULL;

int i;

 

regparam.regid = eXosip_register_build_initial_register(fromuser, proxy,

contact, regparam.expiry * 2, &reg);

LOGE("33333 regid[%d] ",regparam.regid);

if (regparam.regid < 1) {

syslog_wrapper(LOG_ERR,

"eXosip_register_build_initial_register failed");

LOGE("66666");

exit(1);

}

i = eXosip_register_send_register(regparam.regid, reg);

if (i != 0) {

syslog_wrapper(LOG_ERR, "eXosip_register_send_register failed");

LOGE("55555");

exit(1);

}

LOGE("44444");

}

 

#ifdef OSIP_MT

  register_thread = osip_thread_create (20000, register_proc, &regparam);

  if (register_thread==NULL)

    {

      syslog_wrapper (LOG_ERR, "pthread_create failed");

      exit (1);

    }

#endif

 

  for (;;)

    {

      eXosip_event_t *event;

 

     

      if (!(event = eXosip_event_wait(0, 50)))

      {

#ifndef OSIP_MT

      LOGE("77777");

 eXosip_execute();

 eXosip_automatic_action ();

#endif

          osip_usleep (10000);

          continue;

      }

 

#ifndef OSIP_MT

      eXosip_execute();

#endif

 

      LOGE("88888");

 

      eXosip_automatic_action ();

      switch (event->type)

      {

       int res;

          case EXOSIP_REGISTRATION_NEW:

            LOGE("received new registration");

            break;

          case EXOSIP_REGISTRATION_SUCCESS:

         LOGE( "registrered successfully");

            break;

          case EXOSIP_REGISTRATION_FAILURE:

            regparam.auth = 1;

            //注册收到401之后,再次提交授权信息

            //res = eXosip_add_authentication_info(username,username,password, NULL, NULL);

            LOGE("401!!!!");

            break;

          case EXOSIP_REGISTRATION_TERMINATED:

        LOGE("Registration terminated\n");

            break;

          default:

         LOGE("recieved unknown eXosip event (type, did, cid) = (%d, %d, %d)",

                event->type, event->did, event->cid);

      }

      eXosip_event_free (event);

    }

}

 

 

执行结果

写脚本reg.sh(buxiangyi是我们测试用账号):

./sip_reg  \

-r sip:172.16.50.189:5060 \

-u sip:buxiangyi@172.16.50.189 \

-c sip:buxiangyi@172.16.50.189:5060 \

-U buxiangyi \

-P buxiangyi  \

-p 5060 \

-e 1800 \

-d

 

 

执行脚本:

hl@hl-VirtualBox:~/linphone/test_osip_linux$ ./reg.sh 

file[sip_reg.c] line[274] 111111

file[sip_reg.c] line[301]  up and running

file[sip_reg.c] line[302] proxy: sip:172.16.50.189:5060

file[sip_reg.c] line[303] fromuser: sip:buxiangyi@172.16.50.189

file[sip_reg.c] line[304] contact: sip:buxiangyi@172.16.50.189:5060

file[sip_reg.c] line[305] expiry: 1800

file[sip_reg.c] line[306] local port: 5060

file[sip_reg.c] line[307] passwd :buxiangyi

file[sip_reg.c] line[355] 33333 regid[1] 

file[sip_reg.c] line[368] 44444

file[sip_reg.c] line[388] 77777

file[sip_reg.c] line[388] 77777

file[sip_reg.c] line[400] 88888

file[sip_reg.c] line[416] 401!!!!

file[sip_reg.c] line[388] 77777

file[sip_reg.c] line[400] 88888

file[sip_reg.c] line[410] registrered successfully

file[sip_reg.c] line[388] 77777

file[sip_reg.c] line[388] 77777

file[sip_reg.c] line[388] 77777

。。。

 

可以看到客户端收到401之后, eXosip可以自动处理,向server继续发送带nonce的register,之后注册成功

这篇关于一个简单的eXosip的register注册例子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/733880

相关文章

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

使用PyQt5编写一个简单的取色器

《使用PyQt5编写一个简单的取色器》:本文主要介绍PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16进制颜色编码,一款跟随鼠标刷新图像的RGB和16... 目录取色器1取色器2PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16

四种简单方法 轻松进入电脑主板 BIOS 或 UEFI 固件设置

《四种简单方法轻松进入电脑主板BIOS或UEFI固件设置》设置BIOS/UEFI是计算机维护和管理中的一项重要任务,它允许用户配置计算机的启动选项、硬件设置和其他关键参数,该怎么进入呢?下面... 随着计算机技术的发展,大多数主流 PC 和笔记本已经从传统 BIOS 转向了 UEFI 固件。很多时候,我们也

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直