I'm just confused about how SIP works but mine doesn't.
I made a simple android server which open up a server socket and listen to incoming connection on 3G/4G network. Then I made a client that connect to the server, the connection was blocked by my carrier's firewall(AT&T).
After this, I downloaded an open source VOIP app based on SIP, and register these 2 phones on SIP proxy, let them call each other, this works perfectly.
I'm just so confused about how SIP works on cellular network, SIP is a p2p protocol, SIP proxy is just for redirecting. How does these 2 phones connect to each other in VOIP session? Why is this connection not blocked by carrier? Can someone explain to me? Thank you in advance!
update: I just tried sending a UDP packet between AT&T and SPRINT network, it does not work ;(
In basic SIP the endpoints media traffic generally communicate directly between each other in a P2P fashion like you said. They do this be giving each others address/port in the SIP SDP negotiation.
In a "perfect" network world this works fine as all endpoints can talk directly between each other.
As we know, this is not the case.
In most cases, the main barrier in the IPv4 world is NAT.
The first solution people came up with is STUN. STUN will give you your "public" IP address that you are using from behind a NAT and the SIP stack will use that IP address in the SIP/SDP packets. This works as long as hole punching works.
The next solution people came up with is TURN. TURN is a UDP proxy and allows a client (e.g. a SIP client) to allocate and use a IP address/port on a private network from a public network (i.e. the internet). It should work in all cases but can put a lot of network overhead on the TURN server. It will not be as efficient as P2P connections tho. The upside of using TURN is that not both sides need to support it for it to work. So it's good when you are talking between a softphone on the internet to a hardware SIP device on a internal network.
The next solution people came up with is ICE. ICE needs to be supported on both SIP endpoints. It works by extending the SDP protocol to allow it to add all possible connections in the SDP negotiation (all local network adapters, public addresses provided by STUN and TURN allocated addresses in priority order). Then one side goes through the listed connections and tries to make a connection. This allows both connections to be "try" to connect P2P and fallback to a TURN connection if nothing else works. It should also work in any networked environment to any networked environment and find the most efficient network path between the SIP endpoints. The downside of ICE is that both SIP endpoints need to support ICE for it to work. (As a aside, ICE/TURN/STUN is now a requirement for the WEBRTC protocol for web browsers to talk between each other for the same reason)
Other possible solutions would be for you to have some sort of "smart" sip proxy in the middle that maybe fakes ICE on one side if the other side doesn't support it. Another is to have some sort of media gateway or B2BUA if transcoding is required, this would have the same problems as TURN tho.
I would suggest that you setup your SIP client with STUN, TURN and ICE if possible and that will increase the likelihood of the SIP call actually working.
As to why your case doesn't work now, it would require network and/or SIP logs to understand what the exact impediment is.
Related
I'm trying to write an Android app to accept TCP connections from the Internet. Sounds simple but despite weeks of head-banging, I've found no solution and now believe it impossible. I would love to have someone tell me I'm wrong.
I was encouraged by the "ServerSocket()" API function. I was able to create a listening socket (e.g. on port 2000) and connect to it from another app within my device. Unfortunately I find it is bound to (unrouteable) local address 10.0.0.150 which, of course, cannot be seen from the Internet.
I was also able to successfully connect by pointing my device to my local WIFI router and using the router's "Port Forwarding" feature to relay incoming connections to MyPublicIp:2000 to 10.0.0.150:2000. But this is not usable in the field (over an LTE connection) where I have no router.
I've searched StackOverflow and other sites but found no good answer (but plenty of inapplicable or obtuse ones).
From my reading, I hear that most (all?) carriers do not allow incoming connections to be routed to user devices, which may explain my dilemma.
PLEASE: Someone tell me I'm wrong.
I think it is possible.
Looking information about my mobile operator (mobile provider): it can provide a static IP address and my mobile device is available for incoming sessions, but only need to pay for this service.
I'm interested in the viability of implementing an Android application that interacts with a UDP service. I'm sure Android supports UDP:
http://www.helloandroid.com/tutorials/simple-udp-communication-example
What I'm less clear about is whether or not such an application would actually work on an Android phone on a typical tariff - for bidirectional communication. I want the Android client to contact a remotely hosted service by UDP (announcing itself) and for the server to subsequently notify the Android device about real-time events.
I'm concerned that a mobile device on a commercial network might be forced to change IP address - for example - when moving in/out of a Wi-Fi zone... and I'm unclear if NAT would be a problem on a typical 3G network.
Is it really viable to use UDP for bi-directional (best-effort) communications both to and from an Android phone?
There are a few issues for you to look at here. First, UDP is perfectly useable by Android. It can send and receive UDP packets just fine. The larger issue is really that the phone cannot receive incoming UDP connections that it did not open the initial connection for, unless it is on WiFi and rhe connection is coming from the same LAN.
On 3G/4G the phone is not addressable from the outside because the Wireless carrier has in place a firewall with a proxy server. So, incoming connections are not passed over that firewall. If, instead the phone opens the connection from behind the firewall, then bidirectional traffic can flow over that link.
Now, the problem you will have will be
1) Keeping the link alive when the phone goes from network (3G) to network (Wifi)
2) Battery life from the constantly open connection
Most likely, you really want C2DM for what you are looking at.
I have implemented a sip based real time voice transfer under the impression that two of my phones on the same WIFI network can communicate provided that they have each others IP addresses. However, I could not make it work... I am using rtp to transfer voice between these clients.
Also, it's come to my notice that using a PC on the WIFI network as server is better. Now, can I use this PC as a proxy server to establish a sip end to end connection? If yes, how?
Are there existing implementations for initializing a session? Specifically, if someone could give me an example on what address/ports I would need both of my clients to establish the connection to, it would be great.
If you have implemented correctly all the necessary parts that SIP protocol demands, then you have to install a SIP server on your PC and just create two accounts that the phones will connect with them on the server. I have tried with Android the Asterisk server, but I am sure that there will be many others out there...
By default SIP servers are listening on port 5060 using UDP. This port is used only for the initiation of the session (and other control messages) and NOT for the transfer of RTP packets.
All of the documentation, examples and questions I've seen so far on TCP connections with Android have been between an Android device and a computer. As unreliable as wireless can be, is it possible to make a client-server TCP connection between Android devices over WiFi, and if so, how?
Edit: I guess I should elaborate more on my situation.
My Droid does not respond to ping or accept incoming TCP requests from anything unless I first make the Droid a client and my laptop the server. After this initial connection is established I can then ping from my laptop, or make the Droid a server and my laptop the client. What I can't do is make one Droid the server and another a client, I always get a "No route to host" error.
It feels like there is something blocking incoming connections unless the device initiates a connection to something else, and even then the only request the device will accept is with this device. How can I make my Droid a server that accepts all incoming TCP requests from any device on my local intranet?
You should be able to. Just do like you would do with computer/device connections, except run the client and server code on the devices.
One of the neat things about the Internet is that the Internet doesn't care whether you are establishing a connection between two PC's, a PC and a phone, or two phones. I would look at the Socket documentation, that should be enough to get you rolling.
It's certainly possible. The only problem is figuring out the IP address. I don't expect a phone have a fixed IP... However, if there is a fixed "login" server somewhere in the Web which IP is known to both phones then they can do a handshake via that server and after that continue peer-to-peer.
re; The only problem is figuring out the IP address. I don't expect a phone have a fixed IP.
Try this;
Use the web browser on the phone to log into this website: It should provide you the IP address.
http://whatismyipaddress.com/
We want to establish TCP/IP connection between two android devices.
For now we thought that it would be simpler if we make the connection device to device. So there is no server that is between the two phones.
Most of the time (if not always) one has no real IP address (NAT and so on). Is this a problem for creating a TCP socket?
I didn't manage to find any exact information for this. Any advice and opinion will be highly appreciated.
Thanks
Is this a problem for creating a TCP
socket?
Answer is no, it does not make it impossible (unless NAT's have an unpredictable way of mapping IP addresses). However, it is not simple to accomplish.
The short answer is you'll always need a server-like peer with a public IP address to facilitate initial communication between peers located behind NATs. The peers connect to it. A tells server it wants to TCP connect with B. Server notifies B. NAT behavior analysis is performed and if possible, A and B attempt to open TCP communications with each other by predicting the next mapping of the other NAT. If all goes fine (and usually it does) A touches base with B or vice-versa. They close the other connection attempts and communicate with the operational TCP connection. This technique is called STUN for TCP.
Now, there are more complicated reason why things can go wrong. If you want to know more, I have written a book called Practical JXTA II which available for reading online at Scribd. There is a chapter dedicated to NAT traversal.
Hope this helps.
One device behind a NAT is not a problem. The requirement is: the server must be reachable by the client.
I'm using Apache Mina to handle TCP connections. It have really made my life easier. It can be used on both client and server. Give it a try...
Well to make a TCP socket one device must be listening and the other connecting. However in a real world scenario what you describe is sort of hard.
Like if you are going to communicate over a cell network between two phones, I wouldn't be surprised if the network did not allow inbound connections to a phone like that and just sandboxed each phone's IP. So while two phones might be on the same subnet IP range, they might not be on the same physical network which just makes the whole routing problem almost impossible.
If you are in control of the network and are using Wifi and natting the IPs yourself with both devices within your network, you should be able to do this just like any other client server TCP socket.
If both nodes does't have global IPs,, and are not physically in the same network,, then its impossible to communicate over TCP without a server, unless you created a controlling server that act as a relay to tell the nodes about any changes occurring on the other side
It is possible but you can experience some problems.
First of all you have to know the public address of the host you want to contact, and if your two host are in different NATTED networks you should do it using some server (like you do in SIP telephony).
Then you have to hope that the contacted host is behind a 'good' NAT like 'full cone' or similar and not behind a 'bad' NAT like 'symmetric' that not allow incoming connection. The fact you use a TCP connection instead of UDP datagram can help you because of the three-way-handshake. In fact most NAT routers accept incoming TCP connection, but not incoming UDP packets.