iOS device discovery without Bonjour - ios

I'm creating an app that needs to connect to versions of itself running on other devices on the wifi network. The goal is to set up a broadcast / client relationship between one device to the others.
I know that Bonjour is the accepted method to do this, but I'm reticent to do that because it locks me into iOS devices, when I'd like to branch out to others, at least for clients.
If I start a webserver on the broadcaster on a specific port, like 43231 or something, is it acceptable for the client device to get it's own IP and then scan that block range for the broadcaster? Is there anything bad about pinging all the other random devices on the network with a request like that?
As in, Broadcaster is 192.168.1.11. Client is 192.168.1.4. If the client assumes all the devices are in the 192.168.1.* block, can it just iterate up the line from 1-100 or so looking for the broadcaster?
If this method is crazy, what should I do?

You can use SSDP (used by UPnP) or just multicast a message over the network and listen for it at the same time, ignoring the loopback (if you don't want the sender to receive it's own messages).

Maybe it will be better to use Bluetooth Low Energy for broadcasting/discovery? You can send non-connectable advertisement packets on server (with it's IP address) and listen for them on all other devices. Device founds such packet, reads IP address and connects to it via NSURLConnection (or something like that).

Related

Using Twilio to make/receive calls via Cisco SPA504G IP phone

Looking to place calls using our Cisco SPA504G IP phones through Twilio. We have 4 phone lines/numbers with Twilio and we want to use them to place and receive calls on physical phones.
Edited Question:
I found an interesting post in here: https://ertw.com/blog/2013/11/05/using-an-ip-phone-with-twilio/
This where my steps in order to get the phone to ring but I could not hear voice :/
I just bought: http://www.amazon.com/Grandstream-GXP1620-Medium-Business-Device/dp/B00VUU8EZM
Connected phone to my router. I am port forwarding all traffic in the ranges from 10000-20000 to the phone. I am also port forwarding port 5060 to the phone.
Uploaded the following xml file:
<Response>
<Say>Testing</Say>
<Dial>
<Sip>
sip:line1#24.51.221.98
</Sip>
</Dial>
</Response>
that can be found at: http://antnam.com/voip.xml
I called my internet provider and now I have a static IP address so that 24.51.221.98 never changes.
I configured my twilio number (855) 804-0420 to execute a GET # http://antnam.com/voip.xml
When I call (855) 804-0420 I can hear the phone that is connected to my router (voip phone) ring!!! So good news I am able to call the phone I purchased on step 1!
Once I answer the call I am not able to listen to voice :/ . What could I be doing wrong?
In summary everything works great I am just not able to listen to anything. It is as if the call is on mute. Am I missing to open more ports?
It sounds like this may just be a NAT traversal problem; if it is please move or remove this question, as this would only be relevant if you were programming this client. There is a ton of info out there about this issue (for example here is an excellent article that comes up as the first result when I google "voip nat traversal"), but here's a quick summary:
Why NAT causes a problem for VoIP
Most VoIP protocols use a data stream on one port (e.g. 5060 in this case) to negotiate connection information that includes among other things a socket (IP address and port) to receive audio/RTP traffic; there are 2 things about this negotiation of a socket that might be unexpected:
It can be any IP address and port combination, not just one that is on the VoIP device itself. So you might have for instance a VoIP server that negotiates a socket on another host that is not part of the SIP dialog, and which might be behind a NAT
The negotation is done at the OSI Application Layer (Layer 7), so it is normally untouched by the NAT process, which operates at Layers 3 and 4
How to diagnose missing audio due to NAT
If you're able to get packet captures (ideally on both WAN and LAN ports, so you can see your VoIP device's traffic before and after NAT), you can see the problem in action: just look for the packets containing SDP payloads (e.g. if you're doing SIP on UDP 5060, just filter for that port and you will see INVITE requests and 200 OK responses that contain SDP payloads); drill down to the c (Connection Information) and m (Media Description) lines, which should look something like the following:
c=IN IP4 192.168.1.114
m=audio 6094 RTP/AVP 0 8 101
If you're seeing something like this going out your WAN port, it means your VoIP device is requesting to be sent audio on 192.168.1.114:6094; the IP address is a private address and cannot be routed over the internet; the port is just one I picked randomly, but the one you see needs to be open and forwarded to your device
How to fix it
There are various solutions to this problem, which all come down to rewriting the private IP address that your device is giving out into the public one that your device's traffic is being NAT'd out on, so that when the remote device parses the Connection Information line in the SDP, it has a valid, publicly routable IP address to send the audio traffic to, and a UDP port that is NAT'd to your device. Sometimes the VoIP device itself can handle the rewriting (e.g. you can either statically tell the device in its configuration what its public IP is, or it can discover it from a protocol like STUN), sometimes the rewriting is done by the firewall/router that is doing the NAT (there are various names for this, like SIP ALG or SIP Fixup).
Unfortunately due to the variations in NAT implementations across various routers and firewalls, no solution can be guaranteed to work 100% of the time; and if you have multiple devices behind the same firewall, having it do the rewriting will only work for one of them.
In your case:
You mention 2 different VoIP devices, a Cisco SPA504G, and a Grandstream GXP1620. The datasheets for both devices say they support STUN, so I'd start looking in its config for the STUN settings or anything else that references NAT traversal. Also, make sure that the ports you are forwarding to the device are the ones that it uses, this is usually just another item in the config, called something like "RTP base port" or "RTP range"
I would also ensure that you nat transveral enabled with stun using a public stun server such as stun.sipgate.net
Note: STUN operates on TCP and UDP port 3478.
This is required as the phone needs to send the external ip in the sip packets. Without stun it will send the internal ip and the far end sip device will attempt to send the data there.

Is there a way to programmatically change network routes on an iOS device?

Scenario: I want to have an iOS device connect to a LAN that has no upstream Internet connection, yet still retain and use its cellular data connection.
Theoretically, it strikes me that the iOS wifi NIC and the cellular data NIC are similar enough to dual NICs in a PC that I should be able to set up routing such that any request to, say, 192.168.. goes through the wifi connection, and any other request goes through the cellular data connection.
I did a test to see if both NICs are active when the iOS device is connected to wifi by the following steps.
Ensure that my iPhone's wifi is off and that I have a good cellular data connection.
Disconnect my wifi router's Ethernet cable to my cable modem.
Connect my iPhone to the wifi router.
Use another iPhone that's connected only via cellular data to create a game of Words with Friends.
As soon as the other iPhone completed the first move, my iPhone received a notification that there was a new game to play.
This confirmed that the cellular data connection was indeed alive and well enough to receive push notifications despite the wifi NIC's being connected.
The question becomes, then, can an app programmatically connect to a given wifi network, set the cellular data network to be the default route, and route any requests to, say, 192.168.. to go through the wifi network?
I know this post is old, but I happen to have done some work on using multiple network interfaces on iOS.
My experiments showed that accessing via hostname results in iOS choosing the network interface it wants to use, and not trying any further interfaces if the host cannot be resolved.
If you know the DNS Server IP address for any Ethernet/WiFi based network, you can send a DNS request yourself, convert the hostname into an IP address and access via IP address. iOS will then use the correct interface.
My guess is, that if you have the private class IP address space accessible over both connections, there's probably nothing you can do to specify which network interface should be used.

Discover computers with my application installed on network

I am trying to build an app for iOS that can connect to computers running macOS or windows, and control a few stuff on those computers. Another application will be installed on those computers so that the app on iOS can connect to them. But at first I need to discover those computers in the network that has my app installed and running. What is a good way of doing that? I thought about using broadcasting, multicasting or bonjour. Are there any other options? Which one is best for my situation?
I am planning on doing two different applications for macOS and windows, one with objective c and other with c#, so the networking stuff should be available for both of those. Thanks in advance
The simplest option by far would be to use IP/UDP broadcast packets. The application on the computers (running whatever OS) can all sit there listening on a predefined UDP port (e.g. 9999), and when the iOS device wants to 'scan' the network, it will send out an IP/UDP broadcast packet with the destination port of 9999. Upon receiving the broadcast packet(s), the application on the computers can respond since it now knows the IP address of the iOS device, and you can take things from there.
The cleanest way to handle a computer leaving the network is for the application that is running on the computer to communicate this fact to the iOS device since it already knows the IP address of the iOS device. But if keeping a current list of computers is crucial, then some sort of a polling mechanism is unavoidable because the computers may crash for whatever reason without having the chance to send the bye-bye message.
Multicasting can be utilized as follows: computers periodically send IGMP joins for a predefined multicast group (e.g. 224.1.1.1), and iOS device sends the multicast UDP packet destined to 224.1.1.1 when it wants to 'scan' the network. The multicast UDP packet(s) will be received by the computers since they have already joined the multicast group of 224.1.1.1, and then the computers can start communicating with the iOS device now that the IP address is known. However, this seems overly complex, and does not really offer any advantages. The whole point of using multicast is to save bandwidth, but the amount of bandwidth saved will be minuscule. Unless you are going to send the same data in substantial quantities from the iOS device to all the computers, there is simply no reason to go down this path.
As for Bonjour, unfortunately I am unable to comment as I have no experience with it, but I would still vote for simple broadcasting to keep things platform independent... well, at least on the computers side. :)

Best way to find is my custom ethernet device is online and what IP it has got for iOS?

Ideas:
1. Pinging all my subnet ( using simple ping etc )
2. Sending GET to all IP in my subnet? ( may be too slow) waiting for 200 or 404 reply.
Thanx
Can you program your ethernet device to respond to Bonjour (mDNS) requests? That's the preferred discovery mechanism in the OSX/iOS ecosystem. avahi is an open-source mDNS daemon you might be able to run if your device runs a UNIX-like OS. You might also be able to find or write an embeddable mDNS server that you could integrate into your server if you're not running an OS as such.
Otherwise, I'd probably go with a custom broadcast UDP packet that the device will respond to. (which is basically what Bonjour/mDNS does, but less general) To send a broadcast UDP packet, open a UDP (datagram) socket and send a packet to the local subnet's broadcast IP. Make the packet contents suitably unique, and get your device to respond, e.g. using an HMAC, to avoid picking up any other devices or daemons which coincidentally answer on the same port.
This is a pure IP networking question. What you want to do is to send a TCP/IP broadcast message to the network and have you custom device respond to it. See TCP/IP Guide for some basic details.

How do I transfer data through WiFi like bluetoooth?

How do I transfer a file from one BlackBerry device to another over WiFi like I've done with blue tooth?
In Bluetooth, each device can easily become aware of one another because the protocol supports this. In Wifi (which is just a medium for generic networking... TCP/IP in many cases), it's generally expected that one machine already knows how to locate the other... so this is the problem you need to solve.
One option is that you can have one of the devices (or even both) periodically broadcast a message when it wants to connect to something; this message would be on a pre-defined port but as a broadcast, it's open to all receivers. Then the other device (or even both) needs to have a broadcast receiver looking for the message on the right port. One benefit here is the broadcast receiver will not only receive the message, it will also receive the IP address of the sender -- this is your missing component.
Once the receiver has the IP address of the sender, it needs to open a connection to the server port running on the device that sent out the broadcast. Of course, that first device needs to have its server task running at this time also.

Resources