1 /** 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef IMS_MEDIA_DEFINE_H 18 #define IMS_MEDIA_DEFINE_H 19 20 #include <RtpConfig.h> 21 #include <AudioConfig.h> 22 #include <string.h> 23 24 #define DEFAULT_MTU 1500 25 #define SEQ_ROUND_QUARD 655 // 1% of FFFF 26 #define USHORT_SEQ_ROUND_COMPARE(a, b) \ 27 ((((a) >= (b)) && (((b) >= SEQ_ROUND_QUARD) || (((a) <= 0xffff - SEQ_ROUND_QUARD)))) || \ 28 (((a) <= SEQ_ROUND_QUARD) && ((b) >= 0xffff - SEQ_ROUND_QUARD))) 29 #define IMS_MEDIA_WORD_SIZE 4 30 31 using namespace android::telephony::imsmedia; 32 33 enum ImsMediaResult 34 { 35 RESULT_SUCCESS = 0, 36 RESULT_INVALID_PARAM, 37 RESULT_NOT_READY, 38 RESULT_NO_MEMORY, 39 RESULT_NO_RESOURCES, 40 RESULT_PORT_UNAVAILABLE, 41 RESULT_NOT_SUPPORTED, 42 }; 43 44 enum kImsMediaEventType 45 { 46 kImsMediaEventNotifyError = 0, 47 kImsMediaEventStateChanged, 48 kImsMediaEventFirstPacketReceived, 49 kImsMediaEventHeaderExtensionReceived, 50 kImsMediaEventMediaQualityStatus, 51 kImsMediaEventMediaInactivity, 52 kImsMediaEventResolutionChanged, 53 kImsMediaEventNotifyVideoDataUsage, 54 kImsMediaEventNotifyRttReceived, 55 kImsMediaEventNotifyVideoLowestBitrate, 56 }; 57 58 // Internal Request Event 59 enum kImsMediaInternalRequestType 60 { 61 kRequestAudioCmr = 300, 62 kRequestAudioRttdUpdate, 63 kRequestAudioCmrEvs, 64 kRequestVideoCvoUpdate, 65 kRequestVideoBitrateChange, 66 kRequestVideoIdrFrame, 67 kRequestVideoSendNack, 68 kRequestVideoSendPictureLost, 69 kRequestVideoSendTmmbr, 70 kRequestVideoSendTmmbn, 71 kRequestRoundTripTimeDelayUpdate = 310, 72 kRequestAudioPlayingStatus, 73 kCollectPacketInfo, 74 kCollectOptionalInfo, 75 kCollectRxRtpStatus, 76 kCollectJitterBufferSize, 77 kGetRtcpXrReportBlock, 78 kRequestSendRtcpXrReport, 79 }; 80 81 enum kImsMediaErrorNotify 82 { 83 kNotifyErrorSocket = 400, 84 kNotifyErrorSurfaceNotReady, 85 kNotifyErrorCamera, 86 kNotifyErrorEncoder, 87 kNotifyErrorDecoder, 88 }; 89 90 enum ImsMediaStreamType 91 { 92 kStreamRtpTx, 93 kStreamRtpRx, 94 kStreamRtcp, 95 }; 96 97 enum kImsMediaStreamType 98 { 99 kStreamModeRtpTx, 100 kStreamModeRtpRx, 101 kStreamModeRtcp, 102 }; 103 104 enum ImsMediaType 105 { 106 IMS_MEDIA_AUDIO = 0, 107 IMS_MEDIA_VIDEO, 108 IMS_MEDIA_TEXT, 109 }; 110 111 enum kProtocolType 112 { 113 kProtocolRtp = 0, 114 kProtocolRtcp, 115 }; 116 117 enum kEvsBandwidth 118 { 119 kEvsBandwidthNone = 0, 120 kEvsBandwidthNB = 1, 121 kEvsBandwidthWB = 2, 122 kEvsBandwidthSWB = 4, 123 kEvsBandwidthFB = 8, 124 }; 125 126 enum kEvsBitrate 127 { 128 /* 6.6 kbps, AMR-IO */ 129 kEvsAmrIoModeBitrate00660 = 0, 130 /* 8.85 kbps, AMR-IO */ 131 kEvsAmrIoModeBitrate00885 = 1, 132 /* 12.65 kbps, AMR-IO */ 133 kEvsAmrIoModeBitrate01265 = 2, 134 /* 14.25 kbps, AMR-IO */ 135 kEvsAmrIoModeBitrate01425 = 3, 136 /* 15.85 kbps, AMR-IO */ 137 kEvsAmrIoModeBitrate01585 = 4, 138 /* 18.25 kbps, AMR-IO */ 139 kEvsAmrIoModeBitrate01825 = 5, 140 /* 19.85 kbps, AMR-IO */ 141 kEvsAmrIoModeBitrate01985 = 6, 142 /* 23.05 kbps, AMR-IO */ 143 kEvsAmrIoModeBitrate02305 = 7, 144 /* 23.85 kbps, AMR-IO */ 145 kEvsAmrIoModeBitrate02385 = 8, 146 /* 5.9 kbps, EVS Primary - SC-VBR 2.8kbps, 7.2kbps, 8kbps*/ 147 kEvsPrimaryModeBitrate00590 = 9, 148 /* 7.2 kbps, EVS Primary */ 149 kEvsPrimaryModeBitrate00720 = 10, 150 /* 8 kbps, EVS Primary */ 151 kEvsPrimaryModeBitrate00800 = 11, 152 /* 9.6 kbps, EVS Primary */ 153 kEvsPrimaryModeBitrate00960 = 12, 154 /* 13.20 kbps, EVS Primary */ 155 kEvsPrimaryModeBitrate01320 = 13, 156 /* 16.4 kbps, EVS Primary */ 157 kEvsPrimaryModeBitrate01640 = 14, 158 /* 24.4 kbps, EVS Primary */ 159 kEvsPrimaryModeBitrate02440 = 15, 160 /* 32 kbps, EVS Primary */ 161 kEvsPrimaryModeBitrate03200 = 16, 162 /* 48 kbps, EVS Primary */ 163 kEvsPrimaryModeBitrate04800 = 17, 164 /* 64 kbps, EVS Primary */ 165 kEvsPrimaryModeBitrate06400 = 18, 166 /* 96 kbps, EVS Primary */ 167 kEvsPrimaryModeBitrate09600 = 19, 168 /* 128 kbps, EVS Primary */ 169 kEvsPrimaryModeBitrate12800 = 20, 170 /* 2.4 kbps, EVS Primary */ 171 kEvsPrimaryModeBitrateSID = 21, 172 /* SPEECH LOST */ 173 kEvsPrimaryModeBitrateSpeechLost = 22, 174 /* NO DATA */ 175 kEvsPrimaryModeBitrateNoData = 23, 176 }; 177 178 enum kEvsCodecMode 179 { 180 kEvsCodecModePrimary = 0, // EVS PRIMARY mode 0 181 kEvsCodecModeAmrIo = 1, // EVS AMR-WB IO mode 1 182 kEvsCodecModeMax = 0x7FFFFFFF 183 }; 184 185 /* CMR Code in TS 26.445 */ 186 enum kEvsCmrCodeType 187 { 188 kEvsCmrCodeTypeNb = 0, // 000: Narrow band 189 kEvsCmrCodeTypeAmrIO = 1, // 001: AMR IO mode 190 kEvsCmrCodeTypeWb = 2, // 010: Wide band 191 kEvsCmrCodeTypeSwb = 3, // 011: Super wide band 192 kEvsCmrCodeTypeFb = 4, // 100: Full band 193 kEvsCmrCodeTypeWbCha = 5, // 101: Wide band(13.2 Channel aware mode) 194 kEvsCmrCodeTypeSwbCha = 6, // 110: Super wide band (13.2 Channel aware mode) 195 kEvsCmrCodeTypeNoReq = 7, // 111: Reserved 196 }; 197 198 /* CMR Definition in TS 26.445 */ 199 enum kEvsCmrCodeDefine 200 { 201 kEvsCmrCodeDefine59 = 0, // 0000 202 kEvsCmrCodeDefine72 = 1, // 0001 203 kEvsCmrCodeDefine80 = 2, // 0010 204 kEvsCmrCodeDefine96 = 3, // 0011 205 kEvsCmrCodeDefine132 = 4, // 0100 206 kEvsCmrCodeDefine164 = 5, // 0101 207 kEvsCmrCodeDefine244 = 6, // 0110 208 kEvsCmrCodeDefine320 = 7, // 0111 209 kEvsCmrCodeDefine480 = 8, // 1000 210 kEvsCmrCodeDefine640 = 9, // 1001 211 kEvsCmrCodeDefine960 = 10, // 1010 212 kEvsCmrCodeDefine1280 = 11, // 1011 213 kEvsCmrCodeDefineNoReq = 15, // 1111 214 215 // Channel aware mode 216 kEvsCmrCodeDefineChaOffset2 = 0, // 0000 217 kEvsCmrCodeDefineChaOffset3 = 1, // 0001 218 kEvsCmrCodeDefineChaOffset5 = 2, // 0010 219 kEvsCmrCodeDefineChaOffset7 = 3, // 0011 220 kEvsCmrCodeDefineChaOffsetH2 = 4, // 0100 221 kEvsCmrCodeDefineChaOffsetH3 = 5, // 0101 222 kEvsCmrCodeDefineChaOffsetH5 = 6, // 0110 223 kEvsCmrCodeDefineChaOffsetH7 = 7, // 0111 224 225 // AMR WB-IO 226 kEvsCmrCodeDefineAmrIo660 = 0, // 0000 227 kEvsCmrCodeDefineAmrIo885 = 1, // 0001 228 kEvsCmrCodeDefineAmrIo1265 = 2, // 0010 229 kEvsCmrCodeDefineAmrIo1425 = 3, // 0011 230 kEvsCmrCodeDefineAmrIo1585 = 4, // 0100 231 kEvsCmrCodeDefineAmrIo1825 = 5, // 0101 232 kEvsCmrCodeDefineAmrIo1985 = 6, // 0110 233 kEvsCmrCodeDefineAmrIo2305 = 7, // 0111 234 kEvsCmrCodeDefineAmrIo2385 = 8, // 1000 235 236 kEvsCmrCodeDefineENUM_MAX = 0x7FFFFFFF 237 }; 238 239 enum ImsMediaSubType 240 { 241 MEDIASUBTYPE_UNDEFINED = 0, 242 // rtp payload header + encoded bitstream 243 MEDIASUBTYPE_RTPPAYLOAD, 244 // rtp packet 245 MEDIASUBTYPE_RTPPACKET, 246 // rtcp packet 247 MEDIASUBTYPE_RTCPPACKET, 248 // rtcp packet 249 MEDIASUBTYPE_RTCPPACKET_BYE, 250 // raw yuv or pcm data 251 MEDIASUBTYPE_RAWDATA, 252 MEDIASUBTYPE_RAWDATA_ROT90, 253 MEDIASUBTYPE_RAWDATA_ROT90_FLIP, 254 MEDIASUBTYPE_RAWDATA_ROT270, 255 MEDIASUBTYPE_RAWDATA_CROP_ROT90, 256 MEDIASUBTYPE_RAWDATA_CROP_ROT90_FLIP, 257 MEDIASUBTYPE_RAWDATA_CROP_ROT270, 258 MEDIASUBTYPE_RAWDATA_CROP, 259 // dtmf packet with start bit set 260 MEDIASUBTYPE_DTMFSTART, 261 // dtmf payload 262 MEDIASUBTYPE_DTMF_PAYLOAD, 263 // dtmf packet with end bit set 264 MEDIASUBTYPE_DTMFEND, 265 MEDIASUBTYPE_VIDEO_CONFIGSTRING, 266 MEDIASUBTYPE_VIDEO_IDR_FRAME, 267 MEDIASUBTYPE_VIDEO_NON_IDR_FRAME, 268 MEDIASUBTYPE_VIDEO_SEI_FRAME, 269 MEDIASUBTYPE_ROT0 = 20, 270 MEDIASUBTYPE_ROT90, 271 MEDIASUBTYPE_ROT180, 272 MEDIASUBTYPE_ROT270, 273 MEDIASUBTYPE_REFRESHED, 274 // rtt bitstream of t.140 format 275 MEDIASUBTYPE_BITSTREAM_T140, 276 // rtt bitstream of t.140 redundant format 277 MEDIASUBTYPE_BITSTREAM_T140_RED, 278 MEDIASUBTYPE_PCM_DATA, 279 MEDIASUBTYPE_PCM_NO_DATA, 280 // Jitter Buffer GetData not ready 281 MEDIASUBTYPE_NOT_READY, 282 MEDIASUBTYPE_BITSTREAM_CODECCONFIG, 283 MEDIASUBTYPE_AUDIO_SID, 284 MEDIASUBTYPE_AUDIO_NODATA, 285 MEDIASUBTYPE_AUDIO_NORMAL, 286 MEDIASUBTYPE_MAX 287 }; 288 289 enum ImsMediaAudioMsgRequest 290 { 291 kAudioOpenSession = 101, 292 kAudioCloseSession, 293 kAudioModifySession, 294 kAudioAddConfig, 295 kAudioDeleteConfig, 296 kAudioConfirmConfig, 297 kAudioSendDtmf, 298 kAudioSendRtpHeaderExtension, 299 kAudioSetMediaQualityThreshold, 300 }; 301 302 enum ImsMediaAudioMsgResponse 303 { 304 kAudioOpenSessionSuccess = 201, 305 kAudioOpenSessionFailure, 306 kAudioModifySessionResponse, 307 kAudioAddConfigResponse, 308 kAudioConfirmConfigResponse, 309 kAudioFirstMediaPacketInd, 310 kAudioRtpHeaderExtensionInd, 311 kAudioMediaQualityStatusInd, 312 kAudioTriggerAnbrQueryInd, 313 kAudioDtmfReceivedInd, 314 kAudioCallQualityChangedInd, 315 kAudioSessionClosed, 316 }; 317 318 enum ImsMediaVideoMsgRequest 319 { 320 kVideoOpenSession = 101, 321 kVideoCloseSession, 322 kVideoModifySession, 323 kVideoSetPreviewSurface, 324 kVideoSetDisplaySurface, 325 kVideoSendRtpHeaderExtension, 326 kVideoSetMediaQualityThreshold, 327 kVideoRequestDataUsage, 328 }; 329 330 enum ImsMediaVideoMsgResponse 331 { 332 kVideoOpenSessionSuccess = 201, 333 kVideoOpenSessionFailure, 334 kVideoModifySessionResponse, 335 kVideoFirstMediaPacketInd, 336 kVideoPeerDimensionChanged, 337 kVideoRtpHeaderExtensionInd, 338 kVideoMediaInactivityInd, 339 kVideoBitrateInd, 340 kVideoDataUsageInd, 341 kVideoSessionClosed, 342 }; 343 344 enum ImsMediaTextMsgRequest 345 { 346 kTextOpenSession = 101, 347 kTextCloseSession, 348 kTextModifySession, 349 kTextSetMediaQualityThreshold, 350 kTextSendRtt, 351 }; 352 353 enum ImsMediaTextMsgResponse 354 { 355 kTextOpenSessionSuccess = 201, 356 kTextOpenSessionFailure, 357 kTextModifySessionResponse, 358 kTextMediaInactivityInd, 359 kTextRttReceived, 360 kTextSessionClosed, 361 }; 362 363 #define UNDEFINED_SOCKET_FD (-1) 364 #define T140_BUFFERING_TIME (300) 365 #define RTT_MAX_CHAR_PER_SEC (30) // ATIS_GTT : 30 characters per second 366 #define RTT_MAX_UNICODE_UTF8 (4) 367 #define MAX_RTT_LEN (RTT_MAX_CHAR_PER_SEC * RTT_MAX_UNICODE_UTF8) 368 #define PAYLOADENCODER_TEXT_MAX_REDUNDANT_INTERVAL (16383) 369 370 struct EventParamOpenSession 371 { 372 public: 373 void* mConfig; 374 int rtpFd; 375 int rtcpFd; 376 EventParamOpenSession( 377 int rtp = UNDEFINED_SOCKET_FD, int rtcp = UNDEFINED_SOCKET_FD, void* config = nullptr) : mConfigEventParamOpenSession378 mConfig(config), 379 rtpFd(rtp), 380 rtcpFd(rtcp) 381 { 382 } 383 }; 384 385 struct EventParamDtmf 386 { 387 public: 388 char digit; 389 int duration; 390 EventParamDtmfEventParamDtmf391 EventParamDtmf(char dig, int d) 392 { 393 digit = dig; 394 duration = d; 395 } 396 }; 397 398 enum kAudioCodecType 399 { 400 kAudioCodecNone = 0, 401 kAudioCodecAmr, 402 kAudioCodecAmrWb, 403 kAudioCodecPcmu, 404 kAudioCodecPcma, 405 kAudioCodecEvs, 406 }; 407 408 enum kVideoCodecType 409 { 410 kVideoCodecNone = 0, 411 kVideoCodecAvc, 412 kVideoCodecHevc, 413 }; 414 415 enum kRtpPyaloadHeaderMode 416 { 417 // Amr mode 418 kRtpPyaloadHeaderModeAmrOctetAligned = 0, // octet aligned mode 419 kRtpPyaloadHeaderModeAmrEfficient = 1, // efficient mode 420 // Video packetization mode 421 kRtpPyaloadHeaderModeSingleNalUnit = 0, // packet mode 0 422 kRtpPyaloadHeaderModeNonInterleaved = 1, // packet mode 1 423 // Evs mode 424 kRtpPyaloadHeaderModeEvsCompact = 0, // EVS compact format 0 425 kRtpPyaloadHeaderModeEvsHeaderFull = 1, // EVS header-full format 1 426 kRtpPyaloadHeaderModeMax 427 }; 428 429 enum kIpVersion 430 { 431 IPV4, 432 IPV6, 433 }; 434 435 enum StreamState 436 { 437 /** The state of the stream created but any nodes are not created */ 438 kStreamStateIdle, 439 /** The state of the stream and nodes are created */ 440 kStreamStateCreated, 441 /** The state of the stream nodes are started and running */ 442 kStreamStateRunning, 443 /** Video state wait surface in stating */ 444 kStreamStateWaitSurface, 445 }; 446 447 enum SessionState 448 { 449 /** The state that the session is created but graph is not created */ 450 kSessionStateOpened, 451 /** The state that the session is created and the TX rtp StreamGraphs are running */ 452 kSessionStateSending, 453 /** The state that the session is created and the RX rtp StreamGraphs are running */ 454 kSessionStateReceiving, 455 /** The state that the session is created and the both TX and Rx rtp StreamGraphs are running */ 456 kSessionStateActive, 457 /** The state that the session is created and the Rtp StreamGraphs is not running */ 458 kSessionStateSuspended, 459 /** The state that the session is closed */ 460 kSessionStateClosed, 461 }; 462 463 enum kSocketOption 464 { 465 kSocketOptionNone = 0, 466 kSocketOptionIpTos = 1, 467 kSocketOptionIpTtl = 2, 468 }; 469 470 enum kRtpPacketStatus 471 { 472 kRtpStatusNotDefined = 0, 473 kRtpStatusNormal, 474 kRtpStatusLate, 475 kRtpStatusDiscarded, 476 kRtpStatusDuplicated, 477 kRtpStatusLost, 478 }; 479 480 enum kRtpDataType 481 { 482 kRtpDataTypeNoData = 0, 483 kRtpDataTypeSid, 484 kRtpDataTypeNormal, 485 }; 486 487 enum kAudioPlayingStatus 488 { 489 kAudioTypeNoData = 0, 490 kAudioTypeVoice, 491 }; 492 493 enum kRtpOptionalType 494 { 495 kTimeToLive, 496 kRoundTripDelay, 497 kReportPacketLossGap, 498 kAudioPlayingStatus, 499 }; 500 501 /** TODO: change the name to avoid confusion by similarity */ 502 struct RtpPacket 503 { 504 public: RtpPacketRtpPacket505 RtpPacket() : 506 ssrc(0), 507 seqNum(0), 508 TTL(0), 509 jitter(0), 510 arrival(0), 511 rtpDataType(kRtpDataTypeNoData), 512 status(kRtpStatusNotDefined) 513 { 514 } RtpPacketRtpPacket515 RtpPacket(const RtpPacket& p) 516 { 517 ssrc = p.ssrc; 518 seqNum = p.seqNum; 519 TTL = p.TTL; 520 jitter = p.jitter; 521 arrival = p.arrival; 522 rtpDataType = p.rtpDataType; 523 status = p.status; 524 } 525 526 uint32_t ssrc; 527 uint32_t seqNum; 528 uint32_t TTL; 529 /** transit time difference */ 530 int32_t jitter; 531 /** arrival time */ 532 int32_t arrival; 533 kRtpDataType rtpDataType; 534 kRtpPacketStatus status; 535 }; 536 537 /** 538 * @brief It is lost packet data structure to store the start number of packet sequence and the 539 * number of lost packets 540 */ 541 struct LostPacket 542 { 543 public: 544 LostPacket(uint16_t s = 0, uint32_t num = 0, uint32_t time = 0, uint32_t opt = 0) : seqNumLostPacket545 seqNum(s), 546 numLoss(num), 547 markedTime(time), 548 option(opt) 549 { 550 } 551 /** The rtp sequence number of beginning of lost packet */ 552 uint16_t seqNum; 553 /** The number of lost packets */ 554 uint32_t numLoss; 555 /** The time in milliseconds when determined to lost */ 556 uint32_t markedTime; 557 /** optional parameter for nack */ 558 uint32_t option; 559 }; 560 561 struct RtpHeaderExtensionInfo 562 { 563 public: 564 enum 565 { 566 // RFC 8285#section-4.2, The bit pattern for one byte header 567 kBitPatternForOneByteHeader = 0xBEDE, 568 // RFC 8285#section-4.3, The bit pattern for two byte header 569 kBitPatternForTwoByteHeader = 0x1000, 570 }; 571 572 uint16_t definedByProfile; 573 uint16_t length; // length in word unit 574 int8_t* extensionData; 575 uint16_t extensionDataSize; 576 577 RtpHeaderExtensionInfo( 578 uint16_t profile = 0, uint16_t len = 0, int8_t* data = nullptr, uint16_t size = 0) 579 { 580 definedByProfile = profile; 581 length = len; 582 extensionData = nullptr; 583 extensionDataSize = 0; 584 setExtensionData(data, size); 585 } 586 RtpHeaderExtensionInfoRtpHeaderExtensionInfo587 RtpHeaderExtensionInfo(const RtpHeaderExtensionInfo& extension) 588 { 589 definedByProfile = extension.definedByProfile; 590 extensionData = nullptr; 591 length = extension.length; 592 setExtensionData(extension.extensionData, extension.extensionDataSize); 593 } 594 ~RtpHeaderExtensionInfoRtpHeaderExtensionInfo595 ~RtpHeaderExtensionInfo() 596 { 597 if (extensionData != nullptr) 598 { 599 delete[] extensionData; 600 extensionData = nullptr; 601 } 602 } 603 604 RtpHeaderExtensionInfo& operator=(const RtpHeaderExtensionInfo& extension) 605 { 606 if (this != &extension) 607 { 608 definedByProfile = extension.definedByProfile; 609 length = extension.length; 610 setExtensionData(extension.extensionData, extension.extensionDataSize); 611 } 612 613 return *this; 614 } 615 setExtensionDataRtpHeaderExtensionInfo616 void setExtensionData(int8_t* data, uint16_t dataSize) 617 { 618 if (extensionData != nullptr) 619 { 620 delete[] extensionData; 621 extensionData = nullptr; 622 extensionDataSize = 0; 623 } 624 625 if (data != nullptr) 626 { 627 extensionDataSize = dataSize; 628 extensionData = new int8_t[extensionDataSize]; 629 memcpy(extensionData, data, extensionDataSize); 630 } 631 } 632 }; 633 634 #define MAX_IP_LEN 128 635 #define MAX_REMOTE_POINT 40 636 637 class RtpAddress 638 { 639 public: 640 RtpAddress(const char* ip = nullptr, uint32_t p = 0) 641 { 642 memset(this->ipAddress, 0, MAX_IP_LEN); 643 if (ip != nullptr) 644 { 645 std::strncpy(ipAddress, ip, MAX_IP_LEN); 646 } 647 port = p; 648 } ~RtpAddress()649 ~RtpAddress() {} RtpAddress(const RtpAddress & address)650 RtpAddress(const RtpAddress& address) : 651 port(address.port) 652 { 653 memset(this->ipAddress, 0, MAX_IP_LEN); 654 std::strncpy(this->ipAddress, address.ipAddress, MAX_IP_LEN); 655 } 656 RtpAddress& operator=(const RtpAddress& address) 657 { 658 if (this != &address) 659 { 660 memset(this->ipAddress, 0, MAX_IP_LEN); 661 std::strncpy(this->ipAddress, address.ipAddress, MAX_IP_LEN); 662 this->port = address.port; 663 } 664 665 return *this; 666 } 667 bool operator==(const RtpAddress& address) 668 { 669 return (std::strcmp(this->ipAddress, address.ipAddress) == 0 && this->port == address.port); 670 } 671 bool operator!=(const RtpAddress& address) 672 { 673 return (std::strcmp(this->ipAddress, address.ipAddress) != 0 || this->port != address.port); 674 } 675 char ipAddress[MAX_IP_LEN]; 676 uint32_t port; 677 }; 678 679 #endif 680