m curently working on converting an esxisting asterisk server to opensips, for better perfomance
for the most part it is working, but ive encountered an issue i cant really figure out.
asterisk is doing this :
if ("${fromourmobile}" != "") // Check if mobile Call Waiting is set to "n"
{
set(phonenumber=${FROM});
set(GROUP()=${phonenumber});
noop(Group Count: ${GROUP_COUNT(${phonenumber})});
if (${GROUP_COUNT(${phonenumber})} > 1)
{
Busy();
}
}
and this
if (${MATH(${EPOCH} % 2)} = 0)
{
set(dialhost=193.88.58.86);
Dial(SIP/${numbertodial}#${dialhost},60,wWtT);
&hangupcausecheck(${numbertodial}, ${dialhost});
switch (${DIALSTATUS})
{
case BUSY:
busy;
break;
default:
break;
}
set(dialhost=195.215.252.15);
Dial(SIP/${numbertodial}#${dialhost},60,wWtT);
&hangupcausecheck(${numbertodial}, ${dialhost});
switch (${DIALSTATUS})
{
case BUSY:
busy;
break;
default:
break;
}
i cant seem to find a similar way to do this in opensips, mostly the group_count() and the hangupcausecheck()
furthermore is there any equivalent to the $server variable from asterisk?
First think you need understand is
Asterisk is pbx-like software. Opensips is PROXY software.
There are no GROUPs, playback etc in Opensips. For programming opensips you have be expert in programming and FULLY understand how SIP protocol works.
Channel count can be emulated by using dialogs and caching servers. But it will not work if you config have any single error in BYE/CANCEL handling. There are no way check channel is active in most cases(becuase it not track channel's RTP data).
There is no application like Dial. Instead of that you have rewrite INVITE packet for proper destination/number.
Related
I'm implementing a Thrift client in order to make connection to a built-in scribe server.
Everything is going OK if I use a standard Log method, like this:
public boolean log(List<LogEntry> messages) {
boolean ret = false;
PooledClient client = borrowClient();
try {
if ((client != null) && (client.getClient() != null)) {
ResultCode result = client.getClient().Log(messages);
ret = (result != null && result.equals(ResultCode.OK));
returnClient(client);
}
} catch (Exception ex) {
logger.error(LogUtil.stackTrace(ex));
invalidClient(client);
}
return ret;
}
However, when I use send_Log instead:
public void send_Log(List<LogEntry> messages) {
PooledClient client = borrowClient();
try {
if ((client != null) && (client.getClient() != null)) {
client.getClient().send_Log(messages);
returnClient(client);
}
} catch (Exception ex) {
logger.error(LogUtil.stackTrace(ex));
invalidClient(client);
}
}
It acctually causes some problems:
Total network connection to port 1463 (default port for a scribe server) is going to increase so much, and always in a CLOSE_WAIT state.
Cause my application got stuck without throwing any error, I think it may be an issue with network connection.
what if send without recv
As this is clearly TCP, the sender will block (in blocking mode), or incur EAGAIN/EWOULDBLOCK in non-blocking mode. EDIT It is now clear that you want to send without receiving the reply. You can do that by just sending and then closing the socket, but that may cause the peer to incur ECONNRESET, which may upset it. You should really implement the application protocol correctly.
1/ Total network connection to port 1463 (default port for a scribe server) is going to increase so much, and always in a CLOSE_WAIT state.
Lots of ports in CLOSE_WAIT state indicates a socket leak on the part of the local application.
2/ Cause my application got stuck without throwing any error. I think it may be an issues with network connection.
It is an issue with sending and not receiving.
Since you labelled this as a Thrift related question, the answer is oneway.
service foo {
oneway void FireAndForget(1: some args)
}
The oneway keyword does exactly what the name suggests. You get a client implementation that only sends and does not wait for anything to be returned from the server. This rule also includes exceptions. Hence a oneway method must always be void and can't throw any exceptions.
However, when I use send_Log instead ...
client.getClient().send_Log(messages);
Neither one of the Thrift-generated send_Xxx and recv_Xxx methods are meant to be public. That's why they are usually either private or protected methods. They should not be called directly, unless you are sure that you know what you are doing (and very obviously the latter is not the case here).
And since the real question is about performance: Why don't you just delegate the call(s) into a secondary thread? That way the I/O will not block the UI.
How one forces Windows to disconnect from BLE device being used in UWP app? I receive notifications from some characteristics but at some point I want to stop receiving them and make sure I disconnect from the BLE device to save BLE device's battery?
Assuming your application is running as a gatt client and you have the following instances your are working with in your code:
GattCharacteristic myGattchar; // The gatt characteristic you are reading or writing on your BLE peripheral
GattDeviceService myGattServ; // The BLE peripheral' gatt service on which you are connecting from your application
BluetoothLEDevice myBleDev; // The BLE peripheral device your are connecting to from your application
When you are already connected to your BLE peripheral, if you call the Dispose() methods like this :
myBleDev.Dispose(); and/or myGattServ.Dispose(); and/or myGattchar.Service.Dispose()
you surely will free resources in your app but will not cleanly close the BLE connection: The application looses access to control resources for the connection. Nevertheless, connection remains established on the lower levels of the stack (On my peripheral device the Bluetooth connection active LED remains ON after calling any of Dispose() methods).
Forcing disconnection is done by first disabling notifications and indications on the concerned characteristic (i.e. myGattchar in my example above) by writing a 0 (zero) to the Client Characteristic Configuration descriptor for that characteristic through call to method WriteClientCharacteristicConfigurationDescriptorAsync with parameter GattClientCharacteristicConfigurationDescriptorValue.None :
GattCommunicationStatus status =
await myGattchar.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.None);
Just dispose all objects related to the device. That will disconnect the device, unless there are other apps connected to it.
For my UWP app, even though I've used Dispose() methods, I still received notifications. What helped me was setting my device and characteristics to null. Example:
device.Dispose();
device = null;
Not all to certain of how "correct" this programming is, but it's been working fine for me so far.
The UWP Bluetooth BLE sample code from Microsoft (dispose the BLE device) didn't work for me. I had to add code (dispose the service) to disconnect the device.
private async Task<bool> ClearBluetoothLEDeviceAsync()
{
if (subscribedForNotifications)
{
// Need to clear the CCCD from the remote device so we stop receiving notifications
var result = await registeredCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.None);
if (result != GattCommunicationStatus.Success)
{
return false;
}
else
{
selectedCharacteristic.ValueChanged -= Characteristic_ValueChanged;
subscribedForNotifications = false;
}
}
selectedService?.Dispose(); //added code
selectedService = null; //added code
bluetoothLeDevice?.Dispose();
bluetoothLeDevice = null;
return true;
}
Remember you must call -= for events you have called += or Dispose() will never really garbage collect correctly. It's a little more code, I know. But it's the way it is.
Not just with bluetooth stuff, I will remind you - with everything. You can't have hard referenced event handlers and get garbage collection to work as expected.
Doing all the disposing and null references suggested didn't achieve the Windows (Windows Settings) disconnection I was looking for.
But dealing with IOCTL through DeviceIoControl did the job.
I found that after calling GattDeviceService.GetCharacteristicsAsync(), BluetoothLeDevice.Dispose() does not work. So I dispose the Service I don't need.
GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsAsync();
if (characteristicsResult.Status == GattCommunicationStatus.Success)
{
foreach (GattCharacteristic characteristic in characteristicsResult.Characteristics)
{
if (characteristic.Uuid.Equals(writeGuid))
{
write = characteristic;
}
if (characteristic.Uuid.Equals(notifyGuid))
{
notify = characteristic;
}
}
if (write == null && notify == null)
{
service.Dispose();
Log($"Dispose service: {service.Uuid}");
}
else
{
break;
}
}
Finally, when I want to disconnect the Bluetooth connection
write.Service.Dispose();
device.Dispose();
device = null;
I want to assign specific information for the server's characters and as well as the client's characters. Now, how do I know if the player is the host or the client? I tried using isServer and isClient, but it both return true. Are these the correct keywords that I should use?
void Update () {
if(isServer){
Debug.Log("I'm the server");
}
if(isClient){
Debug.Log("I'm the client");
}
}
If you're connecting as a "host", you're actually both the "client" and "server" at the same time. This is in contrast to running a "dedicated server", which acts as the server authority, but doesn't represent a "client" connection. Like you suggest in your own answer, you can use isServer and !isServer, or probably:
void Update() {
if (isServer) {
Debug.Log("I'm the server (or host)");
} else {
Debug.Log("I'm the client");
}
}
Instead of using isClient to determine if player is the client, i use !isServer instead.
void Update () {
if(isServer){
Debug.Log("I'm the server");
}
if(!isServer){
Debug.Log("I'm the client");
}
}
Not sure if this applies to every situation, so I apologize if it does not - I am using a plugin called NATTraversal for Unity, and I was having a similar issue. I needed to find which connection is the host. However for me, since I am not using the relay servers (this is for you guys who are avoiding the relay) I found that I can do this check..
using UnityEngine.Networking;
void Start(){
if(NetworkServer.connections.Count > 0){
Debug.Log("This is the host.");
} else {
Debug.Log("This is a client.");
}
}
This works in my scenario because the client's connection list is empty, but the host's is not. There very well may be a better way to do this, but I didn't know of one without a previous built list of NetworkIdentity's.
The Network.isServer bool always returns false for me, so this is how I got around it. Hopefully it helps someone out there.
Edit: (Adding crucial information)
Please note, that this is AFTER matchmaking and connections have been established.
Another way to do it I have found is by listening to OnServerConnect in the NATLobbyManager.
public override void OnServerConnect(NetworkConnection conn){ }
That event only triggers for the host with the NATTraversal plugin, more info for anyone who may come across this while trying to figure all this stuff out. :)
Today my asterisk could not receive calls for a while. when I checked the asterisk logs, the error below was raising during this period.
Purely numeric hostname (1002), and not a peer--rejecting!
After I restarted the asterisk the problem solved. What is the problem?
Very likly that mean your dns server was not working. Use local dns caching server or more then one dns server.
Other posible situation - you calling somethign like SIP/1234, which is not in your sip.conf.
Here is related source part, it have description:
peer = sip_find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
if (peer) {
int res;
if (newdialog) {
set_socket_transport(&dialog->socket, 0);
}
res = create_addr_from_peer(dialog, peer);
dialog->relatedpeer = sip_ref_peer(peer, "create_addr: setting dialog's relatedpeer pointer");
sip_unref_peer(peer, "create_addr: unref peer from sip_find_peer hashtab lookup");
return res;
} else if (ast_check_digits(peername)) {
/* Although an IPv4 hostname *could* be represented as a 32-bit integer, it is uncommon and
* it makes dialing SIP/${EXTEN} for a peer that isn't defined resolve to an IP that is
* almost certainly not intended. It is much better to just reject purely numeric hostnames */
ast_log(LOG_WARNING, "Purely numeric hostname (%s), and not a peer--rejecting!\n", peername);
return -1;
} else {
I'm currently working with an Arduino trying to build an ad hoc network to which a device can connect to and send web requests to. The problem I am currently having is that I can only set up one connection and then when that connection is terminated (with client.stop()), all subsequent connections are not picked up by the server, even a cURL command just sits there spinning. The first connection I start when I reset the server works fine, and I am able to talk to the server; but after that, the Arduino can no longer find new clients (even though it's trying with the library given).
I`m using the SparkFun library for the WiFly shield cloned from GitHub, along with an Arduino Uno.
My current code is based off their default example 'WiFly_AdHoc_Example', but I had to remove a few things to get the network to start up which might be the cause of this problem.
Here is the .ino file that I am running.
#include <SPI.h>
#include <WiFly.h>
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial( 5, 4); //Part from example not used (see below)
WiFlyServer server(80); //Use telnet port instead, if debugging with telnet
void setup()
{
Serial.begin(9600);
//The code below is from the example, but when I run it the WiFly will hang
// on Wifly.begin(). Without it, the WiFly starts up fine.
//mySerial.begin(9600);
//WiFly.setUart(&mySerial); // Tell the WiFly library that we are not
// using the SPIUart
Serial.println("**************Starting WiFly**************");
// Enable Adhoc mod
WiFly.begin(true);
Serial.println("WiFly started, creating network.");
if (!WiFly.createAdHocNetwork("wifly"))
{
Serial.print("Failed to create ad hoc network.");
while (1)
{
// Hang on failure.
}
}
Serial.println("Network created");
Serial.print("IP: ");
Serial.println(WiFly.ip());
Serial.println("Starting Server...");
server.begin();
Serial.print("Server started, waiting for client.");
}
void loop()
{
delay(200);
WiFlyClient client = server.available();
if (client)
{
Serial.println("Client Found.");
// A string to store received commands
String current_command = "";
while (client.connected())
{
if (client.available())
{
//Gets a character from the sent request.
char c = client.read();
if (c=='#' || c=='\n') //End of extraneous output
{
current_command = "";
}
else if(c!= '\n')
{
current_command+=c;
}
if (current_command== "get")
{
// output the value of each analog input pin
for (int i = 0; i < 6; i++)
{
client.print("analog input ");
client.print(i);
client.print(" is ");
client.print(analogRead(i));
client.println("<br />");
}
}
else if(current_command== "hello")
{
client.println("Hello there, I'm still here.");
}
else if (current_command== "quit")
{
client.println("Goodbye...");
client.stop();
current_command == "";
break;
}
else if (current_command == "*OPEN*")
{
current_command == "";
}
}
}
// Give the web browser time to receive the data
delay(200);
// close the connection
client.stop();
}
}
This script is just a mini protocol I set up to test. Once connected with the wifly module you can send text such as "get" "hello" or "quit" and the wifly module should respond back.
Using Telnet I can successfully connect (the first time) and send commands to the Arduino including "quit" to terminate the connection (calls the client.stop() method). But when I try to reconnect though Telnet, it says the connection was successful, but on the Arduino it's still looping thinking the client is still false. What??
I know right, I'm getting mixed messages from Telnet vs Arduino. None of the commands work obviously since the Ardunio is still looping waiting for a client that evaluates to true. I'm going to take a look at WiFlyServer from the library I imported and see if I can dig up the problem, because somehow that server.available() method isn't finding new clients.
I am noticing a lot of TODO's in the library code....
So I found the reason for the problem. It was in the WiFlyServer.cpp file from the SparkFun library. The code that was causing the reconnect issue was in fact the server.availible() method. Right at the top of the method, there is a check:
// TODO: Ensure no active non-server client connection.
if (!WiFly.serverConnectionActive) {
activeClient._port = 0;
}
For some reason when I comment this out, I can connect and reconnect perfectly fine and everything works as it should. I will now dive into the library and see if I can fix this, I'm not exactly sure what this is doing, but it gets called when the server connection is not active and is somehow blocking subsequent connections. The problem with this solution is that the Arduino always thinks it has found a client since client and client.connected() evaluate to true even if one doesn't exist. Even client.available() evaluates to true right when the connection is terminated and the ghost "client" is found, but after that first run through the if-statement the ghost "client" is no longer available(). Even with this flaw it still picks up a new client when it comes along which is why it works.
How might I get to the root of this problem without using this commenting hack?
Are their any risks or future problems I might run into doing it this way?
What is the purpose of the block that I commented out in the first place?
Well, when you're calling client.stop(); how does the Arduino know whether the client has to start again?
Remember setup() executes only once.
Have you tried to include the following code in your loop to tell the Arduino to create the WiFly AdHoc network again? This may or may not work. I don't have one myself and haven't played with the Wifly shield but it's worth a try.
Remember to only ever execute the code once every time you need to connect again since it's sitting inside a loop that's always going to be running.
WiFly.begin(true);
Serial.println("WiFly started, creating network.");
if (!WiFly.createAdHocNetwork("wifly"))
{
Serial.print("Failed to create ad hoc network.");
while (1)
{
// Hang on failure.
}
}