Browse Source

Merge no-self-connect branch

Conflicts:
	common/JackEngine.cpp
	common/JackServer.cpp
tags/v1.9.10
Adrian Knoth 12 years ago
parent
commit
f1a5a7dc43
11 changed files with 210 additions and 24 deletions
  1. +2
    -0
      common/JackConstants.h
  2. +70
    -0
      common/JackControlAPI.cpp
  3. +91
    -12
      common/JackEngine.cpp
  4. +4
    -1
      common/JackEngine.h
  5. +2
    -2
      common/JackLockedEngine.h
  6. +2
    -3
      common/JackServer.cpp
  7. +1
    -1
      common/JackServer.h
  8. +4
    -3
      common/JackServerGlobals.cpp
  9. +2
    -1
      common/JackServerGlobals.h
  10. +10
    -0
      common/JackTypes.h
  11. +22
    -1
      common/Jackdmp.cpp

+ 2
- 0
common/JackConstants.h View File

@@ -82,4 +82,6 @@
#define EMPTY 0xFFFD #define EMPTY 0xFFFD
#define FREE 0xFFFC #define FREE 0xFFFC


#define JACK_DEFAULT_SELF_CONNECT_MODE JackSelfConnectIgnoreAll

#endif #endif

+ 70
- 0
common/JackControlAPI.cpp View File

@@ -47,6 +47,13 @@


using namespace Jack; using namespace Jack;


#define SELF_CONNECT_MODE_ALLOW_CHAR ' '
#define SELF_CONNECT_MODE_FAIL_EXTERNAL_ONLY_CHAR 'E'
#define SELF_CONNECT_MODE_IGNORE_EXTERNAL_ONLY_CHAR 'e'
#define SELF_CONNECT_MODE_FAIL_ALL_CHAR 'A'
#define SELF_CONNECT_MODE_IGNORE_ALL_CHAR 'a'
#define SELF_CONNECT_MODES_COUNT 5

struct jackctl_server struct jackctl_server
{ {
JSList * drivers; JSList * drivers;
@@ -94,6 +101,12 @@ struct jackctl_server
/* bool, synchronous or asynchronous engine mode */ /* bool, synchronous or asynchronous engine mode */
union jackctl_parameter_value sync; union jackctl_parameter_value sync;
union jackctl_parameter_value default_sync; union jackctl_parameter_value default_sync;

/* char enum, self connect mode mode */
union jackctl_parameter_value self_connect_mode;
union jackctl_parameter_value default_self_connect_mode;
jack_driver_param_value_enum_t self_connect_mode_possible_values[SELF_CONNECT_MODES_COUNT];
jack_driver_param_constraint_desc_t self_connect_mode_constraint;
}; };


struct jackctl_driver struct jackctl_driver
@@ -869,6 +882,40 @@ SERVER_EXPORT jackctl_server_t * jackctl_server_create(
goto fail_free_parameters; goto fail_free_parameters;
} }


server_ptr->self_connect_mode_constraint.flags = JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE;
server_ptr->self_connect_mode_constraint.constraint.enumeration.count = SELF_CONNECT_MODES_COUNT;
server_ptr->self_connect_mode_constraint.constraint.enumeration.possible_values_array = server_ptr->self_connect_mode_possible_values;

server_ptr->self_connect_mode_possible_values[0].value.c = SELF_CONNECT_MODE_ALLOW_CHAR;
strcpy(server_ptr->self_connect_mode_possible_values[0].short_desc, "Don't restrict self connect requests");

server_ptr->self_connect_mode_possible_values[1].value.c = SELF_CONNECT_MODE_FAIL_EXTERNAL_ONLY_CHAR ;
strcpy(server_ptr->self_connect_mode_possible_values[1].short_desc, "Fail self connect requests to external ports only");

server_ptr->self_connect_mode_possible_values[2].value.c = SELF_CONNECT_MODE_IGNORE_EXTERNAL_ONLY_CHAR;
strcpy(server_ptr->self_connect_mode_possible_values[2].short_desc, "Ignore self connect requests to external ports only");

server_ptr->self_connect_mode_possible_values[3].value.c = SELF_CONNECT_MODE_FAIL_ALL_CHAR;
strcpy(server_ptr->self_connect_mode_possible_values[3].short_desc, "Fail all self connect requests");

server_ptr->self_connect_mode_possible_values[4].value.c = SELF_CONNECT_MODE_IGNORE_ALL_CHAR;
strcpy(server_ptr->self_connect_mode_possible_values[4].short_desc, "Ignore all self connect requests");

value.c = SELF_CONNECT_MODE_ALLOW_CHAR;
if (jackctl_add_parameter(
&server_ptr->parameters,
"self-connect-mode",
"Self connect mode.",
"Whether JACK clients are allowed to connect their own ports",
JackParamChar,
&server_ptr->self_connect_mode,
&server_ptr->default_self_connect_mode,
value,
&server_ptr->self_connect_mode_constraint) == NULL)
{
goto fail_free_parameters;
}

JackServerGlobals::on_device_acquire = on_device_acquire; JackServerGlobals::on_device_acquire = on_device_acquire;
JackServerGlobals::on_device_release = on_device_release; JackServerGlobals::on_device_release = on_device_release;


@@ -953,6 +1000,7 @@ jackctl_server_open(
jackctl_server *server_ptr, jackctl_server *server_ptr,
jackctl_driver *driver_ptr) jackctl_driver *driver_ptr)
{ {
JackSelfConnectMode self_connect_mode;
JSList * paramlist = NULL; JSList * paramlist = NULL;


try { try {
@@ -986,6 +1034,27 @@ jackctl_server_open(
server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */
} }


switch (server_ptr->self_connect_mode.c)
{
case SELF_CONNECT_MODE_ALLOW_CHAR:
self_connect_mode = JackSelfConnectAllow;
break;
case SELF_CONNECT_MODE_FAIL_EXTERNAL_ONLY_CHAR:
self_connect_mode = JackSelfConnectFailExternalOnly;
break;
case SELF_CONNECT_MODE_IGNORE_EXTERNAL_ONLY_CHAR:
self_connect_mode = JackSelfConnectIgnoreExternalOnly;
break;
case SELF_CONNECT_MODE_FAIL_ALL_CHAR:
self_connect_mode = JackSelfConnectFailAll;
break;
case SELF_CONNECT_MODE_IGNORE_ALL_CHAR:
self_connect_mode = JackSelfConnectIgnoreAll;
break;
default:
self_connect_mode = JACK_DEFAULT_SELF_CONNECT_MODE;
}

/* check port max value before allocating server */ /* check port max value before allocating server */
if (server_ptr->port_max.ui > PORT_NUM_MAX) { if (server_ptr->port_max.ui > PORT_NUM_MAX) {
jack_error("Jack server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); jack_error("Jack server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX);
@@ -1002,6 +1071,7 @@ jackctl_server_open(
server_ptr->port_max.ui, server_ptr->port_max.ui,
server_ptr->verbose.b, server_ptr->verbose.b,
(jack_timer_type_t)server_ptr->clock_source.ui, (jack_timer_type_t)server_ptr->clock_source.ui,
self_connect_mode,
server_ptr->name.str); server_ptr->name.str);
if (server_ptr->engine == NULL) if (server_ptr->engine == NULL)
{ {


+ 91
- 12
common/JackEngine.cpp View File

@@ -38,13 +38,15 @@ namespace Jack


JackEngine::JackEngine(JackGraphManager* manager, JackEngine::JackEngine(JackGraphManager* manager,
JackSynchro* table, JackSynchro* table,
JackEngineControl* control)
JackEngineControl* control,
JackSelfConnectMode self_connect_mode)
: JackLockAble(control->fServerName), : JackLockAble(control->fServerName),
fSignal(control->fServerName) fSignal(control->fServerName)
{ {
fGraphManager = manager; fGraphManager = manager;
fSynchroTable = table; fSynchroTable = table;
fEngineControl = control; fEngineControl = control;
fSelfConnectMode = self_connect_mode;
for (int i = 0; i < CLIENT_NUM; i++) { for (int i = 0; i < CLIENT_NUM; i++) {
fClientTable[i] = NULL; fClientTable[i] = NULL;
} }
@@ -803,10 +805,10 @@ int JackEngine::ClientDeactivate(int refnum)


// First disconnect all ports // First disconnect all ports
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) {
PortDisconnect(refnum, input_ports[i], ALL_PORTS);
PortDisconnect(-1, input_ports[i], ALL_PORTS);
} }
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) {
PortDisconnect(refnum, output_ports[i], ALL_PORTS);
PortDisconnect(-1, output_ports[i], ALL_PORTS);
} }


// Then issue port registration notification // Then issue port registration notification
@@ -874,7 +876,7 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index)
assert(client); assert(client);


// Disconnect port ==> notification is sent // Disconnect port ==> notification is sent
PortDisconnect(refnum, port_index, ALL_PORTS);
PortDisconnect(-1, port_index, ALL_PORTS);


if (fGraphManager->ReleasePort(refnum, port_index) == 0) { if (fGraphManager->ReleasePort(refnum, port_index) == 0) {
if (client->GetClientControl()->fActive) { if (client->GetClientControl()->fActive) {
@@ -886,6 +888,72 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index)
} }
} }


// this check is to prevent apps to self connect to other apps
// TODO: make this work with multiple clients per app
int JackEngine::CheckPortsConnect(int refnum, jack_port_id_t src, jack_port_id_t dst)
{
JackPort* src_port = fGraphManager->GetPort(src);
JackPort* dst_port = fGraphManager->GetPort(dst);

jack_log("CheckPortsConnect(caller = %d, src = %d, dst = %d)", refnum, src_port->GetRefNum(), dst_port->GetRefNum());

int src_self = src_port->GetRefNum() == refnum ? 1 : 0;
int dst_self = dst_port->GetRefNum() == refnum ? 1 : 0;

jack_log("src_self is %s", src_self ? "true" : "false");
jack_log("dst_self is %s", dst_self ? "true" : "false");

// 0 means client is connecting other client ports (i.e. control app patchbay functionality)
// 1 means client is connecting its own port to port of other client (i.e. self hooking into system app)
// 2 means client is connecting its own ports (i.e. for app internal functionality)
// TODO: Make this check an engine option and more tweakable (return error or success)
// MAYBE: make the engine option changable on the fly and expose it through client or control API

switch (fSelfConnectMode)
{
case JackSelfConnectFailExternalOnly:
if (src_self + dst_self == 1)
{
jack_info("rejecting port self connect request to external port (%s -> %s)", src_port->GetName(), dst_port->GetName());
return -1;
}

return 1;

case JackSelfConnectIgnoreExternalOnly:
if (src_self + dst_self == 1)
{
jack_info("ignoring port self connect request to external port (%s -> %s)", src_port->GetName(), dst_port->GetName());
return 0;
}

return 1;

case JackSelfConnectFailAll:
if (src_self + dst_self != 0)
{
jack_info("rejecting port self connect request (%s -> %s)", src_port->GetName(), dst_port->GetName());
return -1;
}

return 1;

case JackSelfConnectIgnoreAll:
if (src_self + dst_self != 0)
{
jack_info("ignoring port self connect request (%s -> %s)", src_port->GetName(), dst_port->GetName());
return 0;
}

return 1;

case JackSelfConnectAllow: // fix warning
return 1;
}

return 1;
}

int JackEngine::PortConnect(int refnum, const char* src, const char* dst) int JackEngine::PortConnect(int refnum, const char* src, const char* dst)
{ {
jack_log("JackEngine::PortConnect src = %s dst = %s", src, dst); jack_log("JackEngine::PortConnect src = %s dst = %s", src, dst);
@@ -926,7 +994,12 @@ int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst)
return -1; return -1;
} }


int res = fGraphManager->Connect(src, dst);
int res = CheckPortsConnect(refnum, src, dst);
if (res != 1) {
return res;
}

res = fGraphManager->Connect(src, dst);
if (res == 0) { if (res == 0) {
NotifyPortConnect(src, dst, true); NotifyPortConnect(src, dst, true);
} }
@@ -969,15 +1042,21 @@ int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t ds
} }


return res; return res;
} else if (fGraphManager->CheckPorts(src, dst) < 0) {
return -1;
} else if (fGraphManager->Disconnect(src, dst) == 0) {
// Notifications
NotifyPortConnect(src, dst, false);
return 0;
} else {
}

if (fGraphManager->CheckPorts(src, dst) < 0) {
return -1; return -1;
} }

int res = CheckPortsConnect(refnum, src, dst);
if (res != 1) {
return res;
}

res = fGraphManager->Disconnect(src, dst);
if (res == 0)
NotifyPortConnect(src, dst, false);
return res;
} }


int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name)


+ 4
- 1
common/JackEngine.h View File

@@ -49,6 +49,7 @@ class SERVER_EXPORT JackEngine : public JackLockAble


JackGraphManager* fGraphManager; JackGraphManager* fGraphManager;
JackEngineControl* fEngineControl; JackEngineControl* fEngineControl;
JackSelfConnectMode fSelfConnectMode;
JackClientInterface* fClientTable[CLIENT_NUM]; JackClientInterface* fClientTable[CLIENT_NUM];
JackSynchro* fSynchroTable; JackSynchro* fSynchroTable;
JackServerNotifyChannel fChannel; /*! To communicate between the RT thread and server */ JackServerNotifyChannel fChannel; /*! To communicate between the RT thread and server */
@@ -94,9 +95,11 @@ class SERVER_EXPORT JackEngine : public JackLockAble
return (refnum >= 0 && refnum < CLIENT_NUM && fClientTable[refnum] != NULL); return (refnum >= 0 && refnum < CLIENT_NUM && fClientTable[refnum] != NULL);
} }


int CheckPortsConnect(int refnum, jack_port_id_t src, jack_port_id_t dst);

public: public:


JackEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler);
JackEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler, JackSelfConnectMode self_connect_mode);
~JackEngine(); ~JackEngine();


int Open(); int Open();


+ 2
- 2
common/JackLockedEngine.h View File

@@ -83,8 +83,8 @@ class SERVER_EXPORT JackLockedEngine


public: public:


JackLockedEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler):
fEngine(manager, table, controler)
JackLockedEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler, JackSelfConnectMode self_connect_mode):
fEngine(manager, table, controler, self_connect_mode)
{} {}
~JackLockedEngine() ~JackLockedEngine()
{} {}


+ 2
- 3
common/JackServer.cpp View File

@@ -40,8 +40,7 @@ namespace Jack
//---------------- //----------------
// Server control // Server control
//---------------- //----------------

JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, const char* server_name)
JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, JackSelfConnectMode self_connect_mode, const char* server_name)
{ {
if (rt) { if (rt) {
jack_info("JACK server starting in realtime mode with priority %ld", priority); jack_info("JACK server starting in realtime mode with priority %ld", priority);
@@ -51,7 +50,7 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio


fGraphManager = JackGraphManager::Allocate(port_max); fGraphManager = JackGraphManager::Allocate(port_max);
fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name);
fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl);
fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl, self_connect_mode);


// A distinction is made between the threaded freewheel driver and the // A distinction is made between the threaded freewheel driver and the
// regular freewheel driver because the freewheel driver needs to run in // regular freewheel driver because the freewheel driver needs to run in


+ 1
- 1
common/JackServer.h View File

@@ -64,7 +64,7 @@ class SERVER_EXPORT JackServer


public: public:


JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, const char* server_name);
JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, JackSelfConnectMode self_connect_mode, const char* server_name);
~JackServer(); ~JackServer();


// Server control // Server control


+ 4
- 3
common/JackServerGlobals.cpp View File

@@ -47,10 +47,11 @@ int JackServerGlobals::Start(const char* server_name,
int priority, int priority,
int port_max, int port_max,
int verbose, int verbose,
jack_timer_type_t clock)
jack_timer_type_t clock,
JackSelfConnectMode self_connect_mode)
{ {
jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose);
new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, server_name); // Will setup fInstance and fUserCount globals
new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, self_connect_mode, server_name); // Will setup fInstance and fUserCount globals
int res = fInstance->Open(driver_desc, driver_params); int res = fInstance->Open(driver_desc, driver_params);
return (res < 0) ? res : fInstance->Start(); return (res < 0) ? res : fInstance->Start();
} }
@@ -336,7 +337,7 @@ bool JackServerGlobals::Init()
free(argv[i]); free(argv[i]);
} }


int res = Start(server_name, driver_desc, master_driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source);
int res = Start(server_name, driver_desc, master_driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source, JACK_DEFAULT_SELF_CONNECT_MODE);
if (res < 0) { if (res < 0) {
jack_error("Cannot start server... exit"); jack_error("Cannot start server... exit");
Delete(); Delete();


+ 2
- 1
common/JackServerGlobals.h View File

@@ -60,7 +60,8 @@ struct SERVER_EXPORT JackServerGlobals
int priority, int priority,
int port_max, int port_max,
int verbose, int verbose,
jack_timer_type_t clock);
jack_timer_type_t clock,
JackSelfConnectMode self_connect_mode);
static void Stop(); static void Stop();
static void Delete(); static void Delete();
}; };


+ 10
- 0
common/JackTypes.h View File

@@ -50,4 +50,14 @@ typedef enum {
Finished, Finished,
} jack_client_state_t; } jack_client_state_t;



enum JackSelfConnectMode
{
JackSelfConnectAllow,
JackSelfConnectFailExternalOnly,
JackSelfConnectIgnoreExternalOnly,
JackSelfConnectFailAll,
JackSelfConnectIgnoreAll,
};

#endif #endif

+ 22
- 1
common/Jackdmp.cpp View File

@@ -203,8 +203,8 @@ int main(int argc, char** argv)
jackctl_driver_t * master_driver_ctl; jackctl_driver_t * master_driver_ctl;
jackctl_driver_t * loopback_driver_ctl = NULL; jackctl_driver_t * loopback_driver_ctl = NULL;
int replace_registry = 0; int replace_registry = 0;

const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:" const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:"
"a:"
#ifdef __linux__ #ifdef __linux__
"c:" "c:"
#endif #endif
@@ -234,6 +234,7 @@ int main(int argc, char** argv)
{ "version", 0, 0, 'V' }, { "version", 0, 0, 'V' },
{ "silent", 0, 0, 's' }, { "silent", 0, 0, 's' },
{ "sync", 0, 0, 'S' }, { "sync", 0, 0, 'S' },
{ "autoconnect", 1, 0, 'a' },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };


@@ -296,6 +297,26 @@ int main(int argc, char** argv)
break; break;
#endif #endif


case 'a':
param = jackctl_get_parameter(server_parameters, "self-connect-mode");
if (param != NULL) {
bool value_valid = false;
for (uint32_t k=0; k<jackctl_parameter_get_enum_constraints_count( param ); k++ ) {
value = jackctl_parameter_get_enum_constraint_value( param, k );
if( value.c == optarg[0] )
value_valid = true;
}

if( value_valid ) {
value.c = optarg[0];
jackctl_parameter_set_value(param, &value);
} else {
usage(stdout);
goto destroy_server;
}
}
break;

case 'd': case 'd':
master_driver_name = optarg; master_driver_name = optarg;
break; break;


Loading…
Cancel
Save