I need to know a name of the host machine for a iPhone/iPad Simulator. My guess is it should be possible but I was not able to find the way yet. Why do I need it? This is because [[UIDevice currentDevice] name] returns the same name "iPhone Simulator" for any simulator running on the same network. And I need to work with a particular one located on the Mac with name "My Mac Dev Machine". An application that runs on the simulators should be able to determine that is runs on "My Mac Dev Machine"'s simulator and should allow the connection from the network. Any ideas?
I had this same problem, and was able to use uname() within the simulator to get the host's node name, like so:
#if TARGET_IPHONE_SIMULATOR
#include <sys/utsname.h>
#endif
...
#if TARGET_IPHONE_SIMULATOR
- (NSString *)testProxyHeaderValue {
struct utsname name = {};
uname(&name);
return [NSString stringWithFormat:#"iPhone Simulator # %s", name.nodename];
}
#else
- (NSString *)testProxyHeaderValue {
return [[UIDevice currentDevice] name];
}
#endif
The simulator's node name is the same as the host's node name, which can be obtained with uname -n on the command-line.
In Swift 2:
var name = utsname()
uname(&name)
return withUnsafePointer(&name.nodename) {
String.fromCString(UnsafePointer($0))!
}
Hmm... I've you're dealing with a simulator/emulator, isn't it logical that whatever is being simulated has absolutely no idea that it's simulated?
Related
I wrote a small software using .net6 which should run on Windows and Linux (Ubuntu). In this software I need to access a file in a folder.
Linux: /folder1/folder2/file.txt
Windows: d:\folder1\folder2\file.txt
The folder structure and the filename is the same on both systems.
This code works so far
string[] pfad;
pfad = new[] { "folder1", "folder2","file.txt" };
Console.WriteLine(System.IO.Path.Combine(pfad));
and delivers the correct folder structur under Linux and Windows.
How can I define the root directory?
/ in Linux and d:\ in Windows
Can I detect the OS type somehow or what is the best approach?
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); is "fix" under Windows to C:... - I want to use another drive.
Borrowing from stefan answer but using OperatingSystem class instead of RuntimeInformation (since OperatingSystem is part of System i believe it's preferable)
string rootPath;
if (OperatingSystem.IsWindows())
rootPath = #"d:\";
else if (OperatingSystem.IsLinux())
rootPath = "/";
else
{
// maybe throw an exception
}
You can use System.Runtime.InteropServices.RuntimeInformation like this:
string rootPath;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
rootPath = #"d:\";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
rootPath = "/";
}
I have a computer with a GPS connected to a serial port that is running gpsd with a pretty basic configuration. Here is the contents of /etc/default/gpsd:
START_DAEMON="true"
USBAUTO="false"
DEVICES="/dev/ttyS0"
GPSD_OPTIONS="-n -G"
GPSD_SOCKET="/var/run/gpsd.sock"
With this config, gpsd runs fine and all gpsd client utilities, e.g. cgps, gpspipe, gpsmon, can get data from the GPS.
I am trying to access GPS data from a Qt QML program using the PositionSource element with the following syntax but lat and long show as NaN so it doesn't work:
PositionSource {
id: gpsPos
updateInterval: 500
active: true
nmeaSource: "socket://localhost:2947"
onPositionChanged: {
myMap.update( gpsPos.position )
}
}
I tried piping the NMEA data from the GPS to another port using gpspipe -r | nc -l 6000 and specifying nmeaSource: "socket://localhost:6000 and everything works fine!
How do I make Qt talk to gpsd directly?
After tinkering (i.e. compiling from source, installing, configuring, testing, etc.) with gps-share, Gypsy, geoclue2, serialnmea and other ways to access data from a GPS connected to a serial port (thanks to Pa_ for all the suggestions), but all with no results while gpsd was working perfectly for other apps, I decided to make Qt support gpsd by making a very crude change to the QDeclarativePositionSource class to implement support for a gpsd scheme in the URL for the nmeaSource property. With this change, a gpsd source can now be defined as nmeaSource: "gpsd://hostname:2947" (2947 is the standard gpsd port).
The changed code is shown below. I would suggest this should be added to Qt at some point but in the meantime, I guess I need to derive this class to implement my change in a new QML component but, being new to QML, I have no idea how that is done. I suppose it would also probably be a good idea to stop and start the NMEA stream from gpsd based on the active property of the PositionSource item... I will get to it at some point but would appreciate pointers on how to do this in a more elegant way.
void QDeclarativePositionSource::setNmeaSource(const QUrl &nmeaSource)
{
if ((nmeaSource.scheme() == QLatin1String("socket") )
|| (nmeaSource.scheme() == QLatin1String("gpsd"))) {
if (m_nmeaSocket
&& nmeaSource.host() == m_nmeaSocket->peerName()
&& nmeaSource.port() == m_nmeaSocket->peerPort()) {
return;
}
delete m_nmeaSocket;
m_nmeaSocket = new QTcpSocket();
connect(m_nmeaSocket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)> (&QAbstractSocket::error),
this, &QDeclarativePositionSource::socketError);
connect(m_nmeaSocket, &QTcpSocket::connected,
this, &QDeclarativePositionSource::socketConnected);
// If scheme is gpsd, NMEA stream must be initiated by writing a command
// on the socket (gpsd WATCH_ENABLE | WATCH_NMEA flags)
// (ref.: gps_sock_stream function in gpsd source file libgps_sock.c)
if( nmeaSource.scheme() == QLatin1String("gpsd")) {
m_nmeaSocket->connectToHost(nmeaSource.host(),
nmeaSource.port(),
QTcpSocket::ReadWrite);
char const *gpsdInit = "?WATCH={\"enable\":true,\"nmea\":true}";
m_nmeaSocket->write( gpsdInit, strlen(gpsdInit);
} else {
m_nmeaSocket->connectToHost(nmeaSource.host(), nmeaSource.port(), QTcpSocket::ReadOnly);
}
} else {
...
So this might be a bit basic of a question, but I don't have much experience on the hardware side of things. I am using DJI Android Mobile SDK to communicate with a M600 flight controller and have a FTDI CU/TTY device I am trying to send info back and forth.
This successfully works to send "Hello World" to my USB device:
//sends data to onboard sdk device
final byte[] helloWorld = "HelloWorld".getBytes();
mFlightController.sendDataToOnboardSDKDevice(helloWorld, new CommonCallbacks.CompletionCallback() {
#Override
public void onResult(DJIError djiError) {
if (djiError != null) {
showToast(djiError.getDescription());
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(djiError.getDescription(), "sendOnboardErrorFile.txt");
} else {
showToast("Hopefully Hello World");
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(helloWorld.toString(), "sendOnboardSuccessFile.txt");
}
}
});
I can see this when I run either of the following in terminal:
screen /dev/cu.usbserial-BLAHBLAH 38400
screen /dev/tty.usbserial-BLAHBLAH 38400
A bunch of gibberish/ hieroglyphics show up and then the text "Hello World" pops up every time I click a button that triggers the above DJI code.
Now, I want to get the flips side of this working i.e. send something back from the USB to the DJI sdk using the following:
if (mFlightController.isOnboardSDKDeviceAvailable()) {
showToast("Set Onboard SDk Callback");
mFlightController.setOnboardSDKDeviceDataCallback(new FlightController.OnboardSDKDeviceDataCallback() {
#Override
public void onReceive(byte[] bytes) {
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(bytes.toString(), "onboardCallbackFile.txt");
}
});
}
The trouble is I never seem to get anything in response.
As per this question, I made sure I have read write permission on the USB device:
chmod o+rw /dev/ttyS1
And I have tried all sorts of echo and cat commands (I don't know which one is read and write). They either say device is busy, or if not, they seem to open a port of communication (the terminal blinks indefinitely), but nothing sends to my device.
Commands I've tried:
echo 'HelloTest' > /dev/cu.usbserial-BLAHBLAH
Nothing special happens, goes to next terminal line
echo 'HelloTest' > /dev/tty.usbserial-BLAHBLAH
Terminal returns HelloTest
echo 'HelloTest' < /dev/tty.usbserial-BLAHBLAH
cursor blinks indefinitely
echo 'HelloTest' < /dev/cu.usbserial-BLAHBLAH
Terminal returns HelloTest
cat < /dev/cu.usbserial-BLAHBLAH
cat -v < /dev/tty.usbserial-BLAHBLAH
cat -v > /dev/tty.usbserial-BLAHBLAH
cat -v > /dev/cu.usbserial-BLAHBLAH
No such file or directory (I guess I need 2 terminals running for this?)
Questions
Does this have to do with Baud rate? I have set that up in DJI Assistant. What is the difference between TTY and CU and Echo and Cat? I have tried all sorts of combinations. I am able to use the screen command with both cu and tty. Finally, what is a simple hello world I can send back to the sdk to see that I am actually receiving data from my usb device? I would think echo would success, but I'm not receiving anything.
Edit
I almost feel like I need to use something like usb-serial-for-android; however, I'm not actually connecting the usb device to my android device. Instead, I am connecting to the DJI RC Controller, which connects to Lightbridge/ M600, which connects through the API port with my usb device.
I came across this issue a while back as well using the Matrice M100 with the ROS onboardSDK.
if (mFlightController.isOnboardSDKDeviceAvailable()) {
showToast("Set Onboard SDk Callback");
mFlightController.setOnboardSDKDeviceDataCallback(new FlightController.OnboardSDKDeviceDataCallback() {
#Override
public void onReceive(byte[] bytes) {
WriteFileAppendAsync writeAppend = new WriteFileAppendAsync();
writeAppend.execute(bytes.toString(), "onboardCallbackFile.txt");
}
});
}
Where are you calling this?. Here's how I solved my issue: I wrote a function:
private void addCallback()
{
mFlightController.setOnboardSDKDeviceDataCallback(new
FlightController.OnboardSDKDeviceDataCallback() {
#Override
public void onReceive(byte[] bytes) {
// Do stuff with the data here..
}
});
}
Then in my onResume method I did something like:
#Override
public void onResume() {
Log.e(TAG, "onResume");
super.onResume();
if (mFlightController != null) {
addCallback();
}
}
It's not the most elegant way but it seemed to do the trick for me. You can find my solution here. It's been a while since I worked on it though!
If you have an FTDI device then you need an FTDI driver. :)
Did you install something like this by chance? https://www.ftdichip.com/FTDrivers.htm
Serial port emulation through USB requires virtual serial port software to function.
I believe you need to understand the DJI OpenProtocol to make this work. The "bunch of gibberish" is in fact the problem here. That gibberish is the protocol that DJI drones use to properly relay communications.
In order to send from "Onboard" to "Mobile" with the latest code you need the 0xFE CMD_Set Id as a header to your data:
https://developer.dji.com/onboard-sdk/documentation/protocol-doc/open-protocol.html
So, either, figure out the proper format to your data or buy a cheap PC and install the OSDK.
This question already has an answer here:
How to check if network address is local in Qt
(1 answer)
Closed 6 years ago.
My application connects to a tcp server. I'd like it to be aware of being running on the same host as the server app, so it can eventually directly lauch the server process if it's not up.
As the server listens on an interface and the application resolves a hostname to connect to the server, it's not so obvious for me to determine if the configured hostname used to connect the server points to the same host as the server or not.
I'd like something like this:
bool isThisLocalHost(QString hostName) {
//resolve hostname's address
//list localhost interfaces ip or hw addresses ?
//if the hostname address matches one of the host interfaces address
//pseudo code
bool bRes = interfaces_addresses_list.contains(hostname_address);
return bRes;
}
I'm actually trying to achieve this with
QNetworkInterface, QNetworkAddressEntry, QHostInfo, QHostAddress.
Maybe is there a simple way?
Here is what i got:
bool isThisLocalHost(QString hostName) {
QList <QHostAddress> lAddrHostName = QHostInfo::fromName(hostName).addresses();
QList <QHostAddress> lAddrLocalHostInterfaces = QNetworkInterface::allAddresses();
bool bRes = false;
foreach (QHostAddress addr, lAddrHostName) {
bRes = bRes || lAddrLocalHostInterfaces.contains(addr);
}
return bRes;
}
QHostAddress has isLoopback() which should get you what you need.
If you just want to know if you're connected to yourself this is (partly?) a duplicate of this question.
void connect ( String portName ) throws Exception
{
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if ( portIdentifier.isCurrentlyOwned() )
{
System.out.println("Error: Port is currently in use");
}
else
{
System.out.println(portIdentifier.getCurrentOwner());
CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
if ( commPort instanceof SerialPort )
{
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(115200,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
}
else
{
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}
is giving
gnu.io.PortInUseException: Unknown Application
at gnu.io.CommPortIdentifier.open(CommPortIdentifier.java:354)
i am using RXTX with Java in windows 7 home 64-bit.
Check that /var/lock folder exist on your machine.
mkdir /var/lock
chmod go+rwx /var/lock
Reboot the system / disable the port.
Actual problem is when the program runs port is opened and it didn't close after the program terminates.
it works.
I ran into this problem because the port was actually in use. A previous instance of javaw.exe appeared in the Windows task manager, it hogged the port.
The reason why that previous java process hung was a hardware issue: When plugging the USB-2-serial converter that I happened to use into a USB-2 port, all worked fine. When plugged into a USB-3 port, RXTX CommPortIdentifier code would hang, and then subsequent instances of Java received the PortInUseException.
I used Process Explorer to find a process with the handle \Device\PCISerial0 and closed the handle. If your com ports aren't on a PCI card, the name might be different.
For Windows
Open Task Manager
under Eclipse (or your ide) find Java application.
Right click on it -> End Task
May be useful, I solved such problem by remove gateway from service and stop it , gateway is instance of SerialModemGateway.
Service.getInstance().stopService();
Service.getInstance().removeGateway(gateway);
gateway.stopGateway();