I am using MobileSDK. 1) Can u send me an example of how I can get "ConnectionId" with a SOAP request? (without disabling user/pas encryption)2)How can I use MobileSDK with Maven in Java?

Hi Mohammad,

  1. ConnectionId is the GUID of an existing client connection. You can initiate a new connection by calling Connect command.

Example request:

<?xml version="1.0" encoding="utf-8"?>
<Communication xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<Command SequenceId="1">
		<Type>Request</Type>
		<Name>Connect</Name>
		<InputParams>
			<Param Name="PublicKey" Value="N4jwsKA......IHlVsYgwA="/>
			<Param Name="PrimeLength" Value="2048"/>
			<Param Name="EncryptionPadding" Value="ISO10126"/>
			<Param Name="ProcessingMessage" Value="No"/>
		</InputParams>
	</Command>
</Communication>

ConnectionId is one of the OutputParams in the response.

  1. I’m not familiar with Maven or Java but SOAP requests should work fine in any context.

Br,

Nikolay

We want to do “connect” and then “login” in java or .net core(in Linux).

we use this to send connectionId to the Client-side for getting streams–> we need to do this because we don’t want to have user/pass in client-side.

we can do it when we disable encryption in the Mobile server.

our main problem is about we need an example in c# or java for creating the public key and encrypting user/pass.

Hi Mohammad,

Your question is not really related to the Mobile SDK (or to Milestone software).

Here are a couple of useful articles that I just found. Second one is code-based. You can probably find better by using your favorite search engine.

https://www.khanacademy.org/computing/computers-and-internet/xcae6f4a7ff015e7d:online-data-security/xcae6f4a7ff015e7d:data-encryption-techniques/a/public-key-encryption

https://www.c-sharpcorner.com/article/encryption-and-decryption-using-a-symmetric-key-in-c-sharp/

I think milestone use specific implementation for this:

https://doc.developer.milestonesys.com/mipsdkmobile/reference/protocols/mobile_logon.html

and I meant, we need this implementation in c# or java

Hi Mohammad,

If you can use .NET Core, you could reference Nuget package with MIP SDK Mobile.

Then you can make a connection and get the Connection Id via reflection (it is not publicly exposed).

Code would look like this:

            var maxCommandTimeout = TimeSpan.FromSeconds(30);
            var connection = new Connection(VideoOS.Mobile.Portable.MetaChannel.ChannelTypes.HTTP, "mobile_servre_address", 8081);
            var connResponse = connection.Connect(new ConnectParams(), maxCommandTimeout);
            var loginResponse = connection.LogIn("username", "passwrod", "", maxCommandTimeout, UserType.Basic);
            // search for this via reflection
            // connection._connectionId

Alternatively you can use directly the DHEncryption class from the VideoOS.Mobile.Portable.Encryption namespace (in the same nuget package - MilestoneSystems.VideoOS.Mobile.SDK).

The code for your Connect command should be something like:

var connectParams = new ConnectParams();
connectParams.PrimeLength = PrimeLength.Prime2048;
connectParams.EncodingPadding = EncodingPadding.Iso10126;
 
// persist this between commands
_encryption = new DHEncryption(connectParams.EncodingPadding, connectParams.PrimeLength);
 
string clientPublicKey = _encryption.GetPublicKey();
connectParams.PublicKey = clientPublicKey;
 
// send Connect command with already set connectParams

When you receive the response of the Connect command from the server, you should do something like:

// ServerPublicKey should be received on Connect response
_encryption.GenerateSecretKey(ServerPublicKey);

The code for the Login will be something like:

username = _encryption.Encrypt(username);
password = _encryption.Encrypt(password);
 
// send Login command with already encrypted username and password

Btw. DHKE algorithm used in the MoS protocol is standard. You could implement it by yourself (if you want). Just have to use prime modulus from the link.

Btw, if Java is more suitable for you,

you could read this thread. There is an example code for DHKE implementation in Java there (attached to one of the responses).

Without guarantee it will work :slight_smile:

Tnx

and I have another question:

can I use connectionId in MilestoneSystems.VideoOS.Mobile.SDK?

I mean can I connect to server with connectionId in .net core like javaScript?

If you decide to use .NET SDK, you don’t have to take care of connection ID. It’s built into the Connection class.

You create a Connection object like Petar already explained

var connection = new Connection(VideoOS.Mobile.Portable.MetaChannel.ChannelTypes.HTTP, "mobile_servre_address", 8081);

and then you use it to call various commands, e.g.

connection.LogIn("username", "passwrod", "", maxCommandTimeout, UserType.Basic);

@Mohammad Hatami

If you are asking for something similar to what is available in the JS, namely:

function connectWithId(server, connectionId, serverId) {
		XPMobileSDK.library.Connection.connectWithId(server, connectionId, serverId);
	}

I’m afraid such is not available in .NET.

Could you please elaborate a little bit more on why you need something like this?

This will help us understand better your use case and consider if we would like to introduce such in the future.

Thanks in advance !

Yes, we need something similar with "connectWithId javaScript" in the .net.

We need this for:

We have some clients that they want to connect to the mobile server(.net clients), but we don’t want to share user/pass with them.

so if we can send them connection Id and the use it–> it really usefull

Thanks @Mohammad Hatami​ !

That makes sense.

Just one theoretical question.

I would assume you have another application that customers are login into.

Isn’t it event better if the VMS and MoS support third party authentication/login and your customers authenticate with this (already existing for your system) credentials directly in the VMS ?

Just trying to understand which will be better for use-cases as yours.

Thanks !

I think both of them are useful.

We have some experience in this scenario with some third-party applications, for example, Rabbitmq.

They support external token base authentication–> but sometimes your Authentication server is not math with their requirements.

and in a large product, u use many third parties → it’s not possible to have an Authentication server that math with all of them.

so, both are the best🙂

@Mohammad Hatami

I’m trying to implement something like ConnectWithId right now.

But of course it could be officially available no earlier than 2022R2.

Are you interested in beta-testing it ? Of course without any guarantee (from Milestone) it will work as well with the note that it is not designed for production (at this stage).

Sorry for the delay:)

Yes we need it ASAP

Please send me

Hi Mohammad,

You can download pre-release from here.

Hey Peter;

I think there is a problem:

My video stream display code is based on MobileSDKXamarinSample (just scaled up to accompany more cameras). The problem I’m facing for some time is that the connection gets disconnected over and over again. I get ConnectionState.Disconnecting regularly (seems to fix itself multiple times) and after some time - ConnectionStates.Disconnected and I no longer receive streams (subscribed to _video.StateChange.OnStateChange). I can reconnect to Milestone with a new Id, but I think it should not be disconnecting, to begin with. JS ConnectWithId on our Milestone server works fine and without disconnections.

but this one works fine in js library

Hey Mohammad,

Could you ensure that you never call Dispose() on your Connection objects (or leave them and called by the CLR), but instead call explicitly DisposeQuiet() method ?

If one of the automatic disposers is called, it will instruct the server to actively close the connections related to this ConnectionId.

I integrated the basic MobileSDKXamarinSample code to your SingleProcess sample provided with TestConnectWithId. The connection is still disconnected after some time. No disposing is done inside the code. Can you please check if this code also fails on your side or if it’s somehow the issue on my server.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VideoOS.Mobile.Portable.MetaChannel;
using VideoOS.Mobile.Portable.VideoChannel.Params;
using VideoOS.Mobile.SDK.Portable.Server.Base;
using VideoOS.Mobile.SDK.Portable.Server.Base.CommandResults;
using VideoOS.Mobile.SDK.Portable.Server.Base.Connection;
using VideoOS.Mobile.SDK.Portable.Server.Base.Video;
namespace Parent
{
    class Program
    {
        public static TimeSpan MaxCommandTimeout = TimeSpan.FromSeconds(30);
        static void Main(string[] args)
        {
            var channelType = ChannelTypes.HTTP;
            var address = "server-ip";
            var port = 8081u;
            VideoOS.Mobile.SDK.Portable.Environment.Instance.Initialize();
            #region Parent connecton
            var parent = ConnectionFactory.Create(channelType, address, port);
            parent.ChapSecurityEnabled = false;
            var connectResponse = parent.Connect(new ConnectParams(), MaxCommandTimeout);
            if (connectResponse.ErrorCode != ErrorCodes.Ok)
                throw new ArgumentOutOfRangeException("Check ChannelType, IP and Port");
            var loginResponse = parent.LogIn("basic", "username", "pass", MaxCommandTimeout, UserType.Basic);
            if (connectResponse.ErrorCode != ErrorCodes.Ok)
                throw new UnauthorizedAccessException("Check credentials");
            var connectionId = parent.ConnectionId;
            parent.DisposeQuiet();
            #endregion
            #region Child Connection
            var child = ConnectionFactory.CreateWithConnectionId(channelType, address, port, connectionId);
			var viewResponse = child.Views.GetAllViewsAndCameras(new ViewParams(), MaxCommandTimeout);
            if (viewResponse.ErrorCode != ErrorCodes.Ok)
                throw new Exception("Red Tomatos Attack !");
			#endregion
			#region streamConnect
			var videoParams = GetVideoParams();
			var response = child.Video.RequestStream(videoParams, null, MaxCommandTimeout);
			var _video = child.VideoFactory.CreateLiveVideo(new RequestStreamResponseLive(response));
			var proxy = new VideoPullProxy(_video, _video, (int)videoParams.FPS) { NewFrame = OnVideoFrameReceived };
			_video.Start();
			_video.StateChange.OnStateChange += StateChange_OnStateChange;
			Console.ReadKey();
			#endregion
		}
		private static void OnVideoFrameReceived(VideoFrame frame)
		{
			Console.WriteLine("frame "+ DateTime.Now.ToLongTimeString());
		}
		private static void StateChange_OnStateChange(object sender, EventArgs e)
		{
			if (e is ConnectionEventArgs args)
			{
				if (args.State == ConnectionStates.Disconnected)
				{
					Console.WriteLine("Disconected");
				}
				else if (args.State == ConnectionStates.Disconnecting)
				{
					Console.WriteLine("Disconecting");
				}
			}
		}
		private static VideoParams GetVideoParams()
		{
			return new VideoParams
			{
				SignalType = StreamParamsHelper.SignalType.Live,
				MethodType = StreamParamsHelper.MethodType.Pull,
				FPS = 5,
				CompressionLvl = 90,
				CameraId = new Guid("00000000-0000-0000-0000-000000000000"), //TODO change to your camera ID
				DestWidth = Convert.ToInt32(500),
				DestHeight = Convert.ToInt32(500),
				RequiresDownsampling = false,
			};
		}
	}
}

HI Mohammad

It fails on my side also.

I’m checking it right now.

Seems like something with the periodic live message.

Thanks for the test app !