Jump to content
Mumble forums

Building Mumble JSON Bridge


LilyC
 Share

Recommended Posts

Hello, I am attempting to build the json_bridge portion of the Mumble JSON bridge. I am using cmake 3.18 and am unsure what version of Boost I am meant to have. I know that Boost is not great with backwards compatibility, so I am curious what version of Boost should be used to build this?

Link to comment
Share on other sites

  • Administrators

Since you are building it from source, the only requirement is for your Boost version to already include the functionality that is used (the JSON Bridge does not ship with any prebuilt parts that you'd have to maintain compatibility with).

 

Iirc the functionality required from Boost is quite basic so I would assume that pretty much any version of Boost that is not completely ancient should do. If in doubt, use the latest version.

Link to comment
Share on other sites

Thank you.

 

I ended up using Boost 1.77, compiled for Win32. I am also using Visual Studio 2019 command line to build, with toolset 14.29.30037. When I try compiling, I get the following error (and other similar errors):

C:\mumble\mumble-json-bridge\json_bridge\src\NamedPipe.cpp(227): error C2664: 'Mumble::JsonBridge::FileHandleWrapper<HANDLE,BOOL (__cdecl *)(HANDLE),0xffffffff,1>::FileHandleWrapper(handle_t,close_handle_function_t)': cannot convert argument 2 from 'BOOL (__stdcall *)(HANDLE)' to 'close_handle_function_t'
        with
        [
            handle_t=HANDLE,
            close_handle_function_t=BOOL (__cdecl *)(HANDLE)
        ]
        and
        [
            close_handle_function_t=BOOL (__cdecl *)(HANDLE)
        ]
C:\mumble\mumble-json-bridge\json_bridge\src\NamedPipe.cpp(229): note: This conversion requires a reinterpret_cast, a C-style cast or function-style cast

I am currently trying to change to a newer toolset since I know FileSystem was handled differently in different versions of Visual Studio. Would you have any other suggestions of what to look into if this does not work?

Link to comment
Share on other sites

  • Administrators

@LilyC hm it seems as if the calling convention for the CloseHandle function is different for some reason.

 

Could you try changing json_bridge/src/NamedPipe.cpp:157 (https://github.com/mumble-voip/mumble-json-bridge/blob/93a2aba680f3e9579842ff5b880532ed851fda0f/json_bridge/src/NamedPipe.cpp#L157) from

using handle_t = FileHandleWrapper< HANDLE, BOOL (*)(HANDLE), INVALID_HANDLE_VALUE, true >;

to

using handle_t = FileHandleWrapper< HANDLE, decltype(&CloseHandle), INVALID_HANDLE_VALUE, true >;

 

In theory that should automatically adapt to the required type whatever it might end up being.

 

(And please let me know the result of this since in case this works, I would like this to be changed in the repo as well)

Link to comment
Share on other sites

Thank you for the quick turnaround on the fix!

 

I was able to successfully build the project. However, I was trying to install the json_bridge_plugin.dll into my locally built version of Mumble (that supports the installation of plugins), but Mumble gave me this error:

Unable to load plugin "json_bridge_plugin.dll" - check the plugin interface!

 

If I place the plugin manually into Mumble's plugin directory, I get: 

Non-plugin found in plugin directory: "C:/mumble/out/build/x86-Release/plugins/json_bridge_plugin.dll"

 

After poking around a bit, I realized that if I removed the m_bridge variable (specifically, if it is not in the constructor) in mumble-json-bridge\plugin\plugin.cpp then I am able to install the plugin. Is there a way to fix this so that the plugin can be installed properly?

 

Link to comment
Share on other sites

  • Administrators

Uhm removing m_bridge is certainly not a proper solution for this issue...

My best guess without looking into it is that there was some update to the plugin interface during the development of 1.4.0 that has not been ported to the JSON bridge yet...

Unfortunately I do not have the time to look into this myself right now but if you poke me again in about a month or so, I should be able to look into this.

 

EDIT: Did you perhaps not build with static boost libraries and the dynamic ones are not in PATH so they can't be loaded when attempting to create m_bridge?

Link to comment
Share on other sites

  • 4 weeks later...

Yeah I wasn't trying to remove m_bridge as an overall solution, I was just trying to narrow down what could be causing the issue. 

 

I downloaded Boost with vcpkg using the manifest file that was available. It looks like it chose the proper static libraries.

 

I will probably do some digging around in Mumble as well. But it has also been about a month or so, so here is a friendly poke 😛 @Krzmbrzl

Link to comment
Share on other sites

  • Administrators
8 hours ago, LilyC said:

will probably do some digging around in Mumble as well. But it has also been about a month or so, so here is a friendly poke 😛 @Krzmbrzl

Indeed and thanks 😄

However I wasn't too accurate with my prediction it seems. I am actually not available until October 19th. So if you don't figure this out by then, feel free to poke me again 🙂

Link to comment
Share on other sites

Wow I feel very foolish... I had thought I built with Boost static libs but it turns out they were dynamic, and adding it to PATH like you said worked 🤦‍♀️

 

I am unfamiliar with vcpkg and I am now trying to figure out how to specify the static versions of the libraries, since I think this would be easier to deal with.

 

Link to comment
Share on other sites

  • Administrators

Ah yes the classic Boost issue - it's just a PITA to get everything set up correctly on Windows xD

 

15 hours ago, LilyC said:

I am unfamiliar with vcpkg and I am now trying to figure out how to specify the static versions of the libraries, since I think this would be easier to deal with.

Normally you should be able to change the build type by changing the so-called "triplet" that you use for installing the packages. You can see the available triplets by issuing [tt]vcpkg help triplet[/tt].

You should use one with "static" in its name. For instance for the Mumble main client we are using x64-windows-static-md.

 

Admittedly though I never attempted to change the triplet when using the vcpkg.json file. Presumably you can still specify the triplet when invoking vcpkg even if it is reading the packages from that file...

Link to comment
Share on other sites

Quote

it's just a PITA to get everything set up correctly on Windows xD

Oh yes

 

I will definitely try to change the vcpkg name and get back to you!

 

I am curious now how to properly use the mumble JSON bridge- I tried using the CLI, but I am unsure if I am using the proper syntax. I installed and enabled the plugin in Mumble, connected to a server, and ran the mumble_json_bridge_cli.exe. I tried passing the following code through the CLI from the example in the CLI readme:

{
    "message_type": "api_call",
    "message": {
        "function": "getActiveServerConnection"
    }
}

but I am not sure where the output is supposed to be, or if I am missing steps.

 

I also want to use named pipes in my C++ code. Is it required to use the headers from "include/mumble/json_bridge" in order to interface with the plugin?

Link to comment
Share on other sites

New question that I should probably figure out first: I enabled the JSON Bridge plugin in Mumble and ran the following in Powershell to see what named pipes were running:

[System.IO.Directory]::GetFiles("\\.\\pipe\\") | Select-String -Pattern mumble

The output was "\\.\\pipe\\Mumble" which I believe is for Mumble generically and not the plugin (if I disable the JSON Bridge plugin, the output of the Powershell command is still the same). No errors show in the Mumble log. Am I missing something to get the pipe created successfully?

 

UPDATE: I am not sure what was wrong, but I rebuilt the plugin and the PS command above now shows that the mumble json bridge pipe is running.

Edited by LilyC
Link to comment
Share on other sites

  • Administrators

The name of the named pipe created by the plugin should be ".mumble-json-bridge" (as to https://github.com/mumble-voip/mumble-json-bridge/blob/6cf398f0871e040f6684db7844ee4d32c0dd2389/json_bridge/src/Bridge.cpp#L34). Idk if powershell might be hiding this from you since formally files starting with a dot tend to be treated as hidden files (on Unix anyways).

 

23 hours ago, LilyC said:

but I am not sure where the output is supposed to be

The output is supposed to be a JSON string that informs you about the outcome of the performed operation.

 

23 hours ago, LilyC said:

I tried passing the following code through the CLI from the example in the CLI readme:

How did you pass that string to the CLI? Via stdin? If so: did you use Ctrl+D (or was it Ctrl+Z on WIndows?) to tell the program your input is done?

Link to comment
Share on other sites

I've tried running the CLI and passing

{
    "message_type": "operation",
    "message": {
        "operation": "get_local_user_name"
    }
}

and then hitting "Enter", "Ctrl+D", "Ctrl+Z", or "Ctrl+C" after the commands, but this does not output anything.

 

I also tried passing in the same information as a command line argument (but formatted on one line):

mumble_json_bridge_cli.exe {"message_type": "operation","message": {"operation": "get_local_user_name"}}

But this produced a parsing error

([ERROR]: [json.exception.parse_error.101] parse error at line 1, column 1:
syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal).

 

I also tried running the CLI from a standard command line and passing in the same information as above, but this also did not output anything when using the different signals.

 

I also tried running the CLI from Cygwin in case it behaved differently in Unix, but got the same output.

 

Link to comment
Share on other sites

  • Administrators
13 hours ago, LilyC said:

but this does not output anything.

Did you return to the command prompt - aka to a point where you could input another command and execute it? Or where you stuck in the "give-me-input-mode" of the program? If you returned to the command prompt, what was the program's exit code?

 

13 hours ago, LilyC said:

I also tried passing in the same information as a command line argument (but formatted on one line):

You are missing the --json argument if you want to pass in the JSON directly (see also mumble_json_bridge_cli.exe --help):

mumble_json_bridge_cli.exe --json "<YourJsonHere>"

 

13 hours ago, LilyC said:

and then hitting "Enter", "Ctrl+D", "Ctrl+Z", or "Ctrl+C" after the commands, but this does not output anything.

Note that you have to be at a newline when pressing Ctrl+Z in order for it to take effect

Link to comment
Share on other sites

Quote

Did you return to the command prompt

When hitting "Enter", "Ctrl + D", and "Ctrl + Z" it did not return. "Ctrl + C" returned, but kills the process.

 

I tried adding the "--json" arg and sending the JSON itself with quotes, without quotes, tried escaping the quotation character in the actual JSON...

mumble_json_bridge_cli.exe --json "{"message_type": "operation","message": {"operation": "get_local_user_name"}}"
mumble_json_bridge_cli.exe --json {"message_type": "operation","message": {"operation": "get_local_user_name"}}
mumble_json_bridge_cli.exe --json {\"message_type\": \"operation\",\"message\": {\"operation\": \"get_local_user_name\"}}
mumble_json_bridge_cli.exe --json "{\"message_type\": \"operation\",\"message\": {\"operation\": \"get_local_user_name\"}}"

 and ended up with similar parser errors:

[ERROR]: [json.exception.parse_error.101] parse error at line 1, column 2:
syntax error while parsing object key - invalid literal; last read: '{m'; expected string literal
[ERROR]: [json.exception.parse_error.101] parse error at line 1, column 17:
syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal

 

 

I was at least able to get one method of input working (I changed the command to 'toggle_local_user_deaf' since it was easier to see if there was an effect or not):

On the command line, I ran

mumble_json_bridge_cli.exe

then passed in the JSON

{
    "message_type": "operation",
    "message": {
        "operation": "toggle_local_user_deaf"
    }
}

Then hit "Enter", then "Ctrl + Z", then had to hit "Enter" again and this gave the proper response

{
  "response": {
    "function": "requestLocalUserDeaf",
    "return_value": 0,
    "status": "executed"
  },
  "response_type": "api_call"
}

 

Link to comment
Share on other sites

  • Administrators
27 minutes ago, LilyC said:

Then hit "Enter", then "Ctrl + Z", then had to hit "Enter" again and this gave the proper response

Yes this is pretty much how it is supposed to work.

 

So that shows that everything seems to be working as expected whereas the other issues seem to be related to the your command prompt not acting the way you intend it to.

 

27 minutes ago, LilyC said:

I tried adding the "--json" arg and sending the JSON itself with quotes, without quotes, tried escaping the quotation character in the actual JSON...

You have to use quotes in order for the entire string to be interpreted as a single argument, but you also have to escape the quotes in the JSON string as they are required in the JSON format. So your last attempt seems somewhat correct.

29 minutes ago, LilyC said:
mumble_json_bridge_cli.exe --json "{\"message_type\": \"operation\",\"message\": {\"operation\": \"get_local_user_name\"}}"

What's the exact error you get for that input?

Link to comment
Share on other sites

Quote

Yes this is pretty much how it is supposed to work.

Gotcha. I didn't realize this was supposed to be the order of input.

 

Quote

What's the exact error you get for that input?

Whelp I guess I had a typo when I ran it last, because this time it gave the correct output and not a syntax error 🤦‍♀️

 

Thank you for your help!

Link to comment
Share on other sites

  • Administrators

Ah great to hear that! 😄

 

I suppose though that the whole stdin-handling could use some documenting in the repo (it's definitely complicated enough). Do you think a simple "write your JSON, hit enter, hit Ctrl+D (Unix) or Ctrl+Z (Windows) and then hit enter again" is enough of an explanation or would you add some more info around it (e.g. what that is supposed to achive)?

Link to comment
Share on other sites

I think adding a line to the README on the CLI page like that and an example of a successful response would be very useful.

 

A few things I was also confused on during development was what the name of the pipe was supposed to be. I also didn't realize that there was a "--help" option for the CLI, and I think it would also be useful to mention that the JSON arg should be in quotes. I also didn't realize I was meant to use the vcpkg.json (most likely due to my inexperience with vcpkg) so noting this and how to install the dependencies could be useful.

Link to comment
Share on other sites

  • Administrators

The necessity to quote the argument has nothing to do with the JSON bridge but is a general quirk of how terminals work. So not sure if that should be mentioned there explicitly. But nonetheless a usage example doing this would probably still be useful.

 

Would you mind creating a PR with the necessary descriptions written? I think given that you have worked yourself through all these complications, you are probably the one best suited to write these things down in such a way that another new user will understand best. I have the feeling that if I write this, then a few things will probably be assumed to be known again xD

Link to comment
Share on other sites

Quote

So not sure if that should be mentioned there explicitly. But nonetheless a usage example doing this would probably still be useful.

Yeah I think that makes sense

 

Quote

Would you mind creating a PR with the necessary descriptions written?

Sure!

Link to comment
Share on other sites

I am trying to use the NamedPipe implementation to communicate with the Mumble JSON bridge in my code. I am a little confused on how to read from the pipe, because I cannot understand how to get a handle to it. In NamedPipe.h, the comments for create() say "If such a pipe (or other file) already exists at the given location, this function will fail." However, (if I am understanding correctly) it looks like that is what is happening (and not failing) in the test code:

 

 In Bridge.cpp in Bridge::doStart(), the pipe gets created with

m_pipe = NamedPipe::create(s_pipePath);

and then in test_pipeIO.cpp in setupPipeReader(), it looks like the pipe is created again to get the handle.

m_testPipe = NamedPipe::create(pipePath);
ASSERT_EQ(m_testPipe.getPath(), pipePath);
test_read();

 

I am curious if I am interpreting this correctly, and what the proper way to get a handle to the NamedPipe would be?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...