Пример #1
0
 public override void Setup()
 {
     base.Setup();
     _callMgr = _fixture.Freeze <Mock <ICallManagerInternal> >();
     _call    = _fixture.Freeze <Mock <ICallInternal> >();
     _session = _fixture.CreateAnonymous <InviteSession>();
 }
        async Task ReceiveShortSingleMessageAsync(InviteSession session, InviteRequestPacket req)
        {
            string receivedMessage;

            try
            {
                receivedMessage = await session.ReceiveShortSingleMessageAsync(session.RemoteSessionDescription.UserCertificate);
            }
            finally
            {
                session.Dispose();
            }

            // call app
            _drpPeerApp.OnReceivedShortSingleMessage(receivedMessage, req);
        }
        async Task Ike1Async_AtInviteResponder(InviteSession session, InviteRequestPacket req)
        {
            try
            {
                var localIke1Data = _drpPeerApp.OnReceivedInvite_GetLocalIke1Data(req.ContactInvitationTokenNullable);
                if (localIke1Data == null)
                {
                    throw new BadSignatureException();
                }
                var remoteIke1Data = await session.Ike1Async_AtInviteResponder(session.LocalSessionDescription.UserCertificate,
                                                                               localIke1Data, session.RemoteSessionDescription.UserCertificate);

                remoteIke1Data.RemoteEndPoint = session.RemoteSessionDescription.DirectChannelEndPoint;
                _drpPeerApp.OnReceivedInvite_SetRemoteIke1Data(req.ContactInvitationTokenNullable, remoteIke1Data);
            }
            finally
            {
                session.Dispose();
            }
        }
Пример #4
0
        public static DmpPingPacket DecodeAndVerify(byte[] udpData, InviteSession session)
        {
            var reader = BinaryProcedures.CreateBinaryReader(udpData, 1);

            var r = new DmpPingPacket();

            r.DirectChannelToken32 = DirectChannelToken32.Decode(reader);
            r.PingRequestId32      = reader.ReadUInt32();

            var flags = reader.ReadByte();

            if ((flags & FlagsMask_MustBeZero) != 0)
            {
                throw new NotImplementedException();
            }

            if ((flags & Flags_PublicEcdheKeySet) != 0)
            {
                r.PublicEcdheKey = EcdhPublicKey.Decode(reader);
            }

            r.PingPongHMAC = HMAC.Decode(reader);

            // verify DirectChannelToken32
            if (!r.DirectChannelToken32.Equals(session.LocalSessionDescription.DirectChannelToken32))
            {
                throw new BadSignatureException("invalid DMP PING DirectChannelToken32 136");
            }

            // verify PingPongHMAC
            if (r.PingPongHMAC.Equals(
                    session.GetPingPongHMAC(r.GetSignedFieldsForPingPongHMAC)
                    ) == false)
            {
                throw new BadSignatureException("invalid DMP PING PingPongHMAC 1237");
            }

            return(r);
        }
Пример #5
0
        internal static LowLevelUdpResponseScanner GetScanner(uint messageId32, InviteSession session, MessageSessionStatusCode statusCode)
        {
            BinaryProcedures.CreateBinaryWriter(out var ms, out var w);
            w.Write((byte)PacketTypes.MessageAck);
            w.Write(messageId32);
            w.Write((byte)statusCode);

            return(new LowLevelUdpResponseScanner
            {
                ResponseFirstBytes = ms.ToArray(),
                OptionalFilter = (udpData) =>
                {
                    var msgAck = Decode(udpData);
                    if (msgAck.MessageHMAC.Equals(
                            session.GetMessageHMAC(msgAck.GetSignedFieldsForMessageHMAC)
                            ) == false)
                    {
                        return false;
                    }
                    return true;
                }
            });
        }
        /// <summary>
        /// Timestamp32S, NeighborToken32 and NeighborHMAC are verified at this time
        /// </summary>
        internal async Task AcceptInviteRequestAsync(RoutedRequest routedRequest)
        {
            if (routedRequest.ReceivedFromNeighborNullable == null)
            {
                throw new ArgumentException();
            }
            var req = routedRequest.InviteReq;

            if (!req.ResponderRegistrationId.Equals(this.Configuration.LocalPeerRegistrationId))
            {
                throw new ArgumentException();
            }
            var logger = routedRequest.Logger;

            logger.ModuleName = DrpPeerEngine.VisionChannelModuleName_inv_responderSide;

            if (logger.WriteToLog_detail_enabled)
            {
                logger.WriteToLog_detail($"accepting {req} from sourcePeer={routedRequest.ReceivedFromNeighborNullable}");
            }

            // check if regID exists in contact book, get userID from the local contact book
            // ignore the REQ packet if no such user in contacts
            this._drpPeerApp.OnReceivedInvite(req.RequesterRegistrationId, req.ContactInvitationTokenNullable, out var remoteRequesterUserIdFromLocalContactBookNullable, out var localUserCertificateWithPrivateKey, out var autoReply);
            if (autoReply == false)
            {
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_needsAttention($"ignored invite: autoReply = false");
                }
                return;
            }
            localUserCertificateWithPrivateKey?.AssertHasPrivateKey();

            if (remoteRequesterUserIdFromLocalContactBookNullable != null)
            {
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"resolved user {remoteRequesterUserIdFromLocalContactBookNullable} by requester regID={req.RequesterRegistrationId}");
                }
            }

            if (!Engine.RecentUniquePublicEcdhKeys.Filter(req.RequesterEcdhePublicKey.Ecdh25519PublicKey))
            {
                logger.WriteToLog_mediumPain($"RequesterEcdhePublicKey {req.RequesterEcdhePublicKey} is not unique, it has been recently processed");
                return;
            }
            if (!Engine.RecentUniqueInviteRequests.Filter(req.GetUniqueRequestIdFields))
            {
                logger.WriteToLog_mediumPain($"{req} fields are not unique, the request has been recently processed");
                return;
            }

            // verify requester reg. signature
            if (!req.RequesterRegistrationSignature.Verify(Engine.CryptoLibrary, req.GetSharedSignedFields, req.RequesterRegistrationId))
            {
                throw new BadSignatureException("invalid INVITE REQ RequesterRegistrationSignature 2349");
            }

            _pendingInviteRequests.Add(req.RequesterRegistrationId);

            try
            {
                // send NPACK to REQ
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"sending NPACK to REQ source peer");
                }
                routedRequest.SendNeighborPeerAck_accepted_IfNotAlreadyReplied();

                var session = new InviteSession(this)
                {
                    Logger = logger
                };
                try
                {
                    session.DeriveSharedInviteAckDhSecret(Engine.CryptoLibrary, req.RequesterEcdhePublicKey.Ecdh25519PublicKey);

                    session.LocalSessionDescription = new InviteSessionDescription
                    {
                        DirectChannelEndPoint = routedRequest.ReceivedFromNeighborNullable.LocalEndpoint,
                        NatBehaviour          = Engine.LocalNatBehaviour,
                        DirectChannelToken32  = session.LocalDirectChannelToken32
                    };
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"responding with local session {session.LocalSessionDescription}");
                    }

                    session.LocalSessionDescription.UserCertificate = localUserCertificateWithPrivateKey;

                    #region send ACK1. sign local SD by local user
                    var ack1 = new InviteAck1Packet
                    {
                        ReqTimestamp32S         = req.ReqTimestamp32S,
                        RequesterRegistrationId = req.RequesterRegistrationId,
                        ResponderRegistrationId = req.ResponderRegistrationId,
                        ResponderEcdhePublicKey = new EcdhPublicKey(session.LocalInviteAckEcdhePublicKey),
                    };
                    session.LocalSessionDescription.UserCertificateSignature = UserCertificateSignature.Sign(Engine.CryptoLibrary,
                                                                                                             w =>
                    {
                        req.GetSharedSignedFields(w);
                        ack1.GetSharedSignedFields(w, false);
                        session.LocalSessionDescription.WriteSignedFields(w);
                    },
                                                                                                             localUserCertificateWithPrivateKey);

                    ack1.ToResponderSessionDescriptionEncrypted = session.LocalSessionDescription.Encrypt(Engine.CryptoLibrary,
                                                                                                          req, ack1, session, false);
                    ack1.ResponderRegistrationSignature = RegistrationSignature.Sign(Engine.CryptoLibrary, w =>
                    {
                        req.GetSharedSignedFields(w);
                        ack1.GetSharedSignedFields(w, true);
                    },
                                                                                     this.Configuration.LocalPeerRegistrationPrivateKey
                                                                                     );

                    var ack1UdpData = ack1.Encode_SetP2pFields(routedRequest.ReceivedFromNeighborNullable);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending ACK1 to source peer, awaiting for NPACK");
                    }
                    _ = routedRequest.ReceivedFromNeighborNullable.SendUdpRequestAsync_Retransmit_WaitForNPACK("ack1 1450", ack1UdpData, ack1.ReqP2pSeq16, ack1.GetSignedFieldsForNeighborHMAC);
                    // not waiting for NPACK, wait for ACK2
                    #endregion

                    // wait for ACK2
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"waiting for ACK2");
                    }
                    var ack2UdpData = await Engine.OptionallySendUdpRequestAsync_Retransmit_WaitForResponse("ack2 23467789", routedRequest.ReceivedFromNeighborNullable.ToString(), null, routedRequest.ReceivedFromNeighborNullable.RemoteEndpoint,
                                                                                                            InviteAck2Packet.GetScanner(logger, req, routedRequest.ReceivedFromNeighborNullable));

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"received ACK2");
                    }
                    var ack2 = InviteAck2Packet.Decode(ack2UdpData);
                    if (!ack2.RequesterRegistrationSignature.Verify(Engine.CryptoLibrary, w =>
                    {
                        req.GetSharedSignedFields(w);
                        ack1.GetSharedSignedFields(w, true);
                        ack2.GetSharedSignedFields(w);
                    }, req.RequesterRegistrationId))
                    {
                        throw new BadSignatureException("invalid INVITE ACK2 RequesterRegistrationSignature 2348");
                    }
                    // decrypt, verify SD remote user's certificate and signature
                    session.RemoteSessionDescription = InviteSessionDescription.Decrypt_Verify(Engine.CryptoLibrary,
                                                                                               ack2.ToRequesterSessionDescriptionEncrypted,
                                                                                               req, ack1, true, session, remoteRequesterUserIdFromLocalContactBookNullable, Engine.DateTimeNowUtc);
                    session.LocalSessionDescription.SessionType = session.RemoteSessionDescription.SessionType;

                    switch (session.RemoteSessionDescription.SessionType)
                    {
                    case SessionType.asyncShortSingleMessage: break;

                    case SessionType.ike1:
                        if (_drpPeerApp.OnReceivedInvite_GetLocalIke1Data(req.ContactInvitationTokenNullable) == null)
                        {
                            throw new BadSignatureException("bad ContactInvitationToken 21379");
                        }
                        break;

                    default: throw new NotImplementedException();
                    }

                    // send NPACK to ACK2
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending NPACK to ACK2 to source peer");
                    }
                    SendNeighborPeerAckResponseToAck2(ack2, routedRequest.ReceivedFromNeighborNullable);

                    // send CFM with signature
                    var cfm = new InviteConfirmationPacket
                    {
                        ReqTimestamp32S         = req.ReqTimestamp32S,
                        RequesterRegistrationId = req.RequesterRegistrationId,
                        ResponderRegistrationId = req.ResponderRegistrationId,
                    };
                    cfm.ResponderRegistrationSignature = RegistrationSignature.Sign(Engine.CryptoLibrary, w =>
                    {
                        req.GetSharedSignedFields(w);
                        ack1.GetSharedSignedFields(w, true);
                        ack2.GetSharedSignedFields(w);
                    }, this.Configuration.LocalPeerRegistrationPrivateKey);
                    var cfmUdpData = cfm.Encode_SetP2pFields(routedRequest.ReceivedFromNeighborNullable);

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending CFM to source peer, waiting for NPACK");
                    }
                    await routedRequest.ReceivedFromNeighborNullable.SendUdpRequestAsync_Retransmit_WaitForNPACK("cfm 49146", cfmUdpData, cfm.ReqP2pSeq16, cfm.GetSignedFieldsForNeighborHMAC);

                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"received NPACK to CFM");
                    }

                    session.DeriveSharedPingPongHmacKey(req, ack1, ack2, cfm);

                    await session.SetupAEkeysAsync();
                }
                catch
                {
                    session.Dispose();
                    throw;
                }

                if (autoReply)
                {
                    switch (session.RemoteSessionDescription.SessionType)
                    {
                    case SessionType.asyncShortSingleMessage:
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"autoReply=true: receiving message");
                        }
                        _ = ReceiveShortSingleMessageAsync(session, req);
                        break;

                    case SessionType.ike1:
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"autoReply=true: starting IKE1");
                        }
                        _ = Ike1Async_AtInviteResponder(session, req);
                        break;

                    default: throw new NotImplementedException();
                    }
                }
                else
                {
                    session.Dispose(); // todo implement other cases
                }
            }
            catch (DrpTimeoutException exc)
            {
                logger.WriteToLog_lightPain($"could not accept INVITE request: {exc}");
            }
            catch (Exception exc)
            {
                logger.WriteToLog_mediumPain($"could not accept INVITE request: {exc}");
            }
            finally
            {
                _pendingInviteRequests.Remove(req.RequesterRegistrationId);
            }
        }
Пример #7
0
 public static LowLevelUdpResponseScanner GetScanner(DirectChannelToken32 senderToken32, uint pingRequestId32, InviteSession session)
 {
     BinaryProcedures.CreateBinaryWriter(out var ms, out var w);
     GetHeaderFields(w, senderToken32, pingRequestId32);
     return(new LowLevelUdpResponseScanner
     {
         ResponseFirstBytes = ms.ToArray(),
         OptionalFilter = (udpData) =>
         {
             var pong = Decode(udpData);
             if (pong.PingPongHMAC.Equals(
                     session.GetPingPongHMAC(pong.GetSignedFieldsForPingPongHMAC)
                     ) == false)
             {
                 return false;
             }
             return true;
         }
     });
 }
Пример #8
0
        /// <summary>
        /// sends INVITE, autenticates users, returns Session to be used to create direct cannel
        /// </summary>
        /// <param name="responderUserId">
        /// comes from local contact book
        /// </param>
        /// <param name="responderRegId">
        /// comes from local contact book
        /// </param>
        /// <param name="loggerCb">may be invoked more than one time (in case of retrying)</param>
        public async Task <InviteSession> SendInviteAsync(UserCertificate requesterUserCertificate, RegistrationId responderRegistrationId, UserId responderUserId,
                                                          SessionType sessionType, Action <Logger> loggerCb = null)
        {
            InviteSession session = null;

            try
            {
                var           sw            = Stopwatch.StartNew();
                RoutedRequest routedRequest = null;
                int           trialsCount   = 0;
                Exception     latestTriedNeighborException = null;


_retry:
                trialsCount++;
                session = new InviteSession(this);
                var req = new InviteRequestPacket
                {
                    NumberOfHopsRemaining   = InviteRequestPacket.MaxNumberOfHopsRemaining,
                    RequesterEcdhePublicKey = new EcdhPublicKey(session.LocalInviteAckEcdhePublicKey),
                    RequesterRegistrationId = this.Configuration.LocalPeerRegistrationId,
                    ResponderRegistrationId = responderRegistrationId,
                    ReqTimestamp32S         = Engine.Timestamp32S,
                };
                var logger = new Logger(Engine, this, req, DrpPeerEngine.VisionChannelModuleName_inv_requesterSide);
                if (!Engine.RecentUniqueInviteRequests.Filter(req.GetUniqueRequestIdFields))
                {
                    if (trialsCount > 50)
                    {
                        throw new NonUniquePacketFieldsException($"could not find unique fields to send INVITE request");
                    }
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"waiting a second to generate ne wunique INVITE request");
                    }
                    await Engine.EngineThreadQueue.WaitAsync(TimeSpan.FromSeconds(1), "inv_wait_1236");

                    goto _retry;
                }


                session.Logger = logger;
                loggerCb?.Invoke(logger);
                Engine.RecentUniquePublicEcdhKeys.AssertIsUnique(req.RequesterEcdhePublicKey.Ecdh25519PublicKey, "req.RequesterEcdhePublicKey");
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"generated unique ECDH key {req.RequesterEcdhePublicKey}");
                }
                req.RequesterRegistrationSignature = RegistrationSignature.Sign(Engine.CryptoLibrary, req.GetSharedSignedFields, this.Configuration.LocalPeerRegistrationPrivateKey);

                this.TestDirection(logger, req.ResponderRegistrationId);
                routedRequest = new RoutedRequest(logger, null, null, null, req, null, routedRequest);

                // find best connected peer to send the request
                var destinationPeer = Engine.RouteInviteRequest(this, routedRequest);
                if (destinationPeer == null)
                {
                    if (latestTriedNeighborException == null)
                    {
                        throw new NoNeighborsToSendInviteException();
                    }
                    else
                    {
                        throw latestTriedNeighborException;
                    }
                }
                InviteAck1Packet ack1;
                try
                {
                    var reqUdpData = req.Encode_SetP2pFields(destinationPeer);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"sending {req} (ReqTimestamp32S={MiscProcedures.Uint32secondsToDateTime(req.ReqTimestamp32S)}), waiting for NPACK");
                    }

                    var sentRequest = new SentRequest(Engine, logger, destinationPeer.RemoteEndpoint, destinationPeer, reqUdpData, req.ReqP2pSeq16, InviteAck1Packet.GetScanner(logger, req, destinationPeer));
                    var ack1UdpData = await sentRequest.SendRequestAsync("ack1 4146");

                    #region process ACK1
                    // NeighborHMAC and NeighborToken32 are already verified by scanner
                    ack1 = InviteAck1Packet.Decode(ack1UdpData);
                    Engine.RecentUniquePublicEcdhKeys.AssertIsUnique(ack1.ResponderEcdhePublicKey.Ecdh25519PublicKey, $"ack1.ResponderEcdhePublicKey");
                    if (!ack1.ResponderRegistrationSignature.Verify(Engine.CryptoLibrary, w =>
                    {
                        req.GetSharedSignedFields(w);
                        ack1.GetSharedSignedFields(w, true);
                    },
                                                                    responderRegistrationId))
                    {
                        throw new BadSignatureException("invalid REGISTER ACK1 ResponderRegistrationSignature 2349");
                    }
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"verified ACK1");
                    }
                    session.DeriveSharedInviteAckDhSecret(Engine.CryptoLibrary, ack1.ResponderEcdhePublicKey.Ecdh25519PublicKey);

                    // send NPACK to ACK1
                    SendNeighborPeerAckResponseToAck1(ack1, destinationPeer);
                    #endregion
                }
                catch (RequestFailedException exc2)
                {
                    latestTriedNeighborException = exc2;
                    if (trialsCount > 50)
                    {
                        throw;
                    }
                    logger.WriteToLog_higherLevelDetail($"trying again on error {exc2.Message}... alreadyTriedProxyingToDestinationPeers.Count={routedRequest.TriedNeighbors.Count}");
                    routedRequest.TriedNeighbors.Add(destinationPeer);
                    goto _retry;
                }

                // decode and verify SD
                session.RemoteSessionDescription = InviteSessionDescription.Decrypt_Verify(Engine.CryptoLibrary,
                                                                                           ack1.ToResponderSessionDescriptionEncrypted,
                                                                                           req, ack1, false, session,
                                                                                           responderUserId, Engine.DateTimeNowUtc);

                // sign and encode local SD
                session.LocalSessionDescription = new InviteSessionDescription
                {
                    DirectChannelEndPoint = destinationPeer.LocalEndpoint,
                    SessionType           = sessionType,
                    DirectChannelToken32  = session.LocalDirectChannelToken32
                };

                session.LocalSessionDescription.UserCertificate = requesterUserCertificate;

                session.LocalSessionDescription.UserCertificateSignature = UserCertificateSignature.Sign(Engine.CryptoLibrary,
                                                                                                         w =>
                {
                    req.GetSharedSignedFields(w);
                    ack1.GetSharedSignedFields(w, true);
                    session.LocalSessionDescription.WriteSignedFields(w);
                },
                                                                                                         requesterUserCertificate
                                                                                                         );

                #region send ack2
                var ack2 = new InviteAck2Packet
                {
                    RequesterRegistrationId = req.RequesterRegistrationId,
                    ResponderRegistrationId = req.ResponderRegistrationId,
                    ReqTimestamp32S         = req.ReqTimestamp32S,
                    ToRequesterSessionDescriptionEncrypted = session.LocalSessionDescription.Encrypt(Engine.CryptoLibrary, req, ack1, session, true)
                };
                ack2.RequesterRegistrationSignature = RegistrationSignature.Sign(Engine.CryptoLibrary, w =>
                {
                    req.GetSharedSignedFields(w);
                    ack1.GetSharedSignedFields(w, true);
                    ack2.GetSharedSignedFields(w);
                }, this.Configuration.LocalPeerRegistrationPrivateKey);
                var ack2UdpData = ack2.Encode_SetP2pFields(destinationPeer);

                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"sending ACK2, waiting for NPACK");
                }
                await destinationPeer.SendUdpRequestAsync_Retransmit_WaitForNPACK("ack2 234575672", ack2UdpData, ack2.ReqP2pSeq16, ack2.GetSignedFieldsForNeighborHMAC);

                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"received NPACK");
                }
                #endregion

                #region wait for CFM
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"waiting for CFM");
                }
                var cfmUdpData = await Engine.WaitForUdpResponseAsync(new PendingLowLevelUdpRequest("cfm 1235695", destinationPeer.RemoteEndpoint,
                                                                                                    InviteConfirmationPacket.GetScanner(logger, req, destinationPeer),
                                                                                                    Engine.DateTimeNowUtc, Engine.Configuration.CfmTimoutS
                                                                                                    ));

                if (cfmUdpData == null)
                {
                    throw new DrpTimeoutException($"did not get CFM at invite requester from destination peer {destinationPeer} (timeout={Engine.Configuration.CfmTimoutS}s)");
                }

                // NeighborHMAC and NeighborToken32 are already verified by scanner
                var cfm = InviteConfirmationPacket.Decode(cfmUdpData);

                if (!cfm.ResponderRegistrationSignature.Verify(Engine.CryptoLibrary, w =>
                {
                    req.GetSharedSignedFields(w);
                    ack1.GetSharedSignedFields(w, true);
                    ack2.GetSharedSignedFields(w);
                },
                                                               responderRegistrationId))
                {
                    throw new BadSignatureException("invalid REGISTER CFM ResponderRegistrationSignature 6398");
                }

                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"verified CFM");
                }

                // send NPACK to CFM
                SendNeighborPeerAckResponseToCfm(cfm, destinationPeer);
                #endregion

                session.DeriveSharedPingPongHmacKey(req, ack1, ack2, cfm);
                return(session);
            }
            catch
            {
                session?.Dispose();
                throw;
            }
        }
Пример #9
0
 public override void Teardown()
 {
     base.Teardown();
     _call    = null;
     _session = null;
 }
Пример #10
0
        public override int OnInviteEvent(InviteEvent e)
        {
            tsip_invite_event_type_t type    = e.getType();
            InviteSession            session = e.getSession();
            SipMessage message = e.getSipMessage();

            switch (type)
            {
            case tsip_invite_event_type_t.tsip_i_newcall:
                SdpMessage sdp = message.getSdpMessage();

                if (session != null)
                {
                    Console.WriteLine("ERRRRRRRRRRRORRRR");
                    return(0);
                }
                else
                {
                    switch (e.getMediaType())
                    {
                    case twrap_media_type_t.twrap_media_audio:
                    case twrap_media_type_t.twrap_media_video:
                    case twrap_media_type_t.twrap_media_audiovideo:
                        session = e.takeCallSessionOwnership();
                        break;

                    case twrap_media_type_t.twrap_media_msrp:
                        if ((session = e.takeMsrpSessionOwnership()) != null)
                        {
                            (session as MsrpSession).setCallback(Program.msrpCallback);
                        }
                        break;
                    }
                    if (session != null)
                    {
                        ActionConfig actionConfig = new ActionConfig();
                        session.accept(actionConfig);
                        actionConfig.Dispose();
                    }
                }

                /*else if ((session = e.takeSessionOwnership()) != null)
                 * {
                 *  SdpMessage sdp = message.getSdpMessage();
                 *  if (sdp != null)
                 *  {
                 *      String fileSelector = sdp.getSdpHeaderAValue("message", "file-selector");
                 *      Console.WriteLine("file-selector={0}", fileSelector);
                 *  }
                 *
                 *  ActionConfig actionConfig = new ActionConfig();
                 *  //actionConfig.setMediaInt(twrap_media_type_t.twrap_media_audiovideo, "bandwidth-level", (int)tmedia_bandwidth_level_t.tmedia_bl_low);
                 *  actionConfig.setMediaString(twrap_media_type_t.twrap_media_file, "file-path", "C:\\tmp\\myfile");
                 *  session.accept(actionConfig);
                 *  actionConfig.Dispose();
                 * }*/
                break;

            case tsip_invite_event_type_t.tsip_i_request:
                break;

            case tsip_invite_event_type_t.tsip_ao_request:
                break;

            case tsip_invite_event_type_t.tsip_o_ect_ok:
                break;

            case tsip_invite_event_type_t.tsip_o_ect_nok:
                break;

            case tsip_invite_event_type_t.tsip_i_ect:
                break;

            case tsip_invite_event_type_t.tsip_m_local_hold_ok:
                Console.WriteLine("Local Hold OK");
                break;

            case tsip_invite_event_type_t.tsip_m_local_hold_nok:
                Console.WriteLine("Local Hold NOK");
                break;

            case tsip_invite_event_type_t.tsip_m_local_resume_ok:
                Console.WriteLine("Local Resume OK");
                break;

            case tsip_invite_event_type_t.tsip_m_local_resume_nok:
                Console.WriteLine("Local Resume NOK");
                break;

            case tsip_invite_event_type_t.tsip_m_remote_hold:
                Console.WriteLine("Remote Hold");
                break;

            case tsip_invite_event_type_t.tsip_m_remote_resume:
                Console.WriteLine("Remote Resume");
                break;
            }



            return(0);
        }
Пример #11
0
            /// <summary>
            /// Call (MSRP, Audio, Video, T.38, ...) events
            /// </summary>
            /// <param name="e"></param>
            /// <returns></returns>
            public override int OnInviteEvent(InviteEvent e)
            {
                tsip_invite_event_type_t type = e.getType();
                short         code            = e.getCode();
                String        phrase          = e.getPhrase();
                InviteSession session         = e.getSession();

                switch (type)
                {
                case tsip_invite_event_type_t.tsip_i_newcall:
                    if (session != null)     /* As we are not the owner, then the session MUST be null */
                    {
                        LOG.Error("Invalid incoming session");
                        session.hangup();     // To avoid another callback event
                        return(-1);
                    }

                    SipMessage message = e.getSipMessage();
                    if (message == null)
                    {
                        LOG.Error("Invalid message");
                        return(-1);
                    }
                    twrap_media_type_t sessionType = e.getMediaType();

                    switch (sessionType)
                    {
                    case twrap_media_type_t.twrap_media_msrp:
                    {
                        if ((session = e.takeMsrpSessionOwnership()) == null)
                        {
                            LOG.Error("Failed to take MSRP session ownership");
                            return(-1);
                        }

                        MyMsrpSession msrpSession = MyMsrpSession.TakeIncomingSession(this.sipService.SipStack, session as MsrpSession, message);
                        if (msrpSession == null)
                        {
                            LOG.Error("Failed to create new session");
                            session.hangup();
                            session.Dispose();
                            return(0);
                        }
                        msrpSession.State = MyInviteSession.InviteState.INCOMING;

                        InviteEventArgs eargs = new InviteEventArgs(msrpSession.Id, InviteEventTypes.INCOMING, phrase);
                        eargs.AddExtra(InviteEventArgs.EXTRA_SESSION, msrpSession);
                        EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs);
                        break;
                    }

                    case twrap_media_type_t.twrap_media_audio:
                    case twrap_media_type_t.twrap_media_audiovideo:
                    case twrap_media_type_t.twrap_media_video:
                    {
                        if ((session = e.takeCallSessionOwnership()) == null)
                        {
                            LOG.Error("Failed to take audio/video session ownership");
                            return(-1);
                        }
                        MyAVSession avSession = MyAVSession.TakeIncomingSession(this.sipService.SipStack, session as CallSession, sessionType, message);
                        avSession.State = MyInviteSession.InviteState.INCOMING;

                        InviteEventArgs eargs = new InviteEventArgs(avSession.Id, InviteEventTypes.INCOMING, phrase);
                        eargs.AddExtra(InviteEventArgs.EXTRA_SESSION, avSession);
                        EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs);
                        break;
                    }

                    default:
                        LOG.Error("Invalid media type");
                        return(0);
                    }
                    break;

                case tsip_invite_event_type_t.tsip_ao_request:
                    if (code == 180 && session != null)
                    {
                        EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService,
                                                                           new InviteEventArgs(session.getId(), InviteEventTypes.RINGING, phrase));
                    }
                    break;

                case tsip_invite_event_type_t.tsip_i_request:
                case tsip_invite_event_type_t.tsip_o_ect_ok:
                case tsip_invite_event_type_t.tsip_o_ect_nok:
                case tsip_invite_event_type_t.tsip_i_ect:
                {
                    break;
                }

                case tsip_invite_event_type_t.tsip_m_early_media:
                {
                    EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService,
                                                                       new InviteEventArgs(session.getId(), InviteEventTypes.EARLY_MEDIA, phrase));
                    break;
                }

                case tsip_invite_event_type_t.tsip_m_local_hold_ok:
                {
                    EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService,
                                                                       new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_HOLD_OK, phrase));
                    break;
                }

                case tsip_invite_event_type_t.tsip_m_local_hold_nok:
                {
                    EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService,
                                                                       new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_HOLD_NOK, phrase));
                    break;
                }

                case tsip_invite_event_type_t.tsip_m_local_resume_ok:
                {
                    EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService,
                                                                       new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_RESUME_OK, phrase));
                    break;
                }

                case tsip_invite_event_type_t.tsip_m_local_resume_nok:
                {
                    EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService,
                                                                       new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_RESUME_NOK, phrase));
                    break;
                }

                case tsip_invite_event_type_t.tsip_m_remote_hold:
                {
                    EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService,
                                                                       new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_HOLD, phrase));
                    break;
                }

                case tsip_invite_event_type_t.tsip_m_remote_resume:
                {
                    EventHandlerTrigger.TriggerEvent <InviteEventArgs>(this.sipService.onInviteEvent, this.sipService,
                                                                       new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_RESUME, phrase));
                    break;
                }
                }


                return(0);
            }
Пример #12
0
        internal static LowLevelUdpResponseScanner GetScanner(DirectChannelToken32 localDirectChannelToken32, InviteSession session)
        {
            if (!session.DerivedDirectChannelSharedDhSecretsAE)
            {
                throw new InvalidOperationException("DerivedDirectChannelSharedDhSecretsAE=false");
            }

            BinaryProcedures.CreateBinaryWriter(out var ms, out var w);
            w.Write((byte)PacketTypes.MessageStart);
            localDirectChannelToken32.Encode(w);
            return(new LowLevelUdpResponseScanner
            {
                ResponseFirstBytes = ms.ToArray(),
                OptionalFilter = (udpData) =>
                {
                    if (!session.DerivedDirectChannelSharedDhSecretsAE)
                    {
                        return false;
                    }
                    var msgStart = Decode(udpData);
                    if (msgStart.MessageHMAC.Equals(
                            session.GetMessageHMAC(w2 => msgStart.GetSignedFieldsForMessageHMAC(w2, true))
                            ) == false)
                    {
                        return false;
                    }
                    return true;
                }
            });
        }