SIP registration using Ozeki SDK not working - c#

i'm trying to build a simple VoIP application using c# so i found that the Ozeki SDK is the simple way to do that but when i'm trying to registration SIP account using the SIPAccount class from the Ozeki SDK and my local IP it fail always and this is the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ozeki.VoIP;
using Ozeki.VoIP.SDK;
namespace SIP_R
{
class Program
{
private static ISoftPhone softphone; // softphone object
private static IPhoneLine phoneLine; // phoneline object
private static void Main(string[] args)
{
// Create a softphone object with RTP port range 5000-10000
softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000);
// SIP account registration data, (supplied by your VoIP service provider)
var registrationRequired = true;
var userName = "1000";
var displayName = "1000";
var authenticationId = "1000";
var registerPassword = "1000";
var domainHost = SoftPhoneFactory.GetLocalIP().ToString();
var domainPort = 9000;
var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort);
// Send SIP regitration request
RegisterAccount(account);
// Prevents the termination of the application
Console.ReadLine();
}
static void RegisterAccount(SIPAccount account)
{
try
{
phoneLine = softphone.CreatePhoneLine(account);
phoneLine.RegistrationStateChanged += sipAccount_RegStateChanged;
softphone.RegisterPhoneLine(phoneLine);
}
catch (Exception ex)
{
Console.WriteLine("Error during SIP registration: " + ex);
}
}
static void sipAccount_RegStateChanged(object sender, RegistrationStateChangedArgs e)
{
if (e.State == RegState.Error || e.State == RegState.NotRegistered)
Console.WriteLine("Registration failed!");
if (e.State == RegState.RegistrationSucceeded)
Console.WriteLine("Registration succeeded - Online!");
}
}
}
so please any help on what to do many thanks in advance for any help..
when trying to make softphone calls using Ozeki SDK and local IP it give an error NatType:UDPBlocked

Do you have both UDP and TCP port 5060 open? (The standard SIP Port)
Can you register a normal SIP softphone from your development machine?
From your error message it sounds like you have a firewall issue, not a code issue.
And looking at your code, I would check all the ports you've entered: 5,000 through 10,000.

After studying your code and the SIP registration explanation at the SDK's website, I think this line generates the problem:
var domainHost = SoftPhoneFactory.GetLocalIP().ToString();
To be able to communicate, we need to register our softphone to a PBX.
To do this, the example uses the Register method. We need to create a
phone line for this registration, which needs a SIP account and a NAT
Traversal method.
(Source: How to register to a PBX using SIP Account?)
So the aim of this code snippet is to define a SIP account that will be registered to a certain PBX. Accordingly, the domainHost should be the IP address of the PBX that you wish to register to. (And the domainPort should be the port number of this PBX.)

Error : NatType:UDPBlocked
SDK code :
<member name="F:Ozeki.Network.Nat.NatType.UdpBlocked">
<summary>
Firewall that blocks UDP.
</summary>
<remarks>
Probably no internet connection available or firewall issue.
</remarks>
</member>
Probably no internet connection available or firewall issue.
Try Enabling advanced outbound NAT, change the default outbound rule to enable static-port. Reboot adapter.
As the SDK code suggests,
Check Firewall and ports you have the issue tackled

Related

IBMMQDotnet client retry mechanism

Hi everyone i am completely new to queues and especialy to IBMMQDotnet cleint library. Currently my application trying to send DTO object to the queue and sometimes it could faailed for various reasons like exception occuring or network issue. Is there any retrie mechanism ?i would like to implement retry mechansim, i tried to google it but could not found any example. Bellow is the current code
if (!TryConnectToQueueManager())
{
return;
}
using var destination = GetMqObjectForWrite(message.Destination, message.DestinationType);
var mqMessage = new MQMessage
{
Format = MQC.MQFMT_STRING,
CharacterSet = 1208
};
if (message.Headers?.Count > 0)
{
foreach (var (key, value) in message.Headers)
{
mqMessage.SetStringProperty(key, value);
}
}
mqMessage.WriteString(JsonSerializer.Serialize(message.Data));
destination.Put(mqMessage);
destination.Close();
IBM MQ provides a feature called as Client Auto Reconnect.You could refer the following KC page Client Auto Reconnect
If there is a connection failure because of the network issue, the IBM MQ client will try to re-establish a connection to the Queue Manager for a specific time period(which is configurable) before throwing an exception to the application
You could refer to the sample "SimpleClientAutoReconnectPut" & "SimpleClientAutoReconnectGet" which are available as part of the client installation.

Connection Refused for Android device as emulator using WebClient in VS 2019 on localhost

The Asp.Net Core web app I built is taken from a tutorial guide on Microsoft that targeted Phone 8. The controller in the backend had to upgrade by replacing HttpRequest calls with IActionResult. Data for the tutorial is pulled from an xml file. The web page loads up fine.
For the front end project Mobile app was used. For now I'm focusing on Android although IOS and UWP were included in the build. The Android manifest file has permissions for Internet and Network_State.
Visual Studio is running on a PC wired to the router. My Android phone uses the wifi from the router and for debugging is USB tethered to the PC.
WebClient is used to request data from the server app. A basic view of the code is:
class MainViewModel : WebClient
{
//Assigned IP for local PC hosting the web page
static string uriBase = DeviceInfo.Platform == DevicePlatform.Android ? "http://192.168.50.250" : "http://localhost";
//Port set in launchSetting.json for Http; Https is 8081
const string urlPort = "8080";
static string apiUrl = $"{uriBase}:{urlPort}/api/books";
void LoadData()
{
var webClient = new WebClient();
webClient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadCatalogCompleted);
webClient.DownloadStringAsync(new Uri(apiUrl));
}
private void webClient_DownloadCatalogCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
if (e.Result != null)
{
//recover the List<items> from json serialized object
}
}
catch (Exception ex)
{
//put the error text into an item for display on the device
}
}
}
Depending on the state of the firewall different responses are observed. Firewall on, the call times out and the inner exception says so. In fact, checking e.Result jumps immediately to the catch block. Disable the firewall and the call-back method picks up immediately with exception "Connection-Failure: Connection Refused".
Everything tried so far ends up with the same failure. Except, if I run an Android emulator in my Windows 10 home machine (using 10.0.2.2 for ip).
I have tried adding :
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Before instantiating webClient. I have also included :
ServicePointManager.ServerCertificateValidationCallback =
new System.Net.Security.RemoteCertificateValidationCallback(
delegate
{ return true; }
);
Which I assume is to take advantage of the development certificate.
At this point I will look into any further suggestion. Have not found anything that seems to get out of this anywhere.
Thanks

How to get device key using device id from IoT hub using C#?

I have created a IoT hub in Azure.
Register a device into IoT hub using below code -
public async Task<HttpResponseMessage> RegisterDeviceAsyncData(DeviceData deviceApp)
{
deviceApp.PlatformName = _appSettingsAccessor.GetAppSettingValue(DEFAULT_HUB_KEY);
var result = await _deviceRegistrationHandler.RegisterDeviceAsync(deviceApp);
response = HttpResponseMessageFactory.CreateMessageWithObjectBody(results);
}
it is successfully registering devices into Iot hub, now I want to send data to these devices using C#.
I have code to send data to device below but I don't know how to get connection string of particular device or key to send data.
private static async Task SendDeviceToCloudMessagesAsync()
{
DeviceClient deviceClient = DeviceClient.CreateFromConnectionString("deviceConnectionString");
while (true)
{
string messageString = string.Empty;
Message iotHubMsg = new Message();
foreach (BaseMessage msg in currentDevice.Messages)
{
iotHubMsg = msg.ReadAsIotHubMessage();
messageString = Encoding.UTF8.GetString(iotHubMsg.GetBytes());
//Send the current messages and clear them
await deviceClient.SendEventAsync(iotHubMsg);
}
}
}
For now I tried to get connection string using portal.azure.com, but in real time after register device how can I retrieve a connection string? Can I use a SAS token or something like that?
I would try to solve this issue with one of these approaches:
Using a generic device connection string:
a) go to IoT Hub and from 'Shared access policies" get a connection string for the 'device' policy (e.g. HostName=iothub.azure-devices.net;SharedAccessKeyName=device;SharedAccessKey=abcd1234)
b) This is a generic connection string. If you add "DeviceId=" it would be specific to your device and IotHub would be able to identify your new/existing device (e.g. HostName=iothub.azure-devices.net;SharedAccessKeyName=device;SharedAccessKey=abcd1234;DeviceId=device001)
Using automatic device provisioning with the help of Azure Device provisioning Service. I have never personally used it, but it should be working. Furthermore, this should be the approach if you have a really big number of devices.
Hopefully, this helps you.

Trust certs and capture traffic using Fiddler on Safari, IE and iOS devices

I have set-up my Fiddler Proxy like in the gist here.
Code:
public class ProxyConfig
{
private readonly string _secureEndpointHostname = IPAddress.Any.ToString();
private readonly int _secureEndpointPort = 4555;
private readonly int _port = 18882;
private static readonly ICollection<Session> AllSessions = new List<Session>();
private static Fiddler.Proxy _secureEndpoint;
private static readonly LoggerCnx Logger = new LoggerCnx();
private Action<string> onRequest;
public ProxyConfig()
{
}
public ProxyConfig(Action<string> onRequest)
{
this.onRequest = onRequest;
}
public void SetupProxyListener()
{
FiddlerApplication.SetAppDisplayName("FiddlerCoreProxyApp");
// This is a workaround for known issue in .NET Core - https://github.com/dotnet/coreclr/issues/12668
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
// Simply echo notifications to the console. Because Fiddler.CONFIG.QuietMode=true
// by default, we must handle notifying the user ourselves.
//Fiddler.FiddlerApplication.OnNotification += delegate (object sender, NotificationEventArgs oNEA) { System.Diagnostics.Debug.WriteLine("** NotifyUser: " + oNEA.NotifyString); };
FiddlerApplication.Log.OnLogString += delegate (object sender, LogEventArgs oLEA) { Logger.Info("** LogString: " + oLEA.LogString); };
FiddlerApplication.BeforeRequest += delegate (Session session)
{
if (!CertMaker.rootCertIsTrusted())
{
CertMaker.trustRootCert();
}
if (onRequest != null)
{
onRequest(session.fullUrl);
}
// In order to enable response tampering, buffering mode MUST
// be enabled; this allows FiddlerCore to permit modification of
// the response in the BeforeResponse handler rather than streaming
// the response to the client as the response comes in.
session.bBufferResponse = false;
lock (AllSessions)
{
AllSessions.Add(session);
Logger.Info("Session: " + session.fullUrl);
}
session["X-AutoAuth"] = "(default)";
if ((session.oRequest.pipeClient.LocalPort == _secureEndpointPort) && (session.hostname == _secureEndpointHostname))
{
session.utilCreateResponseAndBypassServer();
session.oResponse.headers.SetStatus(200, "OK");
session.oResponse["Content-Type"] = "text/html; charset=UTF-8";
session.oResponse["Cache-Control"] = "private, max-age=0";
session.utilSetResponseBody("<html><body>Request for httpS://" + _secureEndpointHostname + ":" + _secureEndpointPort.ToString() + " received. Your request was:<br /><plaintext>" + session.oRequest.headers.ToString());
}
};
Logger.Info($"Starting {FiddlerApplication.GetVersionString()}...");
CONFIG.IgnoreServerCertErrors = true;
CONFIG.bCaptureCONNECT = true;
FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true);
FiddlerCoreStartupFlags startupFlags = FiddlerCoreStartupFlags.Default;
startupFlags = (startupFlags | FiddlerCoreStartupFlags.DecryptSSL);
startupFlags = (startupFlags | FiddlerCoreStartupFlags.AllowRemoteClients);
startupFlags = (startupFlags & ~FiddlerCoreStartupFlags.MonitorAllConnections);
startupFlags = (startupFlags & ~FiddlerCoreStartupFlags.CaptureLocalhostTraffic);
FiddlerApplication.Startup(_port, startupFlags);
Logger.Info("Created endpoint listening on port {0}", _port);
Logger.Info("Starting with settings: [{0}]", startupFlags);
Logger.Info("Gateway: {0}", CONFIG.UpstreamGateway.ToString());
// Create a HTTPS listener, useful for when FiddlerCore is masquerading as a HTTPS server
// instead of acting as a normal CERN-style proxy server.
_secureEndpoint = FiddlerApplication.CreateProxyEndpoint(_secureEndpointPort, true, _secureEndpointHostname);
if (null != _secureEndpoint)
{
Logger.Info("Created secure endpoint listening on port {0}, using a HTTPS certificate for '{1}'", _secureEndpointPort, _secureEndpointHostname);
}
}
}
Its purpose is to capture and analyze traffic from Windows, Mac OS X, Android and iOS browsers (Chrome, Firefox and Safari mostly, on both Desktop and Mobile devices).
So far, it seems to be working on:
Windows browsers: Chrome, Firefox. Not working on IE and Edge
Android: Chrome
Mac OS: Chrome, Firefox. Safari is not working
iOS: none
In my logs files I'm seeing the following errors logged by Fiddler on browsers not working (for all devices). Example for an HTTPS request:
2018-02-14 17:25:50.3860 | INFO | ** LogString:
!SecureClientPipeDirect failed: System.IO.IOException Authentication
failed because the remote party has closed the transport stream. for
pipe (CN=*.optimizely.com, O=DO_NOT_TRUST_BC, OU=Created by
http://www.fiddler2.com)
From what I read in the last couple of day trying to figure out a solution for this, the reason would be the certificates that are not trusted on the device.
The tests are being ran on BrowserStack using the feature they provide called BrowserStack Local. Details about it are here and here.
Now my questions could be split between Desktop and Mobile:
Why is Chrome and Firefox able to make HTTPS requests while IE, Edge and Safari fails to do so?
For iOS specifically, there's a Fiddler for iOS documentation here specifying the steps required in order to configure the device. However, as I already mentioned, I'm not using in-house iOS devices, but physical ones provided by BrowserStack. Is there a way to programatically trust a certificate on an iOS device (iOS 9.x, iOS 10.x, iOS 11.x)?
Are there any workarounds that I could use?
EDIT:
FiddlerCore and BrowserStack Local logs are here.
Starting from your second question, there is a discussion regarding IOS devices here on the official Telerik forums stating:
SSL2 shouldn't ever be enabled, and it isn't enabled in Fiddler unless
you go out of the way to shoot yourself in the foot.
If you've properly configured your iOS device to trust Fiddler's root
certificate, then HTTPS interception will work properly in clients
except where certificate pinning is in use. While Certificate Pinning
in Chrome won't matter on the Desktop, on iOS they ignore the Trusted
Certificates store and as a consequence Fiddler interception will not
work. But most sites and apps do not use pinning. If a site or app
uses pinning, there's no workaround short of jailbreaking the device.
This isn't a limitation unique to Fiddler-- every HTTPS-decrypting
proxy has exactly the same limitation.
I guess that will answer your first answer as well as IE is using certificate pinning as well as much as I recall.

Are they any additional requirements for UPNP/WCF porting?

Im using http://managedupnp.codeplex.com/ API to open up a port using UPNP on my NetGear DG834g ROUTER with the following code..
public void UPNPOpenPort(int port)
{
Services lsServices;
lsServices = Discovery.FindServices("urn:schemas-upnp-org:service:WANPPPConnection:1");
if (lsServices.Count > 0)
using (Service lsService = lsServices[0])
{
try
{
object[] loObj = new object[] { "", port, "TCP", port, "10.0.0.100", true, "Custom Mapping", 0 };
lsService.InvokeAction("AddPortMapping", loObj);
}
catch (Exception loE)
{
MessageBox.Show(
String.Format(
"{0}: HTTPSTATUS: {1}",
loE.Message,
lsService.LastTransportStatus));
}
}
else
{
MessageBox.Show("Doh No Router Found");
return;
}
}
I have a service host with a NetTCP binding with the same port im feeding into the sub routine to set the UPNP forwarding and I can see an active UPNP record on the router configuration. I can see the port is listening on my local machine and other PC's on my LAN can connect to the port however using an online Port checker it shows as closed, even though the Router says that it should be forwarding to the correct internal IP.
Does anyone have any ideas or am i missing something?
Best Regards,
Christopher Leach
Yes. I performed a factory restore on the router, enabled UPnP, opened the service host and created a forward. It worked.
Even Teredo decided to come online.
Its great to know from a beginners perspective that its not always your codes(your understanding) fault. Sometimes its your hardware.
Thanks,
Christopher Leach

Categories