How to set Powered property of /org/bluez/hci0 using sd_bus_set_property? - dbus

Recently I started to develop a bluetooth app using API exposed via D-BUS. After some research, I chose to use sd-bus library to communicate with D-Bus.
Here is my code:
#include <systemd/sd-bus.h>
sd_bus* bus_;
if (sd_bus_open_system(&bus_) < 0)
{
throw std::runtime_error("sd_bus_open_system");
}
sd_bus_error sd_error;
bool powered = true;
if (sd_bus_set_property(bus_,
"org.bluez",
"/org/bluez/hci0",
"org.bluez.Adapter1",
"Powered",
&sd_error,
"b", &powered) < 0)
{
throw std::runtime_error("Bluetooth Power On");
}
The code above throws "Bluetooth Power On" and the return value of sd_bus_set_property is -22 (EINVAL). I couldn't make much sense from sd_error, but for to whom may be interested, here is the details:
name:0x7fffffffdce8 "И\277UUU"
message:0x5555555d6fbd <handler::handler(std::span<door, 18446744073709551615ul>)+191> "\220H\213E\350dH+\004%("
_need_free:1439044320
I have checked the literal strings using D-Feet app and everything seems to be right.
I've tried running as root or without root.
I've tried adding the user to bluetooth group.
What is wrong with this code?
source code of sd_bus_set_property shows that internally, it calls "Set" from "org.freedesktop.DBus.Properties". Most of the bluetooth examples I've seen, do this without using "sd_bus_set_property", but I'm curious to see how it can be done via "sd_bus_set_property".
Thanks for reading.

I built systemd from source and stepped into its functions and saw at some point it checks the error and since it's not null, returns.
sd_bus_error sd_error = SD_BUS_ERROR_NULL;
fixed the issue.

Related

How to Execute (Vector) Storage.getInstance().readObject(filePath); in Java 8 Swing Package

Windows 10 Pro
Latest Simulator
Java Swing Project
I would like to execute "Vector a1 = (Vector) Storage.getInstance().readObject(filePath);"
In a Java Swing Application running on Windows 10 platform, I tried import CodenameOne.jar in Swing package, however when executing above code, get null pointer exception in Storage.getInstance()
Is there a way to execute this in Swing?
Thoughts?
Best Regards.
Thanks, I did not init the Display, however "Display.init(Object m)" requires an Object Argument and the Init method is deprecated.
Can you please provide me the codenameone Display dependencies?
And perhaps a java Swing snippet of code to initialize Display in order to execute Storage.getInstance().readObject(filePath)
Thoughts?
Best Regards
Thanks, Passing init(working directory) solved the Exception thrown.
Here is the Code snippet used to allow me to execute:
Storage.getInstance().readObject(filePath).
String filePath = incSrv.Pwd();// gets working directory
try {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Display.init(filePath);
String fileName = "A1-MMA.properties";
Vector a1 = (Vector) Storage.getInstance().readObject(filePath);
}
});
} catch (Exception e) {
}
And it does appear to work,
However I am left with a blacked out form that appears modal.
How can I avoid this or dispose it?.
FYI: What I am creating here is a work around for serializing Vector in Codenameone. I Save Vector to file using "Storage.getInstance().writeObject(Path, Vector)"
I convert the file to bytes and write it to the Swing Server VIA socket.
Using Storage.getInstance().readObject(file) on the Swing Server I have deserialize the object into the Vector from my app.
This appears to work well and is more efficient than the current method I use to deliver complex Vectors from the app to the Swing Server.
Can you please let me know if you see a red flag with this workaround?
Like The ability to Storage.getInstance().readObject(file) on the Swing Server may go away?
This method will save a lot of time in movind Vector data to and from the App/Server.
Thoughts Best Regards
Storage.getInstance().readObject(file) // (A1ServiceSrv.java:571)
Caused this Exception:
java.lang.NullPointerException
at com.codename1.io.Storage.init(Storage.java:89)
at com.codename1.io.Storage.getInstance(Storage.java:112)
at Main.A1ServiceSrv.loadVectorFromFile(A1ServiceSrv.java:571)
Regards
12/11/2021:
Thanks Shai,
I am including in my classpath CodenameOne.jar with update date of 12/11/2021 after CN1 refresh.
Getting Same null pointer exception.
Passing in Path "C:\Src1\A1-Arms\A1-Server\A1-MMA.properties" (Absolute Path)
Also Tried "A1-MMA.properties", however I don't think Codenameone knows where my home path is since we are not initializing it as we did with
Display.init("Current Working Directory where files reside");
This is the Fresh Stack Trace w/o calling Display.init (12-20-2021)
java.lang.NullPointerException at
com.codename1.ui.Display.getResourceAsStream(Display.java:3086)
at com.codename1.io.Log.print(Log.java:327)
at com.codename1.io.Log.logThrowable(Log.java:299)
at com.codename1.io.Log.e(Log.java:285)
at com.codename1.io.Storage.readObject(Storage.java:271)
at Main.A1ServiceSrv.loadVectorFromFile(A1ServiceSrv.java:596)
vector = (Vector) Storage.getInstance().readObject(filePath); // (A1ServiceSrv.java:596)
This is hopefully fixed by this commit: https://github.com/codenameone/CodenameOne/commit/72bf283bdaaefe5207bb9fd6787578e3ef61522c if not let me know with a fresh stack

BlueNRG Bluetooth: read central device name

I'm using the STM BlueNRG-MS chip on my peripheral device and after connection I'd like to read the name of the connected central device (android phone).
I thought I can do this directly in my user_notify routine which is registered as hci callback
/* Initialize the Host-Controller Interface */
hci_init(user_notify, NULL);
So on the EVT_LE_CONN_COMPLETE event, I take the provided handle for the central device and I use aci_gatt_read_using_charac_uuid() to read what I thought is the characteristic with the device name (uuid 0x2a00).
case EVT_LE_META_EVENT:
{
evt_le_meta_event *evt = (void *)event_pckt->data;
switch(evt->subevent){
case EVT_LE_CONN_COMPLETE:
{
evt_le_connection_complete *cc = (void *)evt->data;
GAP_ConnectionComplete_CB(cc->peer_bdaddr, cc->handle);
uint16_t uuid = 0x2a00;
resp = aci_gatt_read_using_charac_uuid(cc->handle, 0, 1, UUID_TYPE_16, (uint8_t*)&uuid);
LOG("GATT read status: %d", resp);
enqueEvent(EVENT_BLE_CONNECTED);
}
break;
}
}
Long story short, it doesn't work. First thing I'm not sure about is, what is the start_handle and end_handle parameter of aci_gatt_read_using_charac_uuid(), it returns ERR_INVALID_HCI_CMD_PARAMS.
Can someone shed some light here?
update
What also puzzles me is that the function aci_gatt_read_using_charac_uuid() is nowehere referenced in the BlueNRG-MS Programming Guidelines.
update2
I changed the function call to aci_gatt_read_using_charac_uuid(cc->handle, 0x0001, 0xffff, UUID_TYPE_16, (uint8_t*)&uuid); but I still get the ERR_INVALID_HCI_CMD_PARAMS. What which paramter could even be invalid? The uuid exists, I can read the device name if I use the BlueNRG GUI with a bluetooth dongle.
update3
Has anyone ever used this function or somehow managed to read a characteristic from a central device? I'd highly appreciate any help or hint.
Here you go, The BlueNRG-MS Bluetooth® LE stack application command interface (ACI) - User manual
page 75 - 4.6.25 Aci_Gatt_Read_Charac_Using_UUID()
and make sure you have called Aci_Gatt_Init()
The user manual is last revised July 2019, the document you link to is from 2018, don't know if this is why ?
The start_handle and end_handle is the range of handles in your service as pictured here -
Here is a discussion to the closest thing I could find to match your question.
As it turned out there are two bugs in the BlueNRG API.
In bluenrg_aci_const.h file the OCF code OCF_GATT_READ_USING_CHARAC_UUID shall be 0x119 instead of 0x109.
And in the implementation of the aci_gatt_read_using_charac_uuid() function, there is a missing setting on event:
rq.event = EVT_CMD_STATUS;
Patching them fixed the issue.

Implementation of time in Zynq

I'm trying to do a simple STANDALONE application for Zynq. I want to use the 'time.h' to manipulate date/time. I know that there is no hardware implementation on a stanalone BSP, but I want to wire it up on my own.
During compilation, when I call 'time(NULL)' I get a error, that there is no implementation of '_gettimeofday()'. I've found it in and implemented it according to the function definition, so that the errors disappear and everything looks ok, but when I run my project on hardware, I see only zeroes from time().
Can anybody help?
Regards,
G2
Ok, I've done some research, and found this link. This is almost what I'v been searching, but instead of '_times()' I needed '_gettimeofday()' and this is my implementation:
int _gettimeofday(struct timeval *__p, void *__tz)
{
__p->tv_sec = (systemUsCounter / 1000000);
__p->tv_usec = systemUsCounter;
return 0;
}
I left the '__tz' pointer with no chainges.
So this is basicly how to utilize 'time.h' in a standalone application on Zynq.

Runtime debugging tips for Windows Service?

I have a Windows Service that monitors a COM port connected to a vendors hardware. This is a very busy piece of hardware that is constantly polling other devices on the wire (this is a twisted-pair RS485 "network"). My software needs to emulate X number of hardware devices on this wire, so I've got a multi-threaded thing going on with a multi-tiered state machine to keep track of where the communications protocol is at any moment.
Problem is with a Windows Service (this is my first one, BTW) is that you need some debugging to let you know if stuff is working properly. When I was first developing this state machine/multi-thread code I had a windows form with a RichTextBox that displayed the ASCII chars going back-n-forth on the line. Seems like I can't really have that GUI niceness with a service. I tried opening a form in the service via another program that sent the service messages that are received via the OnCustomCommand() handler but it didn't seem to work. I had "Allow service to interact with desktop" checked and everything. I was using the Show() and Hide() methods of my debug form.
I guess I don't need to see all of the individual characters going on the line but man that sure would be nice (I think I really need to see them :-) ). So does anyone have any crazy ideas that could help me out? I don't want to bog down the system with some IPC that isn't meant for the voluminous amount of data that is sure to come through. It will only be very short-term debugging though, just confirmation that the program, the RS485-to-USB dongle, and hardware is all working.
Use OutputDebugString to write to the debugging buffer and then use DebugView to watch it. If you're running on Windows XP or earlier, then you can use PortMon to see the raw bytes going through the serial port. The advantage over a log file is that there's very little overhead, particularly when you're not watching it. You can even run DebugView from another machine and monitor your service remotely.
I dunno if it will work for you, but I always build my services with a extra Main that build them as console app to get debug output.
Edit:
Some example:
class Worker : ServiceBase
{
#if(RELEASE)
/// <summary>
/// The Main Thread where the Service is Run.
/// </summary>
static void Main()
{
ServiceBase.Run(new Worker());
}
#endif
#if(DEBUG)
public static void Main(String[] args)
{
Worker worker = new Worker();
worker.OnStart(null);
Console.ReadLine();
worker.OnStop();
}
#endif
// Other Service code
}
You could write the output to a log file and then use another application to watch that file. This question about "tail" outlines several options for watching log files with windows.
What I usually do when working on a Windows Service is to create it so that it can be run either as a service, or as a plain old command-line application. You can easily check whether you are running as a service by checking Environment.UserInteractive. If this property is true, then you are running from the command line. If the property is false, then you are running as a service. Add this code to Program.cs, and use it where you would normally call ServiceBase.Run(servicesToRun)
/// <summary>Runs the provided service classes.</summary>
/// <param name="servicesToRun">The service classes to run.</param>
/// <param name="args">The command-line arguments to pass to the service classes.</param>
private static void RunServices(IEnumerable<ServiceBase> servicesToRun, IEnumerable args)
{
var serviceBaseType = typeof(ServiceBase);
var onStartMethod = serviceBaseType.GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (var service in servicesToRun)
{
onStartMethod.Invoke(service, new object[] { args });
Console.WriteLine(service.ServiceName + " started.");
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
var onStopMethod = serviceBaseType.GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (var service in servicesToRun)
{
onStopMethod.Invoke(service, null);
Console.WriteLine(service.ServiceName + " stopped.");
}
}
Now you can debug your service, set breakpoints, anything you want. When you run your application, you'll get a console window, appropriate for displaying console messages, and it will stay open until you hit a key.
I'm answering my own question here. I tried a couple of suggestions here but here's what I ended up doing...
I created a Windows Form application with a single Button and RichTextBox. This application constructed a NamedPipeServerStream on it's end. The Button's job was to send either "debug on" (command 128) or "debug off" (129) to the Windows Service. The initial value was "debug off". When the button was clicked, a command of 128 was sent to the Windows Service to turn debugging on. In the Windows Service this triggered an internal variable to be true, plus it connected to the Form application with a NamedPipeClientStream and started sending characters with a BinaryWriter as they were received or sent on the COM port. On the Form side, a BackgroundWorker was created to WaitForConnection() on the pipe. When it got a connection, a BinaryReader.ReadString() was used to read the data off of the pipe and shoot it to the RichTextBox.
I'm almost there. I'm breaking my pipe when I click the debug button again and a subsequent click doesn't correctly redo the pipe. All in all I'm happy with it. I can post any code if anyone is interested. Thanks for the responses!

Creating Windows service without Visual Studio

So creating a Windows service using Visual Studio is fairly trivial. My question goes a bit deeper as to what actually makes an executable installable as a service & how to write a service as a straight C application. I couldn't find a lot of references on this, but I'm presuming there has to be some interface I can implement so my .exe can be installed as a service.
Setting up your executable as a service is part of it, but realistically it's usually handled by whatever installation software you're using. You can use the command line SC tool while testing (or if you don't need an installer).
The important thing is that your program has to call StartServiceCtrlDispatcher() upon startup. This connects your service to the service control manager and sets up a ServiceMain routine which is your services main entry point.
ServiceMain (you can call it whatever you like actually, but it always seems to be ServiceMain) should then call RegisterServiceCtrlHandlerEx() to define a callback routine so that the OS can notify your service when certain events occur.
Here are some snippets from a service I wrote a few years ago:
set up as service:
SERVICE_TABLE_ENTRY ServiceStartTable[] =
{
{ "ServiceName", ServiceMain },
{ 0, 0 }
};
if (!StartServiceCtrlDispatcher(ServiceStartTable))
{
DWORD err = GetLastError();
if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
return false;
}
ServiceMain:
void WINAPI ServiceMain(DWORD, LPTSTR*)
{
hServiceStatus = RegisterServiceCtrlHandlerEx("ServiceName", ServiceHandlerProc, 0);
service handler:
DWORD WINAPI ServiceHandlerProc(DWORD ControlCode, DWORD, void*, void*)
{
switch (ControlCode)
{
case SERVICE_CONTROL_INTERROGATE :
// update OS about our status
case SERVICE_CONTROL_STOP :
// shut down service
}
return 0;
}
Hope this helps:
http://support.microsoft.com/kb/251192
It would seem that you simple need to run this exe against a binary executable to register it as a service.
Basically there are some registry settings you have to set as well as some interfaces to implement.
Check out this: http://msdn.microsoft.com/en-us/library/ms685141.aspx
You are interested in the SCM (Service Control Manager).
I know I'm a bit late to the party, but I've recently had this same question, and had to struggle through the interwebs looking for answers.
I managed to find this article in MSDN that does in fact lay the groundwork. I ended up combining many of the files here into a single exe that contains all of the commands I need, and added in my own "void run()" method that loops for the entirely life of the service for my own needs.
This would be a great start to someone else with exactly this question, so for future searchers out there, check it out:
The Complete Service Sample
http://msdn.microsoft.com/en-us/library/bb540476(VS.85).aspx

Resources