reSIProcate实现GB28181服务——修改Date头域为GB28181格式

本文档详细介绍了在reSIProcate中如何修改源码以支持国标日期时间格式。主要修改了Symbols头文件、DateCategory头文件和源文件,增加了对国标时间格式的解析和编码,并提供了示例代码展示如何使用新添加的功能。
摘要由CSDN通过智能技术生成

reSIProcate的时间格式

reSIProcate的Date时间格式和国标的不一致,reSIProcate的格式一般为“Mon, 04 Nov 2002 17:34:15 GMT”,显示的格林威治时间,国标规定的事件格式为“2022-03-10T11:11:11.123”,显示的一般是本地时间。

我的方案

我的修改方案是在reSIProcate的源码中增加一个if分支,通过if分支来判断哪种时间格式,如有更好的方案或错误望交流指正。涉及修改的文件如下:
涉及修改的文件

修改的方法

1、修改Symbols头文件和源文件,增加‘T’的字符定义
头文件:
在这里插入图片描述
源文件:
在这里插入图片描述
2、修改DateCategory头文件,增加时间格式类型的枚举类型,并修改构造函数,增加默认的时间格式参数
(1)增加枚举定义:
在这里插入图片描述
(2)修改构造函数,默认还是原来的格式:
在这里插入图片描述
3、修改DateCategory源文件,增加国标的处理逻辑
(1)修改构造函数,增加参数后对应的修改

DateCategory::DateCategory(DateType dateType)
   : ParserCategory(),
     mDayOfWeek(Sun),
     mDayOfMonth(),
     mMonth(Jan),
     mYear(0),
     mHour(0),
     mMin(0),
     mSec(0),
     mMillisec(0),
     mDateType(dateType)
{
   time_t now;
   time(&now);
   if (now == ((time_t)-1))
   {
      int e = getErrno();
      DebugLog (<< "Failed to get time: " << strerror(e));
      Transport::error(e);
      return;
   }
   
   setDatetime(now);
}

DateCategory::DateCategory(time_t datetime,
                           DateType dateType)
   : ParserCategory(),
     mDayOfWeek(Sun),
     mDayOfMonth(),
     mMonth(Jan),
     mYear(0),
     mHour(0),
     mMin(0),
     mSec(0),
     mMillisec(0),
     mDateType(dateType)
{
   setDatetime(datetime);
}

DateCategory::DateCategory(const HeaderFieldValue& hfv, 
                           Headers::Type type,
                           PoolBase* pool,
                           DateType dateType)
   : ParserCategory(hfv, type, pool),
     mDayOfWeek(Sun),
     mDayOfMonth(),
     mMonth(Jan),
     mYear(0),
     mHour(0),
     mMin(0),
     mSec(0),
     mMillisec(0),
     mDateType(dateType)
{}

DateCategory::DateCategory(const DateCategory& rhs,
                           PoolBase* pool)
   : ParserCategory(rhs, pool),
     mDayOfWeek(rhs.mDayOfWeek),
     mDayOfMonth(rhs.mDayOfMonth),
     mMonth(rhs.mMonth),
     mYear(rhs.mYear),
     mHour(rhs.mHour),
     mMin(rhs.mMin),
     mSec(rhs.mSec),
     mMillisec(rhs.mMillisec),
     mDateType(rhs.mDateType)
{}

DateCategory&
DateCategory::operator=(const DateCategory& rhs)
{
   if (this != &rhs)
   {
      ParserCategory::operator=(rhs);
      mDayOfWeek = rhs.mDayOfWeek;
      mDayOfMonth = rhs.mDayOfMonth;
      mMonth = rhs.mMonth;
      mYear = rhs.mYear;
      mHour = rhs.mHour;
      mMin = rhs.mMin;
      mSec = rhs.mSec;
      mMillisec = rhs.mMillisec,
      mDateType = rhs.mDateType;
   }
   return *this;
}

(2)setDatetime添加获取本地时间的逻辑

bool 
DateCategory::setDatetime(time_t datetime)
{
   struct tm gmt;
#if defined(WIN32) || defined(__sun)
   struct tm *gmtp=nullptr;
   if(mDateType == reSIPDate)
     gmtp = gmtime(&datetime);
   else
     gmtp = localtime(&datetime);
   if (gmtp == 0)
   {
        int e = getErrno();
        DebugLog (<< "Failed to convert to gmt: " << strerror(e));
        Transport::error(e);
        return false;
   }
   memcpy(&gmt,gmtp,sizeof(gmt));
#else
   if (mDateType == reSIPDate)
   {
     if (gmtime_r(&datetime, &gmt) == 0)
     {
       int e = getErrno();
       DebugLog(<< "Failed to convert to gmt: " << strerror(e));
       Transport::error(e);
       return false;
     }
   }
   else
   {
      if (localtime_r(&datetime, &gmt) == 0)
      {
         int e = getErrno();
         DebugLog(<< "Failed to convert to gmt: " << strerror(e));
         Transport::error(e);
         return false;
      }
   }
#endif

   mDayOfWeek = static_cast<DayOfWeek>(gmt.tm_wday);
   mDayOfMonth = gmt.tm_mday;
   mMonth = static_cast<Month>(gmt.tm_mon);
   mYear = gmt.tm_year + 1900;
   mHour = gmt.tm_hour;
   mMin = gmt.tm_min;
   mSec = gmt.tm_sec;
   DebugLog (<< "Set date: day=" << mDayOfWeek 
             << " month=" << mMonth
             << " year=" << mYear
             << " " << mHour << ":" << mMin << ":" << mSec);
   return true;
}

(3)修改parse函数,添加解析国标格式的逻辑(未验证)

void
DateCategory::parse(ParseBuffer& pb)
{
   if (mDateType == reSIPDate)
   {
     // Mon, 04 Nov 2002 17:34:15 GMT
     // Note: Day of Week is optional, so this is also valid: 04 Nov 2002 17:34:15 GMT

     const char* anchor = pb.skipWhitespace();

     // If comma is present, then DayOfWeek is present
     pb.skipToChar(Symbols::COMMA[0]);
     if (!pb.eof())
     {
        Data dayOfWeek;
        pb.data(dayOfWeek, anchor);
        mDayOfWeek = DateCategory::DayOfWeekFromData(dayOfWeek);

        pb.skipChar(Symbols::COMMA[0]);
     }
     else
     {
        pb.reset(pb.start());
        mDayOfWeek = DayOfWeek::NA;
     }

     pb.skipWhitespace();

     mDayOfMonth = pb.integer();

     anchor = pb.skipWhitespace();
     pb.skipNonWhitespace();

     Data month;
     pb.data(month, anchor);
     mMonth = DateCategory::MonthFromData(month);

     pb.skipWhitespace();
     mYear = pb.integer();

     pb.skipWhitespace();

     mHour = pb.integer();
     pb.skipChar(Symbols::COLON[0]);
     mMin = pb.integer();
     pb.skipChar(Symbols::COLON[0]);
     mSec = pb.integer();

     pb.skipWhitespace();
     pb.skipChar('G');
     pb.skipChar('M');
     pb.skipChar('T');
   } 
   else 
   {
     //Date: 2022-02-25T15:22:41.380
     const char* anchor = pb.skipWhitespace();
     mYear = pb.integer();
     pb.skipChar(Symbols::DASH[0]);
  
     mMonth = (Month)pb.integer();
     pb.skipChar(Symbols::DASH[0]);

     mDayOfMonth = pb.integer();
     pb.skipChar(Symbols::GBTIMET[0]);

     mHour = pb.integer();
     pb.skipChar(Symbols::COLON[0]);

     mMin = pb.integer();
     pb.skipChar(Symbols::COLON[0]);

     mSec = pb.integer();
     pb.skipChar(Symbols::DOT[0]);

     mMillisec = pb.integer();
   }
   pb.skipWhitespace();
   pb.assertEof();
}

(4)添加填充3个占位的处理,修改encodeParsed,添加时间格式生成代码(已验证)

static void pad3(const int x, EncodeStream& str)
{
   if (x < 100)
   {
      str << resip::Symbols::ZERO[0];
      if (x < 10)
      {
         str << resip::Symbols::ZERO[0];
      }
   }
   str << x;
}

EncodeStream& 
DateCategory::encodeParsed(EncodeStream& str) const
{
   if (mDateType == reSIPDate)
   {
     if (mDayOfWeek != DayOfWeek::NA)
     {
       str << DayOfWeekData[mDayOfWeek] // Mon
           << Symbols::COMMA[0] << Symbols::SPACE[0];
     }

     pad2(mDayOfMonth, str);  //  04

     str << Symbols::SPACE[0]
        << MonthData[mMonth] << Symbols::SPACE[0] // Nov
        << mYear << Symbols::SPACE[0]; // 2002

     pad2(mHour, str);
     str << Symbols::COLON[0];
     pad2(mMin, str);
     str << Symbols::COLON[0];
     pad2(mSec, str);
     str << " GMT";
   }
   else
   {
     pad2(this->year(), str);
     str << Symbols::DASH[0];
     pad2(this->month(), str);
     str << Symbols::DASH[0];
     pad2(this->dayOfMonth(), str);
     str << Symbols::GBTIMET[0];
     pad2(this->hour(), str);
     str << Symbols::COLON[0];
     pad2(this->minute(), str);
     str << Symbols::COLON[0];
     pad2(this->second(), str);
     str << Symbols::DOT[0];
     pad3(0, str);
   }
    return str;
}

使用方法

代码片段示例,详情参考https://blog.csdn.net/qq_24022755/article/details/121862063

resip::SipMessage success;
resip::Helper::makeResponse(success, reg, 200);
if (!reg.empty(resip::h_Paths))
{
   success.header(resip::h_Paths) = reg.header(resip::h_Paths);
   success.header(resip::h_Supporteds).push_back(resip::Token(resip::Symbols::Path));
}
//添加国标格式Date
resip::DateCategory curTime(resip::GB28181Date);
success.header(resip::h_Date) = curTime;
sr->accept(success);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值