reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
RemoteIMSessionParticipant.cxx
Go to the documentation of this file.
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
6
8#include "Conversation.hxx"
9#include "UserAgent.hxx"
10#include "ReconSubsystem.hxx"
11
12#include <rutil/ResipAssert.h>
13#include <rutil/Log.hxx>
14#include <rutil/Logger.hxx>
15#include <rutil/DnsUtil.hxx>
16#include <rutil/Random.hxx>
23
25
26#include <utility>
27
28using namespace recon;
29using namespace resip;
30using namespace std;
31
32#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON
33
34// UAC
36 ConversationManager& conversationManager,
38 RemoteParticipantDialogSet& remoteParticipantDialogSet)
39: Participant(partHandle, ConversationManager::ParticipantType_RemoteIMSession, conversationManager),
40 RemoteParticipant(partHandle, conversationManager, dum, remoteParticipantDialogSet)
41{
42 InfoLog(<< "RemoteIMSessionParticipant created (UAC), handle=" << mHandle);
43}
44
45// UAS - or forked leg
48 RemoteParticipantDialogSet& remoteParticipantDialogSet)
49: Participant(ConversationManager::ParticipantType_RemoteIMSession, conversationManager),
50 RemoteParticipant(conversationManager, dum, remoteParticipantDialogSet)
51{
52 InfoLog(<< "RemoteIMSessionParticipant created (UAS or forked leg), handle=" << mHandle);
53}
54
56{
57 // Note: Ideally this call would exist in the Participant Base class - but this call requires
58 // dynamic_casts and virtual methods to function correctly during destruction.
59 // If the call is placed in the base Participant class then these things will not
60 // function as desired because a classes type changes as the descructors unwind.
61 // See https://stackoverflow.com/questions/10979250/usage-of-this-in-destructor.
63
64 InfoLog(<< "RemoteIMSessionParticipant destroyed, handle=" << mHandle);
65}
66
67void
69{
70 if (mHandle) mConversationManager.onIncomingIMSessionParticipant(mHandle, msg, autoAnswer, conversationProfile);
71}
72
73void
74RemoteIMSessionParticipant::buildSdpOffer(bool holdSdp, CallbackSdpReady sdpReady, bool preferExistingSdp)
75{
76 std::unique_ptr<SdpContents> _offer(new SdpContents);
77 SdpContents& offer = *_offer;
79 resip_assert(profile);
80
81 offer = profile->sessionCaps(); // FIXME MediaStackAdapter
82
83 // Set sessionid and version for this sdp
84 uint64_t currentTime = Timer::getTimeMicroSec();
85 offer.session().origin().getSessionId() = currentTime;
86 offer.session().origin().getVersion() = currentTime;
87
88 offer.session().media().clear(); // Clear any media lines and add in one approproate for message sessions
89
90 // Added Message Session medium (ala. Microsoft): https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-confim/70925df9-ee05-4f8f-9eda-e22ef32fd414
91 SdpContents::Session::Medium medium("message", 5060, 1, "sip");
92 medium.addFormat("null");
93 offer.session().addMedium(medium);
94
95 setProposedSdp(offer);
96 sdpReady(true, std::move(_offer));
97}
98
99void
100RemoteIMSessionParticipant::buildSdpAnswer(const SdpContents& offer, CallbackSdpReady sdpReady)
101{
102 bool valid = false;
103 std::unique_ptr<SdpContents> _answer(new SdpContents);
104 SdpContents& answer = *_answer;
105
106 try
107 {
109 resip_assert(profile);
110
111 answer = profile->sessionCaps(); // FIXME MediaStackAdapter
112
113 uint64_t currentTime = Timer::getTimeMicroSec();
114 answer.session().origin().getSessionId() = currentTime;
115 answer.session().origin().getVersion() = currentTime;
116
117 // Copy t= field from sdp (RFC3264)
118 if (offer.session().getTimes().size() >= 1)
119 {
120 answer.session().getTimes().clear();
121 answer.session().addTime(offer.session().getTimes().front());
122 }
123
124 // Clear any media lines and add in media line responses below
125 answer.session().media().clear();
126
127 // Loop through each offered m= line and provide a response
128 // We leave our offer m=message line in and use this as the response if the offer contains a valid m=message line as well.
129 for(auto it = offer.session().media().begin(); it != offer.session().media().end(); it++)
130 {
131 if (!valid && it->name() == "message" && it->port() == 5060 && it->protocol() == "sip")
132 {
133 // Added Message Session medium (ala. Microsoft): https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-confim/70925df9-ee05-4f8f-9eda-e22ef32fd414
134 SdpContents::Session::Medium medium("message", 5060, 1, "sip");
135 medium.addFormat("null");
136 answer.session().addMedium(medium);
137
138 valid = true;
139 }
140 else
141 {
142 SdpContents::Session::Medium rejmedium(it->name(), 0, 1, // Reject medium by specifying port 0 (RFC3264)
143 it->protocol());
144 if (it->codecs().size() > 0)
145 {
146 rejmedium.addCodec(it->codecs().front());
147 }
148 answer.session().addMedium(rejmedium);
149 }
150 } // end loop through m= offers
151 }
152 catch(BaseException &e)
153 {
154 WarningLog( << "buildSdpAnswer: exception parsing SDP offer: " << e.getMessage());
155 valid = false;
156 }
157 catch(...)
158 {
159 WarningLog( << "buildSdpAnswer: unknown exception parsing SDP offer");
160 valid = false;
161 }
162
163 //InfoLog( << "SDPOffer: " << offer);
164 //InfoLog( << "SDPAnswer: " << answer);
165 if(valid)
166 {
167 setLocalSdp(answer);
168 setRemoteSdp(offer);
169 }
170 sdpReady(valid, std::move(_answer));
171}
172
173void
175{
176 WarningLog(<<"requestKeyframe not implemented"); // FIXME
177}
178
179
180/* ====================================================================
181
182 Copyright (c) 2022, SIP Spectrum, Inc. http://www.sipspectrum.com
183 All rights reserved.
184
185 Redistribution and use in source and binary forms, with or without
186 modification, are permitted provided that the following conditions are
187 met:
188
189 1. Redistributions of source code must retain the above copyright
190 notice, this list of conditions and the following disclaimer.
191
192 2. Redistributions in binary form must reproduce the above copyright
193 notice, this list of conditions and the following disclaimer in the
194 documentation and/or other materials provided with the distribution.
195
196 3. Neither the name of Plantronics nor the names of its contributors
197 may be used to endorse or promote products derived from this
198 software without specific prior written permission.
199
200 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
201 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
202 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
203 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
206 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
207 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
208 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
209 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
210 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
211
212 ==================================================================== */
#define InfoLog(args_)
Definition Logger.hxx:131
#define WarningLog(args_)
Definition Logger.hxx:134
#define resip_assert(x)
This file needs to work for both C and C++ code.
This class is one of two main classes of concern to an application using the UserAgent library.
virtual void onIncomingIMSessionParticipant(ParticipantHandle partHandle, const resip::SipMessage &msg, bool autoAnswer, ConversationProfile &conversationProfile)
Notifies an application about a new remote IM session mode participant that has sent an INVITE.
This class extends the resip UserProfile to include Conversation Manager specific settings.
virtual resip::SdpContents & sessionCaps()
Get/Set the session capabilities.
This is the base class for a RemoteParticipant, LocalParticipant and a MediaResourceParticipant.
virtual void unregisterFromAllConversations()
ParticipantHandle mHandle
ConversationManager & mConversationManager
RemoteIMSessionParticipant(ParticipantHandle partHandle, ConversationManager &conversationManager, resip::DialogUsageManager &dum, RemoteParticipantDialogSet &remoteParticipantDialogSet)
virtual void notifyIncomingParticipant(const resip::SipMessage &msg, bool autoAnswer, ConversationProfile &conversationProfile) override
virtual void buildSdpOffer(bool holdSdp, CallbackSdpReady sdpReady, bool preferExistingSdp=false) override
This class is used by Invite DialogSets.
std::shared_ptr< ConversationProfile > getConversationProfile()
This class represent a remote participant.
void setProposedSdp(const resip::SdpContents &sdp)
void setRemoteSdp(const resip::SdpContents &sdp, bool answer=false)
std::function< void(bool sdpOk, std::unique_ptr< resip::SdpContents > sdp)> CallbackSdpReady
void setLocalSdp(const resip::SdpContents &sdp)
RemoteParticipantDialogSet & getDialogSet()
The abstract base-class for all exceptions thrown by resip code.
const Data & getMessage() const noexcept
process m= (media announcement) blocks
void addFormat(const Data &format)
add a format identifier to the m= line
const uint64_t & getVersion() const
returns the session version
const uint64_t & getSessionId() const
returns the session ID
const std::list< Time > & getTimes() const
return session Time lines
void addMedium(const Medium &medium)
add an m= (Medium) section to session
void addTime(const Time &t)
add a t= (Time) line to session
const Origin & origin() const
return session Origin line
const MediumContainer & media() const
return session Media lines
Provides an interface to process and generate SDP bodies (MIME content-type application/sdp).
Session & session()
get the parsed SDP
Represents a SIP message.
static uint64_t getTimeMicroSec()
Returns the current clock time in microseconds.
Definition Timer.hxx:66
unsigned int ParticipantHandle
dcm! – add UnusedChecking(_enum) below;
unsigned __int64 uint64_t
Definition stdint.h:95