How to tell the difference between an offline and online mobile phone via sip? - sip

For a toy project I want to find out if a mobile phone is connected to gsm or not. So I thought "Okay, let's use my local sip provider and see".
But in both cases, the thing goes like this:
I send an INVITE
0 s: I get a 100 Trying
5 s: I get a 183 Session description
I get an audio stream, in the one case with the ringing, in the other case with a "The person you are calling is…"
If I wait long enough (~ 40 s), I get a more appropiate status code like 180 Ringing.
Audio analysis is not an option, really.
Any hints on where to go now?
(I used twinkle for testing and a local german sip-provider.)

This issue is endemic in the way telephone networks work, and is not specific to SIP or IP. It's why, when you place a call to another country and the number is busy, you might sometimes hear your local country's busy tone, or you might hear a different busy tone that comes from the other country. In the latter case you cannot detect except by audio analysis, what the problem is. In SS7 and ISDN we speak of Q.931 cause codes instead of SIP error codes, but the principle is the same.
There's an argument to be made for configuring telephone systems to emit status codes instead of audio error messages. For callers using normal phones, the originating switch (the one closest to the caller) can then map that code to the appropriate spoken error message or audio tone. That way, when the call is being placed by software rather than by a person, the software can have access to the actual error code right away.
On the other hand you can also argue for having the remote switch (the one nearest the destination or the one that encounters the problem) speak its own error message. That switch knows best what the actual problem is. For example, a mobile operator can emit a spoken error message saying that the mobile phone you are trying to call is currently out of range. There is no Q.931 code (or SIP error code for that matter) with that meaning. It could return 27=Destination out of order?? Or 35=Destination unattainable?? Both of those codes are so esoteric, who knows what error message the local switch would translate them to (in practice: probably just a reorder tone, which is really user-unfriendly to a human caller). And when you try to map Q.931 cause codes to SIP error codes back and forth, even more information is lost because the codes really don't match up well at all. It's likely to be a much better user experience for the caller if the remote switch just plays back an informative, appropriate, recording which describes the problem.
Since there is this dilemma (arguments on both sides), we can conclude that this will not likely be resolved by completely standardizing on one way or ther other way anytime soon.
Anyway, sometimes this is configurable: your SIP provider may be able to configure your trunk for coded errors instead of recorded messages. If they offer this (some do), it's worth a try to set this option. But results will vary: this option only affects its local behaviour. In general if you want immediately call clearing with cause code and are instead getting a recorded error message from the other end, you will not be able to do anything about it, because the switch that makes the decision on which way it's going to respond is the remote one.
When using the audio message method, a proper Q.931 cause code or SIP error code usually comes eventually (after the recording is finished), but as you point out, it's probably too late by then.

Related

What use cases are there for Early Media with IVRs?

I would say that the following are valid use cases for Early Media when used for IVRs:
Filtering
Disconnect incoming calls based on certain criteria (such as callers from a specific area code, or to play a message before hanging up on after hour callers).
Rate limiting
For example to limit the number of simultaneous callers, where the excess calls are either disconnected, or placed in a queue. (I'm not sure if the queue example is possible though without answering the call.)
Are there more?
Some links that were helpful:
https://www.dialogic.com/webhelp/csp1010/8.4.1_ipn3/sip_software_chap_-_early_media.htm
https://wiki.asterisk.org/wiki/display/AST/Early+Media+and+the+Progress+Application
https://freeswitch.org/confluence/display/FREESWITCH/Early+Media
3) Legal: in some countries it is illegal for a call center using payed line (caller pay per minute) to accept a call without sending it straight to an agent. So you can't accept the call, give the user some waiting music for 15 minutes (and make them pay for the privilege of waiting as well).
Result: you don't accept the call. However, this creates a new problem: if the caller only hears the ring back tone for those 15 minutes, he/she will assume no one will answer and hangs up.
Using early media, you can give them the traditional "your call is very important to us, please hold on"-type of experience without accepting the call and without starting to charge money. Of course this also depends somewhat on how much the provider is willing to tolerate, as this can also affects their income (depending on their own business model).
4) Comfort: you may not be aware of this, but the sound you hear as caller when the other side is ringing (ring-back tone), is not universally the same throughout the world. A company with a global number may wish to use early media to provide a ring-back tone more familiar to you, depending on where you are calling from. It was always a bit niche of a concept but some target audiences are statistically more likely to hangup if they hear an unfamiliar sound. 15-20 year ago this might have been a concern to some, but in the era of smartphones and internet calls, I doubt anyone really worries about it anymore.

Can too many WSASend in short time be a problem?

I'm making a simple mmorpg server with IOCP.
I implemented a simple movement function so I tested with dummy clients(also IOCP).
Everything works fine only when few clients are connected. After around 500~1000 clients are connected, some dummy clients occasionally read weird data. I checked that server sends data as I expected but when it comes to dummy clients reading them, they read random data.
My guess is that it could be related to operation system's recv buffer being overflowed but I'm only guessing right now... I have no idea how to check them.
Any suggestion would be very thankful!
The problem with too many WSASends doesn't usually manifest as corrupted data; that's more likely to be a bug in your code. Perhaps your problem is caused by you failing to manage the lifetime of the buffer that is being used to send data correctly? It needs to stay stable until you get the completion for the WSASend call. If you were reusing it sooner than that then you would corrupt the data being sent.
The reason this may show up when you have lots of WSASends outstanding to lots of clients is that the send operations may be taking longer to complete and so make it more likely that your bug will be hit...
It doesn't matter how many WSASends you issue as long as your clients are able to receive the data as fast as you can send it. As soon as you are sending faster than they can receive then there will be problems. I address these problems in this answer.

Read from a serial port in Swift 4 using ORSSerialPort

I've been wanting to make an app that sends instructions over serial to my LED controller. For this to work, I need to read what the controller sends back after sending it a command. I found the following function in ORSSerialPort:
func serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) {
// Do things
}
However, is there something like ORSSerialPort.read()?
I don't think ORSSerialPort.read() is a good idea. I know some other serial libraries are written that way, but the only way for that to work is for read() to block (possibly with a timeout) until a byte comes in on the port. Blocking I/O makes it a lot harder to write a good, responsive app, and I want to guide developers using ORSSerialPort away from that approach.
Instead, you should indeed implement serialPort(_:, didReceive:) in your ORSSerialPort delegate. When data is received by the serial port, that method will be called with the received data and you can do whatever you'd like with it.
That said, if your device communicates using a command/response type protocol (ie. every time you send a command, the device sends some response), you ought to look at ORSSerialPort's request/response API. It allows you to explicitly define the format of expected responses to commands, and ORSSerialPort itself will handle asynchronously waiting for, parsing, and validating responses. See the documentation for more info about this part of ORSSerialPort. The library also includes a sample project, RequestResponseDemo, that demonstrates using this API. Both Swift and Objective-C versions are included.
The ORSSerialPort library is popular and generally good. However, I'd found that it didn't work well with TTY serial devices. This was primarily because of its use of IOKit to discover serial ports -- it would only discover physical devices.
This is likely OK in your case but where you want to test your code but don't want to connect to a physical device, it falls over. Good code always needs a testing framwork. So, check out https://github.com/kpishere/POSIXSerialPort for a very simple serial interface API it is just what you need to write and respond to incoming data and also works with physical or virtual devices (as Unix was originally envisoned!).
To your question though, you don't want to call read() directly. You get into understanding whether or not, "is it a blocking read?" Then you get into dealing with threads. Both of the suggested APIs insulate you from that and allow you to think in terms of an event driven model -- this makes for much simpler code.

text-chat xmpp message stanzas never make it to the network - iphone project using libjingle

i thought it'd be better to rephrase. my earlier formulation of my question could have been better focused. the trouble with presence notifications, while real and still recurring, is kind of minor. the things i haven't figured out yet i can fake or work around. much less of a concern than getting basic text chat messages moving between users.
again, still fairly new with this combo of tech flavors - using libjingle as the heart (and liver and kidneys...) of an iphone xmpp/jabber app. got the sign on part, the presence notification/roster updating business actually seems to be working more or less as it should. but xmpp text chat message stanzas seem to vanish before making it out on the wire. capturing other network traffic, and perusing the pretty packets, i yeah, i can see the exchanges for sign on, etc. that got us going, but then nothing for chat.
i've checked and double checked how i'm putting together the stanzas, attributes, namespaces, etc. everything looks jim-dandy to me. i can see that a message is getting queued in the libjingle internal infrastructure. but no results on the ethernet.
hoping somebody who has played around with this stuff before might remember a similar stumbling block and can offer up a hint, suggestion, or pointer in the right direction.
thanks for any help.
mike

iPhone Remote IO Issues

I've been playing around with the SDK recently, and I had an idea to just build a personal autotuner (because I am just as awesome as T-Pain).
Intro aside, I wanted to attach a high-quality microphone into the headphone jack, and I wanted my audio to be processed in a callback, and then copied to the output buffer. This has several implications:
When my audio-in is being routed through the built-in microphone, I need to be able to process this input, and send it once my input has stopped (this works).
When my audio-in is being routed through the microphone-in input from the headset jack, I want the output to be sent immediately.
Routing, however, doesn't seem to work properly when using AudioSession modes and overrides, which technically should allow you to reroute output to the iPhone speakers, no matter where the input is coming from. This is documented to work, but in practice, doesn't really work.
Remote IO, however, is not documented at all. Anyone with experience using Remote IO audio units, can you give me a reasonable high-level overview on how to do this properly? I have been using the aurioTouch example code, but I am running into errors where I get error codes like -50 and -10863, none of which are documented.
Thanks in advance.
The aurioTouch example implements remoteIO play through.
You could modify the samples before passing them on.
It simply calls AudioUnitRender in the output render callback.
NB this trick does not seem to work if you port the code
to OSX style CoreAudio. There, 99% of the time, you need
to create two AUHALs (RemoteIO-a-likes) and pass
the samples between them.