I'd like to make my WM-based device reconnect to GPRS network, if connection has been broken.
There is a function in WinAPI
HRESULT WINAPI ConnMgrConnectionStatus(
HANDLE hConnection,
DWORD *pdwStatus
);
but it requires previous connection handle, and in my case it can be established manually.
Is there a way to get connection status without handles or subscribe to break event?
I can just check google.com, but that doesn't look good.
Regards,
Why can't you use the ConnMgrQueryDetailedStatus to get all the connections and run through them to check what you have?
Related
How do I close tcp v4 and tcp v6 connections on Windows? I don't want to kill the entire process that has the open connection as this obviously will kick everyone else off that process. I need to do this from a separate process, and so will not have access to socket handles, etc. I am using Windows API to get tcp table, etc. so I know which connections are active.
One way might be to enumerate all open handles on the system, or at least the open handles of a given target process, until you find the SOCKET handle you are interested in (see HOWTO: Enumerate handles, Socket Handles, and C++ Get Handle of Open Sockets of a Program - though I'm not sure how you would be able to retrieve the IP/Port pairs of a SOCKET to compare to the active connection you are interested in, without injecting remote getsockname()/getpeername() calls into the owning process of the SOCKET).
Once you have found the SOCKET handle you want, you can then close it by using DuplicateHandle() with the DUPLICATE_CLOSE_SOURCE flag 1.
1: This is how the "Close Handle" feature in Process Explorer works.
Since I'm using C#, I cannot PInvoke SetTcpEntry, even as administrator with an app.manifest file, it always sends a 317 error. So I created a C++ .exe to close a comma separated list of ipv4 addresses on the command line using SetTcpEntry, works fine even without an app.manifest file. That solves kicking ipv4 connections.
I tried using the get handles approach with NtQuerySystemInformation but never could get it working quite right, and it is a private mostly undocumented API and seems unsafe to use.
So, for ipv6, I am using windivert and injecting RST flag to ipv6 packets with certain ip addresses. It is as simple as setting the RST flag of an incoming packet before sending it on through with windivert. The downside is, if the client never sends another packet, the ipv6 socket still stays open indefinitely.
Perhaps someday Microsoft will add a SetTcpEntry6 function, but until then this appears to be the only realistic way.
UPDATE 2022-05-01, found this gem at https://www.x86matthew.com/view_post?id=settcpentry6
Working on USB Modem, Used RAS interface for dial/hangup.
For connection used RASDial() and for disconnection used RASHangUp() API's.
After successful connection waiting for the disconnect event using function RasConnectionNotification(rasHandle, event, RASCN_Disconnection), event notifies successfully when disconnect happens.
I need to find out the reason of disconnection, if it disconnect due to lost network signal then put my application on auto reconnect.
Is there any method or API which provides the reason for disconnection like LINK_FAILED, USER_SWITCH, USER_LOGOFF ... etc.
RasGetConnectStatus API can give you the reason in RASCONNSTATUS.dwError field.
Im trying to open a L2Cap HID Channel And Interrupt channel so I can send HID commands to a bluetooth device.
I've done all my service advertising and device paring and established a baseband connection.
The Hid Control channel opens fine.
When I try to create my kBluetoothL2CAPPSMHIDInterrupt connection
l2capChannelQueueSpaceAvailable
delegate method called (not sure what this means) followed by
l2capChannelOpenComplete
but the connection closes immediately calling
l2capChannelClosed
How can I correctly open these connection?
I've spent a long time digging through the IOBlueTooth framework and the bluetooth.org HID spec but theres barely any helpful information (that I can find at least).
When i trace out my L2Cap channels I see some null values for
mIncomingDataListener
and
mEventDataListener
. I dont know how to set these or if they have anything to do with my problem.... just speculating.
The code snippet below is my attempt so far to make the connections after a connection to the device has been established.
-(void)establishL2CappConnections:(IOBluetoothDevice*)device
{
IOReturn r;
IOBluetoothL2CAPChannel *ch1;
r = [device openL2CAPChannelSync:&ch1
withPSM:(BluetoothL2CAPPSM)kBluetoothL2CAPPSMHIDControl
delegate:self];
self.mL2CappChannel=ch1;
NSLog(#"r == %i",r);
IOBluetoothL2CAPChannel *ch2;
r = [device openL2CAPChannelSync:&ch2
withPSM:(BluetoothL2CAPPSM)kBluetoothL2CAPPSMHIDInterrupt
delegate:self];
self.mL2CappInterruptChannel=ch2;
NSLog(#"r == %i",r);
}
Edit:1
I've attached my packet logs. It's strange, a request for
kBluetoothL2CAPPSMSDP 0x0001
gets made without me requesting it and then everything starts disconnecting.
BT Packet Logs
As per your logs its very clear that your device in in Limited Connection mode, its stays Active for 30sec or less. change device settings to make it General Discoverable.
kBluetoothL2CAPPSMSDP 0x0001
means Bit 13 - Limited Discoverable Mode
Playing with the Bluetooth settings will solve your problem
I need to close UDP socket which has unsent data immediately.
There is SO_LINGER parameter for TCP sockets but I didn't find out anything for UDP.
It's on Windows.
Thanks in advance.
Update 0:
I give background of this question. I have application 1st thread opens/binds/closes socket, 2nd thread sends datagrams to it.
In some cases after closing the socket (errorcode = 0) bind function returns errorcode 10048 "Address already in use". I found out after close() execution port is still used (via netstat command). Maybe I ask incorrect question and the reason of such behavior is something else?
For all application purposes once your send() returns, the packet is "sent". There's no send-buffer like in TCP, and you have no control over the NIC packet queue. Normal close() is all you need.
Edit 0:
#EJP, here's a quote from UNP for you (Section 2.11 "UDP Output"):
This time, we show the socket send buffer as a dashed box bacause it
doesn't really exist. A UDP socket has a send buffer size (which we
can change with the SO_SNDBUF socket option, Section 7.5), but this
is simply an upper limit on the maximum-sized UDP datagram that can
be written to the socket. If an application writes a datagram larget
than the socket send buffer size, EMSGSIZE is returned. Since UDP is
unreliable, it does not need tp keep a copy of the application's data
and does not need an actual send buffer. (The application data is
normally copied into a kernel buffer of some form as it passes down
the protocol stack, but this copy is discarded by the datalink layer
after the data is transmitted.)
This is what I meant in my answer - you have no control over the send buffer - , so "for all application purposes" it does not exist.
I was having this problem with a windows UDP socket as well. After hours of trying everything I finally found my problem was that I was calling socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) on the main thread to create the socket, calling bind(...) and recvfrom() on a worker thread, then after closing the worker thread I called closesocket(...) on the main thread. None of the functions returned an error but tor some reason, doing this leaves the UDP address/port combination in use (so a future call to bind() triggers error 10048 WSAEADDRINUSE and netstat -abot -p UDP also shows the port still in use until the whole application is closed). The solution was to move socket(...) and closesocket(...) calls into the worker thread.
Other than weird issues like the case above, there is normally no way that a UDP server socket can be left open after calling closesocket() on it. Microsoft explains that there is no connection maintained with a UDP socket and no need to call shutdown() or any other function. Usually the reason a TCP socket is left open after calling closesocket() is that it wasn't disconnected gracefully and it's waiting for about 4 minutes in TCP_WAIT state for possible additional data to come in before it actually closes. In the case above, netstat showed the UDP socket never closed until the application was closed even if I waited 30+ minutes.
If you're using a wrapper around winsock like the .NET framework, I've also read some features like setting up async callbacks can leave a UDP socket bound open if you don't clean up the callbacks correctly, but I don't think there are any such features in the win32 winsock API that can cause that.
Just close it. There's nothing in UDP that says that pending data will be sent, unlike TCP.
In order to receive datagrams through an UDP connection I have created an object of type UDPClient.
receivedNotificationSock = new UdpClient();
However once done and on using the receive method:
receivedHostNameBuffer=receivedNotificationSock.Receive(ref receivedNotificationIP);
I am getting an exception saying that I must call the bind method.
But there is no bind method in the UDPClient class.
Could You guys please provide me with the code if possible as to what should be done to overcome this exception.
You need I think to know some more about sockets.
All sockets possess a port number. First, you create a socket - which is almost useless on its own. It just floats there. But then you bind it - you assign it a port number. Now it's useful - now you can send and receive data on it.
Remember, all UDP communications are defined by the quad data set of the IP and port of the source and the IP and port of the destination. A freshly created socket doesn't have an IP address or port; binding gives it an IP address and port.
Unfortunately, I'm not a C# programmer, so I can't properly answer your question. But at least you know why it's important.
Pass the port number into the constructor of your UDP client.
receivedNotificationSock = new UdpClient(21000);
You may need to change firewall settings to allow the bind, though a popup window normally opens when you first run this on your dev machine.
For Socket proramming you need to know the sequence of syscalls you need to do on client side and on the server side.
If you are writting a client :
you open a socket with a socket call.
you then connect to the server port with a connect call
once connect is successful
then you send the request to the server using either a send or sendto or a write
which results in reception of data that you can read using a receive or read
On Server Side
you create a socket
bind it to a port
start listening on the socket for incoming connections from various clients using a listen.
There is a non blocking way of listening for connections as well with a select syscall.
Once the you establish a connection you can essentially read the request and start processing it.
Here's an example in C# that may be useful to you.
http://www.developerfusion.com/article/3918/socket-programming-in-c-part-1/