[jitsi-users] Issues developing plugin for generic USB-HID support


#1

A little help would be appreciated, how to trigger a "pick-up"/"hang-up"
action. I already found some other plugin that uses a seperate XML
config file - I would use that trick as well for build in supported
devices. Possibly adding an additional user generated file that could be
submitted to the devs for integration, when another working device has
been found by some user. but anyway...

Well for calls, basically you'd need to go through OSGi services of type
ProtocolProviderService, query them for an operation set
OperationSetBasicTelephony and add a CallListener to that. This is how the
shortcut work. In the end it might be best to somehow interface with the code
that is currently handling the shortcuts as there's quite some code for
different call states in there (cf. CallShortcut). I'm not yet sure how that
could be handled best though.

I've had a look on the code you mentioned. I've seen that there is some
code duplication along the plugins, concerning answering/hanging up
calls. Wouldn't it be sufficient to just call
net.java.sip.communicator.impl.gui.main.call.CallManager.answerCall(Call)
and the corresponding hangup method? (btw. that class should be split
up in a GUI part handling dialogues and a backend part, that could offer
functionality that is (also) found in the CallShortcut).

All the *.impl.* classes are not intended to be called from anywhere but the same package. I don't know the relevant code parts well enough out of my head to comment how it should be done, but some code sharing with refactoring could probably de done by providing the parts backend parts of the CallManager as a service (and consume this service in the GUI part, the shortcut handler and your plugin).

Ahm, this might work for testing purposes, but if we want to integrate
that, these should be separate three jars:
- usbhidmapper (your work)
- jna (we already have that in Jitsi, might need to be updated though) -
hid4java (run "mvn package" to get an OSGi enabled jar)

How would I configure that then?
1. where to put the external jars

- lib/installer-exclude for the raw jars - if they come with an OSGi
manifest, simply copy them in your target to ${bundlest.dest} -
otherwise add the manifest to the jar and put the output to
${bundles.dest}

There are plenty of examples in the build.xml, e.g. bundle-hsql for the
first and bundle-architectureviewer for the second.

Ok, but then it is not bundled with the plugin, so before I can install
the (my) plugin, I need to install the dependencies first - right?

Unfortunately, yes. But if it's going to be included in the stock Jitsi this won't be a problem for end users.

I managed to build it and add the manifest data - see the ant target:

<!-- BUNDLE-PLUGIN-USBHIDMAPPER PLUGIN -->
<target name="bundle-plugin-usbhidmapper">
   <jar compress="false" destfile="${bundles.dest}/usbhidmapper.jar"
manifest="${src}/net/java/sip/communicator/plugin/usbhidmapper/usbhidmapp
er.m anifest.mf">
     <zipfileset dir="${dest}/net/java/sip/communicator/plugin/usbhidmapper"
  prefix="net/java/sip/communicator/plugin/usbhidmapper"/>
   </jar>

This looks good.

   <!-- just copy jna-4.1.0 as it has an OSGI manifest -->
   <copy file="${lib.noinst}/jna-4.1.0.jar"
tofile="${bundles.dest}/jna-4.1.0.jar"/>

This too.

   <!-- add OSGI manifest to hid4java -->
   <jar compress="false" destfile="${bundles.dest}/hid4java.jar"
       filesetmanifest="merge">
     <zipfileset src="${lib.noinst}/hid4java-0.3.1.jar"/>
     <manifest>
       <attribute name="Bundle-Name" value="hid4java" /> <attribute
       name="Bundle-Description" value="A cross-platform Java Native
       Access (JNA) wrapper for the signal11/hidapi library." />
       <attribute name="Bundle-Vendor"
       value="https://github.com/gary-rowe/hid4java" /> <attribute
       name="Bundle-Version" value="0.3.1"/> <attribute
       name="Bundle-SymbolicName" value="org.hid4java"/> <attribute
       name="Export-Package" value="org.hid4java,
    org.hid4java.event,
    org.hid4java.jna"/>
       <attribute name="Import-Package" value="com.sun.jna"/>
       <attribute name="Bundle-NativeCode" value="
    win32-x86/hidapi.dll; processor=x86;osname=win32,
    win32-x86-64/hidapi.dll; processor=x86-64;osname=win32,
    win32-amd64/hidapi.dll; processor=amd64;osname=win32,
    linux-x86/libhidapi.so; processor=x86;osname=linux,
    linux-x86-64/libhidapi.so; processor=x86-64;osname=linux,
    linux-amd64/libhidapi.so; processor=amd64;osname=linux,
    darwin/libhidapi.dylib;
osname=macosx;processor=x86;processor=x86-64;processor=ppc" />
     </manifest>
   </jar>
</target>

AFAIK we never tried to load native libraries through OSGi NativeCode instruction. See below.

2. how to reference them

Add an entry to felix.client.run.properties, jna and hid4java must come
before yours. Level 67 seems appropriate. Jna is already there (level
40) as jnalib.jar.

Did so, and it seems like it's almost working. One Problem is now, that
when loading the plugin, it complains about not beeing able to load the
native library that is bundled with hid4java.
It's likely due to the manifest data in the build file, but I don't know
what might be wrong.

The error is: java.lang.UnsatisfiedLinkError: Unable to load library
'hidapi': libhidapi.so: Kann die Shared-Object-Datei nicht öffnen: Datei
oder Verzeichnis nicht gefunden (English error message is: "Unable to
load library 'hidapi': libhidapi.so: Can't open shared object file: file
or directory not found)

I speak German, no need to translate :slight_smile:

  at
[...]

As you can see, my code is executed, the hid4java code is executed, jna
is used to load the library, but then it fails.
Any suggestions how to tell him the location of the native library?
I think, it is due to the wrong version of JNA (see below).

Try to put the dll/so/dylibs into /lib/native/<platform> and remove the Bundle-NativeCode attribute from the manifest and see if that works. Although I like OSGi's idea of having them declared and inside the bundle, I not sure that it will be a viable solution. We'd need to investigate how to get it to work with our Debian package, the one in Debians repository and the Windows/Mac builds. But let's focus on getting it to work in the most simple way first.

3. I used some mvn assembly configuration to get the hid4java-0.3.1.jar

Check and see if the created jar contains a META-INF/MANIFEST.MF file that
contains definition for Bundle-Name, Bundle-SymbolicName,
Export-Package, etc.

No, it has no OSGI info, so I added it manually - see above.

Just noticed. You could also add the following snippet to the project/build/plugins/ section of the pom.xml and then run "mvn package". But the manifest is most likely missing in the Debian package, so there's actually no point.

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <version>2.4.0</version>
  <extensions>true</extensions>
  <configuration />
</plugin>

There are 2 lib jars in the jitsi source tree. But the bundle ant target
creates a single jar with dependencies (as I would expect for a plugin).

This works and is well for private plugins. But we have to consider Linux
packaging and there we cannot duplicate libraries and need to reference the
ones from the system. Hid4java might not have a package (yet), but jna does
and we must use that (or it will not be accepted by the distro maintainers).

As you can see, I use JNA 4.1.0. I tried to run the whole bundle with
your jna version, which leads to the above error. When I include JNA
4.1.0 with my bundle (as is did earlier) or include it with the hid4java
bundle, it finds the native library, but I still have the problem on
windows, that no devices are detected. Could I somehow upgrade the JNA
version of jitsi? (at least for testing to see if that helps) Or force a
bundle to use a specific version of it?

I'm not sure how easy it is to update our current JNA version, I think there were API changes. The basic process would be:
- delete jna-platform.jar, jna.jar from installer-exclude
- add the new jna jar(s) to installer-exclude
- update .classpath, jitsi.eml and nbproject/project.xml
- update the build.xml accordingly
- update felix.client.run.properties and felix.unit.test.properties

I will share my code on github asap.

Thanks so far and kind regards,
Peter

Ingo