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 c44043a  [OPENMEETINGS-2239] initial commit, basic work with jain-sip
c44043a is described below

commit c44043a6d3a1dc34844d1ddd580c0569cb47adbf
Author: Maxim Solodovnik <solomax...@gmail.com>
AuthorDate: Mon Oct 12 13:31:39 2020 +0700

    [OPENMEETINGS-2239] initial commit, basic work with jain-sip
---
 openmeetings-db/pom.xml                            |   4 +
 .../apache/openmeetings/db/dao/room/SipConfig.java | 123 ++++++++
 .../apache/openmeetings/db/dao/room/SipDao.java    | 339 +++++++++++++++++++--
 .../src/site/markdown/AsteriskIntegration.md       | 107 +++++--
 openmeetings-web/pom.xml                           |   2 +-
 .../webapp/WEB-INF/classes/applicationContext.xml  |  24 +-
 6 files changed, 538 insertions(+), 61 deletions(-)

diff --git a/openmeetings-db/pom.xml b/openmeetings-db/pom.xml
index ef733ec..cd6d82a 100644
--- a/openmeetings-db/pom.xml
+++ b/openmeetings-db/pom.xml
@@ -109,6 +109,10 @@
                        <version>${mssql.version}</version>
                </dependency>
                <dependency>
+                       <groupId>javax.sip</groupId>
+                       <artifactId>jain-sip-ri</artifactId>
+               </dependency>
+               <dependency>
                        <groupId>org.apache.openmeetings</groupId>
                        <artifactId>openmeetings-util</artifactId>
                        <version>${project.version}</version>
diff --git 
a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipConfig.java
 
b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipConfig.java
new file mode 100644
index 0000000..e1a5646
--- /dev/null
+++ 
b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipConfig.java
@@ -0,0 +1,123 @@
+/*
+ * 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
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.db.dao.room;
+
+public class SipConfig {
+       private String sipHostname;
+       private int managerPort;
+       private String managerUser;
+       private String managerPass;
+       private long managerTimeout;
+
+       private int localWsPort = 6666;
+       private String localWsHost;
+       private int wsPort;
+       private String omSipUser;
+       private String omSipPasswd;
+
+       private String uid; //FIXME TODO is this still required ?!
+
+       public String getSipHostname() {
+               return sipHostname;
+       }
+
+       public void setSipHostname(String sipHostname) {
+               this.sipHostname = sipHostname;
+       }
+
+       public int getManagerPort() {
+               return managerPort;
+       }
+
+       public void setManagerPort(int managerPort) {
+               this.managerPort = managerPort;
+       }
+
+       public String getManagerUser() {
+               return managerUser;
+       }
+
+       public void setManagerUser(String managerUser) {
+               this.managerUser = managerUser;
+       }
+
+       public String getManagerPass() {
+               return managerPass;
+       }
+
+       public void setManagerPass(String managerPass) {
+               this.managerPass = managerPass;
+       }
+
+       public long getManagerTimeout() {
+               return managerTimeout;
+       }
+
+       public void setManagerTimeout(long managerTimeout) {
+               this.managerTimeout = managerTimeout;
+       }
+
+       public int getLocalWsPort() {
+               return localWsPort;
+       }
+
+       public void setLocalWsPort(int localWsPort) {
+               this.localWsPort = localWsPort;
+       }
+
+       public String getLocalWsHost() {
+               return localWsHost;
+       }
+
+       public void setLocalWsHost(String localWsHost) {
+               this.localWsHost = localWsHost;
+       }
+
+       public int getWsPort() {
+               return wsPort;
+       }
+
+       public void setWsPort(int wsPort) {
+               this.wsPort = wsPort;
+       }
+
+       public String getOmSipUser() {
+               return omSipUser;
+       }
+
+       public void setOmSipUser(String omSipUser) {
+               this.omSipUser = omSipUser;
+       }
+
+       public String getOmSipPasswd() {
+               return omSipPasswd;
+       }
+
+       public void setOmSipPasswd(String omSipPasswd) {
+               this.omSipPasswd = omSipPasswd;
+       }
+
+       public String getUid() {
+               return uid;
+       }
+
+       public void setUid(String uid) {
+               this.uid = uid;
+       }
+}
diff --git 
a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipDao.java 
b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipDao.java
index 900ce29..c41fdc6 100644
--- 
a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipDao.java
+++ 
b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipDao.java
@@ -18,6 +18,41 @@
  */
 package org.apache.openmeetings.db.dao.room;
 
+import static javax.sip.message.Request.INVITE;
+import static javax.sip.message.Request.REGISTER;
+import static javax.sip.message.Response.OK;
+import static javax.sip.message.Response.RINGING;
+import static javax.sip.message.Response.TRYING;
+import static javax.sip.message.Response.UNAUTHORIZED;
+
+import java.text.ParseException;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Consumer;
+
+import javax.annotation.PostConstruct;
+import javax.sip.ClientTransaction;
+import javax.sip.DialogTerminatedEvent;
+import javax.sip.IOExceptionEvent;
+import javax.sip.ListeningPoint;
+import javax.sip.RequestEvent;
+import javax.sip.ResponseEvent;
+import javax.sip.ServerTransaction;
+import javax.sip.SipException;
+import javax.sip.SipFactory;
+import javax.sip.SipProvider;
+import javax.sip.TimeoutEvent;
+import javax.sip.TransactionTerminatedEvent;
+import javax.sip.address.Address;
+import javax.sip.address.AddressFactory;
+import javax.sip.header.ContactHeader;
+import javax.sip.header.HeaderFactory;
+import javax.sip.message.MessageFactory;
+import javax.sip.message.Request;
+import javax.sip.message.Response;
+
 import org.apache.openmeetings.db.entity.room.Room;
 import org.asteriskjava.manager.DefaultManagerConnection;
 import org.asteriskjava.manager.ManagerConnection;
@@ -35,40 +70,94 @@ import org.asteriskjava.manager.response.ManagerError;
 import org.asteriskjava.manager.response.ManagerResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import gov.nist.javax.sip.DialogTimeoutEvent;
+import gov.nist.javax.sip.SipListenerExt;
+import gov.nist.javax.sip.SipStackExt;
+import gov.nist.javax.sip.address.SipUri;
+import gov.nist.javax.sip.clientauthutils.AuthenticationHelper;
+import gov.nist.javax.sip.clientauthutils.UserCredentials;
+import gov.nist.javax.sip.stack.NioMessageProcessorFactory;
 
-public class SipDao {
+@Service
+public class SipDao implements SipListenerExt {
        private static final Logger log = LoggerFactory.getLogger(SipDao.class);
        public static final String ASTERISK_OM_FAMILY = "openmeetings";
        public static final String ASTERISK_OM_KEY = "rooms";
        public static final String SIP_FIRST_NAME = "SIP Transport";
        public static final String SIP_USER_NAME = "--SIP--";
-       private String sipHostname;
-       private int sipPort;
-       private String sipUsername;
-       private String sipPassword;
-       private String uid;
-       private long timeout;
+       private static final String SIP_TRANSPORT = "ws";
+       private static final <T> Consumer<T> NOOP() {
+               return t -> {};
+       }
+
+       private final AtomicLong cseq = new AtomicLong();
+       private final Random rnd = new Random();
+
+       private String tag;
+       private String branch;
+
+       private SipProvider sipProvider;
+       private SipFactory sipFactory;
+       private SipStackExt sipStack;
+       private MessageFactory messageFactory;
+       private HeaderFactory headerFactory;
+       private AddressFactory addressFactory;
+       private ContactHeader contactHeader;
        private ManagerConnectionFactory factory;
 
-       public SipDao() {
-               // enabled for @SpringBean
-       }
+       @Autowired
+       private SipConfig config;
+
+       @PostConstruct
+       public void init() throws Exception {
+               if (config.getSipHostname() != null) {
+                       factory = new ManagerConnectionFactory(
+                                       config.getSipHostname()
+                                       , config.getManagerPort()
+                                       , config.getManagerUser()
+                                       , config.getManagerPass());
+                       sipFactory = SipFactory.getInstance();
+                       sipFactory.setPathName("gov.nist");
 
-       public SipDao(String sipHostname, int sipPort, String sipUsername, 
String sipPassword, long timeout) {
-               this.sipHostname = sipHostname;
-               this.sipPort = sipPort;
-               this.sipUsername = sipUsername;
-               this.sipPassword = sipPassword;
-               this.timeout = timeout;
-               factory = new ManagerConnectionFactory(this.sipHostname, 
this.sipPort, this.sipUsername, this.sipPassword);
+                       final Properties properties = new Properties();
+                       properties.setProperty("javax.sip.STACK_NAME", "stack");
+                       
//properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
+                       
properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
+                       
properties.setProperty("gov.nist.javax.sip.MESSAGE_PROCESSOR_FACTORY", 
NioMessageProcessorFactory.class.getName());
+                       sipStack = (SipStackExt) 
sipFactory.createSipStack(properties);
+                       tag = getRnd(10);
+                       branch = getRnd(14);
+
+                       messageFactory = sipFactory.createMessageFactory();
+                       headerFactory = sipFactory.createHeaderFactory();
+                       addressFactory = sipFactory.createAddressFactory();
+                       final ListeningPoint listeningPoint = 
sipStack.createListeningPoint(
+                                       config.getLocalWsHost()
+                                       , config.getLocalWsPort()
+                                       , SIP_TRANSPORT);
+                       sipProvider = 
sipStack.createSipProvider(listeningPoint);
+                       sipProvider.addSipListener(this);
+                       Address contact = createAddr(config.getOmSipUser(), 
config.getLocalWsHost(), uri -> {
+                               try {
+                                       uri.setPort(config.getLocalWsPort());
+                                       uri.setTransportParam(SIP_TRANSPORT);
+                               } catch (ParseException e) {
+                                       log.error("fail to create contact 
address", e);
+                               }
+                       });
+                       contactHeader = 
headerFactory.createContactHeader(contact);
+               }
        }
 
        private ManagerConnection getConnection() {
                DefaultManagerConnection con = 
(DefaultManagerConnection)factory.createManagerConnection();
-               con.setDefaultEventTimeout(timeout);
-               con.setDefaultResponseTimeout(timeout);
-               con.setSocketReadTimeout((int)timeout);
-               con.setSocketTimeout((int)timeout);
+               con.setDefaultEventTimeout(config.getManagerTimeout());
+               con.setDefaultResponseTimeout(config.getManagerTimeout());
+               con.setSocketReadTimeout((int)config.getManagerTimeout());
+               con.setSocketTimeout((int)config.getManagerTimeout());
                return con;
        }
 
@@ -126,6 +215,10 @@ public class SipDao {
                return ASTERISK_OM_KEY + "/" + confno;
        }
 
+       private static String getSipNumber(Room r) {
+               return (r != null && r.getConfno() != null) ? r.getConfno() : 
null;
+       }
+
        public String get(String confno) {
                String pin = null;
                DbGetAction da = new DbGetAction(ASTERISK_OM_FAMILY, 
getKey(confno));
@@ -175,7 +268,7 @@ public class SipDao {
         *            room to be connected to the call
         */
        public void joinToConfCall(String number, Room r) {
-               String sipNumber = (r != null && r.getConfno() != null) ? 
r.getConfno() : null;
+               String sipNumber = getSipNumber(r);
                if (sipNumber == null) {
                        log.warn("Failed to get SIP number for room: {}", r);
                        return;
@@ -186,16 +279,208 @@ public class SipDao {
                oa.setContext("rooms-out");
                oa.setExten(number);
                oa.setPriority(1);
-               oa.setTimeout(timeout);
+               oa.setTimeout(config.getManagerTimeout());
 
                exec(oa);
        }
 
-       public String getUid() {
-               return uid;
+       @Override
+       public void processDialogTerminated(DialogTerminatedEvent evt) {
+               log.error("processDialogTerminated: \n{}", evt);
+       }
+
+       @Override
+       public void processIOException(IOExceptionEvent evt) {
+               log.error("processIOException: \n{}", evt);
        }
 
-       public void setUid(String uid) {
-               this.uid = uid;
+       @Override
+       public void processTimeout(TimeoutEvent evt) {
+               log.error("processTimeout: \n{}", evt);
+       }
+
+       @Override
+       public void processTransactionTerminated(TransactionTerminatedEvent 
evt) {
+               log.error("processTransactionTerminated: \n{}", evt);
+       }
+
+       @Override
+       public void processDialogTimeout(DialogTimeoutEvent timeoutEvent) {
+               log.error("processDialogTimeout: \n{}", timeoutEvent);
+       }
+
+       @Override
+       public void processRequest(RequestEvent evt) {
+               log.debug("processRequest: \n\n{}", evt.getRequest());
+               Request rq = evt.getRequest();
+               String method = rq.getMethod();
+               try {
+                       if (Request.OPTIONS.equals(method)) {
+                               ServerTransaction transaction = 
sipProvider.getNewServerTransaction(rq);
+                               Response resp = 
messageFactory.createResponse(200, rq);
+                               resp.addHeader(contactHeader);
+                               transaction.sendResponse(resp);
+                       }
+               } catch (Exception e) {
+                       log.error("processRequest", e);
+               }
+       }
+
+       @Override
+       public void processResponse(ResponseEvent evt) {
+               Response resp = evt.getResponse();
+               ClientTransaction curTrans = evt.getClientTransaction();
+               Request prevReq = curTrans.getRequest();
+               log.warn("Response code: {} on {}", resp.getStatusCode(), 
prevReq.getMethod());
+               switch (resp.getStatusCode()) {
+                       case UNAUTHORIZED:
+                               processUnauth(evt);
+                               break;
+                       case OK:
+                               break;
+                       case TRYING:
+                       case RINGING:
+                               break;
+                       // FIXME TODO other codes: 404
+                       default:
+                               log.debug("No handler for response: \n\n{}", 
resp);
+               }
+       }
+
+       private String getRnd(int count) {
+               return rnd.ints('0', 'z' + 1)
+                               .filter(ch -> (ch >= '0' && ch <= '9') || (ch 
>= 'a' && ch <= 'z'))
+                               .limit(count)
+                               .collect(StringBuilder::new, 
StringBuilder::appendCodePoint, StringBuilder::append)
+                               .toString();
+       }
+
+       private Address createAddr(String user) {
+               return createAddr(user, config.getSipHostname(), NOOP());
+       }
+
+       private Address createAddr(String user, String host, Consumer<SipUri> 
cons) {
+               try {
+                       SipUri uri = new SipUri();
+                       uri.setHost(host);
+                       uri.setUser(user);
+                       cons.accept(uri);
+                       return addressFactory.createAddress(user, uri);
+               } catch (ParseException e) {
+                       log.error("fail to create address", e);
+               }
+               return null;
+       }
+
+       private void sendRequest(String method, String to, Consumer<SipUri> 
uriCons, Consumer<Request> reqCons) throws Exception {
+               SipUri uri = new SipUri();
+               uri.setHost(config.getSipHostname());
+               uri.setPort(config.getWsPort());
+               uri.setTransportParam(SIP_TRANSPORT);
+               uri.setMethodParam("GET");
+               uri.setHeader("Host", config.getSipHostname());
+               uri.setHeader("Location", "/ws");
+               uriCons.accept(uri);
+
+               Request request = messageFactory.createRequest(
+                               uri
+                               , method
+                               , sipProvider.getNewCallId()
+                               , 
headerFactory.createCSeqHeader(cseq.incrementAndGet(), method)
+                               , 
headerFactory.createFromHeader(createAddr(config.getOmSipUser()), tag)
+                               , headerFactory.createToHeader(createAddr(to), 
null)
+                               , 
List.of(headerFactory.createViaHeader(config.getLocalWsHost(), 
config.getLocalWsPort(), SIP_TRANSPORT, branch))
+                               , headerFactory.createMaxForwardsHeader(70));
+               request.addHeader(contactHeader);
+               request.addHeader(headerFactory.createExpiresHeader(600));
+
+               reqCons.accept(request);
+
+               log.debug("sendRequest: \n\n{}", request);
+
+               ClientTransaction trans = 
sipProvider.getNewClientTransaction(request);
+               trans.sendRequest();
+       }
+
+       private void processUnauth(ResponseEvent evt) {
+               Response resp = evt.getResponse();
+               ClientTransaction curTrans = evt.getClientTransaction();
+               AuthenticationHelper helper = 
sipStack.getAuthenticationHelper((trans, s) -> new UserCredentials() {
+                       @Override
+                       public String getUserName() {
+                               return config.getOmSipUser();
+                       }
+
+                       @Override
+                       public String getPassword() {
+                               return config.getOmSipPasswd();
+                       }
+
+                       @Override
+                       public String getSipDomain() {
+                               return "asterisk";
+                       }
+               }, headerFactory);
+               try {
+                       ClientTransaction trans = helper.handleChallenge(resp, 
curTrans, sipProvider, 5);
+                       trans.sendRequest();
+               } catch (SipException e) {
+                       log.error("Error while sending AUTH", e);
+               }
+       }
+
+       private void addAllow(Request req) throws ParseException {
+               
req.addHeader(headerFactory.createAllowHeader("ACK,CANCEL,INVITE,MESSAGE,BYE,OPTIONS,INFO,NOTIFY,REFER"));
+       }
+
+       private void register() throws Exception {
+               sendRequest(
+                               REGISTER
+                               , config.getOmSipUser()
+                               , NOOP()
+                               , req -> {
+                                       try {
+                                               addAllow(req);
+                                       } catch (ParseException e) {
+                                               log.error("fail to create allow 
header", e);
+                                       }
+                               });
+       }
+
+       private void invite(Room r, String sdp) throws Exception {
+               final String sipNumber = getSipNumber(r);
+               if (sipNumber == null) {
+                       log.warn("Failed to get SIP number for room: {}", r);
+                       return;
+               }
+               sendRequest(
+                               INVITE
+                               , sipNumber
+                               , uri -> uri.setUser(sipNumber)
+                               , req -> {
+                                       /*
+                                        * ContentLengthHeader contentLength =
+                                        * 
this.headerFactory.createContentLengthHeader(300);
+                                        * ContentTypeHeader contentType =
+                                        * 
this.headerFactory.createContentTypeHeader("application",
+                                        * "sdp");
+                                        *
+                                        * String sdpData = "v=0\n" +
+                                        * "o=user1 392867480 292042336 IN IP4 
xx.xx.xx.xx\n" + "s=-\n"
+                                        * + "c=IN IP4 xx.xx.xx.xx\n" + "t=0 
0\n" +
+                                        * "m=audio 8000 RTP/AVP 0 8 101\n" + 
"a=rtpmap:0 PCMU/8000\n" +
+                                        * "a=rtpmap:8 PCMA/8000\n" +
+                                        * "a=rtpmap:101 
telephone-event/8000\n" + "a=sendrecv"; byte[]
+                                        * contents = sdpData.getBytes(); 
this.contactHeader =
+                                        * 
this.headerFactory.createContactHeader(contactAddress);
+                                        */
+                                       try {
+                                               addAllow(req);
+                                               
req.addHeader(headerFactory.createContentLengthHeader(sdp.length()));
+                                               req.setContent(sdp, 
headerFactory.createContentTypeHeader("application", "sdp"));
+                                       } catch (Exception e) {
+                                               log.error("fail to create allow 
header", e);
+                                       }
+                               });
        }
 }
diff --git a/openmeetings-server/src/site/markdown/AsteriskIntegration.md 
b/openmeetings-server/src/site/markdown/AsteriskIntegration.md
index 44107ce..2fd9105 100644
--- a/openmeetings-server/src/site/markdown/AsteriskIntegration.md
+++ b/openmeetings-server/src/site/markdown/AsteriskIntegration.md
@@ -125,19 +125,22 @@ rtcachefriends=yes
 maxexpiry=43200
 ```
 
-** FIXME TODO Add user for the "SIP Transport"**
+**Add user for the "SIP Transport"**
 
 ```
-; FIXME TODO commented for now
-; [red5sip_user]
-; type=friend
-; secret=12345
-; disallow=all
-; allow=ulaw
-; allow=h263
-; host=dynamic
-; nat=force_rport,comedia
-; context=rooms-red5sip
+[omsip_user]
+host=dynamic
+secret=12345
+context=rooms-omsip
+transport=ws,wss
+type=friend
+encryption=no
+avpf=yes
+icesupport=yes
+directmedia=no
+disallow=all
+allow=ulaw,opus
+allow=vp8
 ```
 
 ### Configure extensions:
@@ -187,11 +190,10 @@ exten => _400X!,n,Hangup
 ; Extensions for outgoing calls from Openmeetings room.
 ; *****************************************************
 
-; FIXME TODO commented for now
-;[rooms-red5sip]
-;exten => 
_400X!,1,GotoIf($[${DB_EXISTS(openmeetings/rooms/${EXTEN})}]?ok:notavail)
-;exten => _400X!,n(ok),Confbridge(${EXTEN},default_bridge,red5sip_user)
-;exten => _400X!,n(notavail),Hangup
+[rooms-omsip]
+exten => 
_400X!,1,GotoIf($[${DB_EXISTS(openmeetings/rooms/${EXTEN})}]?ok:notavail)
+exten => _400X!,n(ok),Confbridge(${EXTEN},default_bridge,omsip_user)
+exten => _400X!,n(notavail),Hangup
 ```
 
 ### Configure Confbridge
@@ -203,12 +205,11 @@ Modify `/etc/asterisk/confbridge.conf`
 ```
 [general]
 
-; FIXME TODO commented for now
-;[red5sip_user]
-;type=user
-;marked=yes
-;dsp_drop_silence=yes
-;denoise=true
+[omsip_user]
+type=user
+marked=yes
+dsp_drop_silence=yes
+denoise=true
 
 [sip_user]
 type=user
@@ -247,8 +248,8 @@ write = all
 Update OpenMeetings with credentials for Asterisk manager.
 Modify `/opt/om/webapps/openmeetings/WEB-INF/classes/applicationContext.xml`
 
-find **&lt;bean id="sipDao" 
class="org.apache.openmeetings.db.dao.room.SipDao"&gt;**
-uncomment its parameters and set it to your custom values.
+find **&lt;bean class="org.apache.openmeetings.db.dao.room.SipConfig"&gt;**
+uncomment its properties and set it to your custom values.
 
 set value for `uid` property to unique secret value (can be generated here <a 
href="https://www.uuidtools.com";>https://www.uuidtools.com</a>)
 
@@ -257,3 +258,61 @@ set value for `uid` property to unique secret value (can 
be generated here <a hr
        otherwise all SIP related room information will be lost
 </p>
 
+### Configure Asterisk's built-in HTTP server
+
+To communicate with WebSocket clients, Asterisk uses its built-in HTTP server. 
Configure `/etc/asterisk/http.conf` as follows:
+
+```
+[general]
+enabled=yes
+bindaddr=127.0.0.1  ; or your Asterisk IP
+bindport=8088
+tlsenable=yes
+tlsbindaddr=0.0.0.0:8089
+tlscertfile=/etc/asterisk/keys/asterisk.crt
+tlsprivatekey=/etc/asterisk/keys/asterisk.key
+```
+
+### Configure PJSIP
+
+If you're not already familiar with configuring Asterisk's chan_pjsip driver, 
visit the res_pjsip configuration page.
+
+Modify `/etc/asterisk/pjsip.conf` as follows:
+
+```
+[transport-wss]
+type=transport
+protocol=wss
+bind=0.0.0.0
+; All other transport parameters are ignored for wss transports.
+
+[webrtc_client]
+type=aor
+max_contacts=5
+remove_existing=yes
+
+[webrtc_client]
+type=auth
+auth_type=userpass
+username=webrtc_client
+password=webrtc_client ; This is a completely insecure password!  Do NOT 
expose this
+                       ; system to the Internet without utilizing a better 
password.
+
+[webrtc_client]
+type=endpoint
+aors=webrtc_client
+auth=webrtc_client
+dtls_auto_generate_cert=yes
+webrtc=yes
+; Setting webrtc=yes is a shortcut for setting the following options:
+; use_avpf=yes
+; media_encryption=dtls
+; dtls_verify=fingerprint
+; dtls_setup=actpass
+; ice_support=yes
+; media_use_received_transport=yes
+; rtcp_mux=yes
+context=default
+disallow=all
+allow=opus,ulaw
+```
diff --git a/openmeetings-web/pom.xml b/openmeetings-web/pom.xml
index 8734b46..c9a6fd1 100644
--- a/openmeetings-web/pom.xml
+++ b/openmeetings-web/pom.xml
@@ -663,7 +663,7 @@
                <dependency>
                        <groupId>org.webjars</groupId>
                        <artifactId>font-awesome</artifactId>
-                       <version>5.14.0</version>
+                       <version>${font-awesome.version}</version>
                </dependency>
                <dependency>
                        <groupId>org.apache.commons</groupId>
diff --git 
a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml 
b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
index 567814b..0edbe2b 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
@@ -124,16 +124,22 @@
        </bean>
        <!-- End of Services -->
 
-       <!-- Interface Transactional -->
-       <bean id="sipDao" class="org.apache.openmeetings.db.dao.room.SipDao">
-       <!-- Should be uncommented and updated with real values for Asterisk
-               <constructor-arg index="0" value="127.0.0.1"/>
-               <constructor-arg index="1" value="5038" type = "int"/>
-               <constructor-arg index="2" value="openmeetings"/>
-               <constructor-arg index="3" value="12345"/>
-               <constructor-arg index="4" value="10000" type = "long"/>
+       <bean class="org.apache.openmeetings.db.dao.room.SipConfig">
+               <!-- Should be uncommented and updated with real values for 
Asterisk-
+               <property name="sipHostname" value="192.168.1.102"/>
+               <property name="managerPort" value="5038"/>
+               <property name="managerUser" value="openmeetings"/>
+               <property name="managerPass" value="12345"/>
+               <property name="managerTimeout" value="10000"/>
+
+               <property name="localWsPort" value="6666"/>
+               <property name="localWsHost" value="192.168.1.211"/>
+               <property name="wsPort" value="8088"/>
+               <property name="omSipUser" value="omsip_user"/>
+               <property name="omSipPasswd" value="12345"/>
+
                <property name="uid" 
value="87dddad4-9ca5-475b-860f-2e0825d02b76"/>
-       -->
+               -  -->
        </bean>
 
        <!-- Thread Executor -->

Reply via email to