Re-opening Closed Serial Port - serial-port

i have an application that detects a USB 3G Dongle that will be used for sending SMS. My application queries the Dongle via AT Commands to determine if it is the RIGHT dongle, this means that that certain dongle can only be used in my application (even if the Dongle is of the same model). Sending and receiving is fine, no problems or whatsoever. If the 3G Dongle is removed from the USB port, the system detects this and executes the proper procedures.
Here's my problem. When the 3G Dongle is re-inserted, say on the same port (COM5), my application detects this and executes some AT Command to determine that the re-inserted dongle is the RIGHT dongle. But an error occurs stating:
THE RESOURCE IS IN USE
The application must be terminated or closed to be able to use the same port (say COM5). Then I encountered an application, almost with the same function, but is able to use the dongle when re-inserted.
BTW, my dongle is ZTE MF190, and the application I saw is from Huawei. I am using C#. Is there any work around on this? or better, is there a better logic on this? say using a service, etc..
EDIT:
every query done to the Dongle is done in a separate thread so as to be able to use my application while sending and receiving..
Thanks!

I too had a similar issue with the windows serial port component. There appears to be bugs in the C# code.
Long story short, I managed to get around this by closing the port in a background thread.
Here is my code, note that you may need to modify to fit your application:
private bool ClosePort()
{
_Closing = true;
_SerialPort.DiscardInBuffer();
_SerialPort.DiscardOutBuffer();
if (!_SerialPort.IsOpen) return true;
//We run this in a new thread to avoid issue when opening and closing
//The .NET serial port sucks apparently - and has issues such as hanging and random exceptions
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(DoClosePort));
t.Start();
//here we wait until is **SHOULD*** be closed - note the better way is to fire an internal event when its finished
//We may need to tinker with this wait time
System.Threading.Thread.Sleep(500);
return _SerialPort.IsOpen;
}
private void DoClosePort()
{
try
{
//System.Threading.Thread.Sleep(500);
_SerialPort.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error closing " + _SerialPort.PortName + ". Error Message: " + ex.Message + "\r\n");
}
}
Note that if you try sending/receiving while you are closing, check the _Closing class variable before you attempt the send.
Hope this helps anyone.

Related

Handle BLE user event on FreeRTOS

I'm running FreeRTOS on a ST Nucleo board with the BlueNRG shield.
The initialization of the BLE stack works, the devices advertises itself and I can establish a connection. My problem is that as soon as user event arrives (e.g. service discovery) the program ends up in the hardfault_handler().
I have 3 tasks running on my RTOS of which one should be a dedicated BLE task handling the user events.
void hci_user_evt_proc(void)
{
tHciDataPacket * hciReadPacket = NULL;
/* process any pending events read */
while (list_is_empty(&hciReadPktRxQueue) == FALSE)
{
list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
if (hciContext.UserEvtRx != NULL)
{
hciContext.UserEvtRx(hciReadPacket->dataBuff);
}
list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
}
}
This is taken from an ST example code.
The whole thing works if I either
Just run this one task or
Give the BLE task a higher priority
Both solutions have the same outcome - and don't have a multitasking system anymore.
I don't know if a have to adapt the example code to run in a multitask system or if I have to run the BLE process interrupt driven, but if yes, how would I do that and how can I elaborate the root cause of a hardfault?
What I tried is to surround my user_evt_handler with a vTaskSuspendAll/xTaskResumeAll but that didn't change anything.
Issue solved by giving the BLE task more stack size

Qt: Detect a QTcpSocket disconnection in a console app when the user closes it

My question title should be enough. I already tried (without success):
Using a C-style destructor in a function: __attribute__((destructor)):
void sendToServerAtExit() __attribute__((destructor)) {
mySocket->write("$%BYE_CODE%$");
}
The application destructor is called, but the socket is already disconnected and I can't write to the server.
Using the standard C function atexit(), but the TCP connection is already lost so I can't send anything to the server.
atexit(sendToServerAtExit); // is the same function of point 1
The solution I found is check every second if all connected sockets are still connected, but I don't want to do so inefficient thing. It's only a temporary solution. Also, I want that others apps (even web ones) can join the chat room of my console app, and I don't want to request data every second.
What should I do?
Handle the below signal (QTcpSocket is inherited from QAbstractSocket)
void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState)
Inside the slot called, check if socketState is QAbstractSocket::ClosingState.
QAbstractSocket::ClosingState indicates the socket is about to close.
http://doc.qt.io/qt-5/qabstractsocket.html#SocketState-enum
You can connect a slot to the disconnect signal.
connect(m_socket, &QTcpSocket::disconnected, this, &Class::clientDisconnected);
Check the documentation.
You can also know which user has been disconnected using a slot like this:
void Class::clientDisconnected
{
QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
if(client)
{
// Do something
client->deleteLater();
}
else
{
// Handle error
}
}
This method is usefull if you have a connections pool. You can use it as well if you have a single connection, but do not forget nullptr after client->deleteLater().
If I understand you question correctly, you want to send data over TCP to notify the remote computer that you are closing the socket.
Technically this can be done in Qt by listenning to the QIODevice::aboutToClose() or QAbstractSocket::stateChanged() signals.
However, if you graciously exit your program and close the QTcpSocket by sending a FIN packet to the remote computer. This means that on the remote computer,
the running program will be notified that the TCP connection finished. For instance, if the remote program is also using QTcpSocket, the QAbstractSocket::disconnected()
signal will be emitted.
The real issues arise when one of the program does not graciously exit (crash, hardware issue, cable unplugged, etc.). In this case, the TCP FIN packet will
not be sent and the remote computer will never get notified that the other side of the TCP connection is disconnected. The TCP connection will just time-out after a few minutes.
However, in this case you cannot send your final piece of data to the server either.
In the end the only solution is to send a "I am here" packet every now and then. Even though you claim it is ineficient, it is a widely used technique and it also has the advantage that it works.

Unable to send data using QSerialPort

I am trying to write a QT application that will be able to communicate with my embedded system using serial port. For now I am testing the config with Null Modem emulator as I don't have the embedded system ready yet.
The emulator works fine as I have tested it in other software like Terraterm, RealTerm or Putty. My problem is that my example code doesn't work - it doesn't send the string to another com port.
This is my code:
void CSettingsDialog::on_pbSerialCheck_clicked()
{
QSerialPort serial;
serial.setPortName(ui->cbSerialPort->currentText());
if (!serial.open(QIODevice::ReadWrite))
{
QMessageBox::warning(this, tr("Serial port"),
tr("Serial port %1 is busy!")
.arg(ui->cbSerialPort->currentText()));
}
else
{
serial.setBaudRate(QSerialPort::Baud115200);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
serial.write("TEST\n");
serial.close();
}
}
I am certain that I have everything set correctly looking at the QT examples.
I am certain that I have everything set correctly looking at the QT
examples. I would aprichiate all help!
When reading flush documentation, it seems that calling "write" buffers, with writes possible finishing asynchronously.
Also see "Certain subclasses of...are asynchronous", with comments on waitForBytesWritten

Detecting Serial port disconnect in Chrome App

I'm using Chrome's Serial Port API (http://developer.chrome.com/apps/serial.html) in a Web App.
The problem I have is that pretty much all serial ports now are implemented via USB devices. If the user disconnects (or just resets) the USB device, I don't have any way of knowing. Not only that, because the app hasn't disconnected in Chrome (because it didn't know), if the USB device is plugged back in, bad things happen (on Linux it just gets a different name, but in Windows it is not usable at all).
The best I can manage is:
var checkConnection = function() {
chrome.serial.getControlSignals(connectionInfo.connectionId, function (sigs) {
var connected = "cts" in sigs;
if (!connected) console.log("Disconnected");
});
} // called every second or so
Is there a better way? a callback would be ideal!
It looks it should be safe on all platforms to assume that getting a read callback with 0 bytes means EOF, which in turn is a good indication that the device has been disconnected.
chrome.serial.read(connectionId, function(readInfo) {
if (readInfo.bytesRead === 0) {
/// Safely assume the device is gone. Clean up.
chrome.serial.close(connectionId);
/// ...
}
});
The serial API will be improving over the next few weeks (in Canary at least) to add stability improvements, an event-based read API, and the ability to more clearly detect timeouts and error conditions (like a disconnected device). You can track that progress at http://crbug.com/307184.

Can a blackberry HTTP request error out immediately if there's no connection available?

I have an HTTP connection, opened by
HttpConnection c = (HttpConnection)Connector.open(url);
where url is one of:
http://foo.bar;deviceside=false
http://foo.bar;deviceside=false;ConnectionType=mds-public
http://foo.bar;deviceside=true;ConnectionUID=xxxxxxx
http://foo.bar;deviceside=true;interface=wifi
Is there any way to cause the request to error out immediately if the connection cannot be established because the device is not connected to a network? As it is, it takes about a minute to timeout in many cases (specifically on the first call to get the information from the network: c.getResponseCode())
Edit: I mean error out. In one case, Wifi, specifically, it will sit around for several minutes if the wifi is not on before timing out, and I want it to stop right away.
I use the RadioInfo class to check if there is a connection and if the radio is turned on before trying to make a connection. Then you can just display a message to the user or turn the radio on (if it's off) before trying to connect, makes for a much better user experience.
Try using:
if (RadioInfo.getState() == RadioInfo.STATE_OFF)
OR
if (RadioInfo.getSignalLevel() == RadioInfo.LEVEL_NO_COVERAGE)
To check connection status before connecting.
I encase my posts in a thread to timeout faster. Make sure your "PostThread" catches all exceptions (and saves them).
public byte[] post(String url, byte[] requestString){
PostThread thread=new PostThread(url, requestString);
synchronized(thread){
try{
thread.start();
thread.wait(TIMEOUT);
}catch(Throwable e){
}//method
}//synch
if (thread.isAlive()){
try{
thread.interrupt();
}catch(Throwable e){
}//method
D.error("Timeout");
}//endif
if (thread.error!=null) D.error(thread.error);
if (thread.output!=null) return thread.output;
throw D.error("No output");
}//method
There is also the ConnectionTimeout parameter, which I have not tested: eg socket://server:80/mywebservice;ConnectionTimeout=2000
Not any way that can be specified programmatically. It can be irritating, but a connection from a mobile device - especially a BlackBerry - generally goes through a few different networks and gateways before reaching the destination server: wireless->Carrier APN->Internet->BES (maybe)->foo.bar server so a large timeout is built-in to account for potential delays at any of those points.
You can control default device connection timeout from your BES/MDS server (or in the JDE, from the MDS\config\rimpublic.property file) - but that probably won't help you.
It would be better to have a Timeout check from a different thread, Because this is gonna happen even when the connection is established, say the network latency is very high, so u dont want the user to wait for so long or such thing.
So, in that case have a check from a different thread, whether the current time minus time entered for initiating the connection is more than your set time, close the connection using connection.close()!

Resources