freeDiameter - 事件时间戳

freeDiameter - Event-Timestamp

我刚刚有一个关于 "Event-Timestamp" AVP 的问题。

我知道我应该把纪元时间放在那里,但我主要关心它的格式,这是我目前在 RFC 中找到的格式:

8.21.  Event-Timestamp AVP

 The Event-Timestamp (AVP Code 55) is of type Time, and MAY be
 included in an Accounting-Request and Accounting-Answer messages to
 record the time that the reported event occurred, in seconds since
 January 1, 1900 00:00 UTC.


Time
  The Time format is derived from the OctetString AVP Base Format.
  The string MUST contain four octets, in the same format as the
  first four bytes are in the NTP timestamp format.  The NTP
  Timestamp format is defined in chapter 3 of [SNTP].

  This represents the number of seconds since 0h on 1 January 1900
  with respect to the Coordinated Universal Time (UTC).

  On 6h 28m 16s UTC, 7 February 2036 the time value will overflow.
  SNTP [SNTP] describes a procedure to extend the time to 2104.
  This procedure MUST be supported by all DIAMETER nodes.

所以,问题是我应该先获取系统当前时间(以纪元格式),然后将其转换为字符串并直接传递给 Event-Timestamp 吗?

但是标准说:“The string MUST contain four octets”。

我不知道如何实现...请详细说明一下好吗?

嗯,RFC 应该是 re-strictly 后跟 :) 将纪元时间转换为字节(长度 = 4)就成功了。

更新: 它并没有真正解决:/

我的意思是现在,从 AVP 格式的角度来看消息没问题..但是时间不正确..

我使用下面的代码创建纪元时间并转换为字节数组:

time_t t = time(NULL);
tm tmp;
tmp.tm_isdst = -1;
tmp = *localtime( &t );
time_t t2 = mktime( &tmp );

bytes[0] = (t2 >> 24) & 0xFF;
bytes[1] = (t2 >> 16) & 0xFF;
bytes[2] = (t2 >> 8) & 0xFF;
bytes[3] = t2 & 0xFF;

但是正如您在下面的屏幕截图中看到的,时间实际上是不正确的:

你能告诉我我做错了什么吗?

谢谢

"fd_dictfct_Time_encode" 函数就是答案:)

好吧,这里的问题是您正在阅读的 RFC 中有一个参考链接到 NTP rfc 以定义 NTP 时间戳。

NTP 时间戳的前 4 个字节显示从纪元到获取时间戳的时间的整数部分(以秒为单位)。

time(2)函数给你一个time_t值(有的架构是64位的time_t,有的是32位的,你要能知道你是哪一个) 但时代不同。这就是你做的不好。 NTP 中的纪元是 00:00h 1st/jan/1900,在 UNIX 中是 00:00h 1st/jan/1970 ,因此您必须以秒为单位更正该差异以补偿这 70 年的差异。

要将 unix time() 时间转换为 NTP 秒,您必须添加常量 2208988800U(注意,因为此常量在 32 位架构中必须是无符号的,因为它具有 msb on,不被解释为负值)到 time_t 值,或者在 64 位模式下进行计算。

所以,最后,您的代码应该是:

time_t t = time(NULL);
time_t t2 = t + 2208988800UL;

bytes[0] = (t2 >> 24) & 0xFF;
bytes[1] = (t2 >> 16) & 0xFF;
bytes[2] = (t2 >> 8) & 0xFF;
bytes[3] = t2 & 0xFF;

(因为两个时间戳都是 UTC,不需要本地转换)