GCDAsyncSocket client/server not working over iOS access point - ios

I have a very simple TCP client/server implementation using GCDAsyncSocket (7.5.0) and I'm using NSNetService for service discovery.
It's used only on a local wifi network and it works for 2 years with no problem (just to say : I have a proper use of GCDAsyncSocket).
...Until I tried using a third iOS device as access point providing the wifi network to which the client and server connect.
Same when the third iOS device connects both client and server by sharing its connection via Bluetooth.
The service discovery is OK, but once I get the ip address and port, I can't connect and get this error :
Error Domain=NSPOSIXErrorDomain Code=64 "Host is down" UserInfo={NSLocalizedDescription=Host is down, NSLocalizedFailureReason=Error in connect() function}
I tried restricting to IPv4 and IPv6 (both are provided by the service discovery), I also tried using the ipv6 git branch of the GCDAsyncSocket repository and various parameters.
My primary question is : is establishing a simple TCP connexion over a wifi or bluetooth iOS access point possible, if so how ?
My secondary question is : why does the NSNetService service discovery work and not the simple TCP connection ? I know that the protocols are not comparable but still, it confuses me.

It sounds like to me, that your problem lies in connection from the cellular network. When connected to cell network, it causes issues with ip address. Refer to this discussion from the Cocoaasyncsocket Github page.

Related

OBD 2 iOS wifi swift communication

I want to create an iOS app to connect my Wifi OBD 2 to the iPhone. But i have no idea on how to do the peer connection with swift 2. I have the OBD doc to communicate with it (https://www.elmelectronics.com/wp-content/uploads/2016/07/ELM327DS.pdf - page 30).
I tried to search the same thing on android and windows but the problem is my knowledge on peer to peer iOS communication.
I see a lot of iOS app for OBD protocol on app store, I'm sure that anybody can help me !
Thank you !
You don't need to know about real wifi peer2peer communication. Once you attached your phone to the wifi network created by the obd2 wifi adapter, you will be able to establish a good old TCP-connection to it. By default most wifi adapters listen at 192.168.0.10:35000 for incoming connections.
After establishing the TCP connection you can communicate via AT and PIDs by writing/reading to/from the socket. The actual protocol is described in ELM327 manual and the ISO/SAE standard documents.

GCDAsyncSocket: [socket acceptOnPort: error:] not accepting

So I have been trying to create two GCDAsyncSocket's in my project, one (socket) that uploads a file to my server and the other (listenSocket) waits for another process from the server to communicate with it. In my ViewController I have initialized them in viewDidLoad method and setup delegate to self for both sockets.
socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
listenSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
I then made the listenSocket start listening by
NSError *err = nil;
if (![listenSocket acceptOnPort:19920 error:&err]) {
NSLog(#"listenSocket failed to accept: %#", err);
}
I then made socket to connect to remote server and start uploading files.
The problem is that socket works fine and can upload and also read response from my server, but it seems that I can't access the accepting listenSocket by any way. Not by the other process on server, nor by using telnet or by typing the ip address and port number into browser. Why is this and how do I fix it?
Edit:
Here's what I am doing with my app:
I am working on an app that programs for Arduino on iPhone. Due to App Store policy the compiling and uploading process has to be on server, so I'm using socket to upload the code to server to get it compiled. In order to upload the compiled binaries to Arduino, I have to run avrdude which fortunately would accept an ip + port address instead of a usb connection as target. avrdude is implemented so that it connects to the address as a client, so I have to open a listening socket on my app.
I imagine your issue relates to your device not having a routable IP address from the outside world. I have assumed here that you are not testing on a local network with your server and phone both using this network via wifi/cable.
When you are on your device using a mobile network, it is assigned an IP address from the mobile operator. This address is more than likely an address which is part of their internal mobile network. When you connect outside of the mobile network to a server, the address the server sees for your device is not the address you see on the device. The addresses are mapped in transit as your IP packet passes through the various gateways while on its way to the server. Thus when you server sees a connection requested on a listen socket, it has a reply address which when used allows the reply to traverse back to your device.
A similar issue occurs when your device is on WiFi behind a NAT router. Connections made outgoing are seen by the router and it changes the from IP address to be that of the router. Since it sees the start of the conversation, it know where return packets with a given port and sequencing should be routed. However if somebody wants to connect to your device from outside, you have to have set up port forwarding on the router for a known port telling it where to send connection packets.
So applying this to your situation:
Outgoing Works (Why):
Your outgoing socket works, because you are connecting to an externally visible IP. When you connect, the network knows exactly where the packet has to go and the reply address is provided in the packet by the network.
Incoming Does Not Work (Why):
Your listen socket will not be working because the address you are sending to does not exist on the open internet. To make a connection from the server or anywhere else to your device you would need an IP which has a routing mapped through to your device. If the device is on a mobile network, you need an external IP for the mobile network which maps to your device. If the device was behind a NAT router, you would need port forwarding set up.
Solution:
Unfortunately, there is no easy solution as your need an IP address for your device in the outside world. Much depends on your use case which you have not mentioned. You either need an external IP which is reliable or you need to use an intermediate server to handle messaging or you need to change your approach and have the device poll every so often for information.
This is a problem which has existed for a long time and is why peer to peer companies have smart algoithms for connecting peer to peer services which use clever techniques like hole punching to connect devices.
IMHO I would move to a model where your device always initiates the connection if you can.

creating a UDP connection with iOS and an embeddeddevice

If I have an iOS client and an embedded device that I want to communicate between the two with a WiFi connection using UDP, do I need to write a server (python or something) to facilitate the connection? I am trying to look online but there are a lot of ambigious articles.
Thanks
You'll have to write a server application for the device (iOS or embedded) that will be listening for data.
However, for a simple, single-client UDP connection, your server is basically just a UDP socket, which you bind to the port you want to use - and then start listening for data on. You don't need any connection-handling as UDP is connectionless.
On your client, you just send data to the IP and port of your server, and that's it.
I've done this myself, connecting my iPod Touch to a small ITX computer (running WinXP), to control a small mobile robot over WiFi.

Force iOS device app to talk through the local WIFI network

I'm building an application that will run in a museum with a local area wifi network without internet access, for some strange reason I'm not able to fully "join" this network with an iOS device. Enabling internet access on this network solves the problem...
The network should provide only a web server and a DNS server, the access point has a DHCP server, android devices can connect to the network without problems.
When I try to join the network with the device it remains in a "spinning wheel" status, the DHCP server log on the debian server says it has assigned an address to the iOS device, and if I check for the wifi address with an application (like iSys o SBSettings) I see the WIFI DHCP assigned address.
But when my app (or safari) tries to connect to the web server the request is routed through the 3G connection and not completed.
In my app I'm using the standard "Reachability" framework from Apple to check the reachability of a provided host name through the wifi connection and I get 0 on the SCNetworkReachabilityFlags mask....
I'm quite sure the problem is due to the fact iOS (5.1 in my case) tries to check the reachability for some "standard" host in the network, before routing traffic through the WIFI connection.
Anyone knows what an iOS device do to "validate" a WIFI network? I can add hostnames or simple dummy services to the server machine if this can help me connect the device to a LOCAL-only network :)
It seems that iOS doesn't like to join networks without a gateway, also if the network is local you have to setup a correct gateway address.
Setting the gateway as the server itself did the trick and the device started to route TCP/IP over my local area wifi network.

Query related to Connection type BIS-B Socket in Blackberry application

I am trying to establish BIS Socket connection. I am able to establish BIS Http connection from my service provider.
I have downloaded one chat application that checks network types supported by my device/service plan which has following list:
1)BIS-Http : OK
2)BIS-SOCKET :OK
3)BES-HTTP : NA
4)BES-SOCKET : NA
5)TCP-HTTP : BAD DNS
6)TCP-SOCKET : TIMED OUT
As I know direct TCP is not supported by my service provider. So I would like to use BIS-Socket connection.
Can anypne please help me in achieving this type of connectivity?
Use of BIS-B connectivity is available to members of the Blackberry Developer Alliance program. Not being a member I can't tell you if if supports random socket connection or not.
Normal BIS access available through the API supports web protocols and is not a TCP/IP protocol between the Blackberry and the BIS. Hence the deviceSide= parameter in the connection stream. DeviceSide=true the Blackberry uses an internal TCP stack to establish a connection through direct access to the wireless carrier's access point (APN). DeviceSide=false (the default) the Blackberry sends the necessary data to the BIS (or BES) MDS server using a presumably proprietary protocol. The MDS server then establishes the TCP connection on behalf of the Blackberry.
If direct TCP is not available to you, and you can't use BIS-B, you will have to carry your data on top of an http connection. In most cases this is straight forward and works quite well.
To use BIS you need pay $2000. Have you done that? how you know you're using BIS?

Resources