• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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