I'm using WifiManager library to manually add user's network on configuration portal. Already it works fine, but every time I power off and power on again, it does not connect to network I have established previous. To connect I have to pin out the 'Vcc' of ESP8266 and pin in again and then again connect with ESP8266 network and go to configure portal.
For now I have two lines in code with 'WifiManager';
Good news is that connects to Wifi by configurationPortal.
ESP8266WebServer server; //server variable
void setup() {
initializePin(); //call function
Serial.begin(74880);
delay(500);
//Connect to network
WiFiManager wifiManager;
wifiManager.autoConnect("ESP8266","password");
Serial.println("Connected.");
if (!MDNS.begin("esp8266")) { Serial.println("Error setting up MDNS responder!"); }
else { Serial.println("mDNS responder started"); }
serverSection();
server.begin();
Serial.println("Server started");
}
I need to connect to previous established network,
Also it would be fine to run Configuration Portal if there wont be connection to that network ( for example if device would be transfer to other place)
Your code is supposed to connect to the internet. What happens usually when you use auto connect and it fails is that WL_IDLE_STATUS occurs. Read more about it here: https://www.arduino.cc/en/Reference/WiFiStatus . What I would do is to check if I got that status then I would try to reconnect to the wifi with a delay of 2 seconds. Here is an example:
if (WiFi.status() == WL_IDLE_STATUS) {
delay(2000);
WiFi.begin("yourssid", "password");
}
We are using Lettuce in our project. We have a requirement to monitor the status of connection.
I know Lettuce can re-connect Redis when the connection is down. But is there some way to notify application that the connection is down/up?
Thanks,
Steven
Lettuce provides an event-model for connection events. You can subscribe to the EventBus and react to events published on the bus. There are multiple events, but for your case, you'd want to listen to connected and disconnected events:
ConnectionActivatedEvent: The logical connection is activated and can be used to dispatch Redis commands (SSL handshake complete, PING before activating response received)
ConnectionDeactivatedEvent: The logical connection is deactivated. The internal processing state is reset and the isOpen() flag is set to false.
Both events are fired after receiving Transport-related events such as ConnectedEvent respective DisconnectedEvent.
The following example illustrates how to consume these events:
RedisClient client = RedisClient.create()
EventBus eventBus = client.getresources().eventBus();
Disposable subscription = eventBus.get().subscribe(e -> {
if (e instanceOf ConnectionActivatedEvent) {
// …
}
});
…
subscription.dispose();
client.shutdown();
Please note that events are dispatched asynchronously. Anything that happens in the event listener should be non-blocking (i.e. if you need to call blocking code such as further Redis interaction, please offload this task to a dedicated Thread).
Read more
Lettuce Reference Documentation: Events
As I recently found this paper describing a sniffing mechanism for iOS using Apple's NEPacketTunnelProvider Extension, I got curious and it made me want to understand it from a technical point of view. As I usually don't work at a deep network layer like that, I'm not able to comprehend it in the detail I'd like to. As Charles Proxy for iOS must do something very similar without requiring supervised devices, I assume the approach which the author of the paper presented in 2016 might be still working nowadays.
The author claimed that "Everything like IP packet parsing, building
an IP packet or parsing a DNS response had to be implemented ourselves." As I want to fully understand that, I tried to build it myself. I build a NetworkExtension and a message loop for the packetFlow of the NEPacketTunnelProvider. I was able to obtain the ip datagrams and tried to parse them. I used unsigned integers of the corresponding size for the source and target ip, the transport protocol and ip version, but I'm unsure how to handle the treat the payload. My parser uses the ptr.load(fromByteOffset: <offset>, as:<DataType>.self) where ptr is a UnsafeRawPointer to access the packet flow information. Since the data might exceed the storage of UInt64, I don't know how to access and store the payload in a proper way.
Furthermore, I figured that the source IP is always 192.168.20.1 (set as my interface's NEIPv4Settings address) and my target ip is always 192.168.2.1 (my dummy NEDNSSettings server). This leads me to my first questions: Are those DNS queries? Will the datagram packet claim any further information about the actual target? Would that mean that I have to somehow execute the request to the DNS server and reroute the packet to the target which I will obtain from that DNS query?
The next step would be to implement a TCP / UDP handling, right? My current parsing approach is able to distinguish between UDP, TCP and ICMP (even though I don't have investigated in the last one yet). Therefore, I'd iterate over the datagrams and lookup whether they require a UPD or TCP session/connection and transfer the datagram. The problem I currently see their from a conceptional point of view: How do I know which source/target port to use for TCP/UPD connections/sessions? As far as I know, this information is not part of the IP Packet itself (since it's rather some information we need on transport layer level, not on network layer level).
Additionally, I found a project called Specht on github. It uses a self-written library called NEKit which somehow also uses the NEPacketTunnelProvider approach. When I understand their approach correctly, they managed to somehow build a local proxy server by writing some observer mechanisms in order to handle the requests, but since I'm relatively new to networking and swift, I'm not sure whether I understand that completely correct or whether I just haven't find all those TCP/UDP and/or DNS logic. Is this project comparable to the approach of the paper and charles proxy?
One last question: Charles proxy is in most cases able to show the hostname of the target. I'm currently just able to see destination ip addresses (which aren't real destination ip addresses, but the address of my DNS server). How am I able to see the hostname as human readable text? Does Charles do a nslookup somehow? Does Charles obtain that information out of the datagrams?
I know it's quite ambitious of me with much missing knowledge in this topic, to build something similar for test reasons, but I'm still motivated to look deeper into that topic and also have the feeling that I have understand already some key points, but unfortunately not enough to solve the puzzle... Maybe you're able to give me some more hints to get a better understanding. If there might be even an easier way to archive a similar behavior (to see outgoing connections on hostname level), I'd be interested in these as well :-)
I've published a Beta Proxyman iOS (website) - a Network Sniffer by using NEPacketTunnelProvider and Network Extension, so I might have experienced to answer some of your questions.
IP Package, IP Diagram, DNS, How to parse it?
Luckily, there is another way to set up a NEPacketTunnelProvider to provide you with an HTTP Message, not IP Package (it's too low-level, and you have to deal with the Parser, DNS, ...)
HTTP Message is easier to parse because there are plenty of reliable libraries (e.g. http-parser from nodeJS)
How to build a Network Sniffer on iOS?
It's a complicated question to answer, I would break it into small chunks:
MitM / Proxy Server
Firstly, you need a working MitM Proxy Server, which is capable of proxying and intercepting the HTTP/HTTPS Traffic. You can implement it by using SwiftNIO or CocoaAsyncSocket.
How does it work?
In general, the data flow might look like this:
The Internet -> iPhone -> Your Network Extension (VPN) -> Forward to your Local Proxy Server (in the Network Extension) -> Mitm/Proxy Server starts intercepting or monitoring the traffic -> Save to a local database (in Shared Container Group) -> Forward again to the destination server.
From the main app, you can receive the data by reading the local database.
The reason why we need a local database is that the Network Extension and the Main app are two different processes, so they could not communicate directly like a normal app.
Show me the code?
In the Network extension, let start a Proxy Server at Host:Port, then init the NetworkSetting, like the sample:
private func initTunnelSettings(proxyHost: String, proxyPort: Int) -> NEPacketTunnelNetworkSettings {
let settings: NEPacketTunnelNetworkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "127.0.0.1")
/* proxy settings */
let proxySettings: NEProxySettings = NEProxySettings()
proxySettings.httpServer = NEProxyServer(
address: proxyHost,
port: proxyPort
)
proxySettings.httpsServer = NEProxyServer(
address: proxyHost,
port: proxyPort
)
proxySettings.autoProxyConfigurationEnabled = false
proxySettings.httpEnabled = true
proxySettings.httpsEnabled = true
proxySettings.excludeSimpleHostnames = true
proxySettings.exceptionList = [
"192.168.0.0/16",
"10.0.0.0/8",
"172.16.0.0/12",
"127.0.0.1",
"localhost",
"*.local"
]
settings.proxySettings = proxySettings
/* ipv4 settings */
let ipv4Settings: NEIPv4Settings = NEIPv4Settings(
addresses: [settings.tunnelRemoteAddress],
subnetMasks: ["255.255.255.255"]
)
ipv4Settings.includedRoutes = [NEIPv4Route.default()]
ipv4Settings.excludedRoutes = [
NEIPv4Route(destinationAddress: "192.168.0.0", subnetMask: "255.255.0.0"),
NEIPv4Route(destinationAddress: "10.0.0.0", subnetMask: "255.0.0.0"),
NEIPv4Route(destinationAddress: "172.16.0.0", subnetMask: "255.240.0.0")
]
settings.ipv4Settings = ipv4Settings
/* MTU */
settings.mtu = 1500
return settings
}
Then start a VPN,
let networkSettings = initTunnelSettings(proxyHost: ip, proxyPort: port)
// Start
setTunnelNetworkSettings(networkSettings) { // Handle success }
Then forward the package to your local proxy server:
let endpoint = NWHostEndpoint(hostname: proxyIP, port: proxyPort)
self.connection = self.createTCPConnection(to: endpoint, enableTLS: false, tlsParameters: nil, delegate: nil)
packetFlow.readPackets {[weak self] (packets, protocols) in
guard let strongSelf = self else { return }
for packet in packets {
strongSelf.connection.write(packet, completionHandler: { (error) in
})
}
// Repeat
strongSelf.readPackets()
}
From that, your local server can receive the packages then forwarding to the destination server.
Don't forget to save all traffic log to the local database, then notifying the main app to reload it.
One last question: Charles proxy is in most cases able to show the hostname of the target. I'm currently just able to see destination ip addresses (which aren't real destination ip addresses, but the address of my DNS server). How am I able to see the hostname as human readable text? Does Charles do a nslookup somehow? Does Charles obtain that information out of the datagrams?
Since we don't deal with IP Package, we don't need to implement the DNS Resolver. If you need a DNS, you can config like the following code:
let dnsSettings = NEDNSSettings(servers: ["8.8.8.8", "1.1.1.1"])
settings.dnsSettings = dnsSettings
As we receive the HTTP Message package, you can get hostname for free (From the Request's URL or Host Header)
Hope that my answer could help you.
I am trying to connect a dvr using boost asio library in ios. The application works fine in emulator with in ipv4 network. But when I submit the application on Appstore apple rejected the application as it's not work on ipv6 network. And I can see in the apple site that application should support ipv6 network. https://developer.apple.com/news/?id=05042016a
So I think the problem comes at the section where I am trying to connect to DVR using boost library, where the ip address of the DVR is pulled from DB(hard-coded) and below is the relevant part of the code.
boost::asio::io_service io_service_;
tcp::resolver::iterator endpoint_iter_;
tcp::resolver resolver_; //to healp resolving hostname and ip
stringstream strstream;//create a stringstream
strstream << port;//add number to the stream
endpoint_iter_ = resolver_.resolve(tcp::resolver::query(ip.c_str(),strstream.str()));
start_connect(endpoint_iter_);
// Start the deadline actor. You will note that we're not setting any
// particular deadline here. Instead, the connect and input actors will
// update the deadline prior to each asynchronous operation.
deadline_timer_.async_wait(boost::bind(&dvr_obj::check_deadline, this));
//starting thread for dvr connection
io_service_.reset();
thread_ = new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_));
start_connect method
void start_connect(tcp::resolver::iterator endpoint_iter)
{
try
{
if (endpoint_iter != tcp::resolver::iterator())
{
drill_debug_info("trying to connect %s \n",name.c_str());
// Set a deadline for the connect operation.
deadline_timer_.expires_from_now(boost::posix_time::seconds(10));
// Start the asynchronous connect operation.
socket_.async_connect(endpoint_iter->endpoint(),
boost::bind(&dvr_obj::handle_connect,
this, _1, endpoint_iter));
}
else
{
// There are no more endpoints to try. Shut down the client.
connectivity = false;
}
} catch (int e) {
connectivity = false;
}
}
So I am confused how to change above code to work on IPV6 network. Could not find any solution in Internet.
You can iterate through the endpoints to find an IPv6 endpoint using the code below:
endpoint_iter_ = resolver_.resolve(tcp::resolver::query(ip.c_str(),strstream.str()));
while (endpoint_iter_ != tcp::resolver::iterator())
{
if (endpoint_iter_->endpoint().protocol() == tcp::v6())
break;
++endpoint_iter_;
}
if (endpoint_iter_ != tcp::resolver::iterator())
{
start_connect(endpoint_iter_);
...
}
else
std::cerr << "IPv6 host not found" << std::endl;
I have a hardware device Acquisition unit. This device itself act as wifi router and it will send data. I want to connect it from iPhone/iPad.
I heard that using IP address and port number we can connect to the wifi router using socket programming. But I don't have any idea about this socket program to connect to the wifi using IP address and port number.
For this I have tried to get the IP address of a connected wifi router using following code.
NSString *address = #"error";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0) {
// Loop through linked list of interfaces
temp_addr = interfaces;
while(temp_addr != NULL) {
if(temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:#"en0"]) {
// Get NSString from C String
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
return address;
If it is possible to connect to the wifi router using ip address and port number could you please help me with some code or idea.
Please help me..
Thanks
The code you pasted basically returns the device's own IP address, which does not help at all, unless you want to guess router's IPs. You actually can get correct router IP address, see questions below:
Objective-C : How to fetch the router address?
How to get Wi-Fi router IP address on iOS?
Is it possible to get the SSID & MAC Address of Currently connected WiFi Network in an App
After you have this, you can easily connect to it via a normal TCP/IP connection socket, see the following links for more information:
Socket Connection in IOS
http://www.raywenderlich.com/3932/networking-tutorial-for-ios-how-to-create-a-socket-based-iphone-app-and-server
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/UsingSocketsandSocketStreams.html
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Streams/Articles/NetworkStreams.html
Or to make things even easier for you, there are a couple of community libraries that will make connecting to a server like a breeze:
https://github.com/pkyeck/socket.IO-objc
https://github.com/dreese/FastSocket
My suggestion is to read through those documents first, so you understand the basics of networking in iOS / OS X (which is actually fairly similar to Unix in this aspect). After try the libraries and wrappers you can find on CocoaPods and GitHub. If you are stopped by some specific issue at that point, we might be able to help you. We cannot do all the work for you.
So to answer: Yes, it is possible.