GB28181 设备端移植 : 下端注册交互程序编写

该文描述了一个基于GB28181标准的客户端程序,实现了设备注册流程、交互处理、消息解析等功能。程序使用gitee上的开源项目为基础,包含了设备控制、设备信息获取、设备状态查询等回调函数。在注册流程中,程序会不断尝试直到注册成功,并且有心跳保持机制。
摘要由CSDN通过智能技术生成

编写GB28181的下端注册流程以及交互处理流程程序,基于gitee的李通发布的程序作为基础上进行修改
gitee链接:https://gitee.com/zhfqx/c-sip-gb28181-client

gb28181Client.h

#ifndef __GB28181_CLIENT_H__
#define __GB28181_CLIENT_H__ 
#include <stdlib.h>
#include <eXosip2/eXosip.h>
#include <osip2/osip_mt.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#define PROG_NAME "GB28181"
#define PROG_VER  "1.0"
#define UA_STRING "LS-Y"      //厂家
#define  MAXDATASIZE 1500


typedef enum _device_control/*设备控制动作*/
{
  EXOSIP_CTRL_RMT_LEFT = 1,/*向左*/
  EXOSIP_CTRL_RMT_RIGHT,   /*向右*/
  EXOSIP_CTRL_RMT_UP,      /*向上*/
  EXOSIP_CTRL_RMT_DOWN,    /*向下*/
  EXOSIP_CTRL_RMT_LARGE,   /*放大*/
  EXOSIP_CTRL_RMT_SMALL,   /*缩小*/
  EXOSIP_CTRL_RMT_STOP,    /*停止遥控*/
  EXOSIP_CTRL_REC_START,   /*开始手动录像*/
  EXOSIP_CTRL_REC_STOP,    /*停止手动录像*/
  EXOSIP_CTRL_GUD_START,   /*布防*/
  EXOSIP_CTRL_GUD_STOP,    /*撤防*/
  EXOSIP_CTRL_ALM_RESET,   /*报警复位*/
  EXOSIP_CTRL_TEL_BOOT,    /*设备远程启动*/
}DEVICE_CONTROL;

typedef struct _device_info/*设备信息结构体*/
{
    char *server_id;/*SIP服务器ID*//*默认值:34020000002000000001*/
    char *server_ip;/*SIP服务器IP地址*//*默认值:192.168.1.178*/
    char *server_port;/*SIP服务器IP端口*//*默认值:5060*/

    char *ipc_id;/*媒体流发送者ID*//*默认值:34020000001180000002*/
    char *ipc_pwd;/*媒体流发送者密码*//*默认值:12345678*/
    char *ipc_ip;/*媒体流发送者IP地址*//*默认值:192.168.1.144*/
    char *ipc_media_port;/*媒体流发送者IP端口*//*默认值:20000*/
  char *ipc_sess_port; /*会话端口,即SIP端口*/

  char *alarm_id; /*报警器ID*/

  char *media_ip;
  char *media_port;

    char *device_name;/*设备/区域/系统名称*//*默认值:IPC*/
    char *device_manufacturer;/*设备厂商*//*默认值:CSENN*/
    char *device_model;/*设备型号*//*默认值:GB28181*/
    char *device_firmware;/*设备固件版本*//*默认值:V1.0*/
    char *device_encode;/*是否编码*//*取值范围:ON/OFF*//*默认值:ON*/
    char *device_record;/*是否录像*//*取值范围:ON/OFF*//*默认值:OFF*/
}DEVICE_INFO;
typedef struct _device_status/*设备状态结构体*/
{
    char *status_on;/*设备打开状态*//*取值范围:ON/OFF*//*默认值:ON*/
    char *status_ok;/*是否正常工作*//*取值范围:OK/ERROR*//*默认值:OFF*/
    char *status_online;/*是否在线*//*取值范围:ONLINE/OFFLINE*//*默认值:ONLINE*/
    char *status_guard;/*布防状态*//*取值范围:ONDUTY/OFFDUTY/ALARM*//*默认值:OFFDUTY*/
    char *status_time;/*设备日期和时间*//*格式:xxxx-xx-xxTxx:xx:xx*//*默认值:2012-12-20T12:12:20*/
}DEVICE_STATUS;
#if 1
/*回调函数*/
typedef struct _dt_eXosip_callback
{
  /*获取设备信息*/
  /*device_info:设备信息结构体指针*/
  /*返回值:成功时返回0,失败时返回负值*/
  int (*dt_eXosip_getDeviceInfo)(DEVICE_INFO *device_info);

  /*获取设备状态*/
  /*device_info:设备状态结构体指针*/
  /*返回值:成功时返回0,失败时返回负值*/
  int (*dt_eXosip_getDeviceStatus)(DEVICE_STATUS *device_status);

  /*获取录像文件的起始时间与结束时间*/
  /*时间格式:xxxx-xx-xxTxx:xx:xx*/
  /*period_start:录像时间段起始值*/
  /*period_end:录像时间段结束值*/
  /*start_time:当前返回录像文件的起始时间*/
  /*end_time:当前返回录像文件的结束时间*/
  /*返回值:成功时返回符合时间段条件的剩余录像文件数量,失败时返回负值*/
  int (*dt_eXosip_getRecordTime)(char *period_start, char *period_end, char *start_time, char *end_time);

  /*设备控制:向左、向右、向上、向下、放大、缩小、停止遥控/开始手动录像、停止手动录像/布防、撤防/报警复位/设备远程启动*/
  /*ctrl_cmd:设备控制命令,_device_control类型的枚举变量*/
  /*返回值:成功时返回0,失败时返回负值*/
  int (*dt_eXosip_deviceControl)(enum _device_control ctrl_cmd);

  /*媒体控制:实时点播/回放/下载*/
  /*control_type:媒体控制类型,实时点播/Play,回放/Playback,下载/Download*/
  /*media_ip:媒体服务器IP地址*/
  /*media_port:媒体服务器IP端口*/
  /*返回值:成功时返回0,失败时返回负值*/
  int (*dt_eXosip_mediaControl)(char *control_type, char *media_ip, char *media_port);

  /*播放控制:播放/快放/慢放/暂停*/
  /*control_type:播放控制,播放/快放/慢放/PLAY,暂停/PAUSE*/
  /*play_speed:播放速度,1为播放,大于1为快放,小于1为慢放*/
  /*pause_time:暂停时间,单位为秒*/
  /*range_start:播放范围的起始值*/
  /*range_end:播放范围的结束值*/
  /*返回值:成功时返回0,失败时返回负值*/
  int (*dt_eXosip_playControl)(char *control_type, char *play_speed, char *pause_time, char *range_start, char *range_end);
}DT_EXOSIP_CALLBACK;

#endif

//GB28181客户端
class LSMXGb28181Client 
{
public :  
  static LSMXGb28181Client *createNew(DEVICE_INFO device_info,DEVICE_STATUS device_status);
  ~LSMXGb28181Client();
  bool init();
  bool startUp();
  bool setPara(DEVICE_INFO device_info,DEVICE_STATUS device_status);
  int getLinkStatus();   //获取注册状态
  int getRealPlay();
  //DEVICE_INFO getDEVICE_INFO();
  //DEVICE_STATUS getDEVICE_STATUS();
  
protected :
  LSMXGb28181Client(DEVICE_INFO device_info,DEVICE_STATUS device_status);

private :
  int sendRegister(int expires);     /*expires/注册消息过期时间,单位为秒*/
  void keepAlive();  /**/
  void printEvent(eXosip_event_t *p_event);/*检测并打印事件*/
  void paraseMsgBody(eXosip_event_t *p_event);/*解析MESSAGE的XML消息体*/
  void paraseInviteBody(eXosip_event_t *p_event);/*解析INVITE的SDP消息体,同时保存全局INVITE连接ID和全局会话ID*/
  void paraseInfoBody(eXosip_event_t *p_event);/*解析INFO的RTSP消息体*/
  static void *processEvent(void *arg);
  void processEventDispose();   //处理消息
  /*回调函数*/
  /*设备控制:向左、向右、向上、向下、放大、缩小、停止遥控/开始手动录像、停止手动录像/布防、撤防/报警复位/设备远程启动*/
  /*ctrl_cmd:设备控制命令,_device_control类型的枚举变量*/
  /*返回值:成功时返回0,失败时返回负值*/
  int dt_eXosip_deviceControl(enum _device_control ctrl_cmd){return 0;}
  /*获取设备信息*/
  /*device_info:设备信息结构体指针*/
  /*返回值:成功时返回0,失败时返回负值*/
  int dt_eXosip_getDeviceInfo(DEVICE_INFO *device_info){return 0;}
  /*获取设备状态*/
  /*device_info:设备状态结构体指针*/
  /*返回值:成功时返回0,失败时返回负值*/
  int dt_eXosip_getDeviceStatus(DEVICE_STATUS *device_status){return 0;}
  
  /*获取录像文件的起始时间与结束时间*/
  /*时间格式:xxxx-xx-xxTxx:xx:xx*/
  /*period_start:录像时间段起始值*/
  /*period_end:录像时间段结束值*/
  /*start_time:当前返回录像文件的起始时间*/
  /*end_time:当前返回录像文件的结束时间*/
  /*返回值:成功时返回符合时间段条件的剩余录像文件数量,失败时返回负值*/
  int dt_eXosip_getRecordTime(char *period_start, char *period_end, char *start_time, char *end_time){return 0;}
  /*播放控制:播放/快放/慢放/暂停*/
  /*control_type:播放控制,播放/快放/慢放/PLAY,暂停/PAUSE*/
  /*play_speed:播放速度,1为播放,大于1为快放,小于1为慢放*/
  /*pause_time:暂停时间,单位为秒*/
  /*range_start:播放范围的起始值*/
  /*range_end:播放范围的结束值*/
  /*返回值:成功时返回0,失败时返回负值*/
  int dt_eXosip_playControl(char *control_type, char *play_speed, char *pause_time, char *range_start, char *range_end){return 0;}
  /*媒体控制:实时点播/回放/下载    */ 
  /*control_type:媒体控制类型,实时点播/Play,回放/Playback,下载/Download*/
  /*media_ip:媒体服务器IP地址*/
  /*media_port:媒体服务器IP端口*/
  /*返回值:成功时返回0,失败时返回负值*/
  virtual int dt_eXosip_mediaControl(char *control_type, char *media_ip, char *media_port, char *ipc_media_port) = 0;
  /*发送视频流*/
  //static void *SendRtpProc(void *arg) = 0;
  
  /*回调函数 结束*/
  DEVICE_INFO mDevice_info;
  DEVICE_STATUS mDevice_status;  
  DT_EXOSIP_CALLBACK *mCallback;
  pthread_t ntid;
  eXosip_t *mContext;
  int g_register_id  = 0;/*注册ID/用来更新注册或取消注册*/
  int g_call_id      = 0;/*INVITE连接ID/用来分辨不同的INVITE连接,每个时刻只允许有一个INVITE连接*/
  int g_did_realPlay = 0;/*会话ID/用来分辨不同的会话:实时视音频点播*/
  int g_did_backPlay = 0;/*会话ID/用来分辨不同的会话:历史视音频回放*/
  int g_did_fileDown = 0;/*会话ID/用来分辨不同的会话:视音频文件下载*/
  bool SenAliveFlag = false;
  int  LinkStatus = 0;     //连接状态, 0 未注册 , 1注册中, 2注册成功, -1,注册失败
  bool threadStatus = true;
};
#endif


gb28181Client.cpp

#include <eXosip2/eXosip.h>
#include <stdio.h>
#include <sys/types.h>
#include <osip2/osip_mt.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <signal.h>
#include "gb28181Client.h"

//#define dbg(a,...) printf("  DEBUG :%s(%d)-<%s>: %s\r\n",__FILE__, __LINE__, __FUNCTION__,a)
#define LSErr(a,...) printf("  ERROR :%s(%d)-<%s>: %s\r\n",__FILE__, __LINE__, __FUNCTION__,a)

#define dbg(a,...) 



LSMXGb28181Client*
LSMXGb28181Client::createNew(DEVICE_INFO device_info,
                DEVICE_STATUS device_statu){
#if 0
  LSMXGb28181Client* Gb28181Client = new LSMXGb28181Client(device_info,
                              device_statu);
  if(Gb28181Client == NULL)
  {
    return NULL;  
  }
  if (Gb28181Client->init() == false){
    delete Gb28181Client;
    dbg("Gb28181Client->init() NONO!!");
    return NULL;
  }
  if (Gb28181Client->start() == false){
    delete Gb28181Client;
    dbg("Gb28181Client->start() NONO!!");
    return NULL;
  }
  return Gb28181Client;

#endif
  return NULL;
}
LSMXGb28181Client::~LSMXGb28181Client(){
  if(mContext != NULL){
    eXosip_quit(mContext);
  }
  if(ntid){
    threadStatus = false;
    void* retval;
    pthread_join(ntid,&retval);
  }
  if (mCallback)
    delete mCallback;
}

LSMXGb28181Client::LSMXGb28181Client(DEVICE_INFO device_info,
                      DEVICE_STATUS device_status):
mDevice_info(device_info),
mDevice_status(device_status)
{
  



  
}
bool
LSMXGb28181Client::init()
{
  //分配一个eXosip_t结构体
  mContext = eXosip_malloc();

     
  int ret = 0;
  //InitiateWinsock();  //Windows中的初始化sock时使用的这里不用
  ret = eXosip_init(mContext);/*初始化osip和eXosip协议栈*/
  if (0 != ret)
  {
    LSErr("Couldn't initialize eXosip!\r\n");
    system("pause");
    return -1;
  }
  dbg("eXosip_init success!\r\n");
  /*传输层初始化*/
  ret = eXosip_listen_addr(mContext,IPPROTO_UDP, NULL, atoi(mDevice_info.ipc_sess_port), AF_INET, 0);
  if (0 != ret)/*传输层初始化失败*/
  {
    eXosip_quit(mContext);
    LSErr("eXosip_listen_addr error!\r\n");
    system("pause");
    return false;
  }
  dbg("eXosip_listen_addr success!\r\n");
  printf("LSMXGb28181Client::init()  chn = %s  \r\n",mDevice_info.ipc_id);
  return true;
}
bool
LSMXGb28181Client::startUp()
{
  dbg("startUp else.......................................!!");
  LinkStatus = 0;
  threadStatus = true;
  int err=pthread_create(&ntid,NULL,processEvent,this);  //创建一个线程
  dbg("pthread_create!!");
  if(err!=0)
  {
   LSErr("create thread failed:pthreadSendRtpProc\n");
   return -1;
  }
  printf("LSMXGb28181Client::startUp()  chn = %s  \r\n",mDevice_info.ipc_id);
  return true;
}
bool
LSMXGb28181Client::setPara(DEVICE_INFO device_info,
              DEVICE_STATUS device_status)
{
  mDevice_info = device_info;
  mDevice_status = device_status;
  if(ntid){
    printf("ntid ntid ntid ntid\n");
    threadStatus = false;
    LinkStatus = 0;
    void* retval;
    pthread_cancel(ntid);
    pthread_join(ntid,&retval);
  }
  printf("LSMXGb28181Client::setPara()  chn = %s  \r\n",mDevice_info.ipc_id);
  //sleep(2);
  return true;
}

int 
LSMXGb28181Client::getLinkStatus(){
  return LinkStatus;
}

int 
LSMXGb28181Client::getRealPlay(){
  return g_did_realPlay;
}



int
LSMXGb28181Client::sendRegister(int expires){
  int ret = 0; 
  eXosip_event_t *je  = NULL;  
  osip_message_t *reg = NULL;  
  char from[100];/*sip:主叫用户名@被叫IP地址*/  
  char proxy[100];/*sip:被叫IP地址:被叫IP端口*/  
  
  memset(from, 0, 100);  
  memset(proxy, 0, 100);  
  snprintf(from, sizeof(from),"sip:%s@%s:%s", mDevice_info.ipc_id, mDevice_info.ipc_ip,mDevice_info.ipc_sess_port);
  dbg("sip:%s@%s:%s\n", mDevice_info.ipc_id, mDevice_info.ipc_ip, mDevice_info.ipc_sess_port);
  snprintf(proxy,sizeof(proxy), "sip:%s@%s:%s", mDevice_info.server_id,mDevice_info.server_ip, mDevice_info.server_port);  
  dbg("sip:%s@%s:%s\n", mDevice_info.server_id, mDevice_info.server_ip, mDevice_info.server_port);
  /*发送不带认证信息的注册请求*/  
retry:  
  LinkStatus = 1;
  eXosip_masquerade_contact (mContext, mDevice_info.ipc_ip, atoi(mDevice_info.ipc_sess_port));
  eXosip_set_user_agent (mContext, UA_STRING);   //填写用户代理
  
  eXosip_lock(mContext);
  g_register_id = eXosip_register_build_initial_register(mContext,from, proxy, NULL, expires, &reg);  
  if(0 > g_register_id)  
  {
    eXosip_unlock(mContext);  
    LSErr("eXosip_register_build_initial_register error!\r\n");  
    //system("pause");
    return -1;  
  }
  dbg("eXosip_register_build_initial_register success!\r\n");  


  ret = eXosip_register_send_register(mContext,g_register_id, reg);  
  eXosip_unlock(mContext);  
  if(0 != ret)  
  {  
    LSErr("eXosip_register_send_register no authorization error!\r\n");  
    //system("pause");
    return -1;  
  }  
  dbg("eXosip_register_send_register no authorization success!\r\n");  

  dbg("g_register_id=%d\r\n", g_register_id);  


  //for(;;)  
  while(threadStatus)  
  {  
    dbg("forforforfor\r\n");  
    je = eXosip_event_wait(mContext,0, 50);/*侦听消息的到来*/  
    dbg("eXosip_event_wait\r\n"); 
    if(NULL == je)/*没有接收到消息*/  
    {  
      dbg("if(NULL == je)\r\n");
      eXosip_execute(mContext);
      dbg("eXosip_execute(mContext);");
      eXosip_automatic_action (mContext);
      dbg("eXosip_automatic_action (mContext);");
      osip_usleep (1000);
      dbg("osip_usleep (1000);");
      continue;  
    }  
    if(EXOSIP_REGISTRATION_FAILURE == je->type)/*注册失败*/  
    {  
      dbg("<EXOSIP_REGISTRATION_FAILURE>\r\n");  
      dbg("je->rid=%d\r\n", je->rid);  
      /*收到服务器返回的注册失败/401未认证状态*/  
      if((NULL != je->response)&&(401 == je->response->status_code))  
      {  
        reg = NULL;  
        /*发送携带认证信息的注册请求*/  
        eXosip_lock(mContext);  
        eXosip_clear_authentication_info(mContext);/*清除认证信息*/  
        eXosip_add_authentication_info(mContext,mDevice_info.ipc_id, mDevice_info.ipc_id, mDevice_info.ipc_pwd, "MD5", NULL)  ;/*添加主叫用户的认证信息*/  
        //eXosip_add_authentication_info(context, device_info.ipc_id, device_info.ipc_id, device_info.ipc_pwd, NULL, NULL);
        eXosip_register_build_register(mContext,je->rid, expires, &reg);  
        ret = eXosip_register_send_register(mContext,je->rid, reg);  
        eXosip_unlock(mContext);  
        if(0 != ret)  
        {  
          LSErr("eXosip_register_send_register authorization error!\r\n");  
          //system("pause");
          LinkStatus = -1;
          return -1;  
        }  
        dbg("eXosip_register_send_register authorization success!\r\n");  
      }  
      else/*真正的注册失败*/  
      {  
        LinkStatus = -1;
        LSErr("EXOSIP_REGISTRATION_FAILURE error!\r\n"); 
        sleep(3000);
        goto retry;/*重新注册*/  
      }  
    }  
    else if(EXOSIP_REGISTRATION_SUCCESS == je->type)  
    {  
    dbg("EXOSIP_REGISTRATION_SUCCESS == je->type");
      /*收到服务器返回的注册成功*/
      eXosip_execute (mContext);
      eXosip_automatic_action (mContext);
      dbg("<EXOSIP_REGISTRATION_SUCCESS>\r\n");  
      g_register_id = je->rid;/*保存注册成功的注册ID*/  
      dbg("g_register_id=%d\r\n", g_register_id);  
      break;  
    }  
    dbg("end end end end forforforfor\r\n"); 
  } 
  dbg("eXosip_event_free eXosip_event_free eXosip_event_free\r\n"); 
  eXosip_event_free (je);
  dbg("eXosip_event_free (je)eXosip_event_free (je) \r\n"); 
  return true;
}
void
LSMXGb28181Client::keepAlive(){
  
  osip_message_t *rqt_msg = NULL;
  char to[100];/*sip:主叫用户名@被叫IP地址*/
  char from[100];/*sip:被叫IP地址:被叫IP端口*/
  char xml_body[4096];
  
  memset(to, 0, 100);
  memset(from, 0, 100);
  memset(xml_body, 0, 4096);
  snprintf(to,sizeof(to), "sip:%s@%s:%s", mDevice_info.server_id,mDevice_info.server_ip, mDevice_info.server_port);
  snprintf(from,sizeof(from), "sip:%s@%s:%s", mDevice_info.ipc_id, mDevice_info.ipc_ip,mDevice_info.ipc_sess_port);
  eXosip_message_build_request(mContext,&rqt_msg, "MESSAGE", to, from, NULL);/*构建"MESSAGE"请求*/
  snprintf(xml_body, 4096, "<?xml version=\"1.0\"?>\r\n"
    "<Notify>\r\n"
    "<CmdType>Keepalive</CmdType>\r\n"/*命令类型*/
    "<SN>1</SN>\r\n"/*命令序列号*/
    "<DeviceID>%s</DeviceID>\r\n"/*设备编码*/
    "<Status>OK</Status>\r\n"/*是否正常工作*/
    "</Notify>\r\n",
    mDevice_info.ipc_id);
  osip_message_set_body(rqt_msg, xml_body, strlen(xml_body));
  osip_message_set_content_type(rqt_msg, "Application/MANSCDP+xml");
  eXosip_lock(mContext);
  eXosip_message_send_request(mContext,rqt_msg);/*回复"MESSAGE"请求*/
  eXosip_unlock(mContext);
  dbg("dt_eXosip_sendKeepAlive success!\r\n");

}

void 
LSMXGb28181Client::printEvent(eXosip_event_t *p_event){
  osip_message_t *clone_event = NULL;
  size_t length = 0;
  char *message = NULL;

  dbg("\r\n##############################################################\r\n");
  switch (p_event->type)
  {
//  case EXOSIP_REGISTRATION_NEW:
//    dbg("EXOSIP_REGISTRATION_NEW\r\n");
//    break;
  case EXOSIP_REGISTRATION_SUCCESS:
    dbg("EXOSIP_REGISTRATION_SUCCESS\r\n");
    break;
  case EXOSIP_REGISTRATION_FAILURE:
    dbg("EXOSIP_REGISTRATION_FAILURE\r\n");
    break;
//  case EXOSIP_REGISTRATION_REFRESHED:
//    dbg("EXOSIP_REGISTRATION_REFRESHED\r\n");
//    break;
//  case EXOSIP_REGISTRATION_TERMINATED:
//    dbg("EXOSIP_REGISTRATION_TERMINATED\r\n");
//    break;
  case EXOSIP_CALL_INVITE:
    dbg("EXOSIP_CALL_INVITE\r\n");
    break;
  case EXOSIP_CALL_REINVITE:
    dbg("EXOSIP_CALL_REINVITE\r\n");
    break;
  case EXOSIP_CALL_NOANSWER:
    dbg("EXOSIP_CALL_NOANSWER\r\n");
    break;
  case EXOSIP_CALL_PROCEEDING:
    dbg("EXOSIP_CALL_PROCEEDING\r\n");
    break;
  case EXOSIP_CALL_RINGING:
    dbg("EXOSIP_CALL_RINGING\r\n");
    break;
  case EXOSIP_CALL_ANSWERED:
    dbg("EXOSIP_CALL_ANSWERED\r\n");
    break;
  case EXOSIP_CALL_REDIRECTED:
    dbg("EXOSIP_CALL_REDIRECTED\r\n");
    break;
  case EXOSIP_CALL_REQUESTFAILURE:
    dbg("EXOSIP_CALL_REQUESTFAILURE\r\n");
    break;
  case EXOSIP_CALL_SERVERFAILURE:
    dbg("EXOSIP_CALL_SERVERFAILURE\r\n");
    break;
  case EXOSIP_CALL_GLOBALFAILURE:
    dbg("EXOSIP_CALL_GLOBALFAILURE\r\n");
    break;
  case EXOSIP_CALL_ACK:
    dbg("EXOSIP_CALL_ACK\r\n");
    break;
  case EXOSIP_CALL_CANCELLED:
    dbg("EXOSIP_CALL_CANCELLED\r\n");
    break;
//  case EXOSIP_CALL_TIMEOUT:
//    dbg("EXOSIP_CALL_TIMEOUT\r\n");
//    break;
  case EXOSIP_CALL_MESSAGE_NEW:
    dbg("EXOSIP_CALL_MESSAGE_NEW\r\n");
    break;
  case EXOSIP_CALL_MESSAGE_PROCEEDING:
    dbg("EXOSIP_CALL_MESSAGE_PROCEEDING\r\n");
    break;
  case EXOSIP_CALL_MESSAGE_ANSWERED:
    dbg("EXOSIP_CALL_MESSAGE_ANSWERED\r\n");
    break;
  case EXOSIP_CALL_MESSAGE_REDIRECTED:
    dbg("EXOSIP_CALL_MESSAGE_REDIRECTED\r\n");
    break;
  case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
    dbg("EXOSIP_CALL_MESSAGE_REQUESTFAILURE\r\n");
    break;
  case EXOSIP_CALL_MESSAGE_SERVERFAILURE:
    dbg("EXOSIP_CALL_MESSAGE_SERVERFAILURE\r\n");
    break;
  case EXOSIP_CALL_MESSAGE_GLOBALFAILURE:
    dbg("EXOSIP_CALL_MESSAGE_GLOBALFAILURE\r\n");
    break;
  case EXOSIP_CALL_CLOSED:
    dbg("EXOSIP_CALL_CLOSED\r\n");
    break;
  case EXOSIP_CALL_RELEASED:
    dbg("EXOSIP_CALL_RELEASED\r\n");
    break;
  case EXOSIP_MESSAGE_NEW:
    dbg("EXOSIP_MESSAGE_NEW\r\n");
    break;
  case EXOSIP_MESSAGE_PROCEEDING:
    dbg("EXOSIP_MESSAGE_PROCEEDING\r\n");
    break;
  case EXOSIP_MESSAGE_ANSWERED:
    dbg("EXOSIP_MESSAGE_ANSWERED\r\n");
    break;
  case EXOSIP_MESSAGE_REDIRECTED:
    dbg("EXOSIP_MESSAGE_REDIRECTED\r\n");
    break;
  case EXOSIP_MESSAGE_REQUESTFAILURE:
    dbg("EXOSIP_MESSAGE_REQUESTFAILURE\r\n");
    break;
  case EXOSIP_MESSAGE_SERVERFAILURE:
    dbg("EXOSIP_MESSAGE_SERVERFAILURE\r\n");
    break;
  case EXOSIP_MESSAGE_GLOBALFAILURE:
    dbg("EXOSIP_MESSAGE_GLOBALFAILURE\r\n");
    break;
//  case EXOSIP_SUBSCRIPTION_UPDATE:
//    dbg("EXOSIP_SUBSCRIPTION_UPDATE\r\n");
//    break;
//  case EXOSIP_SUBSCRIPTION_CLOSED:
//    dbg("EXOSIP_SUBSCRIPTION_CLOSED\r\n");
//    break;
  case EXOSIP_SUBSCRIPTION_NOANSWER:
    dbg("EXOSIP_SUBSCRIPTION_NOANSWER\r\n");
    break;
  case EXOSIP_SUBSCRIPTION_PROCEEDING:
    dbg("EXOSIP_SUBSCRIPTION_PROCEEDING\r\n");
    break;
  case EXOSIP_SUBSCRIPTION_ANSWERED:
    dbg("EXOSIP_SUBSCRIPTION_ANSWERED\r\n");
    break;
  case EXOSIP_SUBSCRIPTION_REDIRECTED:
    dbg("EXOSIP_SUBSCRIPTION_REDIRECTED\r\n");
    break;
  case EXOSIP_SUBSCRIPTION_REQUESTFAILURE:
    dbg("EXOSIP_SUBSCRIPTION_REQUESTFAILURE\r\n");
    break;
  case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
    dbg("EXOSIP_SUBSCRIPTION_SERVERFAILURE\r\n");
    break;
  case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
    dbg("EXOSIP_SUBSCRIPTION_GLOBALFAILURE\r\n");
    break;
  case EXOSIP_SUBSCRIPTION_NOTIFY:
    dbg("EXOSIP_SUBSCRIPTION_NOTIFY\r\n");
    break;
//  case EXOSIP_SUBSCRIPTION_RELEASED:
//    dbg("EXOSIP_SUBSCRIPTION_RELEASED\r\n");
//    break;
  case EXOSIP_IN_SUBSCRIPTION_NEW:
    dbg("EXOSIP_IN_SUBSCRIPTION_NEW\r\n");
    break;
//  case EXOSIP_IN_SUBSCRIPTION_RELEASED:
//    dbg("EXOSIP_IN_SUBSCRIPTION_RELEASED\r\n");
//    break;
  case EXOSIP_NOTIFICATION_NOANSWER:
    dbg("EXOSIP_NOTIFICATION_NOANSWER\r\n");
    break;
  case EXOSIP_NOTIFICATION_PROCEEDING:
    dbg("EXOSIP_NOTIFICATION_PROCEEDING\r\n");
    break;
  case EXOSIP_NOTIFICATION_ANSWERED:
    dbg("EXOSIP_NOTIFICATION_ANSWERED\r\n");
    break;
  case EXOSIP_NOTIFICATION_REDIRECTED:
    dbg("EXOSIP_NOTIFICATION_REDIRECTED\r\n");
    break;
  case EXOSIP_NOTIFICATION_REQUESTFAILURE:
    dbg("EXOSIP_NOTIFICATION_REQUESTFAILURE\r\n");
    break;
  case EXOSIP_NOTIFICATION_SERVERFAILURE:
    dbg("EXOSIP_NOTIFICATION_SERVERFAILURE\r\n");
    break;
  case EXOSIP_NOTIFICATION_GLOBALFAILURE:
    dbg("EXOSIP_NOTIFICATION_GLOBALFAILURE\r\n");
    break;
  case EXOSIP_EVENT_COUNT:
    dbg("EXOSIP_EVENT_COUNT\r\n");
    break;
  default:
    dbg("..................\r\n");
    break;
  }
  osip_message_clone(p_event->request, &clone_event);
  osip_message_to_str(clone_event, &message, &length);
  dbg("%s\r\n", message);
  dbg("##############################################################\r\n\r\n");




}
void
LSMXGb28181Client::paraseMsgBody(eXosip_event_t *p_event){
  /*与请求相关的变量*/
  osip_body_t *p_rqt_body = NULL;
  char *p_xml_body  = NULL;
  char *p_str_begin = NULL;
  char *p_str_end   = NULL;
  char xml_cmd_type[20];
  char xml_cmd_sn[10];
  char xml_device_id[30];
  char xml_command[30];
  /*与回复相关的变量*/
  osip_message_t *rsp_msg = NULL;
  char to[100];/*sip:主叫用户名@被叫IP地址*/
  char from[100];/*sip:被叫IP地址:被叫IP端口*/
  char rsp_xml_body[4096];

  memset(xml_cmd_type, 0, 20);
  memset(xml_cmd_sn, 0, 10);
  memset(xml_device_id, 0, 30);
  memset(xml_command, 0, 30);
  memset(to, 0, 100);
  memset(from, 0, 100);
  memset(rsp_xml_body, 0, 4096);

  snprintf(to,sizeof(to), "sip:%s@%s:%s", mDevice_info.server_id,mDevice_info.server_ip, mDevice_info.server_port);
  snprintf(from,sizeof(from), "sip:%s@%s:%s", mDevice_info.ipc_id, mDevice_info.ipc_ip,mDevice_info.ipc_sess_port);
  eXosip_message_build_request(mContext,&rsp_msg, "MESSAGE", to, from, NULL);/*构建"MESSAGE"请求*/

  osip_message_get_body(p_event->request, 0, &p_rqt_body);/*获取接收到请求的XML消息体*/
  if (NULL == p_rqt_body)
  {
    dbg("osip_message_get_body null!\r\n");
    return;
  }
  p_xml_body = p_rqt_body->body;
  dbg("osip_message_get_body success!\r\n");

  dbg("**********CMD START**********\r\n");
  p_str_begin = strstr(p_xml_body, "<CmdType>");/*查找字符串"<CmdType>"*/
  p_str_end  = strstr(p_xml_body, "</CmdType>");
  memcpy(xml_cmd_type, p_str_begin+9, p_str_end-p_str_begin-9);/*保存<CmdType>到xml_cmd_type*/
  dbg("<CmdType>:%s\r\n", xml_cmd_type);

  p_str_begin = strstr(p_xml_body, "<SN>");/*查找字符串"<SN>"*/
  p_str_end  = strstr(p_xml_body, "</SN>");
  memcpy(xml_cmd_sn, p_str_begin+4, p_str_end-p_str_begin-4);/*保存<SN>到xml_cmd_sn*/
  dbg("<SN>:%s\r\n", xml_cmd_sn);

  p_str_begin = strstr(p_xml_body, "<DeviceID>");/*查找字符串"<DeviceID>"*/
  p_str_end  = strstr(p_xml_body, "</DeviceID>");
  memcpy(xml_device_id, p_str_begin+10, p_str_end-p_str_begin-10);/*保存<DeviceID>到xml_device_id*/
  dbg("<DeviceID>:%s\r\n", xml_device_id);
  dbg("***********CMD END***********\r\n");

  if(0 == strcmp(xml_cmd_type, "DeviceControl"))/*设备控制*/
  {
    dbg("**********CONTROL START**********\r\n");
    /*向左、向右、向上、向下、放大、缩小、停止遥控*/
    p_str_begin = strstr(p_xml_body, "<PTZCmd>");/*查找字符串"<PTZCmd>"*/
    if (NULL != p_str_begin)
    {
      p_str_end = strstr(p_xml_body, "</PTZCmd>");
      memcpy(xml_command, p_str_begin+8, p_str_end-p_str_begin-8);/*保存<PTZCmd>到xml_command*/
      dbg("<PTZCmd>:%s\r\n", xml_command);
      goto DeviceControl_Next;
    }
    /*开始手动录像、停止手动录像*/
    p_str_begin = strstr(p_xml_body, "<RecordCmd>");/*查找字符串"<RecordCmd>"*/
    if (NULL != p_str_begin)
    {
      p_str_end = strstr(p_xml_body, "</RecordCmd>");
      memcpy(xml_command, p_str_begin+11, p_str_end-p_str_begin-11);/*保存<RecordCmd>到xml_command*/
      dbg("<RecordCmd>:%s\r\n", xml_command);
      goto DeviceControl_Next;
    }
    /*布防、撤防*/
    p_str_begin = strstr(p_xml_body, "<GuardCmd>");/*查找字符串"<GuardCmd>"*/
    if (NULL != p_str_begin)
    {
      p_str_end = strstr(p_xml_body, "</GuardCmd>");
      memcpy(xml_command, p_str_begin+10, p_str_end-p_str_begin-10);/*保存<GuardCmd>到xml_command*/
      dbg("<GuardCmd>:%s\r\n", xml_command);
      goto DeviceControl_Next;
    }
    /*报警复位:30秒内不再触发报警*/
    p_str_begin = strstr(p_xml_body, "<AlarmCmd>");/*查找字符串"<AlarmCmd>"*/
    if (NULL != p_str_begin)
    {
      p_str_end = strstr(p_xml_body, "</AlarmCmd>");
      memcpy(xml_command, p_str_begin+10, p_str_end-p_str_begin-10);/*保存<AlarmCmd>到xml_command*/
      dbg("<AlarmCmd>:%s\r\n", xml_command);
      goto DeviceControl_Next;
    }
    /*设备远程启动*/
    p_str_begin = strstr(p_xml_body, "<TeleBoot>");/*查找字符串"<TeleBoot>"*/
    if (NULL != p_str_begin)
    {
      p_str_end = strstr(p_xml_body, "</TeleBoot>");
      memcpy(xml_command, p_str_begin+10, p_str_end-p_str_begin-10);/*保存<TeleBoot>到xml_command*/
      dbg("<TeleBoot>:%s\r\n", xml_command);
      goto DeviceControl_Next;
    }
DeviceControl_Next:
    dbg("***********CONTROL END***********\r\n");
    if (0 == strcmp(xml_command, "A50F01021F0000D6"))/*向左*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_RMT_LEFT);//调用dt_eXosip_deviceControl函数
    }
    else if (0 == strcmp(xml_command, "A50F01011F0000D5"))/*向右*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_RMT_RIGHT);
    }
    else if (0 == strcmp(xml_command, "A50F0108001F00DC"))/*向上*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_RMT_UP);
    }
    else if (0 == strcmp(xml_command, "A50F0104001F00D8"))/*向下*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_RMT_DOWN);
    }
    else if (0 == strcmp(xml_command, "A50F0110000010D5"))/*放大*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_RMT_LARGE);
    }
    else if (0 == strcmp(xml_command, "A50F0120000010E5"))/*缩小*/
    {

      dt_eXosip_deviceControl(EXOSIP_CTRL_RMT_SMALL);
    }
    else if (0 == strcmp(xml_command, "A50F0100000000B5"))/*停止遥控*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_RMT_STOP);
    }
    else if (0 == strcmp(xml_command, "Record"))/*开始手动录像*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_REC_START);
    }
    else if (0 == strcmp(xml_command, "StopRecord"))/*停止手动录像*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_REC_STOP);
    }
    else if (0 == strcmp(xml_command, "SetGuard"))/*布防*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_GUD_START);
      strcpy(mDevice_status.status_guard, "ONDUTY");/*设置布防状态为"ONDUTY"*/
    }
    else if (0 == strcmp(xml_command, "ResetGuard"))/*撤防*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_GUD_STOP);
      strcpy(mDevice_status.status_guard,"OFFDUTY");/*设置布防状态为"OFFDUTY"*/
    }
    else if (0 == strcmp(xml_command, "ResetAlarm"))/*报警复位*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_ALM_RESET);
    }
    else if (0 == strcmp(xml_command, "Boot"))/*设备远程启动*/
    {
      dt_eXosip_deviceControl(EXOSIP_CTRL_TEL_BOOT);
    }
    else
    {
      dbg("unknown device control command!\r\n");
    }
    snprintf(rsp_xml_body, 4096, "<?xml version=\"1.0\"?>\r\n"
      "<Response>\r\n"
      "<CmdType>DeviceControl</CmdType>\r\n"/*命令类型*/
      "<SN>%s</SN>\r\n"/*命令序列号*/
      "<DeviceID>%s</DeviceID>\r\n"/*目标设备/区域/系统编码*/
      "<Result>OK</Result>\r\n"/*执行结果标志*/
      "</Response>\r\n",
      xml_cmd_sn,
      xml_device_id);
  }
  else if (0 == strcmp(xml_cmd_type, "Alarm"))/*报警事件通知和分发:报警通知响应*/
  {
    dbg("**********ALARM START**********\r\n");
    /*报警通知响应*/
    dbg("local eventAlarm response success!\n");
    dbg("***********ALARM END***********\r\n");
    return;
  }
  else if (0 == strcmp(xml_cmd_type, "Catalog"))/*网络设备信息查询:设备目录查询*/
  {
    dbg("**********CATALOG START**********\r\n");
    /*设备目录查询*/
    dbg("***********CATALOG END***********\r\n");
    snprintf(rsp_xml_body, 4096, "<?xml version=\"1.0\"?>\r\n"
      "<Response>\r\n"
      "<CmdType>Catalog</CmdType>\r\n"/*命令类型*/
      "<SN>%s</SN>\r\n"/*命令序列号*/
      "<DeviceID>%s</DeviceID>\r\n"/*目标设备/区域/系统的编码*/
      "<SumNum>2</SumNum>\r\n"/*查询结果总数*/
      "<DeviceList Num=\"2\">\r\n"/*设备目录项列表*/
      "<Item>\r\n"
      "<DeviceID>%s</DeviceID>\r\n"/*目标设备/区域/系统的编码*/
      "<Name>%s</Name>\r\n"/*设备/区域/系统名称*/
      "<Manufacturer>%s</Manufacturer>\r\n"/*设备厂商*/
      "<Model>%s</Model>\r\n"/*设备型号*/
      "<Owner>Owner</Owner>\r\n"/*设备归属*/
      "<CivilCode>CivilCode</CivilCode>\r\n"/*行政区域*/
      "<Address>Address</Address>\r\n"/*安装地址*/
      "<Parental>0</Parental>\r\n"/*是否有子设备*/
      "<SafetyWay>0</SafetyWay>\r\n"/*信令安全模式/0为不采用/2为S/MIME签名方式/3为S/MIME加密签名同时采用方式/4为数字摘要方式*/
      "<RegisterWay>1</RegisterWay>\r\n"/*注册方式/1为符合sip3261标准的认证注册模式/2为基于口令的双向认证注册模式/3为基于数字证书的双向认证注册模式*/
      "<Secrecy>0</Secrecy>\r\n"
      "<Status>ON</Status>\r\n"
      "</Item>\r\n"
      "<Item>\r\n"
      "<DeviceID>%s</DeviceID>\r\n"/*目标设备/区域/系统的编码*/
      "<Name></Name>\r\n"/*设备/区域/系统名称*/
      "<Manufacturer>%s</Manufacturer>\r\n"/*设备厂商*/
      "<Model>AlarmIn</Model>\r\n"/*设备型号*/
      "<Owner>Owner</Owner>\r\n"/*设备归属*/
      "<CivilCode>CivilCode</CivilCode>\r\n"/*行政区域*/
      "<Address>Address</Address>\r\n"/*安装地址*/
      "<Parental>0</Parental>\r\n"/*是否有子设备*/
      "<SafetyWay>0</SafetyWay>\r\n"/*信令安全模式/0为不采用/2为S/MIME签名方式/3为S/MIME加密签名同时采用方式/4为数字摘要方式*/
      "<RegisterWay>1</RegisterWay>\r\n"/*注册方式/1为符合sip3261标准的认证注册模式/2为基于口令的双向认证注册模式/3为基于数字证书的双向认证注册模式*/
      "<Secrecy>0</Secrecy>\r\n"
      "<Status>ON</Status>\r\n"
      "</Item>\r\n"
      "</DeviceList>\r\n"
      "</Response>\r\n",
      xml_cmd_sn,
      xml_device_id,
      xml_device_id,
      mDevice_info.device_name,
      mDevice_info.device_manufacturer,
      mDevice_info.device_model,
      mDevice_info.alarm_id,
      mDevice_info.device_manufacturer);
  }
  else if (0 == strcmp(xml_cmd_type, "DeviceInfo"))/*网络设备信息查询:设备信息查询*/
  {
    dbg("**********DEVICE INFO START**********\r\n");
    /*设备信息查询*/
    dbg("***********DEVICE INFO END***********\r\n");
    snprintf(rsp_xml_body, 4096, "<?xml version=\"1.0\"?>\r\n"
      "<Response>\r\n"
      "<CmdType>DeviceInfo</CmdType>\r\n"/*命令类型*/
      "<SN>%s</SN>\r\n"/*命令序列号*/
      "<DeviceID>%s</DeviceID>\r\n"/*目标设备/区域/系统的编码*/
      "<Result>OK</Result>\r\n"/*查询结果*/
      "<DeviceType>IPC</DeviceType>\r\n"
      "<Manufacturer>%s</Manufacturer>\r\n"/*设备生产商*/
      "<Model>%s</Model>\r\n"/*设备型号*/
      "<Firmware>%s</Firmware>\r\n"/*设备固件版本*/
      "<MaxCamera>1</MaxCamera>\r\n"
      "<MaxAlarm>1</MaxAlarm>\r\n"
      "</Response>\r\n",
      xml_cmd_sn,
      xml_device_id,
      mDevice_info.device_manufacturer,
      mDevice_info.device_model,
      mDevice_info.device_firmware);
  }
  else if (0 == strcmp(xml_cmd_type, "DeviceStatus"))/*网络设备信息查询:设备状态查询*/
  {
    dbg("**********DEVICE STATUS START**********\r\n");
    /*设备状态查询*/
    dbg("***********DEVICE STATUS END***********\r\n");
    char xml_status_guard[10];
    strcpy(xml_status_guard,mDevice_status.status_guard);/*保存当前布防状态*/
    dt_eXosip_getDeviceStatus(&mDevice_status);/*获取设备当前状态*/
    strcpy(mDevice_status.status_guard, xml_status_guard);/*恢复当前布防状态*/
    snprintf(rsp_xml_body, 4096, "<?xml version=\"1.0\"?>\r\n"
      "<Response>\r\n"
      "<CmdType>DeviceStatus</CmdType>\r\n"/*命令类型*/
      "<SN>%s</SN>\r\n"/*命令序列号*/
      "<DeviceID>%s</DeviceID>\r\n"/*目标设备/区域/系统的编码*/
      "<Result>OK</Result>\r\n"/*查询结果标志*/
      "<Online>%s</Online>\r\n"/*是否在线/ONLINE/OFFLINE*/
      "<Status>%s</Status>\r\n"/*是否正常工作*/
      "<Encode>%s</Encode>\r\n"/*是否编码*/
      "<Record>%s</Record>\r\n"/*是否录像*/
      "<DeviceTime>%s</DeviceTime>\r\n"/*设备时间和日期*/
      "<Alarmstatus Num=\"1\">\r\n"/*报警设备状态列表*/
      "<Item>\r\n"
      "<DeviceID>%s</DeviceID>\r\n"/*报警设备编码*/
      "<DutyStatus>%s</DutyStatus>\r\n"/*报警设备状态*/
      "</Item>\r\n"
      "</Alarmstatus>\r\n"
      "</Response>\r\n",
      xml_cmd_sn,
      xml_device_id,
      mDevice_status.status_online,
      mDevice_status.status_ok,
      mDevice_info.device_encode,
      mDevice_info.device_record,
      mDevice_status.status_time,
      xml_device_id,
      mDevice_status.status_guard);
  }
  else if (0 == strcmp(xml_cmd_type, "RecordInfo"))/*设备视音频文件检索*/
  {
    /*录像文件检索*/
    char xml_file_path[30];
    char xml_start_time[30];
    char xml_end_time[30];
    char xml_recorder_id[30];
    char item_start_time[30];
    char item_end_time[30];
    char rsp_item_body[4096];
    int  record_list_num = 0;
    int  record_list_ret = 0;

    memset(xml_file_path, 0, 30);
    memset(xml_start_time, 0, 30);
    memset(xml_end_time, 0, 30);
    memset(xml_recorder_id, 0, 30);
    memset(item_start_time, 0, 30);
    memset(item_end_time, 0, 30);
    memset(rsp_item_body, 0, 4096);
    dbg("**********RECORD INFO START**********\r\n");
    p_str_begin = strstr(p_xml_body, "<FilePath>");/*查找字符串"<FilePath>"*/
    p_str_end  = strstr(p_xml_body, "</FilePath>");
    memcpy(xml_file_path, p_str_begin+10, p_str_end-p_str_begin-10);/*保存<FilePath>到xml_file_path*/
    dbg("<FilePath>:%s\r\n", xml_file_path);

    p_str_begin = strstr(p_xml_body, "<StartTime>");/*查找字符串"<StartTime>"*/
    p_str_end  = strstr(p_xml_body, "</StartTime>");
    memcpy(xml_start_time, p_str_begin+11, p_str_end-p_str_begin-11);/*保存<StartTime>到xml_start_time*/
    dbg("<StartTime>:%s\r\n", xml_start_time);

    p_str_begin = strstr(p_xml_body, "<EndTime>");/*查找字符串"<EndTime>"*/
    p_str_end  = strstr(p_xml_body, "</EndTime>");
    memcpy(xml_end_time, p_str_begin+9, p_str_end-p_str_begin-9);/*保存<EndTime>到xml_end_time*/
    dbg("<EndTime>:%s\r\n", xml_end_time);

    p_str_begin = strstr(p_xml_body, "<RecorderID>");/*查找字符串"<RecorderID>"*/
    p_str_end  = strstr(p_xml_body, "</RecorderID>");
    memcpy(xml_recorder_id, p_str_begin+12, p_str_end-p_str_begin-12);/*保存<RecorderID>到xml_recorder_id*/
    dbg("<RecorderID>:%s\r\n", xml_recorder_id);
    dbg("***********RECORD INFO END***********\r\n");
    for (;;)
    {
      record_list_ret = mCallback->dt_eXosip_getRecordTime(xml_start_time, xml_end_time, item_start_time, item_end_time);
      if (0 > record_list_ret)
      {
        break;
      }
      else
      {
        char temp_body[1024];
        memset(temp_body, 0, 1024);
        snprintf(temp_body, 1024, "<Item>\r\n"
          "<DeviceID>%s</DeviceID>\r\n"/*设备/区域编码*/
          "<Name>%s</Name>\r\n"/*设备/区域名称*/
          "<FilePath>%s</FilePath>\r\n"/*文件路径名*/
          "<Address>Address1</Address>\r\n"/*录像地址*/
          "<StartTime>%s</StartTime>\r\n"/*录像开始时间*/
          "<EndTime>%s</EndTime>\r\n"/*录像结束时间*/
          "<Secrecy>0</Secrecy>\r\n"/*保密属性/0为不涉密/1为涉密*/
          "<Type>time</Type>\r\n"/*录像产生类型*/
          "<RecorderID>%s</RecorderID>\r\n"/*录像触发者ID*/
          "</Item>\r\n",
          xml_device_id,
          mDevice_info.device_name,
          xml_file_path,
          item_start_time,
          item_end_time,
          xml_recorder_id);
        strcat(rsp_item_body,temp_body);
        record_list_num ++;
        if (0 == record_list_ret)
        {
          break;
        }
      }
    }
    if (0 >= record_list_num)/*未检索到任何设备视音频文件*/
    {
      return;
    }
    snprintf(rsp_xml_body, 4096, "<?xml version=\"1.0\"?>\r\n"
      "<Response>\r\n"
      "<CmdType>RecordInfo</CmdType>\r\n"/*命令类型*/
      "<SN>%s</SN>\r\n"/*命令序列号*/
      "<DeviceID>%s</DeviceID>\r\n"/*设备/区域编码*/
      "<Name>%s</Name>\r\n"/*设备/区域名称*/
      "<SumNum>%d</SumNum>\r\n"/*查询结果总数*/
      "<RecordList Num=\"%d\">\r\n"/*文件目录项列表*/
      "%s\r\n"
      "</RecordList>\r\n"
      "</Response>\r\n",
      xml_cmd_sn,
      xml_device_id,
      mDevice_info.device_name,
      record_list_num,
      record_list_num,
      rsp_item_body);
  }
//  else if (0 == strcmp(xml_cmd_type, "RecordInfo"))/*设备视音频文件检索*/
//  {
//    
//     }
  else/*CmdType为不支持的类型*/
  {
    keepAlive();
    dbg("**********OTHER TYPE START**********\r\n");
    dbg("***********OTHER TYPE END***********\r\n");
    return;
  }
  osip_message_set_body(rsp_msg, rsp_xml_body, strlen(rsp_xml_body));
  osip_message_set_content_type(rsp_msg, "Application/MANSCDP+xml");
  eXosip_message_send_request(mContext,rsp_msg);/*回复"MESSAGE"请求*/
  dbg("eXosip_message_send_request success!\r\n");


}
void 
LSMXGb28181Client::paraseInviteBody(eXosip_event_t *p_event){
  sdp_message_t *sdp_msg = NULL;
  char *media_sever_ip   = NULL;
  char *media_sever_port = NULL;

  sdp_msg = eXosip_get_remote_sdp(mContext,p_event->did);
  if (sdp_msg == NULL)
  {
    LSErr("eXosip_get_remote_sdp NULL!\r\n");
    return;
  }
  dbg("eXosip_get_remote_sdp success!\r\n");

  g_call_id = p_event->cid;/*保存全局INVITE连接ID*/
  /*实时点播*/
  if (0 == strcmp(sdp_msg->s_name, "Play"))
  {
    g_did_realPlay = p_event->did;/*保存全局会话ID:实时视音频点播*/
  }
  /*回放*/
  else if (0 == strcmp(sdp_msg->s_name, "Playback"))
  {
    g_did_backPlay = p_event->did;/*保存全局会话ID:历史视音频回放*/
  }
  /*下载*/
  else if (0 == strcmp(sdp_msg->s_name, "Download"))
  {
    g_did_fileDown = p_event->did;/*保存全局会话ID:视音频文件下载*/
  }
  /*从SIP服务器发过来的INVITE请求的o字段或c字段中获取媒体服务器的IP地址与端口*/
  media_sever_ip   = sdp_message_o_addr_get(sdp_msg);/*媒体服务器IP地址*/
  media_sever_port = sdp_message_m_port_get(sdp_msg, 0);/*媒体服务器IP端口*/
  dbg("%s->%s:%s\r\n", sdp_msg->s_name, media_sever_ip, media_sever_port);
  dt_eXosip_mediaControl(sdp_msg->s_name, media_sever_ip, media_sever_port,mDevice_info.ipc_media_port);

}
void 
LSMXGb28181Client::paraseInfoBody(eXosip_event_t *p_event){
  osip_body_t *p_msg_body = NULL;
  char *p_rtsp_body = NULL;
  char *p_str_begin = NULL;
  char *p_str_end   = NULL;
  char *p_strstr    = NULL;
  char rtsp_scale[10];
  char rtsp_range_begin[10];
  char rtsp_range_end[10];
  char rtsp_pause_time[10];

  memset(rtsp_scale, 0, 10);
  memset(rtsp_range_begin, 0, 10);
  memset(rtsp_range_end, 0, 10);
  memset(rtsp_pause_time, 0, 10);

  osip_message_get_body(p_event->request, 0, &p_msg_body);
  if (NULL == p_msg_body)
  {
    dbg("osip_message_get_body null!\r\n");
    return;
  }
  p_rtsp_body = p_msg_body->body;
  dbg("osip_message_get_body success!\r\n");

  p_strstr = strstr(p_rtsp_body, "PLAY");
  if (NULL != p_strstr)/*查找到字符串"PLAY"*/
  {
    /*播放速度*/
    p_str_begin = strstr(p_rtsp_body, "Scale:");/*查找字符串"Scale:"*/
    p_str_end   = strstr(p_rtsp_body, "Range:");
    memcpy(rtsp_scale, p_str_begin+6, p_str_end-p_str_begin-6);/*保存Scale到rtsp_scale*/
    dbg("PlayScale:%s\r\n", rtsp_scale);
    /*播放范围*/
    p_str_begin = strstr(p_rtsp_body, "npt=");/*查找字符串"npt="*/
    p_str_end   = strstr(p_rtsp_body, "-");
    memcpy(rtsp_range_begin, p_str_begin+4, p_str_end-p_str_begin-4);/*保存RangeBegin到rtsp_range_begin*/
    dbg("PlayRangeBegin:%s\r\n", rtsp_range_begin);
    p_str_begin = strstr(p_rtsp_body, "-");/*查找字符串"-"*/
    strcpy(rtsp_range_end,p_str_begin+1);/*保存RangeEnd到rtsp_range_end*/
    dbg("PlayRangeEnd:%s\r\n", rtsp_range_end);
    dt_eXosip_playControl("PLAY", rtsp_scale, NULL, rtsp_range_begin, rtsp_range_end);
    return;
  }

  p_strstr = strstr(p_rtsp_body, "PAUSE");
  if (NULL != p_strstr)/*查找到字符串"PAUSE"*/
  {
    /*暂停时间*/
    p_str_begin = strstr(p_rtsp_body, "PauseTime:");/*查找字符串"PauseTime:"*/
    strcpy(rtsp_pause_time,p_str_begin+10);/*保存PauseTime到rtsp_pause_time*/
    dbg("PauseTime:%3s\r\n", rtsp_pause_time);
    dt_eXosip_playControl("PAUSE", NULL, rtsp_pause_time, NULL, NULL);
    return;
  }

  dbg("can`t find string PLAY or PAUSE!");

}



void 
LSMXGb28181Client::processEventDispose(){
  unsigned int  keepConunt =0;
  eXosip_event_t *g_event  = NULL;/*消息事件*/
  osip_message_t *g_answer = NULL;/*请求的确认型应答*/
  LinkStatus = 2;
  while (threadStatus)
  {    
    /*等待新消息的到来*/
    g_event = eXosip_event_wait(mContext,0, 200);/*侦听消息的到来*/
    eXosip_lock(mContext);
    eXosip_default_action(mContext,g_event);
    eXosip_automatic_refresh(mContext);/*Refresh REGISTER and SUBSCRIBE before the expiration delay*/
    eXosip_unlock(mContext);
    //检查是否发心跳信息
    if(SenAliveFlag)
    {  
      dbg("SenAliveFlag  SenAliveFlag keepAlive()");
      keepAlive();
      dbg("SenAliveFlag  SenAliveFlag keepAlive() end ");
      SenAliveFlag = false;
    }else{
      keepConunt++;
      //dbg("keepConunt");
      if(keepConunt >= 20){
        keepConunt = 0;
        SenAliveFlag = true;
        dbg("SenAliveFlag = true  SenAliveFlag = true  SenAliveFlag = true");
      }
    }
    if (NULL == g_event)
    {
      continue;
    }
    dbg("printEvent");
    printEvent(g_event);
    dbg("printEvent end");
    /*处理感兴趣的消息*/
    switch (g_event->type)
    {
      /*即时消息:通信双方无需事先建立连接*/
    case EXOSIP_MESSAGE_NEW:/*MESSAGE:MESSAGE*/
      {
        dbg("\r\n<EXOSIP_MESSAGE_NEW>\r\n");
        if(MSG_IS_MESSAGE(g_event->request))/*使用MESSAGE方法的请求*/
        {
          /*设备控制*/
          /*报警事件通知和分发:报警通知响应*/
          /*网络设备信息查询*/
          /*设备视音频文件检索*/
          dbg("<MSG_IS_MESSAGE>\r\n");
          eXosip_lock(mContext);
          eXosip_message_build_answer(mContext,g_event->tid, 200, &g_answer);/*Build default Answer for request*/
          eXosip_message_send_answer(mContext,g_event->tid, 200, g_answer);/*按照规则回复200OK*/
          dbg("eXosip_message_send_answer success!\r\n");
          eXosip_unlock(mContext);
  //          if(poweron)
  //            dt_eXosip_keepAlive(context);
  //          poweron = FALSE;
          paraseMsgBody(g_event);/*解析MESSAGE的XML消息体,同时保存全局会话ID*/
        }
      }
      break;
      /*即时消息回复的200OK*/
    case EXOSIP_MESSAGE_ANSWERED:/*200OK*/
      {
        /*设备控制*/
        /*报警事件通知和分发:报警通知*/
        /*网络设备信息查询*/
        /*设备视音频文件检索*/
        dbg("\r\n<EXOSIP_MESSAGE_ANSWERED>\r\n");
      }
      break;
      /*以下类型的消息都必须事先建立连接*/
    case EXOSIP_CALL_INVITE:/*INVITE*/
      {
        dbg("\r\n<EXOSIP_CALL_INVITE>\r\n");
        if(MSG_IS_INVITE(g_event->request))/*使用INVITE方法的请求*/
        {
          /*实时视音频点播*/
          /*历史视音频回放*/
          /*视音频文件下载*/
          osip_message_t *asw_msg = NULL;/*请求的确认型应答*/
          char sdp_body[4096];

          memset(sdp_body, 0, 4096);
          dbg("<MSG_IS_INVITE>\r\n");

          eXosip_lock(mContext);
          if(0 != eXosip_call_build_answer(mContext,g_event->tid, 200, &asw_msg))/*为请求构建默认的回答*/
          {
            eXosip_call_send_answer(mContext,g_event->tid, 603, NULL);
            eXosip_unlock(mContext);
            LSErr("eXosip_call_build_answer error!\r\n");
            break;
          }
          
          dbg("<eXosip_unlock>\r\n");
          eXosip_unlock(mContext);
          snprintf(sdp_body, 4096, "v=0\r\n"/*协议版本*/
            "o=%s 0 0 IN IP4 %s\r\n"/*会话源*//*用户名/会话ID/版本/网络类型/地址类型/地址*/
            "s=(null)\r\n"/*会话名*/
            "c=IN IP4 %s\r\n"/*连接信息*//*网络类型/地址信息/多点会议的地址*/
            "t=0 0\r\n"/*时间*//*开始时间/结束时间*/
            "m=video %s RTP/AVP 96\r\n"/*媒体/端口/传送层协议/格式列表*/
            "a=sendonly\r\n"/*收发模式*/
            "a=rtpmap:96 PS/90000\r\n"/*净荷类型/编码名/时钟速率*/
            "a=username:%s\r\n"
            "a=password:%s\r\n"
            "y=0999999999\r\n"
            "f=\r\n",
            mDevice_info.ipc_id,
            mDevice_info.ipc_ip,
            mDevice_info.ipc_ip,
            mDevice_info.ipc_media_port,
            mDevice_info.ipc_id,
            mDevice_info.ipc_pwd);
          eXosip_lock(mContext);
          dbg("<eXosip_unlock>end\r\n");
          osip_message_set_body(asw_msg, sdp_body, strlen(sdp_body));/*设置SDP消息体*/
          dbg("<osip_message_set_body>end\r\n");
          osip_message_set_content_type(asw_msg, "application/sdp");
          dbg("<osip_message_set_content_type>end\r\n");
          eXosip_call_send_answer(mContext,g_event->tid, 200, asw_msg);/*按照规则回复200OK with SDP*/
          dbg("eXosip_call_send_answer success!\r\n");
          eXosip_unlock(mContext);
        }
      }
      break;
    case EXOSIP_CALL_ACK:/*ACK*/
      {
        /*实时视音频点播*/
        /*历史视音频回放*/
        /*视音频文件下载*/
        dbg("\r\n<EXOSIP_CALL_ACK>\r\n");/*收到ACK才表示成功建立连接*/
        paraseInviteBody(g_event);/*解析INVITE的SDP消息体,同时保存全局INVITE连接ID和全局会话ID*/
      }
      break;
    case EXOSIP_CALL_CLOSED:/*BEY*/
      {
        /*实时视音频点播*/
        /*历史视音频回放*/
        /*视音频文件下载*/
        dbg("\r\n<EXOSIP_CALL_CLOSED>\r\n");
        if(MSG_IS_BYE(g_event->request))
        {
          dbg("<MSG_IS_BYE>\r\n");
          if((0 != g_did_realPlay)&&(g_did_realPlay == g_event->did))/*实时视音频点播*/
          {
            /*关闭:实时视音频点播*/
            dbg("realPlay closed success!\r\n");
            g_did_realPlay = 0;
          }
          else if((0 != g_did_backPlay)&&(g_did_backPlay == g_event->did))/*历史视音频回放*/
          {
            /*关闭:历史视音频回放*/
            dbg("backPlay closed success!\r\n");
            g_did_backPlay = 0;
          }
          else if((0 != g_did_fileDown)&&(g_did_fileDown == g_event->did))/*视音频文件下载*/
          {
            /*关闭:视音频文件下载*/
            dbg("fileDown closed success!\r\n");
            g_did_fileDown = 0;
          }
          if((0 != g_call_id)&&(0 == g_did_realPlay)&&(0 == g_did_backPlay)&&(0 == g_did_fileDown))/*设置全局INVITE连接ID*/
          {
            dbg("call closed success!\r\n");
            g_call_id = 0;
          }
        }
      }
      break;
    case EXOSIP_CALL_MESSAGE_NEW:/*MESSAGE:INFO*/
      {
        /*历史视音频回放*/
        dbg("\r\n<EXOSIP_CALL_MESSAGE_NEW>\r\n");
        if(MSG_IS_INFO(g_event->request))
        {
          osip_body_t *msg_body = NULL;

          dbg("<MSG_IS_INFO>\r\n");
          osip_message_get_body(g_event->request, 0, &msg_body);
          if(NULL != msg_body)
          {
            eXosip_call_build_answer(mContext,g_event->tid, 200, &g_answer);/*Build default Answer for request*/
            eXosip_call_send_answer(mContext,g_event->tid, 200, g_answer);/*按照规则回复200OK*/
            dbg("eXosip_call_send_answer success!\r\n");
            paraseInfoBody(g_event);/*解析INFO的RTSP消息体*/
          }
        }
      }
      break;
    case EXOSIP_CALL_MESSAGE_ANSWERED:/*200OK*/
      {
        /*历史视音频回放*/
        /*文件结束时发送MESSAGE(File to end)的应答*/
        dbg("\r\n<EXOSIP_CALL_MESSAGE_ANSWERED>\r\n");
      }
      break;
      /*其它不感兴趣的消息*/
    default:
      {
        dbg("\r\n<OTHER>\r\n");
        dbg("eXosip event type:%d\n", g_event->type);
      }
      break;
    }
  }
}

void*
LSMXGb28181Client::processEvent(void *arg){
  LSMXGb28181Client *mGb28181Client = (LSMXGb28181Client*)arg;
  while(mGb28181Client->threadStatus){
    if (mGb28181Client->sendRegister(3600) == false){   //向服务器注册
      printf("processEvent pthread false\r\n");
    }else{
    printf("mGb28181Client->processEventDispose() ................ END\r\n ");
      mGb28181Client->processEventDispose();
    }
    printf("mGb28181Client->processEventDispose() ................ END\r\n ");
    if(mGb28181Client->threadStatus == false){    //停止线程标志位
      printf("processEvent pthread END\r\n ");
      pthread_exit((void*)"processEvent pthread_exit!"); 
    }
  }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值