一个简单的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

相关文章

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(简单几何)

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

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 10130 简单背包

题意: 背包和 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性

一、什么是提升系统的高可用性 JAVA服务端,顾名思义就是23体验网为用户提供服务的。停工时间,就是不能向用户提供服务的时间。高可用,就是系统具有高度可用性,尽量减少停工时间。如何用最简单的方法来搭建一个高效率可用的服务端JAVA呢? 停工的原因一般有: 服务器故障。例如服务器宕机,服务器网络出现问题,机房或者机架出现问题等;访问量急剧上升,导致服务器压力过大导致访问量急剧上升的原因;时间和

简单的角色响应鼠标而移动

actor类 //处理移动距离,核心是找到角色坐标在世界坐标的向量的投影(x,y,z),然后在世界坐标中合成,此CC是在地面行走,所以Y轴投影始终置为0; using UnityEngine; using System.Collections; public class actor : MonoBehaviour { public float speed=0.1f; CharacterCo

docker-compose安装和简单使用

本文介绍docker-compose的安装和使用 新版docker已经默认安装了docker-compose 可以使用docker-compose -v 查看docker-compose版本 如果没有的话可以使用以下命令直接安装 sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-c