UmberHubManager/api/examples/c_cpp/BrainStem2-Client-Cpp-Example/BrainStem2Example/main.cpp

201 lines
7.6 KiB
C++
Executable File

//
// main.cpp
// BrainStem2-Client-Cpp-Example
//
// Created by Acroname Inc. on 5/20/2023.
// Copyright (c) 2023 Acroname Inc. All rights reserved.
//
//This example is intended to highlight the multi-process and
//network capabilities of BrainStem modules. This application
//is intended to be used in conjunction with BrainStem2-Server-Cpp-Example
//however, it will work with any application or even HubTool
//if configured properly.
//Note 1:
// The actual server is created by the first process to connect to the device.
// This means if you run this application first it would create/own
// the server. This is intended to smooth over the user experience
// but is important to remember when closing applications. If
// The "Server" application is closed it will result in the "Clients"
// losing access to the device.
//Note 2:
// This application was created with the aUSBHub3p object. If
// your devices differs (say a USBCSwitch) you will need to change
// all instances of aUSBHub3p to aUSBCSwitch in order to connect to
// the device. This is a result of discoveryAndConnect as it will
// only connect to a device that matches the object type. It is
// possible to use the generic "Module" object; however, this was avoided
// in order to present a simplified example.
//Note 3:
// If you intended to connect to a device that is not connected
// to your local machine or on your local intranet (local network)
// you will need to define a linkSpec with the intended ip and port
// number of the device and then use "connectFromSpec".
// Discovery works through broadcast and multicast packets;
// neither of which work for the internet (global network).
// For more connection types see the "Discovery-and-Connection"
//Note 4:
// Additional network details are described in _configure_aEther().
///////////////////////////////////////////////////////////////////////////////
// Includes
///////////////////////////////////////////////////////////////////////////////
#include "BrainStem2/BrainStem-all.h"
///////////////////////////////////////////////////////////////////////////////
// Private Macros
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Private Types
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Private Function Prototypes
///////////////////////////////////////////////////////////////////////////////
void _configure_aEther(Acroname::BrainStem::Module& m);
void _print_aEtherConfig(Acroname::BrainStem::Module& m);
void _printProgramInfo(void);
void _printFailedConnection(void);
///////////////////////////////////////////////////////////////////////////////
// Public Data
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Private Data
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Public Function Implementations
///////////////////////////////////////////////////////////////////////////////
int main(int argc, const char * argv[]) {
aErr e = aErrNone;
aUSBHub3p stem;
//If your module is different, replace it with the appropriate module
//Such as a USBCSwitch as shown below.
//aUSBCSwitch stem;
_configure_aEther(stem);
e = stem.discoverAndConnect(USB);
if(aErrNone == e) {
_printProgramInfo(); printf("\n");
_print_aEtherConfig(stem);
//Loop for a long time so that we can see the interactions
//of the client and server.
static const uint32_t NUM_LOOPS = 10000;
for(uint32_t x = 0; x < NUM_LOOPS; x++) {
if(x % 20 == 0) { printf("Loop: %d\n", x); }
uint32_t voltage = 0;
e = stem.system.getInputVoltage(&voltage);
printf("System Input Voltage: %0.3f VDC - error: %d\n",
double(voltage)/1000000, e);
}
stem.disconnect();
}
else { _printFailedConnection(); }
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// Private Function Implementations
///////////////////////////////////////////////////////////////////////////////
void
_printProgramInfo(void) {
printf("The aUSBHub3p client has been started.\n");
}
void
_configure_aEther(Acroname::BrainStem::Module& m) {
//NOTE: Network configuration MUST be done before connecting.
Acroname::BrainStem::aEtherConfig config;
aErr err = m.getConfig(&config);
if(err == aErrNone) {
//Controls the exposure of the device. By default,
//the device is only exposed on the localhost.
//True = localhost(default); False = Public;
//config.localOnly = false; //uncomment to test non-default values
//Controls how strictly we honor the linkType (USB, NETWORK).
//Fallback allows for a smoother user experience when getting
//familiar with the device; however, it might be helpful to disable
//this so that you can control who is the server and who is the client.
//For instance if stem.discoverAndConnect(USB) fails it will automatically
//try stem.discoverAndConnect(Network) and vise-versa.
//True = fallback (default); False = NO fallback
//config.fallback = false; //uncomment to test non-default values
//Controls if the Client-Server model is used. If you prefer to restrict
//the device to a single process you can disable this capability.
//By default the stem is enabled for multi-process use.
//True = Client-Server (default); False = Direct connection (not multi-process)
//config.enabled = false; //uncomment to test non-default values
//Allows the user to select what network interface the stem will be exposed to.
//Default = LOCALHOST_IP_ADDRESS; (0 is also accepted for LOCALHOST_IP_ADDRESS);
//Available interfaces can be found with aDiscovery_GetIPv4Interfaces
//NOTE 1:
// If config.localOnly == true; This value is ignored.
// If config.localOnly == false; The stem will automatically pick
// the highest priority network interface and will ignore 0 and
// LOCALHOST_IP_ADDRESS values. However, you may override this value.
//config.networkInterface = LOCALHOST_IP_ADDRESS;
//Apply the configuration.
aErr err = m.setConfig(config);
if(err) { printf("setConfig Error: %d\n", err); }
}
}
void
_print_aEtherConfig(Acroname::BrainStem::Module& m) {
Acroname::BrainStem::aEtherConfig config;
aErr err = m.getConfig(&config);
char sInterface[INET_ADDRSTRLEN];
aDiscovery_ConvertIPv4Interface(config.networkInterface, sInterface, INET_ADDRSTRLEN);
printf("Current aEther Config (error: %d):\n", err);
printf("\t Local Only: %d\n" \
"\t Fallback: %d\n" \
"\t Server Enabled: %d\n" \
"\t Assigned Port: %d\n" \
"\t Network Interface: %d (%s)\n", \
config.localOnly,
config.fallback,
config.enabled,
config.assignedPort,
config.networkInterface,
sInterface);
}
void
_printFailedConnection(void) {
printf("Failed to discover Module\n");
printf(" - Confirm device is connected to your machine\n");
printf(" - Confirm object type. This examples default is \"aUSBHub3p\"\n");
}