Or more specifically how do you request an MTU change when operating at the "Platform Manager" level?
More details
I'm using the sample program LinuxGATM_CLT which acts as a GATT client and it uses the Bluetopia Platform Manager Framework.
I'm using TI's WL183xMOD WiLink hardware which uses Bluetopia (previously owned by Stonestreet One).
The API call exists
The function exists, but seems to be at stack layer lower than the PM:
~/src/ti_bluetopia/ $ grep GATT_Exchange_MTU_Request ./BluetopiaPM/Bluetopia/include/GATTAPI.h
BTPSAPI_DECLARATION int BTPSAPI GATT_Exchange_MTU_Request(unsigned int BluetoothStackID, unsigned int ConnectionID, Word_t RequestedMTU, GATT_Client_Event_Callback_t ClientEventCallback, unsigned long CallbackParameter);
But its not callable from the "Platform Manager" level
Everything within BluetopiaPM/sample/LinuxGATM/LinuxGATM_CLT.c uses GATM functions from BluetopiaPM/include/client/GATMAPI.h
It feels like the GATT_Exchange_MTU_Request() function has not been exposed at the PM level. Its hard to dig deeper into how the PM works because they only ship binaries (doesn't seem to be open-source). For example the only match is the GATTAPI.h header file and a binary library file:
~/src/ti_bluetopia/ $ grep -ri GATT_Initialize ./
Binary file ./BluetopiaPM/Bluetopia/lib/libSS1BTGAT.a matches
I feel like the solution is to find methods to report my current Platform Manager BluetoothStackID, ConnectionID, and callback parameters so that I can call the GATT_Exchange_MTU_Request() function directly.
In short, the workaround is to get an earlier version of Stonestreet One's Bluetopia, before they created the "Platform Manager". These earlier versions (suchas 4.012 and 4.013) don't have the advantage of the Platform Manager, but they do allow you to have more control, operating at a lower level where you can call:
GATT_Initialize() and
GATT_Exchange_MTU_Request()
One good example is 4.013's SPPLEDemo.c which calls the above-mentioned methods.
Related
We have a microservice that needs to be integration tested (real calls, but no network communication with anything outside of the test namespace in kubernetes) in our pipeline. It also relies on an external gRPC server which we have no control over.
Above is a picture of what we'd like to have happen. The white box on the left is code that provides the Microservice Boundary with 'external' data. It then keeps calling the Code via REST until it gets back the proper number of records or it times out. The Code pulls records from an internal database, as well as data associated to those records from a gRPC call. Since we do not own the gRPC service, but are doing integration tests, we need a few pre-defined responses to the two gRPC services we call (blue box).
Since our integration tests are self-contained right now, and we don't want to write an entirely new actual gRPC server implementation just to mimick calls, is there a way to stand up a real gRPC server and configure it to return responses? The request is pretty much like a mock setup, except with an actual server.
We need to be able to:
give the server multiple proto files to interpret and have it expose those as endpoints. Proto files must be able to have different package names
using files we can store in source control, configure the responses to each call
able to run in a linux docker container (no windows)
I did find gripmock which seemed almost exactly what we need, but it only serves one proto file per container. It supposedly can serve more than one, but I can't get it to work and their example that serves two files implies each proto file must have the same package name which will likely never happen with our scenarios. In the meantime we are using it, but if we have 10 gRPC call dependencies, we now have to run 10 gripmock servers.
Wikipedia contains a list of API mocking tools. Looking at that list today there is a commercial tool that supports gRPC called Traffic Parrot which allows you to create gRPC mocks based on your Proto files. You can give it multiple proto files, store the mocks in Git and run the tool in Docker.
There are also open-source tools like GripMock but it does not generate stubs based on Proto files, you have to create them manually. Also, the project up to today was not keeping up to date with Proto and gRPC developments i.e. the package name issue you have discovered yourself above (works only if the package names in different proto files are the same). There are a few other open-source tools like grpc-wiremock, grpc-mock or bloomrpc-mock but they still lack widespread adoption and hence might be risky to adopt for an important enterprise project.
Keep in mind, the mock generated will be only a test double, it will not replicate the full behaviour of the system the Proto file corresponds to. If you wanted to also replicate partially the semantics of the messages consider doing a recording of the gRPC messages to create the mocks, that way you can see the sample data as well.
Take a look at this JS library which hopefully does what you need:
https://github.com/alenon/grpc-mock-server
Usage example:
private static readonly PROTO_PATH: string = __dirname + "example.proto";
private static readonly PKG_NAME: string = "com.alenon.example";
private static readonly SERVICE_NAME: string = "ExampleService";
...
const implementations = {
ex1: (call: any, callback: any) => {
const response: any =
new this.proto.ExampleResponse.constructor({msg: "the response message"});
callback(null, response);
},
};
this.server.addService(PROTO_PATH, PKG_NAME, SERVICE_NAME, implementations);
this.server.start();
The POSIX shm_open() function returns a file descriptor that can be used to access shared memory. This is extremely convenient because one can use all the traditional mechanisms for controlling file descriptors to also control shared memory.
The only drawback is that shm_open() always wants a filename. So I need to do this:
// Open with a clever temp file name and hope for the best.
fd = shm_open(tempfilename, O_RDWR | O_CREAT | O_EXCL, 0600);
// Immediately delete the temp file to keep the shm namespace clean.
shm_unlink(tempfilename);
// Then keep using fd -- the shm object remains as long as there are open fds.
This use of tempfilename is difficult to do portably and reliably. The interpretation of the filename (what the namespace is, how permissions are handled) differs among systems.
In many situations the processes using the shared memory object have no need for a filename because the object can be accessed more simply and safely by just passing a file descriptor from one process to another. So is there something that's just like shm_open() but can be used without touching the shared memory filename namespace?
mmap() with MAP_ANON|MAP_SHARED is great but instead of a file descriptor it gives a pointer. The pointer doesn't survive over an exec boundary and can't be sent to another process over a Unix domain socket like file descriptors can.
The file descriptor returned by shm_open() also doesn't survive an exec boundary by default: the POSIX definition says that the FD_CLOEXEC file descriptor flag associated with the new file descriptor is set. But it is possible to clear the flag using fcntl() on MacOS, Linux, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD and possibly other operating systems.
A library to solve the problem
I managed to write a library that provides the simple interface:
int shm_open_anon(void);
The library compiles without warnings and successfully runs a test program on Linux, Solaris, MacOS, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD and Haiku. You may be able to adapt it to other operating systems; please send a pull request if you do.
The library returns a file descriptor with the close-on-exec flag set. You can clear that flag using fcntl() on all supported operating systems, which will allow you to pass the fd over exec(). The test program demonstrates that this works.
Implementation techniques used in the library
The readme of the library has very precise notes on what was done and what wasn't done for each OS. Here's a summary of the main stuff.
There are several non-portable things that are more or less equivalent to shm_open() without a filename:
FreeBSD can take SHM_ANON as the pathname for shm_open() since 2008.
Linux has a memfd_create() system call since kernel version 3.17.
Earlier versions of Linux can use mkostemp(name, O_CLOEXEC | O_TMPFILE) where name is something like /dev/shm/XXXXXX. Note that we are not using shm_open() at all here -- mkostemp() is implicitly using a perfectly ordinary open() call. Linux mounts a special memory-backed file system in /dev/shm but some distros use /run/shm instead so there are pitfalls here. And you still have to shm_unlink() the temp file.
OpenBSD has a shm_mkstemp() call since release 5.4. You still have to shm_unlink() the temp file but at least it is easy to create safely.
For other OSes, I did the following:
Figure out an OS-dependent format for the name argument of POSIX shm_open(). Please note that there is no name you can pass that is absolutely portable. For example, NetBSD and DragonFlyBSD have conflicting demands about slashes in the name. This applies even if your goal is to use a named shm object (for which the POSIX API was designed) instead of an anonymous one (as we are doing here).
Append some random letters and numbers to the name (by reading from /dev/random). This is basically what mktemp() does, except we don't check whether our random name exists in the file system. The interpretation of the name argument varies wildly so there's no reasonable way to portably map it to an actual filename. Also Solaris doesn't always provide mktemp(). For all practical purposes, the randomness we put in will ensure a unique name for the fraction of a second that we need it.
Open the shm object with that name via shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600). In the astronomical chance that our random filename already exists, O_EXCL will cause this call to fail anyway, so no harm done. The 0600 permissions (owner read-write) are necessary on some systems instead of blank 0 permissions.
Immediately call shm_unlink() to get rid of the random name. The file descriptor remains for our use.
This technique is not quaranteed to work by POSIX, but:
The shm_open() name argument is underspecified by POSIX so nothing else is guaranteed to work either.
I'll let the above compatibility list speak for itself.
Enjoy.
No, there isn't. Since both System V shared memory model and POSIX shared file mapping for IPC require operations with a file, there is always need for a file in order to do mapping.
mmap() with MAP_ANON|MAP_SHARED is great but instead of a file
descriptor it gives a pointer. The pointer doesn't survive over an
exec boundary and can't be sent to another process over a Unix domain
socket like file descriptors can.
As John Bollinger says,
Neither memory mappings created via mmap() nor POSIX shared-memory
segments obtained via shm_open() nor System V shared-memory segments
obtained via shmat() are preserved across an exec.
There must be a well-known place on the memory to meet and exchange information. That's why a file is the requirement. By doing this, after exec, the child is able to reconnect to the appropriate shared memory.
This use of tempfilename is difficult to do portably and reliably. The interpretation of the filename (what the namespace is, how permissions are handled) differs among systems.
You can have mkstemp create a unique filename in /dev/shm/ or /tmp and open the file for you. You can then unlink the filename, so that no other process can open this file, apart from the process that have the file descriptor returned from mkstemp.
mkstemp(): CONFORMING TO 4.3BSD, POSIX.1-2001.
Why not creating it with access rights to 0?
Thus no process would be able to "open" it and let you unlink it safely just after?
I start my qt application in the user's .profile file (not root) to make the app start on boot. Sometimes when my application start, it reports an warning as below:
"No such interface 'org.freedesktop.DBus.Properties' on object at path /org/freedesktop/NetworkManager/ActiveConnection/1"
I searched on google but did not find a explanation.
It seems my app is still working fine, but I want to locate the problem.
The application is running on ubuntu and using Qt5.
Thanks in advance.
Edit
I tried to debug dbus based on Eligijus Pupeikis's help with running:
gdbus introspect --system \
--dest org.freedesktop.NetworkManager \
--object-path /org/freedesktop/NetworkManager/ActiveConnection
it returns:
node /org/freedesktop/NetworkManager/ActiveConnection {
node 0 {
};
};
So, this means there is no such object just as the error message said, right?
And also, this gns3 team member says this problem is about Qt and Ubuntu.
Does this mean I don't need to solve it? I not familiar with the relationship between dbus and qt.
Most likely there is no such object "/org/freedesktop/NetworkManager/ActiveConnection/1" and because of that it can't find 'org.freedesktop.DBus.Properties' interface.
From documentation org.freedesktop.NetworkManager.Connection.Active :
Objects that implement the Connection.Active interface represent an attempt to connect to a network using the details provided by a Connection object. The Connection.Active object tracks the life-cycle of the connection attempt and if successful indicates whether the connected network is the "default" or preferred network for access. NetworkManager has the concept of connections, which can be thought of as settings, a profile or a configuration that can be applied on a networking device. Such settings-connections are exposed as D-Bus object and the active-connection expresses this relationship between device and settings-connection. At any time a settings-connection can only be activated on one device and vice versa. However, during activation and deactivation multiple active-connections can reference the same device or settings-connection as they are waiting to be activated or to be deactivated.
You can't know that that ActiveConnection object with specifically index 1 exists so you need to check by reading ActiveConnections property from /org/freedesktop/NetworkManager object's org.freedesktop.NetworkManager interface.
To have better visualize and understand how it looks I suggest D-Bus debugger. If you are using Gnome check out D-Feet.
My place of business currently uses Reflection for Unix and OpenVMS to handle a database of customers. I access this database directly through the Reflection emulation. The only way to get data out of Reflection is to navigate to a single customer via keyboard input and print the information to a .txt.
Is there anyway I can access the VM other than through Reflection with the end goal of automating retrieval of customer information from a Java script executed outside of the Reflection environment? This is the information I can gather via the Reflection interface about what I am connecting to:
At the bottom of the Reflection interface - VT500-7 -- HOST_NAME via SECURE SHELL
Via the Connection Setup drop-down:
Host name: HOST_NAME
SSH config scheme: AutoKeyLogin
User name: username
Via the Security... button:
General tab:
Port number: 22
User Authentication: [x] Public Key
[x] Password
User Keys tab:
Use Name Type Location
[x] username1user DSA C:\Documents\PathToSSHKey\.ssh
Host Keys tab:
Host Type Fingerprint
HOST_NAME, 111.1.111.11, 22 DSA 39:14:f3:123:fds:restOfFingerprint
There is more information available if the solution is possible but I have just not provided enough to solve it, so please ask.
Given that I have the host name, port, .ssh, and host key, is it possible to connect to and read from the VM that I am otherwise connecting to normally via the Reflection emulator?
NO. Reflection (other example is PuTTY) is just a dumb-terminal emulator, here using the (secure) SSH protocol to connect to some Operating System. From the information provided we cannot even tell which OS. Maybe OpenVMS maybe some Unix. Most certainly not a 'VM', but a physical box. Maybe a Alpha, Integrity, Sun, IBM or Intel server.
IF, big if, it is OpenVMS you would possibly see something like this flash by on entry:
XXX - HP rx2600 (1.50GHz/6.0MB) OpenVMS IA64 V8.3-1H1
Last interactive login on Thursday, 7-DEC-2017 13:23:19.83
Last non-interactive login on Wednesday, 6-DEC-2017 12:35:45.80
Most likely username uses is set up to always start a (shell) script which starts a menu from which a program is activated, which knows how to access data record. IF is it OpenVMS then the actual data is likely stored in RMS (indexed) files, but it could in a proper (Oracle RDB or RDBMS) database.
If bulk access to the data is needed then you need to talk to the system/application manager for the system 'HOST_NAME' and ask them about the application and its database.
You may find that there is FTP, ODBC or JDBC or natice DB (OCI?) access to the data avaiable already, or that this can be requested. Likely tools in this space are ConnX, Attunity Connect, and such.
First you'll need to find out which OS/Platform/Version, which application (3rd party? home grown? 4GL? Cobol? Basic? and ultimately, which database/storage method.
That's not to say that some terminal emulator cannot be 'tricked' (google -
screen scraping) to be programmed to fetch a series of data on command, but that will always be error prone and laboriously for limited volumes.
You are better of trying to get proper data access.
Good luck! You'll need some.
Hein
I am working on the iBeacon technology and I can't find any answer to a particular point concerning the address type.
I found the documenation (bluetooth specification) explaining what are the address types but I can't seem to find how to chose between the two types (public and random).
Here is an example where I found it (it is a sniffed packet transmitted by an iBeacon on a Raspberry PI) :
http://i.stack.imgur.com/QF5gf.png
and http://i.stack.imgur.com/NHY6x.png (sorry I can't post images yet because of my reputation)
Let's try to ask questions and make it more specific :
Since a public address has to be valid, might it be that there is a command to generate a random one (yet correct in formatting the address) to assign it to the concerned device?
If the above is true : what would be the command? and how do you roll back (to the primary public address)?
Or is there a "switch" that allows to chose between the (valid) public address or to generate a random one?
Thank you.
Here's a command that looks pretty much like what you want. See here for details.
Set Static Address Command
==========================
Command Code: 0x002B
Controller Index: <controller id>
Command Parameters: Address (6 Octets)
Return Parameters:
This command allows for setting the static random address. It is
only supported on controllers with LE support. The static random
address is suppose to be valid for the lifetime of the
controller or at least until the next power cycle. To ensure
such behavior, setting of the address is limited to when the
controller is powered off.
The special BDADDR_ANY address (00:00:00:00:00:00) can be used
to disable the static address.
When a controller has a public address (which is required for
all dual-mode controllers), this address is not used. Only when
the controller information reports BDADDR_ANY (00:00:00:00:00:00),
it is required to configure a static address first.
If privacy mode is enabled and the controller is single mode
LE only without a public address, the static random address is
used as identity address.
This command generates a Command Complete event on success or a
Command Status event on failure.
Possible errors: Rejected
Not Supported
Invalid Parameters
Invalid Index
It looks to me like the privacy features of BlueZ are under current active development and may not be complete yet. See this commit from 2014/02/18. If you want to try this with the latest updates, you will have to compile BlueZ from source.