1 /* 2 * Copyright (c) 2013-2016 Cisco Systems, Inc. and others. All rights reserved. 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Public License v1.0 which accompanies this distribution, 6 * and is available at http://www.eclipse.org/legal/epl-v10.html 7 * 8 */ 9 10 #ifndef MSGBUSINTERFACE_HPP_ 11 #define MSGBUSINTERFACE_HPP_ 12 13 #include <sys/types.h> 14 #include <stdint.h> 15 #include <vector> 16 #include <list> 17 #include <string> 18 #include <cstdio> 19 #include <ctime> 20 #include <sys/time.h> 21 22 /** 23 * \class MsgBusInterface 24 * 25 * \brief Abstract class for the message bus interface. 26 * \details Internal memory schema and all expected methods are 27 * defined here. 28 * 29 * It is required that the implementing class follow the 30 * internal schema to store the data as needed. 31 */ 32 class MsgBusInterface { 33 public: 34 35 /* --------------------------------------------------------------------------- 36 * Msg data schema 37 * --------------------------------------------------------------------------- 38 */ 39 uint64_t ribSeq; ///< RIB Message Seq 40 41 /** 42 * OBJECT: collector 43 * 44 * Router table schema 45 */ 46 struct obj_collector { 47 u_char hash_id[16]; ///< Hash ID for collector (is the unique ID) 48 char admin_id[64]; ///< Admin ID for collector 49 u_char descr[255]; ///< Description of collector 50 51 char routers[4096]; ///< List of connected routers hash ID's delimited by PIPE 52 uint32_t router_count; ///< Count of active/connected routers 53 uint32_t timestamp_secs; ///< Timestamp in seconds since EPOC 54 uint32_t timestamp_us; ///< Timestamp microseconds 55 }; 56 57 /// Collector action codes 58 enum collector_action_code { 59 COLLECTOR_ACTION_STARTED =0, 60 COLLECTOR_ACTION_CHANGE, 61 COLLECTOR_ACTION_HEARTBEAT, 62 COLLECTOR_ACTION_STOPPED, 63 }; 64 65 /** 66 * OBJECT: routers 67 * 68 * Router table schema 69 */ 70 struct obj_router { 71 u_char hash_id[16]; ///< Router hash ID of name and src_addr 72 uint16_t hash_type; ///< Router hash type 0:IP, 1:router_name, 2:bgp_id 73 u_char name[255]; ///< BMP router sysName (initiation Type=2) 74 u_char descr[255]; ///< BMP router sysDescr (initiation Type=1) 75 u_char ip_addr[46]; ///< BMP router source IP address in printed form 76 char bgp_id[16]; ///< BMP Router bgp-id 77 uint32_t asn; ///< BMP router ASN 78 uint16_t term_reason_code; ///< BMP termination reason code 79 char term_reason_text[255]; ///< BMP termination reason text decode string 80 81 char term_data[4096]; ///< Type=0 String termination info data 82 char initiate_data[4096]; ///< Type=0 String initiation info data 83 uint32_t timestamp_secs; ///< Timestamp in seconds since EPOC 84 uint32_t timestamp_us; ///< Timestamp microseconds 85 }; 86 87 /// Router action codes 88 enum router_action_code { 89 ROUTER_ACTION_FIRST=0, 90 ROUTER_ACTION_INIT, 91 ROUTER_ACTION_TERM 92 93 }; 94 95 /** 96 * OBJECT: bgp_peers 97 * 98 * BGP peer table schema 99 */ 100 struct obj_bgp_peer { 101 u_char hash_id[16]; ///< hash of router hash_id, peer_rd, peer_addr, and peer_bgp_id 102 u_char router_hash_id[16]; ///< Router hash ID 103 u_char table_name[255]; ///< Table/VRF name (Info TLV=3) 104 105 char peer_rd[32]; ///< Peer distinguisher ID (string/printed format) 106 char peer_addr[46]; ///< Peer IP address in printed form 107 char peer_bgp_id[16]; ///< Peer BGP ID in printed form 108 uint32_t peer_as; ///< Peer ASN 109 bool isL3VPN; ///< true if peer is L3VPN, otherwise it is Global 110 bool isPrePolicy; ///< True if the routes are pre-policy, false if not 111 bool isAdjIn; ///< True if the routes are Adj-Rib-In, false if not 112 bool isLocRib; ///< True if local RIB 113 bool isLocRibFiltered; ///< True if the local rib is filtered 114 bool isIPv4; ///< true if peer is IPv4 or false if IPv6 115 bool isTwoOctet; ///< Indicates if peer is using 2 octet encoding 116 uint32_t timestamp_secs; ///< Timestamp in seconds since EPOC 117 uint32_t timestamp_us; ///< Timestamp microseconds 118 }; 119 120 /** 121 * OBJECT: peer_down_events 122 * 123 * Peer Down Events schema 124 */ 125 struct obj_peer_down_event { 126 u_char bmp_reason; ///< BMP notify reason 127 u_char bgp_err_code; ///< BGP notify error code 128 u_char bgp_err_subcode; ///< BGP notify error sub code 129 char error_text[255]; ///< BGP error text string 130 }; 131 132 /** 133 * OBJECT: peer_up_events 134 * 135 * Peer Up Events schema 136 * 137 * \note open_params are the decoded values in string/text format; e.g. "attr=value ..." 138 * Numeric values are converted to printed form. The buffer itself is 139 * allocated by the caller and freed by the caller. 140 */ 141 struct obj_peer_up_event { 142 char info_data[4096]; ///< Inforamtional data for peer 143 char local_ip[40]; ///< IPv4 or IPv6 printed IP address 144 uint16_t local_port; ///< Local port number 145 uint32_t local_asn; ///< Local ASN for peer 146 uint16_t local_hold_time; ///< BGP hold time 147 char local_bgp_id[16]; ///< Local BGP ID in printed form 148 uint32_t remote_asn; ///< Remote ASN for peer 149 uint16_t remote_port; ///< Remote port number 150 uint16_t remote_hold_time; ///< BGP hold time 151 char remote_bgp_id[16]; ///< Remote Peer BGP ID in printed form 152 153 char sent_cap[4096]; ///< Received Open param capabilities 154 char recv_cap[4096]; ///< Received Open param capabilities 155 }; 156 157 158 /// Peer action codes 159 enum peer_action_code { 160 PEER_ACTION_FIRST=0, 161 PEER_ACTION_UP, 162 PEER_ACTION_DOWN 163 }; 164 165 /** 166 * OBJECT: path_attrs 167 * 168 * Prefix Path attributes table schema 169 */ 170 struct obj_path_attr { 171 172 /** 173 * Path hash 174 */ 175 u_char hash_id[16]; 176 char origin[16]; ///< bgp origin as string name 177 178 /** 179 * as_path. 180 */ 181 std::string as_path; 182 183 uint16_t as_path_count; ///< Count of AS PATH's in the path (includes all in AS-SET) 184 185 uint32_t origin_as; ///< Origin ASN 186 bool nexthop_isIPv4; ///< True if IPv4, false if IPv6 187 char next_hop[40]; ///< Next-hop IP in printed form 188 char aggregator[40]; ///< Aggregator IP in printed form 189 bool atomic_agg; ///< 0=false, 1=true for atomic_aggregate 190 191 uint32_t med; ///< bgp MED 192 uint32_t local_pref; ///< bgp local pref 193 194 /** 195 * standard community list. 196 */ 197 std::string community_list; 198 199 /** 200 * extended community list. 201 */ 202 std::string ext_community_list; 203 204 /** 205 * large community list 206 */ 207 std::string large_community_list; 208 209 210 /** 211 * cluster list. 212 */ 213 std::string cluster_list; 214 215 char originator_id[16]; ///< Originator ID in printed form 216 }; 217 218 /// Base attribute action codes 219 enum base_attr_action_code { 220 BASE_ATTR_ACTION_ADD=0 221 }; 222 223 /** 224 * OBJECT: rib 225 * 226 * Prefix rib table schema 227 */ 228 struct obj_rib { 229 u_char hash_id[16]; ///< hash of attr hash prefix, and prefix len 230 u_char path_attr_hash_id[16]; ///< path attrs hash_id 231 u_char peer_hash_id[16]; ///< BGP peer hash ID, need it here for withdraw routes support 232 u_char isIPv4; ///< 0 if IPv6, 1 if IPv4 233 char prefix[46]; ///< IPv4/IPv6 prefix in printed form 234 u_char prefix_len; ///< Length of prefix in bits 235 uint8_t prefix_bin[16]; ///< Prefix in binary form 236 uint8_t prefix_bcast_bin[16]; ///< Broadcast address/last address in binary form 237 uint32_t path_id; ///< Add path ID - zero if not used 238 char labels[255]; ///< Labels delimited by comma 239 }; 240 241 /// Rib extended with Route Distinguisher 242 struct obj_route_distinguisher { 243 std::string rd_administrator_subfield; 244 std::string rd_assigned_number; 245 uint8_t rd_type; 246 }; 247 248 /// Rib extended with vpn specific fields 249 struct obj_vpn: obj_rib, obj_route_distinguisher { 250 // inherit 251 }; 252 253 /// Rib extended with evpn specific fields 254 struct obj_evpn: obj_rib, obj_route_distinguisher { 255 uint8_t originating_router_ip_len; 256 char originating_router_ip[46]; 257 char ethernet_segment_identifier[255]; 258 char ethernet_tag_id_hex[16]; 259 uint8_t mac_len; 260 char mac[255]; 261 uint8_t ip_len; 262 char ip[46]; 263 int mpls_label_1; 264 int mpls_label_2; 265 }; 266 267 /// Unicast prefix action codes 268 enum unicast_prefix_action_code { 269 UNICAST_PREFIX_ACTION_ADD=0, 270 UNICAST_PREFIX_ACTION_DEL, 271 }; 272 273 /// Vpn action codes 274 enum vpn_action_code { 275 VPN_ACTION_ADD=0, 276 VPN_ACTION_DEL, 277 }; 278 279 /** 280 * OBJECT: stats_reports 281 * 282 * Stats Report schema 283 */ 284 struct obj_stats_report { 285 uint32_t prefixes_rej; ///< type=0 Prefixes rejected 286 uint32_t known_dup_prefixes; ///< type=1 known duplicate prefixes 287 uint32_t known_dup_withdraws; ///< type=2 known duplicate withdraws 288 uint32_t invalid_cluster_list; ///< type=3 Updates invalid by cluster lists 289 uint32_t invalid_as_path_loop; ///< type=4 Updates invalid by as_path loop 290 uint32_t invalid_originator_id; ///< type=5 Invalid due to originator_id 291 uint32_t invalid_as_confed_loop; ///< type=6 Invalid due to as_confed loop 292 uint64_t routes_adj_rib_in; ///< type=7 Number of routes in adj-rib-in 293 uint64_t routes_loc_rib; ///< type=8 number of routes in loc-rib 294 }; 295 296 /** 297 * OBJECT: ls_node 298 * 299 * BGP-LS Node table schema 300 */ 301 struct obj_ls_node { 302 u_char hash_id[16]; ///< hash id for the entry 303 uint64_t id; ///< Routing universe identifier 304 bool isIPv4; ///< True if interface/neighbor is IPv4, false otherwise 305 uint32_t asn; ///< BGP ASN 306 uint32_t bgp_ls_id; ///< BGP-LS Identifier 307 uint8_t igp_router_id[8]; ///< IGP router ID 308 uint8_t ospf_area_Id[4]; ///< OSPF area ID 309 char protocol[32]; ///< String representation of the protocol name 310 uint8_t router_id[16]; ///< IPv4 or IPv6 router ID 311 uint8_t isis_area_id[9]; ///< IS-IS area ID 312 char flags[32]; ///< String representation of the flag bits 313 char name[255]; ///< Name of router 314 char mt_id[255]; ///< Multi-Topology ID 315 char sr_capabilities_tlv[255]; ///< SR Capabilities TLV 316 }; 317 318 /// LS action code (node, link, and prefix) 319 enum ls_action_code { 320 LS_ACTION_ADD=0, 321 LS_ACTION_DEL 322 }; 323 324 /** 325 * OBJECT: ls_link 326 * 327 * BGP-LS Link table schema 328 */ 329 struct obj_ls_link { 330 u_char hash_id[16]; ///< hash id for the entry 331 uint64_t id; ///< Routing universe identifier 332 uint32_t mt_id; ///< Multi-Topology ID 333 334 uint32_t bgp_ls_id; ///< BGP-LS Identifier 335 uint8_t igp_router_id[8]; ///< IGP router ID (local) 336 uint8_t remote_igp_router_id[8]; ///< IGP router ID (remote) 337 uint8_t ospf_area_Id[4]; ///< OSPF area ID 338 uint8_t router_id[16]; ///< IPv4 or IPv6 router ID (local) 339 uint8_t remote_router_id[16]; ///< IPv4 or IPv6 router ID (remote) 340 341 uint32_t local_node_asn; ///< Local node asn 342 uint32_t remote_node_asn; ///< Remote node asn 343 uint32_t local_bgp_router_id; ///< Local BGP router id (draft-ietf-idr-bgpls-segment-routing-epe) 344 uint32_t remote_bgp_router_id; ///< Remote BGP router id (draft-ietf-idr-bgpls-segment-routing-epe) 345 346 uint8_t isis_area_id[9]; ///< IS-IS area ID 347 348 char protocol[32]; ///< String representation of the protocol name 349 uint8_t intf_addr[16]; ///< Interface binary address 350 uint8_t nei_addr[16]; ///< Neighbor binary address 351 uint32_t local_link_id; ///< Local Link ID (IS-IS) 352 uint32_t remote_link_id; ///< Remote Link ID (IS-IS) 353 bool isIPv4; ///< True if interface/neighbor is IPv4, false otherwise 354 u_char local_node_hash_id[16]; ///< Local node hash ID 355 u_char remote_node_hash_id[16]; ///< Remove node hash ID 356 uint32_t admin_group; ///< Admin group 357 uint32_t max_link_bw; ///< Maximum link bandwidth 358 uint32_t max_resv_bw; ///< Maximum reserved bandwidth 359 char unreserved_bw[100]; ///< string for unreserved bandwidth, a set of 8 uint32_t values 360 361 uint32_t te_def_metric; ///< Default TE metric 362 char protection_type[60]; ///< String representation for the protection types 363 char mpls_proto_mask[32]; ///< Either LDP or RSVP-TE 364 uint32_t igp_metric; ///< IGP metric 365 char srlg[128]; ///< String representation of the shared risk link group values 366 char name[255]; ///< Name of router 367 char peer_node_sid[128]; ///< Peer node side (draft-ietf-idr-bgpls-segment-routing-epe) 368 char peer_adj_sid[128]; ///< Peer Adjency Segment Identifier 369 }; 370 371 /** 372 * OBJECT: ls_prefix 373 * 374 * BGP-LS Prefix table schema 375 */ 376 struct obj_ls_prefix { 377 u_char hash_id[16]; ///< hash for the entry 378 uint64_t id; ///< Routing universe identifier 379 char protocol[32]; ///< String representation of the protocol name 380 381 uint32_t bgp_ls_id; ///< BGP-LS Identifier 382 uint8_t igp_router_id[8]; ///< IGP router ID 383 uint8_t ospf_area_Id[4]; ///< OSPF area ID 384 uint8_t router_id[16]; ///< IPv4 or IPv6 router ID 385 uint8_t isis_area_id[9]; ///< IS-IS area ID 386 uint8_t intf_addr[16]; ///< Interface binary address 387 uint8_t nei_addr[16]; ///< Neighbor binary address 388 389 u_char local_node_hash_id[16]; ///< Local node hash ID 390 uint32_t mt_id; ///< Multi-Topology ID 391 uint32_t metric; ///< Prefix metric 392 bool isIPv4; ///< True if interface/neighbor is IPv4, false otherwise 393 u_char prefix_len; ///< Length of prefix in bits 394 char ospf_route_type[32]; ///< String representation of the OSPF route type 395 uint8_t prefix_bin[16]; ///< Prefix in binary form 396 uint8_t prefix_bcast_bin[16]; ///< Broadcast address/last address in binary form 397 char igp_flags[32]; ///< String representation of the IGP flags 398 uint32_t route_tag; ///< Route tag 399 uint64_t ext_route_tag; ///< Extended route tag 400 uint8_t ospf_fwd_addr[16]; ///< IPv4/IPv6 OSPF forwarding address 401 char sid_tlv[128]; ///< Prefix-SID TLV 402 }; 403 404 /* --------------------------------------------------------------------------- 405 * Abstract methods 406 * --------------------------------------------------------------------------- 407 */ ~MsgBusInterface()408 virtual ~MsgBusInterface() { }; 409 410 /*****************************************************************//** 411 * \brief Add/Update/del a collector object 412 * 413 * \details Will generate a message for a new/updated collector. 414 * 415 * \param[in,out] collector Collector object 416 * 417 * \returns collector.hash_id will be updated based on the supplied data. 418 */ 419 virtual void update_Collector(struct obj_collector &c_obj, collector_action_code action_code) = 0; 420 421 /*****************************************************************//** 422 * \brief Add/Update a router object 423 * 424 * \details Will generate a message to add a new router or update an existing 425 * router. 426 * 427 * \param[in,out] router Router object 428 * \param[in] code Action code for router update 429 * 430 * \returns The router.hash_id will be updated based on the 431 * supplied data. 432 * 433 * \note Caller must free any allocated memory, which is 434 * safe to do so when this method returns. 435 *****************************************************************/ 436 virtual void update_Router(struct obj_router &r_object, router_action_code code) = 0; 437 438 /*****************************************************************//** 439 * \brief Add/Update a BGP peer object 440 * 441 * \details Will generate a message to add a new BGP peer 442 * 443 * \param[in,out] peer BGP peer object 444 * \param[in] peer_up_event Peer up event struct (null if not used) 445 * \param[in] peer_down_event Peer down event struct (null if not used) 446 * \param[in] code Action code for router update 447 * 448 * \returns The peer.hash_id will be updated based on the 449 * supplied data. 450 * 451 * \note Caller must free any allocated memory, which is 452 * safe to do so when this method returns. 453 ****************************************************************/ 454 virtual void update_Peer(obj_bgp_peer &peer, obj_peer_up_event *up, obj_peer_down_event *down, peer_action_code code) = 0; 455 456 /*****************************************************************//** 457 * \brief Add/Update base path attributes 458 * 459 * \details Will generate a message to add a new path object. 460 * 461 * \param[in] peer Peer object 462 * \param[in,out] attr Path attribute object 463 * \param[in] code Base attribute action code 464 * 465 * \returns The path.hash_id will be updated based on the 466 * supplied data. 467 * 468 * \note Caller must free any allocated memory, which is 469 * safe to do so when this method returns. 470 *****************************************************************/ 471 virtual void update_baseAttribute(obj_bgp_peer &peer, obj_path_attr &attr, base_attr_action_code code) = 0; 472 473 /*****************************************************************//** 474 * \brief Add/Update RIB objects 475 * 476 * \details Will generate a message to add new RIB prefixes 477 * 478 * \param[in] peer Peer object 479 * \param[in,out] rib List of one or more RIB entries 480 * \param[in] attr Path attribute object (can be null if n/a) 481 * \param[in] code Unicast prefix action code 482 * 483 * \returns The rib.hash_id will be updated based on the 484 * supplied data for each object. 485 * 486 * \note Caller must free any allocated memory, which is 487 * safe to do so when this method returns. 488 *****************************************************************/ 489 virtual void update_unicastPrefix(obj_bgp_peer &peer, std::vector<obj_rib> &rib, obj_path_attr *attr, 490 unicast_prefix_action_code code) = 0; 491 492 /*****************************************************************//** 493 * \brief Add/Update vpn objects 494 * 495 * \details Will generate a message to add new vpn objects 496 * 497 * \param[in] peer Peer object 498 * \param[in,out] rib List of one or more RIB entries 499 * \param[in] attr Path attribute object (can be null if n/a) 500 * \param[in] code Vpn action code 501 * 502 * \returns The vpn.hash_id will be updated based on the 503 * supplied data for each object. 504 * 505 * \note Caller must free any allocated memory, which is 506 * safe to do so when this method returns. 507 *****************************************************************/ 508 virtual void update_L3Vpn(obj_bgp_peer &peer, std::vector<obj_vpn> &vpn, obj_path_attr *attr, 509 vpn_action_code code) = 0; 510 511 /*****************************************************************//** 512 * \brief Add/Update evpn objects 513 * 514 * \details Will generate a message to add new evpn objects 515 * 516 * \param[in] peer Peer object 517 * \param[in,out] rib List of one or more RIB entries 518 * \param[in] attr Path attribute object (can be null if n/a) 519 * \param[in] code Vpn action code 520 * 521 * \returns The vpn.hash_id will be updated based on the 522 * supplied data for each object. 523 * 524 * \note Caller must free any allocated memory, which is 525 * safe to do so when this method returns. 526 *****************************************************************/ 527 virtual void update_eVPN(obj_bgp_peer &peer, std::vector<obj_evpn> &vpn, obj_path_attr *attr, 528 vpn_action_code code) = 0; 529 530 /*****************************************************************//** 531 * \brief Add a stats report object 532 * 533 * \details Will generate a message to add a new stats report object. 534 * 535 * \param[in,out] stats Stats report object 536 *****************************************************************/ 537 virtual void add_StatReport(obj_bgp_peer &peer, obj_stats_report &stats) = 0; 538 539 /*****************************************************************//** 540 * \brief Add/Update BGP-LS nodes 541 * 542 * \details Will generate a message to add/update BGP-LS nodes. 543 * 544 * \param[in] peer Peer object 545 * \param[in] attr Path attribute object 546 * \param[in] nodes List of one or more node tables 547 * \param[in] code Linkstate action code 548 *****************************************************************/ 549 virtual void update_LsNode(obj_bgp_peer &peer, obj_path_attr &attr, 550 std::list<MsgBusInterface::obj_ls_node> &nodes, 551 ls_action_code code) = 0; 552 553 /*****************************************************************//** 554 * \brief Add/Update BGP-LS links 555 * 556 * \details Will generate a message to add/update BGP-LS links. 557 * 558 * \param[in] peer Peer object 559 * \param[in] attr Path attribute object 560 * \param[in] links List of one or more link tables 561 * \param[in] code Linkstate action code 562 * 563 * \returns The hash_id will be updated based on the 564 * supplied data for each object. 565 *****************************************************************/ 566 virtual void update_LsLink(obj_bgp_peer &peer, obj_path_attr &attr, 567 std::list<MsgBusInterface::obj_ls_link> &links, 568 ls_action_code code) = 0; 569 570 /*****************************************************************//** 571 * \brief Add/Update BGP-LS prefixes 572 * 573 * \details Will generate a message to add/update BGP-LS prefixes. 574 * 575 * \param[in] peer Peer object 576 * \param[in] attr Path attribute object 577 * \param[in/out] prefixes List of one or more node tables 578 * \param[in] code Linkstate action code 579 * 580 * \returns The hash_id will be updated based on the 581 * supplied data for each object. 582 *****************************************************************/ 583 virtual void update_LsPrefix(obj_bgp_peer &peer, obj_path_attr &attr, 584 std::list<MsgBusInterface::obj_ls_prefix> &prefixes, 585 ls_action_code code) = 0; 586 587 /*****************************************************************//** 588 * \brief Send BMP packet 589 * 590 * \details Will generate a message to send the BMP packet data/feed 591 * 592 * \param[in] r_hash Router hash 593 * \param[in] peer Peer object 594 * \param[in] data Packet raw data 595 * \param[in] data_len Length in bytes for the raw data 596 * 597 * \returns The hash_id will be updated based on the 598 * supplied data for each object. 599 *****************************************************************/ 600 virtual void send_bmp_raw(u_char *r_hash, obj_bgp_peer &peer, u_char *data, size_t data_len) = 0; 601 602 603 /* --------------------------------------------------------------------------- 604 * Commonly used methods 605 * --------------------------------------------------------------------------- 606 */ 607 608 /** 609 * \brief binary hash to printed string format 610 * 611 * \details Converts a hash unsigned char bytes to HEX string for 612 * printing or storing in the DB. 613 * 614 * \param[in] hash_bin 16 byte binary/unsigned value 615 * \param[out] hash_str Reference to storage of string value 616 * 617 */ hash_toStr(const u_char * hash_bin,std::string & hash_str)618 static void hash_toStr(const u_char *hash_bin, std::string &hash_str){ 619 620 int i; 621 char s[33]; 622 623 for (i=0; i<16; i++) 624 sprintf(s+i*2, "%02x", hash_bin[i]); 625 626 s[32]='\0'; 627 628 hash_str = s; 629 } 630 631 /** 632 * \brief Time in seconds to printed string format 633 * 634 * \param[in] time_secs Time since epoch in seconds 635 * \param[in] time_us Microseconds to add to timestamp 636 * \param[out] ts_str Reference to storage of string value 637 * 638 */ getTimestamp(uint32_t time_secs,uint32_t time_us,std::string & ts_str)639 void getTimestamp(uint32_t time_secs, uint32_t time_us, std::string &ts_str){ 640 char buf[48]; 641 timeval tv; 642 std::time_t secs; 643 uint32_t us; 644 tm *p_tm; 645 646 if (time_secs <= 1000) { 647 gettimeofday(&tv, NULL); 648 secs = tv.tv_sec; 649 us = tv.tv_usec; 650 651 } else { 652 secs = time_secs; 653 us = time_us; 654 } 655 656 p_tm = std::gmtime(&secs); 657 std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", p_tm); 658 ts_str = buf; 659 660 sprintf(buf, ".%06u", us); 661 ts_str.append(buf); 662 } 663 664 protected: 665 666 private: 667 668 }; 669 670 #endif 671