You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2020/12/22 14:41:06 UTC
[openmeetings] branch master updated: [OPENMEETINGS-2239] another
attempt to make 'softphone -> browser' work
This is an automated email from the ASF dual-hosted git repository.
solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git
The following commit(s) were added to refs/heads/master by this push:
new 5608cbf [OPENMEETINGS-2239] another attempt to make 'softphone -> browser' work
5608cbf is described below
commit 5608cbfee7be52e625f0197f1dbad0d53f1421e9
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Tue Dec 22 21:40:51 2020 +0700
[OPENMEETINGS-2239] another attempt to make 'softphone -> browser' work
---
.../openmeetings/core/remote/AbstractStream.java | 12 +-
.../org/apache/openmeetings/core/remote/KRoom.java | 26 ++--
.../apache/openmeetings/core/remote/KStream.java | 140 ++++++++++++---------
.../openmeetings/core/remote/KTestStream.java | 4 +-
.../openmeetings/core/sip/ISipCallbacks.java | 4 +-
.../apache/openmeetings/core/sip/SipManager.java | 47 ++++---
.../openmeetings/core/sip/SipStackProcessor.java | 18 +--
.../openmeetings/core/remote/BaseMockedTest.java | 3 +-
.../src/site/markdown/AsteriskIntegration.md | 1 -
.../web/admin/connection/KStreamDto.java | 40 +++---
.../apache/openmeetings/web/app/TimerService.java | 3 +-
.../org/apache/openmeetings/web/room/raw-room.js | 28 +++--
12 files changed, 181 insertions(+), 145 deletions(-)
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/AbstractStream.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/AbstractStream.java
index cfc18d4..2dd7230 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/AbstractStream.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/AbstractStream.java
@@ -48,8 +48,16 @@ public abstract class AbstractStream {
public abstract void release(boolean remove);
- public static WebRtcEndpoint createWebRtcEndpoint(MediaPipeline pipeline) {
- return new WebRtcEndpoint.Builder(pipeline).build();
+ public static WebRtcEndpoint createWebRtcEndpoint(MediaPipeline pipeline, Boolean send) {
+ WebRtcEndpoint.Builder builder = new WebRtcEndpoint.Builder(pipeline);
+ if (send != null) {
+ if (send) {
+ builder.sendonly();
+ } else {
+ builder.recvonly();
+ }
+ }
+ return builder.build();
}
public static RecorderEndpoint createRecorderEndpoint(MediaPipeline pipeline, String path, MediaProfileSpecType profile) {
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
index 2062c5b..bc90f9b 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KRoom.java
@@ -1,7 +1,4 @@
/*
- * (C) Copyright 2014 Kurento (http://kurento.org/)
- */
-/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -52,15 +49,12 @@ import org.slf4j.LoggerFactory;
import com.github.openjson.JSONObject;
/**
- * Bean object dynamically created representing a conference room on the MediaServer
+ * Dynamically created object representing a conference room on the MediaServer
*
*/
public class KRoom {
private static final Logger log = LoggerFactory.getLogger(KRoom.class);
- /**
- * Not injected by annotation but by constructor.
- */
private final StreamProcessor processor;
private final RecordingChunkDao chunkDao;
private final Room room;
@@ -104,8 +98,6 @@ public class KRoom {
.put("uid", stream.getUid())
.toString()
);
- //FIXME TODO check close on stop sharing
- //FIXME TODO permission can be removed, some listener might be required
}
public boolean isRecording() {
@@ -251,8 +243,22 @@ public class KRoom {
public void updateSipCount(final long count) {
if (count != sipCount) {
- sipCount = count;
processor.getByRoom(room.getId()).forEach(stream -> stream.addSipProcessor(count));
+ if (sipCount == 0) {
+ processor.getClientManager()
+ .streamByRoom(room.getId())
+ .filter(Client::isSip)
+ .findAny()
+ .ifPresent(c -> {
+ StreamDesc sd = c.addStream(StreamType.WEBCAM, Activity.AUDIO, Activity.VIDEO); // TODO check this
+ sd.setWidth(120).setHeight(90);
+ c.restoreActivities(sd);
+ KStream stream = join(sd, processor.getHandler());
+ stream.startBroadcast(sd, "", () -> {});
+ processor.getClientManager().update(c);
+ });
+ }
+ sipCount = count;
}
}
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java
index c7fb37a..ffd91e1 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KStream.java
@@ -40,6 +40,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
import org.apache.openmeetings.core.sip.ISipCallbacks;
import org.apache.openmeetings.core.sip.SipStackProcessor;
@@ -52,6 +53,7 @@ import org.apache.openmeetings.db.entity.record.RecordingChunk.Type;
import org.apache.openmeetings.db.util.ws.RoomMessage;
import org.apache.openmeetings.db.util.ws.TextRoomMessage;
import org.apache.openmeetings.util.OmFileHelper;
+import org.kurento.client.BaseRtpEndpoint;
import org.kurento.client.Continuation;
import org.kurento.client.IceCandidate;
import org.kurento.client.ListenerSubscription;
@@ -60,6 +62,7 @@ import org.kurento.client.MediaObject;
import org.kurento.client.MediaPipeline;
import org.kurento.client.MediaProfileSpecType;
import org.kurento.client.MediaType;
+import org.kurento.client.OfferOptions;
import org.kurento.client.RecorderEndpoint;
import org.kurento.client.RtpEndpoint;
import org.kurento.client.WebRtcEndpoint;
@@ -79,7 +82,7 @@ public class KStream extends AbstractStream implements ISipCallbacks {
private MediaProfileSpecType profile;
private MediaPipeline pipeline;
private RecorderEndpoint recorder;
- private WebRtcEndpoint outgoingMedia = null;
+ private BaseRtpEndpoint outgoingMedia = null;
private RtpEndpoint rtpEndpoint;
private Optional<SipStackProcessor> sipProcessor = Optional.empty();
private final ConcurrentMap<String, WebRtcEndpoint> listeners = new ConcurrentHashMap<>();
@@ -143,7 +146,13 @@ public class KStream extends AbstractStream implements ISipCallbacks {
pipeline = kHandler.createPipiline(Map.of(TAG_ROOM, String.valueOf(getRoomId()), TAG_STREAM_UID, sd.getUid()), new Continuation<Void>() {
@Override
public void onSuccess(Void result) throws Exception {
- internalStartBroadcast(sd, sdpOffer);
+ if (sipClient) {
+ addSipProcessor(1);
+ } else {
+ outgoingMedia = createEndpoint(sd.getSid(), sd.getUid(), true);
+ internalStartBroadcast(sd, sdpOffer);
+ notifyOnNewStream(sd);
+ }
then.run();
}
@@ -155,10 +164,10 @@ public class KStream extends AbstractStream implements ISipCallbacks {
}
private void internalStartBroadcast(final StreamDesc sd, final String sdpOffer) throws Exception {
- outgoingMedia = createEndpoint(sd.getSid(), sd.getUid());
outgoingMedia.addMediaSessionTerminatedListener(evt -> log.warn("Media stream terminated {}", sd));
flowoutSubscription = outgoingMedia.addMediaFlowOutStateChangeListener(evt -> {
- log.info("Media Flow STATE :: {}, type {}, evt {}", evt.getState(), evt.getType(), evt.getMediaType());
+ log.info("Media Flow OUT STATE :: {}, evt {}, source {}"
+ , evt.getState(), evt.getMediaType(), evt.getSource());
if (MediaFlowState.NOT_FLOWING == evt.getState()) {
log.warn("FlowOut Future is created");
flowoutFuture = Optional.of(new CompletableFuture<>().completeAsync(() -> {
@@ -173,12 +182,18 @@ public class KStream extends AbstractStream implements ISipCallbacks {
dropFlowoutFuture();
}
});
- outgoingMedia.addMediaFlowInStateChangeListener(evt -> log.warn("Media FlowIn :: {}", evt));
- addListener(sd.getSid(), sd.getUid(), sdpOffer);
- addSipProcessor(kRoom.getSipCount());
+ outgoingMedia.addMediaFlowInStateChangeListener(evt -> log.warn("Media Flow IN :: {}, {}, {}"
+ , evt.getState(), evt.getMediaType(), evt.getSource()));
+ if (!sipClient) {
+ addListener(sd.getSid(), sd.getUid(), sdpOffer);
+ addSipProcessor(kRoom.getSipCount());
+ }
if (kRoom.isRecording()) {
startRecord();
}
+ }
+
+ private void notifyOnNewStream(final StreamDesc sd) {
Client c = sd.getClient();
WebSocketHelper.sendRoom(new TextRoomMessage(c.getRoomId(), c, RoomMessage.Type.RIGHT_UPDATED, c.getUid()));
if (hasAudio || hasVideo || hasScreen) {
@@ -213,11 +228,13 @@ public class KStream extends AbstractStream implements ISipCallbacks {
return;
}
- final WebRtcEndpoint endpoint = getEndpointForUser(sid, uid);
+ final BaseRtpEndpoint endpoint = getEndpointForUser(sid, uid);
final String sdpAnswer = endpoint.processOffer(sdpOffer);
- log.debug("gather candidates");
- endpoint.gatherCandidates(); // this one might throw Exception
+ if (endpoint instanceof WebRtcEndpoint) {
+ log.debug("gather candidates");
+ ((WebRtcEndpoint)endpoint).gatherCandidates(); // this one might throw Exception
+ }
log.trace("USER {}: SdpAnswer is {}", this.uid, sdpAnswer);
kHandler.sendClient(sid, newKurentoMsg()
.put("id", "videoResponse")
@@ -225,7 +242,7 @@ public class KStream extends AbstractStream implements ISipCallbacks {
.put("sdpAnswer", sdpAnswer));
}
- private WebRtcEndpoint getEndpointForUser(String sid, String uid) {
+ private BaseRtpEndpoint getEndpointForUser(String sid, String uid) {
if (uid.equals(this.uid)) {
log.debug("PARTICIPANT {}: configuring loopback", this.uid);
return outgoingMedia;
@@ -238,7 +255,7 @@ public class KStream extends AbstractStream implements ISipCallbacks {
listener.release();
}
log.debug("PARTICIPANT {}: creating new endpoint for {}", uid, this.uid);
- listener = createEndpoint(sid, uid);
+ listener = createEndpoint(sid, uid, false);
listeners.put(uid, listener);
log.debug("PARTICIPANT {}: obtained endpoint for {}", uid, this.uid);
@@ -266,14 +283,16 @@ public class KStream extends AbstractStream implements ISipCallbacks {
endpoint.addTag("uid", uid);
}
- private RtpEndpoint getRtpEndpoint(MediaPipeline pipeline) {
- RtpEndpoint endpoint = new RtpEndpoint.Builder(pipeline).build();
+ private RtpEndpoint getRtpEndpoint(MediaPipeline pipeline, String direction) {
+ RtpEndpoint endpoint = new RtpEndpoint.Builder(pipeline)
+ //.withProperties(Properties.of(direction, Boolean.TRUE))
+ .build();
setTags(endpoint, uid);
return endpoint;
}
- private WebRtcEndpoint createEndpoint(String sid, String uid) {
- WebRtcEndpoint endpoint = createWebRtcEndpoint(pipeline);
+ private WebRtcEndpoint createEndpoint(String sid, String uid, boolean send) {
+ WebRtcEndpoint endpoint = createWebRtcEndpoint(pipeline, send);
setTags(endpoint, uid);
endpoint.addIceCandidateFoundListener(evt -> kHandler.sendClient(sid
@@ -475,10 +494,10 @@ public class KStream extends AbstractStream implements ISipCallbacks {
public void addCandidate(IceCandidate candidate, String uid) {
if (this.uid.equals(uid)) {
- if (outgoingMedia == null) {
+ if (outgoingMedia == null || !(outgoingMedia instanceof WebRtcEndpoint)) {
return;
}
- outgoingMedia.addIceCandidate(candidate);
+ ((WebRtcEndpoint)outgoingMedia).addIceCandidate(candidate);
} else {
WebRtcEndpoint endpoint = listeners.get(uid);
log.debug("Add candidate for {}, listener found ? {}", uid, endpoint != null);
@@ -488,46 +507,14 @@ public class KStream extends AbstractStream implements ISipCallbacks {
}
}
- void addSipProcessor(long count) {
- if (count > 0) {
- if (sipProcessor.isEmpty()) {
- try {
- sipProcessor = kHandler.getSipManager().createSipStackProcessor(
- randomUUID().toString()
- , kRoom.getRoom()
- , this);
- sipProcessor.ifPresent(SipStackProcessor::register);
- } catch (Exception e) {
- log.error("Unexpected error while creating SipProcessor", e);
- }
- }
- } else {
- releaseRtp();
- }
- }
-
private static JSONObject convert(com.google.gson.JsonObject o) {
return new JSONObject(o.toString());
}
- @Override
- public String getSid() {
- return sid;
- }
-
- @Override
- public String getUid() {
- return uid;
- }
-
public Date getConnectedSince() {
return connectedSince;
}
- public KRoom getKRoom() {
- return kRoom;
- }
-
public Long getRoomId() {
return kRoom.getRoom().getId();
}
@@ -548,10 +535,6 @@ public class KStream extends AbstractStream implements ISipCallbacks {
return recorder;
}
- public WebRtcEndpoint getOutgoingMedia() {
- return outgoingMedia;
- }
-
public Long getChunkId() {
return chunkId;
}
@@ -571,26 +554,61 @@ public class KStream extends AbstractStream implements ISipCallbacks {
+ flowoutFuture + ", chunkId=" + chunkId + ", type=" + type + ", sid=" + sid + ", uid=" + uid + "]";
}
+ void addSipProcessor(long count) {
+ if (count > 0) {
+ if (sipProcessor.isEmpty()) {
+ try {
+ sipProcessor = kHandler.getSipManager().createSipStackProcessor(
+ randomUUID().toString()
+ , kRoom.getRoom()
+ , this);
+ sipProcessor.ifPresent(SipStackProcessor::register);
+ } catch (Exception e) {
+ log.error("Unexpected error while creating SipProcessor", e);
+ }
+ }
+ } else {
+ if (sipClient) {
+ release();
+ } else {
+ releaseRtp();
+ }
+ }
+ }
+
@Override
public void onRegisterOk() {
- if (sipClient) {
-
- } else {
- rtpEndpoint = getRtpEndpoint(pipeline);
+ rtpEndpoint = getRtpEndpoint(pipeline, sipClient ? "recvonly" : "sendonly");
+ OfferOptions options = new OfferOptions();
+ options.setOfferToReceiveAudio(hasAudio);
+ options.setOfferToReceiveVideo(hasVideo);
+ String offer = null;
+ if (!sipClient) {
+ offer = rtpEndpoint.generateOffer(options);
if (hasAudio) {
outgoingMedia.connect(rtpEndpoint, MediaType.AUDIO);
}
if (hasVideo) {
outgoingMedia.connect(rtpEndpoint, MediaType.VIDEO);
}
- sipProcessor.get().invite(kRoom.getRoom(), rtpEndpoint.generateOffer());
}
+ sipProcessor.get().invite(kRoom.getRoom(), offer);
}
@Override
- public void onInviteOk(String sdp) {
+ public void onInviteOk(String sdp, Consumer<String> answerConsumer) {
if (sipClient) {
-
+ String answer = rtpEndpoint.processOffer(sdp);
+ answerConsumer.accept(answer);
+ log.debug(answer);
+ StreamDesc sd = kHandler.getStreamProcessor().getBySid(sid).getStream(uid);
+ try {
+ outgoingMedia = rtpEndpoint;
+ internalStartBroadcast(sd, sdp);
+ notifyOnNewStream(sd);
+ } catch (Exception e) {
+ log.error("Unexpected error");
+ }
} else {
rtpEndpoint.processAnswer(sdp);
}
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java
index 6949528..741c1f6 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KTestStream.java
@@ -72,7 +72,7 @@ public class KTestStream extends AbstractStream {
}
private void startTestRecording(IWsClient c, JSONObject msg) {
- webRtcEndpoint = createWebRtcEndpoint(pipeline);
+ webRtcEndpoint = createWebRtcEndpoint(pipeline, null);
webRtcEndpoint.connect(webRtcEndpoint);
MediaProfileSpecType profile = getProfile(msg);
@@ -134,7 +134,7 @@ public class KTestStream extends AbstractStream {
public void play(final IWsClient inClient, JSONObject msg) {
createPipeline(() -> {
- webRtcEndpoint = createWebRtcEndpoint(pipeline);
+ webRtcEndpoint = createWebRtcEndpoint(pipeline, true);
player = createPlayerEndpoint(pipeline, recPath);
player.connect(webRtcEndpoint);
webRtcEndpoint.addMediaSessionStartedListener(evt -> {
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/ISipCallbacks.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/ISipCallbacks.java
index a04f275..b476c8a 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/ISipCallbacks.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/ISipCallbacks.java
@@ -18,7 +18,9 @@
*/
package org.apache.openmeetings.core.sip;
+import java.util.function.Consumer;
+
public interface ISipCallbacks {
void onRegisterOk();
- void onInviteOk(String sdp);
+ void onInviteOk(String sdp, Consumer<String> answerConsumer);
}
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipManager.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipManager.java
index ac8fc06..a95e419 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipManager.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipManager.java
@@ -26,6 +26,7 @@ import java.util.Optional;
import java.util.function.Function;
import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.user.User;
@@ -35,6 +36,7 @@ import org.apache.wicket.util.string.Strings;
import org.asteriskjava.manager.DefaultManagerConnection;
import org.asteriskjava.manager.ManagerConnection;
import org.asteriskjava.manager.ManagerConnectionFactory;
+import org.asteriskjava.manager.ManagerConnectionState;
import org.asteriskjava.manager.ResponseEvents;
import org.asteriskjava.manager.action.ConfbridgeListAction;
import org.asteriskjava.manager.action.DbDelAction;
@@ -85,6 +87,7 @@ public class SipManager implements ISipManager {
private int maxLocalWsPort = 7666;
private ManagerConnectionFactory factory;
+ private ManagerConnection con;
private String sipUserPicture;
private BitSet ports;
@@ -100,13 +103,23 @@ public class SipManager implements ISipManager {
}
}
- private ManagerConnection getConnection() {
- DefaultManagerConnection con = (DefaultManagerConnection)factory.createManagerConnection();
- con.setDefaultEventTimeout(managerTimeout);
- con.setDefaultResponseTimeout(managerTimeout);
- con.setSocketReadTimeout((int)managerTimeout);
- con.setSocketTimeout((int)managerTimeout);
- return con;
+ @PreDestroy
+ public void destroy() {
+ if (con != null) {
+ con.logoff();
+ }
+ }
+
+ private void connectManager() throws Exception {
+ if (con == null || ManagerConnectionState.CONNECTED != con.getState()) {
+ DefaultManagerConnection defCon = (DefaultManagerConnection)factory.createManagerConnection();
+ defCon.setDefaultEventTimeout(managerTimeout);
+ defCon.setDefaultResponseTimeout(managerTimeout);
+ defCon.setSocketReadTimeout((int)managerTimeout);
+ defCon.setSocketTimeout((int)managerTimeout);
+ con = defCon;
+ con.login("on");
+ }
}
private ManagerResponse exec(ManagerAction action) {
@@ -114,9 +127,8 @@ public class SipManager implements ISipManager {
log.warn("There is no Asterisk configured");
return null;
}
- ManagerConnection con = getConnection();
try {
- con.login();
+ connectManager();
ManagerResponse r = con.sendAction(action);
if (r != null) {
log.debug("{}", r);
@@ -124,12 +136,6 @@ public class SipManager implements ISipManager {
return (r instanceof ManagerError) ? null : r;
} catch (Exception e) {
log.error("Error while executing ManagerAction: {}", action, e);
- } finally {
- try {
- con.logoff();
- } catch (Exception e) {
- // no-op
- }
}
return null;
}
@@ -139,22 +145,15 @@ public class SipManager implements ISipManager {
log.warn("There is no Asterisk configured");
return null;
}
- ManagerConnection con = getConnection();
try {
- con.login("on");
+ connectManager();
ResponseEvents r = con.sendEventGeneratingAction(action);
if (r != null) {
- log.debug("{}", r.getResponse());
+ log.trace("{}", r.getResponse());
}
return (r == null || r.getResponse() instanceof ManagerError) ? null : r;
} catch (Exception e) {
log.error("Error while executing EventGeneratingAction: {}", action, e);
- } finally {
- try {
- con.logoff();
- } catch (Exception e) {
- // no-op
- }
}
return null;
}
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipStackProcessor.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipStackProcessor.java
index 31a1941..dc22235 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipStackProcessor.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipStackProcessor.java
@@ -198,8 +198,7 @@ public class SipStackProcessor implements SipListenerExt {
callbacks.onRegisterOk();
} else if (INVITE.equals(prevReq.getMethod())) {
dialog = evt.getDialog();
- ack(evt);
- callbacks.onInviteOk(new String((byte[])resp.getContent()));
+ callbacks.onInviteOk(new String((byte[])resp.getContent()), answer -> ack(evt, answer));
} else if (BYE.equals(prevReq.getMethod())) {
doDestroy();
}
@@ -212,12 +211,13 @@ public class SipStackProcessor implements SipListenerExt {
}
}
- private void ack(ResponseEvent evt) {
+ private void ack(ResponseEvent evt, String answer) {
try {
Response resp = evt.getResponse();
Dialog dlg = evt.getDialog();
CSeqHeader cseqHead = (CSeqHeader)resp.getHeader(CSeqHeader.NAME);
Request ack = dlg.createAck(cseqHead.getSeqNumber());
+ addSdp(ack, answer);
dlg.sendAck(ack);
} catch (Exception e) {
log.error("ack {}", evt, e);
@@ -336,6 +336,13 @@ public class SipStackProcessor implements SipListenerExt {
});
}
+ private void addSdp(Request req, String sdp) throws Exception {
+ if (sdp != null) {
+ req.addHeader(headerFactory.createContentLengthHeader(sdp.length()));
+ req.setContent(sdp, headerFactory.createContentTypeHeader("application", "sdp"));
+ }
+ }
+
public void invite(Room r, String sdp) {
final String sipNumber = getSipNumber(r);
if (sipNumber == null) {
@@ -349,10 +356,7 @@ public class SipStackProcessor implements SipListenerExt {
, req -> {
try {
addAllow(req);
- if (sdp != null) {
- req.addHeader(headerFactory.createContentLengthHeader(sdp.length()));
- req.setContent(sdp, headerFactory.createContentTypeHeader("application", "sdp"));
- }
+ addSdp(req, sdp);
} catch (Exception e) {
log.error("fail patch invite request", e);
}
diff --git a/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java b/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
index 7402754..3565a64 100644
--- a/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
+++ b/openmeetings-core/src/test/java/org/apache/openmeetings/core/remote/BaseMockedTest.java
@@ -20,6 +20,7 @@
package org.apache.openmeetings.core.remote;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
@@ -94,7 +95,7 @@ public class BaseMockedTest {
return null;
}
});
- streamMock.when(() -> AbstractStream.createWebRtcEndpoint(any(MediaPipeline.class))).thenReturn(mock(WebRtcEndpoint.class));
+ streamMock.when(() -> AbstractStream.createWebRtcEndpoint(any(MediaPipeline.class), anyBoolean())).thenReturn(mock(WebRtcEndpoint.class));
streamMock.when(() -> AbstractStream.createRecorderEndpoint(any(MediaPipeline.class), anyString(), any(MediaProfileSpecType.class))).thenReturn(mock(RecorderEndpoint.class));
streamMock.when(() -> AbstractStream.createPlayerEndpoint(any(MediaPipeline.class), anyString())).thenReturn(mock(PlayerEndpoint.class));
diff --git a/openmeetings-server/src/site/markdown/AsteriskIntegration.md b/openmeetings-server/src/site/markdown/AsteriskIntegration.md
index 0b98140..c6459d4 100644
--- a/openmeetings-server/src/site/markdown/AsteriskIntegration.md
+++ b/openmeetings-server/src/site/markdown/AsteriskIntegration.md
@@ -138,7 +138,6 @@ encryption=no
avpf=yes
icesupport=yes
directmedia=no
-disallow=all
allow=!all,ulaw,opus,vp8
```
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/KStreamDto.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/KStreamDto.java
index 90cc2b7..75265a7 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/KStreamDto.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/KStreamDto.java
@@ -37,30 +37,26 @@ import org.apache.openmeetings.db.entity.record.RecordingChunk.Type;
public class KStreamDto implements IDataProviderEntity {
private static final long serialVersionUID = 1L;
- private String sid;
- private String uid;
- private Long roomId;
- private Date connectedSince;
- private StreamType streamType;
- private String profile;
- private String recorder;
- private Long chunkId;
- private Type type;
+ private final String sid;
+ private final String uid;
+ private final Long roomId;
+ private final Date connectedSince;
+ private final StreamType streamType;
+ private final String profile;
+ private final String recorder;
+ private final Long chunkId;
+ private final Type type;
public KStreamDto(KStream kStream) {
- this.sid = kStream.getSid();
- this.uid = kStream.getUid();
- this.roomId = kStream.getRoomId();
- this.connectedSince = kStream.getConnectedSince();
- this.streamType = kStream.getStreamType();
- this.profile = kStream.getProfile().toString();
- this.recorder = (kStream.getRecorder() == null) ? null : kStream.getRecorder().toString();
- this.chunkId = kStream.getChunkId();
- this.type = kStream.getType();
- }
-
- public static long getSerialversionuid() {
- return serialVersionUID;
+ sid = kStream.getSid();
+ uid = kStream.getUid();
+ roomId = kStream.getRoomId();
+ connectedSince = kStream.getConnectedSince();
+ streamType = kStream.getStreamType();
+ profile = kStream.getProfile().toString();
+ recorder = (kStream.getRecorder() == null) ? null : kStream.getRecorder().toString();
+ chunkId = kStream.getChunkId();
+ type = kStream.getType();
}
public String getSid() {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/TimerService.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/TimerService.java
index 422755a..6829c0f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/TimerService.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/TimerService.java
@@ -102,7 +102,6 @@ public class TimerService {
private void updateSipLastName(Optional<Client> sipClient, Room r) {
long count = sipManager.countUsers(r.getConfno());
final String newLastName = "(" + count + ")";
- kHandler.updateSipCount(r, count);
sipClient.ifPresentOrElse(c -> {
if (!newLastName.equals(c.getUser().getLastname())) {
c.getUser().setLastname(newLastName).resetDisplayName();
@@ -113,11 +112,13 @@ public class TimerService {
User sipUser = sipManager.getSipUser(r);
sipUser.setLastname(newLastName).resetDisplayName();
Client c = new Client("-- unique - sip - session --", 1, sipUser, sipUser.getPictureUri());
+ c.allow(Right.VIDEO, Right.AUDIO);
cm.add(c);
c.setRoom(r);
cm.addToRoom(c);
WebSocketHelper.sendRoom(new TextRoomMessage(r.getId(), c, RoomMessage.Type.ROOM_ENTER, c.getUid()));
});
+ kHandler.updateSipCount(r, count);
}
public void scheduleModCheck(Room r) {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-room.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-room.js
index b54fbf6..0d349c2 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-room.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/raw-room.js
@@ -440,25 +440,27 @@ var Room = (function() {
.css('background-image', 'url(' + c.user.pictureUri + ')')
.find('.user.name').text(c.user.displayName);
- const actions = le.find('.user.actions');
- __rightVideoIcon(c, actions);
- __rightAudioIcon(c, actions);
- __rightOtherIcons(c, actions);
- __activityIcon(actions, '.kick'
- , () => !self && _hasRight('MODERATOR') && !_hasRight('SUPER_MODERATOR', c.rights)
- , null
- , {
- confirmationEvent: 'om-kick'
- , placement: Settings.isRtl ? 'left' : 'right'
- , onConfirm: () => OmUtil.roomAction({action: 'kick', uid: c.uid})
- });
- __activityIcon(actions, '.private-chat'
+ if (c.user.id !== -1) {
+ const actions = le.find('.user.actions');
+ __rightVideoIcon(c, actions);
+ __rightAudioIcon(c, actions);
+ __rightOtherIcons(c, actions);
+ __activityIcon(actions, '.kick'
+ , () => !self && _hasRight('MODERATOR') && !_hasRight('SUPER_MODERATOR', c.rights)
+ , null
+ , {
+ confirmationEvent: 'om-kick'
+ , placement: Settings.isRtl ? 'left' : 'right'
+ , onConfirm: () => OmUtil.roomAction({action: 'kick', uid: c.uid})
+ });
+ __activityIcon(actions, '.private-chat'
, () => options.userId !== c.user.id && $('#chatPanel').is(':visible')
, function() {
Chat.addTab('chatTab-u' + c.user.id, c.user.displayName);
Chat.open();
$('#chatMessage .wysiwyg-editor').click();
});
+ }
if (self) {
options.rights = c.rights;
_setQuickPollRights();