编写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, ®);
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, ®);
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!");
}
}
}