Bluez MediaEndpoint1 Timeout Issue When Replying To Dbus Call From Node Addon - node.js

Bluez Version: 5.43
Let me get straight to the point:
I have following error inside the Bluez log file:
Calling SetConfiguration: name = :1.3 path = /MediaEndpoint/A2DPSink
...
Endpoint replied with an error: org.freedesktop.DBus.Error.NoReply
If I change this line of code
#define REQUEST_TIMEOUT (3 * 1000) /* 3 seconds */
inside the ~/bluez-5.43/profiles/audio/media.c file,
to be a value greater, like 5 or so... The bug goes away.
So what is this bug?
basically, I have nodejs addon code that does the following:
Intialize endpoint
void endpoint_init(DBusConnection *connection, const char *endpoint) {
DBusObjectPathVTable vtable_endpoint;
vtable_endpoint.message_function = endpoint_handler;
dbus_connection_register_object_path(connection, endpoint, &vtable_endpoint, NULL);
}
Inside the Bluez log you will see bluetoothd[25176]: Endpoint registered: sender=:1.130 path=/MediaEndpoint/A2DPSink
The endpoint_handler function will be notified of a call to set_configuration or select_configuration function...
When a call is received, it will be be replied to like so...
sender = dbus_message_get_sender(m);
r = dbus_message_new_method_return(m);
printf("!! ----- endpoint_set_configuration, time_right_before_reply_sent: ");
print_time();
assert( dbus_connection_send(conn, r, NULL) );
dbus_connection_flush(conn);
printf("!! ----- endpoint_set_configuration, time_right_after_reply_sent: ");
print_time();
As you can see I am logging some time information.
Now, I also logged time information inside Bluez and recompiled it.
Here is log from Bluez:
bluetoothd[789]: profiles/audio/media.c:media_endpoint_async_call() Calling SetConfiguration: name = :1.3 path = /MediaEndpoint/A2DPSink
bluetoothd[789]: profiles/audio/media.c:endpoint_reply() [GOT HERE -- endpoint_reply -- original_msg --] SetConfiguration: name = :1.3 path = /MediaEndpoint/A2DPSink
bluetoothd[789]: profiles/audio/media.c:print_time() TIME BEFORE -- dbus_pending_call_steal_reply --: 2017-01-25 04:54:01
bluetoothd[789]: profiles/audio/media.c:print_time() TIME AFTER -- dbus_pending_call_steal_reply --: 2017-01-25 04:54:01
bluetoothd[789]: profiles/audio/media.c:endpoint_reply() [GOT HERE -- endpoint_reply -- reply_msg] (null): name = (null) path = (null)
bluetoothd[789]: Endpoint replied with an error: org.freedesktop.DBus.Error.NoReply
Here is log from my node addon:
endpoint_handler: path=/MediaEndpoint/A2DPSink, interface=org.bluez.MediaEndpoint1, member=SetConfiguration
!! ----- endpoint_set_configuration, endpoint_path: /MediaEndpoint/A2DPSink
!! ----- endpoint_set_configuration, time_right_before_reply_sent:
2017-01-25 04:54:03
!! ----- endpoint_set_configuration, time_right_after_reply_sent:
2017-01-25 04:54:03
You can CLEARLY see with the Bluez default timeout of 3 seconds is too short... the reply is still on its way...
But pulseaudio's implementation does not have this problem... why?
Is it because there are two different event loops, ie the node addon uses lib-uv event loop and Bluez and pulse use the glib event loop...
What is going on here, can anyone please explain.
I would prefer to either identify it as Bluez bug or understand how to fix it on my node addon end...
Thank You Stackoverflowers :)
P.S.
Bluez ~/bluez-5.43/profiles/audio/media.c has code that advises to keep the REQUEST_TIMEOUT at 3, this worries me...
/* Timeout should be less than avdtp request timeout (4 seconds) */
if (g_dbus_send_message_with_reply(btd_get_dbus_connection(),
msg, &request->call,
REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
g_free(request);
return FALSE;
}

I found that there is some conflict with the glib and libuv running together under the same process..
the node-dbus addon i am using is a c level binding and it instantiates a glib event loop...
nodejs has a libuv event loop
they dont work well together...
this is what i can assume the problem is..
my solution was to rip the c code from bluez media enpoint and i created my own nodejs NAN bindings to it...without using any glib event loop.
this is the node-dbus library i am using:
https://github.com/Shouqun/node-dbus

Related

rampUser method is getting stuck in gatling 3.3

I am having issues using rampUser() method in my gatling script. The request is getting stuck after the following entry which had passed half way through.
Version : 3.3
================================================================================
2019-12-18 09:51:44 45s elapsed
---- Requests ------------------------------------------------------------------
> Global (OK=2 KO=0 )
> graphql / request_0 (OK=1 KO=0 )
> rest / request_0 (OK=1 KO=0 )
---- xxxSimulation ---------------------------------------------------
[##################################### ] 50%
waiting: 1 / active: 0 / done: 1
================================================================================
I am seeing the following in the log which gets repeated for ever and the log size increases
09:35:46.495 [GatlingSystem-akka.actor.default-dispatcher-2] DEBUG io.gatling.core.controller.inject.open.OpenWorkload - Injecting 0 users in scenario xxSimulation, continue=true
09:35:47.494 [GatlingSystem-akka.actor.default-dispatcher-6] DEBUG io.gatling.core.controller.inject.open.OpenWorkload - Injecting 0 users in scenario xxSimulation, continue=true
The above issue is happening only with rampUser and not happening with
atOnceUsers()
rampUsersPerSec()
rampConcurrentUsers()
constantConcurrentUsers()
constantUsersPerSec()
incrementUsersPerSec()
Is there a way to mimic rampUser() in some other way or is there a solution for this.
My code is very minimal
setUp(
scenarioBuilder.inject(
rampUsers(2).during(1 minutes)
)
).protocols(protocolBuilder)
I am stuck with this for some time and my earlier post with more information can be found here
Can any of the gatling experts help me on this?
Thanks for looking into it.
It seems you have slightly incorrect syntax for a rampUsers. You should try remove a . before during.
I have in my own script this code and it works fine:
setUp(userScenario.inject(
// atOnceUsers(4),
rampUsers(24) during (1 seconds))
).protocols(httpProtocol)
Also, in Gatling documentation example is also without a dot Open model:
scn.inject(
nothingFor(4 seconds), // 1
atOnceUsers(10), // 2
rampUsers(10) during (5 seconds), // HERE
constantUsersPerSec(20) during (15 seconds), // 4
constantUsersPerSec(20) during (15 seconds) randomized, // 5
rampUsersPerSec(10) to 20 during (10 minutes), // 6
rampUsersPerSec(10) to 20 during (10 minutes) randomized, // 7
heavisideUsers(1000) during (20 seconds) // 8
).protocols(httpProtocol)
)
My guess is that syntax can't be parsed, so instead 0 is substituted. (Here is example of rounding. Not applicable, but as reference: gatling-user-injection-constantuserspersec)
Also, you mentioned that others method work, could you paste working code as well?

TCP Stack Sending A Mbuf Chain: where is the loop?

I am new to BSD TCP stack code here, but we have an application that converted and uses BSD TCP stack code in the user mode. I am debugging an issue that this application would hold (or not sending data) in a strange situation. I included part of the related callstack below.
Before calling sosend in uipc_socket, I have verified that the length stored in the top, _m0->m_pkthdr.len has the right value. The chain should hold 12 pieces of TCP payload each with 1368 bytes long. In the end, my callback function only got called 10 times instead of 12 and the 10 smaller mbuf chains contains less payload data after they were combined.
I checked each function in the call stack and I could not find a loop anywhere to iterate through from the head to the end of the mbuf chain as I expected. Only loops I could find was the nested do ... while() loops in sosend_generic of uipc_socket.c, however, my code path only executed the loop once, since the resid was set to 0 immediately after the (uio == NULL) check.
\#2 0x00007ffff1acb868 in ether_output_frame (ifp=0xbf5f290, m=0x7ffff7dfeb00) at .../freebsd_plebnet/net/if_ethersubr.c:457
\#3 0x00007ffff1acb7ef in ether_output (ifp=0xbf5f290, m=0x7ffff7dfeb00, dst=0x7fffffff2c8c, ro=0x7fffffff2c70) at .../freebsd_plebnet/net/if_ethersubr.c:429
\#4 0x00007ffff1ada20b in ip_output (m=0x7ffff7dfeb00, opt=0x0, ro=0x7fffffff2c70, flags=0, imo=0x0, inp=0x7fffd409e000) at .../freebsd_plebnet/netinet/ip_output.c:663
\#5 0x00007ffff1b0743b in tcp_output (tp=0x7fffd409c000) at /scratch/vindu/ec_intg/ims/src/third-party/nse/nsnet.git/freebsd_plebnet/netinet/tcp_output.c:1288
\#6 0x00007ffff1ae2789 in tcp_usr_send (so=0x7fffd40a0000, flags=0, m=0x7ffeda1b7270, nam=0x0, control=0x0, td=0x7ffff1d5f3d0) at .../freebsd_plebnet/netinet/tcp_usrreq.c:882
\#7 0x00007ffff1a93743 in sosend_generic (so=0x7fffd40a0000, addr=0x0, uio=0x0, top=0x7ffeda1b7270, control=0x0, flags=128, td=0x7ffff1d5f3d0) at .../freebsd_plebnet/kern/uipc_socket.c:1390
\#8 0x00007ffff1a9387d in sosend (so=0x7fffd40a0000, addr=0x0, uio=0x0, top=0x7ffeda1b7270, control=0x0, flags=128, td=0x7ffff1d5f3d0) at .../freebsd_plebnet/kern/uipc_socket.c:1434

Alex lex.x compilation : Not in scope 'begin'

I have the below statements in Lex.x to parse block comments.
<0> "//".* { tokWValue LTokComment }
<0> "/*" { begin blockcomment }
<blockcomment> "*/" { begin 0 }
<blockcomment> . { tokWValue LTokComment }
But If I generate Lex.hs using Alex, it does not add the 'begin' function.
This results in the below compilation error.
src/Lex.x:367:18: Not in scope: ‘begin’
src/Lex.x:368:18: Not in scope: ‘begin’
Any idea what might be wrong?
I am using wrapper 'posn'
Start codes are only available when using any of the monad-... wrappers.
If you read the docs for the monad wrapper -- Section 5.3.3 - The "monad" wrapper -- you see that it is the first wrapper which keeps track of the start code.
You can also verify this by finding the alex wrapper files -- look for the directory containing the files AlexWrapper-basic, AlexWrapper-posn, etc. On OS X when installing the Haskell Platform they are located in a directory like /Library/Haskell/ghc-7.10.2-x86_64/share/alex-3.1.4. The functions begin and andBegin only occur in the monad-related wrappers.

Force lshosts command to return megabytes for "maxmem" and "maxswp" parameters

When I type "lshosts" I am given:
HOST_NAME type model cpuf ncpus maxmem maxswp server RESOURCES
server1 X86_64 Intel_EM 60.0 12 191.9G 159.7G Yes ()
server2 X86_64 Intel_EM 60.0 12 191.9G 191.2G Yes ()
server3 X86_64 Intel_EM 60.0 12 191.9G 191.2G Yes ()
I am trying to return maxmem and maxswp as megabytes, not gigabytes when lshosts is called. I am trying to send Xilinx ISE jobs to my LSF, however the software expects integer, megabyte values for maxmem and maxswp. By doing debugging, it appears that the software grabs these parameters using the lshosts command.
I have already checked in my lsf.conf file that:
LSF_UNIT_FOR_LIMTS=MB
I have tried searching the IBM Knowledge Base, but to no avail.
Do you use a specific command to specify maxmem and maxswp units within the lsf.conf, lsf.shared, or other config files?
Or does LSF force return the most practical unit?
Any way to override this?
LSF_UNIT_FOR_LIMITS should work, if you completely drained the cluster of all running, pending, and finished jobs. According to the docs, MB is the default, so I'm surprised.
That said, you can use something like this to transform the results:
$ cat to_mb.awk
function to_mb(s) {
e = index("KMG", substr(s, length(s)))
m = substr(s, 0, length(s) - 1)
return m * 10^((e-2) * 3)
}
{ print $1 " " to_mb($6) " " to_mb($7) }
$ lshosts | tail -n +2 | awk -f to_mb.awk
server1 191900 159700
server2 191900 191200
server3 191900 191200
The to_mb function should also handle 'K' or 'M' units, should those pop up.
If LSF_UNIT_FOR_LIMITS is defined in lsf.conf, lshosts will always print the output as a floating point number, and in some versions of LSF the parameter is defined as 'KB' in lsf.conf upon installation.
Try searching for any definitions of the parameter in lsf.conf and commenting them all out so that the parameter is left undefined, I think in that case it defaults to printing it out as an integer in megabytes.
(Don't ask me why it works this way)

Qt 5.4 Linux Touchscreen Input with Tslib on Raspberry Pi failing with LinuxFB QPA Platform Plugin

I bought a Tontec 2.4 Inch Touchscreen ( http://elinux.org/MZTX-PI-EXT ) for my Raspberry Pi. The touchscreen controller requires the "tsc2007.ko" and "tsp_raspi.ko" kernel modules as described in the elinux post. The tsc2007.ko module is in the Raspbian Kernel tree but the tsp_raspi.ko can be found here: https://github.com/osandov/raspi/tree/master/tsc2007.
I've cross compiled a new Kernel for the Pi with those modules and they load fine and create a /dev/input/event0 device in Raspbian. If I 'evtest' that device and touch the screen, I get output so I know the events are being delivered in Linux:
pi#raspberry /dev/input $ evtest
Available devices:
/dev/input/event0: TSC2007 Touchscreen
Select the device event number [0-0]: 0
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
Input device name: "TSC2007 Touchscreen"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 330 (BTN_TOUCH)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 1922
Min 0
Max 4095
Fuzz 64
Event code 1 (ABS_Y)
Value 2221
Min 0
Max 4095
Fuzz 64
Event code 24 (ABS_PRESSURE)
Value 0
Min 0
Max 4095
Fuzz 64
Properties:
Testing ... (interrupt to exit)
Event: time 1425521704.199489, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1425521704.199489, type 3 (EV_ABS), code 1 (ABS_Y), value 2085
Event: time 1425521704.199489, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 538
Event: time 1425521704.199489, -------------- SYN_REPORT ------------
Event: time 1425521704.209174, type 3 (EV_ABS), code 0 (ABS_X), value 1455
...
I installed tslib and ran a quick ts_calibrate. I also made sure that ts_test spit out data when I touched the screen.
I added the following environment variables to /etc/profile for tslib support in Qt5:
## For Qt5 Touchscreen Support
export QT_DEBUG_PLUGINS=1
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/arm-linux-gnueabihf/
export QT_PLUGIN_PATH=/usr/lib/plugins
export QT_QPA_FONTDIR=/usr/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/plugins/platforms
export QT_QPA_PLATFORM=linuxfb
export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event0
export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0
export TSLIB_TSEVENTTYPE='INPUT'
export TSLIB_CALIBFILE='/etc/pointercal'
export TSLIB_CONFFILE='/etc/ts.conf'
export TSLIB_CONSOLEDEVICE='none'
export TSLIB_FBDEVICE='/dev/fb0'
export TSLIB_PLUGINDIR='/usr/lib/ts'
export TSLIB_TSDEVICE='/dev/input/event0'
I read up on the Qt5 docs and how to get touch events in my app. I have a main Widget and set the appropriate flags in the constructor:
MainWidget::MainWidget(QLabel *parent)
: QLabel(parent)
{
qDebug() << "Setting WA_AcceptTouchEvents on MainWidget...";
// Accept touch events
setAttribute(Qt::WA_AcceptTouchEvents);
setAttribute(Qt::WA_StaticContents);
}
I setup an event filter to try to catch the touch events:
bool MainWidget::eventFilter( QObject* target, QEvent* e )
{
qDebug() << "Event Type: " << e->type();
return false;
return QLabel::eventFilter(target, e);
}
I launch my app like this:
myapp -platform linuxfb:fb=/dev/fb0 -plugin tslib:/dev/input/event0
I also uncommented a single printf in Qt's source code for the qtslib.cpp:
void QTsLibMouseHandler::readMouseData()
{
ts_sample sample;
while (get_sample(m_dev, &sample, m_rawMode)) {
bool pressed = sample.pressure;
int x = sample.x;
int y = sample.y;
// work around missing coordinates on mouse release
if (sample.pressure == 0 && sample.x == 0 && sample.y == 0) {
x = m_x;
y = m_y;
}
if (!m_rawMode) {
//filtering: ignore movements of 2 pixels or less
int dx = x - m_x;
int dy = y - m_y;
if (dx*dx <= 4 && dy*dy <= 4 && pressed == m_pressed)
continue;
}
QPoint pos(x, y);
//printf("handleMouseEvent %d %d %d %ld\n", m_x, m_y, pressed, sample.tv.tv_usec);
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
m_x = x;
m_y = y;
m_pressed = pressed;
}
}
When I launch my Qt app I see the plugins are loading OK ( even shows the correct event0 file ). I also see that the qt tslib plugin is receiving touch events when I touch the screen. The problem is that the event filter is NEVER called!
Here is the app being launched:
Got keys from plugin meta data ("tslib", "tslibraw")
QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/generic" ...
loaded library "/usr/lib/qt/plugins/generic/libqtslibplugin.so"
QTsLibMouseHandler "tslib" ""
QTsLibMouseHandler "tslib" "/dev/input/event0"
QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/qt/plugins/styles" ...
QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/styles" ...
Setting WA_AcceptTouchEvents on MainWidget...
-----------------------------------------
Waiting for data now...
-----------------------------------------
handleMouseEvent 0 0 1 751196
handleMouseEvent 0 0 1 751196
handleMouseEvent 1696 1615 1 771075
handleMouseEvent 1696 1615 1 771075
handleMouseEvent 1679 1622 1 781368
handleMouseEvent 1671 1638 1 781368
handleMouseEvent 1679 1622 1 781368
handleMouseEvent 1671 1638 1 781368
...
I found a few forum posts where people are having problems with touch input with the linuxfb platform plugin:
http://comments.gmane.org/gmane.comp.lib.qt.user/5686
http://qt-project.org/forums/viewthread/35757
http://qt-project.org/forums/viewthread/36120/
I've tried all their suggestions and still have the problem - no touch events are received by my app even though the Qt tslib plugin says it is receiving them.
It seems that the tslib plugin is having problems injecting the event it receives into my app's event loop with this:
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
I also tried the Qt5.4 touch fingerpaint example and see the same behavior - no touch events are received.
I'm not sure where to go from here. I would greatly appreciate any help solving this issue. Thanks!
UPDATE:
I changed my event filter so it looks like this:
bool MainWidget::eventFilter(QObject *obj, QEvent *event)
{
qDebug() << "Event received" << obj->metaObject()->className() << event->type();
switch (event->type()) {
case QEvent::TouchBegin:
qDebug() << "TouchBegin";
case QEvent::TouchUpdate:
qDebug() << "TouchUpdate";
case QEvent::TouchEnd:
qDebug() << "TouchEnd";
{
// QTouchEvent *touch = static_cast<QTouchEvent *>(event);
// QList<QTouchEvent::TouchPoint> touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
// foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) {
// switch (touchPoint.state()) {
// case Qt::TouchPointStationary:
// // don't do anything if this touch point hasn't moved
// continue;
// default:
// {
// }
// break;
// }
// }
// break;
}
//default:
//return QLabel::event(event);
}
//return true;
}
Now I can see 'socket notifier' events intermingled with Qt Tslib Plugin's prints whenever I touch the screen. Any ideas as to why Event Type 50 but no Touch Events?
Event received QSocketNotifier 50
handleMouseEvent 2702 2618 0 557715
Event received QSocketNotifier 50
handleMouseEvent 2698 2612 1 547758
Event received QSocketNotifier 50
handleMouseEvent 2706 2802 1 759928
Event received QSocketNotifier 50
Event received QSocketNotifier 50
UPDATE #2:
I installed the event filter only to try to catch any events. I'm not sure in Qt5 what translates an event type 50 ( QSocketNotifier ) to a QTouch* or QMouse* event.
Here is some more information:
When I run evtest, I see that the screen resolution is huge ( ~2500 x
~2500 ) and the actual screen is 320x240. I tried changed the
/dev/fb0 framebuffer size in /boot/config.txt to 320x240 and
rebooted. But the evtest and ts_calibrate steps still show the huge
resolution.
Because of the large resolution, I tried making my main widget
10000x10000 to see if I would get a touch or mouse event - but I
still only get the QSocketNotifier
I then tried to force the tslib plugin to always inject events at
screen position X=50 Y=50, but I still only get the event type 50
QSocketNotifier.
The problem was solved by making sure the tslib plugins were installed on the RasbperryPi.
TSLIB_PLUGINDIR=/usr/lib/ts
The directory /usr/lib/ts was not present on the Pi.

Resources