00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdbool.h>
00023 #include <stdint.h>
00024 #include <string.h>
00025 #include <errno.h>
00026 #include <dirent.h>
00027 #include <stdio.h>
00028 #include <assert.h>
00029
00030
00031
00032
00033
00034
00035 #include "driver_interface.h"
00036 #include "JackDriverLoader.h"
00037 #include "JackError.h"
00038 #include "jackctl.h"
00039
00040
00041
00042
00043 struct jackctl_server
00044 {
00045 char * name;
00046 JSList * drivers;
00047 JSList * parameters;
00048
00049
00050
00051 unsigned int xruns;
00052
00053
00054 union jackctl_parameter_value realtime;
00055 union jackctl_parameter_value default_realtime;
00056
00057
00058 union jackctl_parameter_value realtime_priority;
00059 union jackctl_parameter_value default_realtime_priority;
00060
00061
00062 union jackctl_parameter_value no_mem_lock;
00063 union jackctl_parameter_value default_no_mem_lock;
00064
00065
00066 union jackctl_parameter_value temporary;
00067 union jackctl_parameter_value default_temporary;
00068
00069
00070 union jackctl_parameter_value verbose;
00071 union jackctl_parameter_value default_verbose;
00072
00073
00074 union jackctl_parameter_value client_timeout;
00075 union jackctl_parameter_value default_client_timeout;
00076
00077
00078 union jackctl_parameter_value port_max;
00079 union jackctl_parameter_value default_port_max;
00080
00081
00082 union jackctl_parameter_value do_unlock;
00083 union jackctl_parameter_value default_do_unlock;
00084
00085
00086 union jackctl_parameter_value frame_time_offset;
00087 union jackctl_parameter_value default_frame_time_offset;
00088
00089
00090 union jackctl_parameter_value nozombies;
00091 union jackctl_parameter_value default_nozombies;
00092 };
00093
00094 struct jackctl_driver
00095 {
00096 char * filename;
00097 jack_driver_desc_t * desc_ptr;
00098 JSList * parameters;
00099 JSList * set_parameters;
00100 };
00101
00102 struct jackctl_parameter
00103 {
00104 const char * name;
00105 const char * short_description;
00106 const char * long_description;
00107 jackctl_param_type_t type;
00108 bool is_set;
00109 union jackctl_parameter_value * value_ptr;
00110 union jackctl_parameter_value * default_value_ptr;
00111
00112 union jackctl_parameter_value value;
00113 union jackctl_parameter_value default_value;
00114 struct jackctl_driver * driver_ptr;
00115 char id;
00116 jack_driver_param_t * driver_parameter_ptr;
00117 };
00118
00119 static
00120 struct jackctl_parameter *
00121 jackctl_add_parameter(
00122 JSList ** parameters_list_ptr_ptr,
00123 const char * name,
00124 const char * short_description,
00125 const char * long_description,
00126 jackctl_param_type_t type,
00127 union jackctl_parameter_value * value_ptr,
00128 union jackctl_parameter_value * default_value_ptr,
00129 union jackctl_parameter_value value)
00130 {
00131 struct jackctl_parameter * parameter_ptr;
00132
00133 parameter_ptr = (struct jackctl_parameter *)malloc(sizeof(struct jackctl_parameter));
00134 if (parameter_ptr == NULL)
00135 {
00136 jack_error("Cannot allocate memory for jackctl_parameter structure.");
00137 goto fail;
00138 }
00139
00140 parameter_ptr->name = name;
00141 parameter_ptr->short_description = short_description;
00142 parameter_ptr->long_description = long_description;
00143 parameter_ptr->type = type;
00144 parameter_ptr->is_set = false;
00145
00146 if (value_ptr == NULL)
00147 {
00148 value_ptr = ¶meter_ptr->value;
00149 }
00150
00151 if (default_value_ptr == NULL)
00152 {
00153 default_value_ptr = ¶meter_ptr->default_value;
00154 }
00155
00156 parameter_ptr->value_ptr = value_ptr;
00157 parameter_ptr->default_value_ptr = default_value_ptr;
00158
00159 *value_ptr = *default_value_ptr = value;
00160
00161 parameter_ptr->driver_ptr = NULL;
00162 parameter_ptr->driver_parameter_ptr = NULL;
00163 parameter_ptr->id = 0;
00164
00165 *parameters_list_ptr_ptr = jack_slist_append(*parameters_list_ptr_ptr, parameter_ptr);
00166
00167 return parameter_ptr;
00168
00169 fail:
00170 return NULL;
00171 }
00172
00173 static
00174 void
00175 jackctl_free_driver_parameters(
00176 struct jackctl_driver * driver_ptr)
00177 {
00178 JSList * next_node_ptr;
00179
00180 while (driver_ptr->parameters)
00181 {
00182 next_node_ptr = driver_ptr->parameters->next;
00183 free(driver_ptr->parameters->data);
00184 free(driver_ptr->parameters);
00185 driver_ptr->parameters = next_node_ptr;
00186 }
00187
00188 while (driver_ptr->set_parameters)
00189 {
00190 next_node_ptr = driver_ptr->set_parameters->next;
00191 free(driver_ptr->set_parameters->data);
00192 free(driver_ptr->set_parameters);
00193 driver_ptr->set_parameters = next_node_ptr;
00194 }
00195 }
00196
00197 static
00198 bool
00199 jackctl_add_driver_parameters(
00200 struct jackctl_driver * driver_ptr)
00201 {
00202 uint32_t i;
00203 union jackctl_parameter_value jackctl_value;
00204 jackctl_param_type_t jackctl_type;
00205 struct jackctl_parameter * parameter_ptr;
00206 jack_driver_param_desc_t * descriptor_ptr;
00207
00208 for (i = 0 ; i < driver_ptr->desc_ptr->nparams ; i++)
00209 {
00210 descriptor_ptr = driver_ptr->desc_ptr->params + i;
00211
00212 switch (descriptor_ptr->type)
00213 {
00214 case JackDriverParamInt:
00215 jackctl_type = JackParamInt;
00216 jackctl_value.i = descriptor_ptr->value.i;
00217 break;
00218 case JackDriverParamUInt:
00219 jackctl_type = JackParamUInt;
00220 jackctl_value.ui = descriptor_ptr->value.ui;
00221 break;
00222 case JackDriverParamChar:
00223 jackctl_type = JackParamChar;
00224 jackctl_value.c = descriptor_ptr->value.c;
00225 break;
00226 case JackDriverParamString:
00227 jackctl_type = JackParamString;
00228 strcpy(jackctl_value.str, descriptor_ptr->value.str);
00229 break;
00230 case JackDriverParamBool:
00231 jackctl_type = JackParamBool;
00232 jackctl_value.b = descriptor_ptr->value.i;
00233 break;
00234 default:
00235 jack_error("unknown driver parameter type %i", (int)descriptor_ptr->type);
00236 assert(0);
00237 goto fail;
00238 }
00239
00240 parameter_ptr = jackctl_add_parameter(
00241 &driver_ptr->parameters,
00242 descriptor_ptr->name,
00243 descriptor_ptr->short_desc,
00244 descriptor_ptr->long_desc,
00245 jackctl_type,
00246 NULL,
00247 NULL,
00248 jackctl_value);
00249
00250 if (parameter_ptr == NULL)
00251 {
00252 goto fail;
00253 }
00254
00255 parameter_ptr->driver_ptr = driver_ptr;
00256 parameter_ptr->id = descriptor_ptr->character;
00257 }
00258
00259 return true;
00260
00261 fail:
00262 jackctl_free_driver_parameters(driver_ptr);
00263
00264 return false;
00265 }
00266
00267 static
00268 bool
00269 jackctl_load_driver_descriptor(
00270 struct jackctl_server * server_ptr,
00271 struct jackctl_driver * driver_ptr)
00272 {
00273 jack_driver_desc_t * descriptor;
00274 JackDriverDescFunction so_get_descriptor;
00275 void * dlhandle;
00276 const char * dlerr;
00277 int err;
00278
00279 if (server_ptr->verbose.b) {
00280
00281 printf ("getting driver descriptor from %s", driver_ptr->filename);
00282 }
00283
00284 dlhandle = dlopen(driver_ptr->filename, RTLD_NOW|RTLD_GLOBAL);
00285 if (dlhandle == NULL) {
00286 jack_error("could not open driver .so '%s': %s", driver_ptr->filename, dlerror());
00287 return false;
00288 }
00289
00290 so_get_descriptor = (JackDriverDescFunction)
00291 dlsym(dlhandle, "driver_get_descriptor");
00292
00293 dlerr = dlerror();
00294 if (dlerr != NULL) {
00295 jack_error("cannot find driver_get_descriptor symbol: %s", dlerr);
00296 dlclose(dlhandle);
00297 return false;
00298 }
00299
00300 descriptor = so_get_descriptor();
00301 if (descriptor == NULL) {
00302 jack_error("driver from '%s' returned NULL descriptor", driver_ptr->filename);
00303 dlclose(dlhandle);
00304 return false;
00305 }
00306
00307 err = dlclose(dlhandle);
00308 if (err != 0) {
00309 jack_error("error closing driver .so '%s': %s", driver_ptr->filename, dlerror());
00310 free(descriptor->params);
00311 free(descriptor);
00312 return false;
00313 }
00314
00315
00316
00317 snprintf (descriptor->file, sizeof(descriptor->file), "%s", driver_ptr->filename);
00318
00319 driver_ptr->desc_ptr = descriptor;
00320
00321 return true;
00322 }
00323
00324 static int
00325 jack_drivers_load(
00326 struct jackctl_server * server_ptr)
00327 {
00328 struct dirent * dir_entry;
00329 DIR * dir_stream;
00330 const char * ptr;
00331 int err;
00332 char* driver_dir;
00333 struct jackctl_driver * driver_ptr;
00334 struct jackctl_driver * other_driver_ptr;
00335 JSList * node_ptr;
00336 unsigned int drivers_count;
00337
00338 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
00339 driver_dir = ADDON_DIR;
00340 }
00341
00342 if (server_ptr->verbose.b) {
00343
00344 printf ("searching for drivers in %s", driver_dir);
00345 }
00346
00347
00348
00349 dir_stream = opendir (driver_dir);
00350 if (!dir_stream) {
00351 jack_error ("could not open driver directory %s: %s",
00352 driver_dir, strerror (errno));
00353 return false;
00354 }
00355
00356 drivers_count = 0;
00357
00358 while ( (dir_entry = readdir (dir_stream)) ) {
00359
00360 if (strncmp ("jack_", dir_entry->d_name, 5) != 0) {
00361 continue;
00362 }
00363
00364 #if SETTINGS_PERSISTENCE_USE_LIBXML2
00365
00366
00367
00368
00369 if (strcmp ("jack_firewire.so", dir_entry->d_name) == 0) {
00370 continue;
00371 }
00372 #endif
00373
00374 ptr = strrchr (dir_entry->d_name, '.');
00375 if (!ptr) {
00376 continue;
00377 }
00378 ptr++;
00379 if (strncmp ("so", ptr, 2) != 0) {
00380 continue;
00381 }
00382
00383 driver_ptr = (struct jackctl_driver *)malloc(sizeof(struct jackctl_driver));
00384 if (driver_ptr == NULL)
00385 {
00386 jack_error("memory allocation of jackctl_driver structure failed.");
00387 continue;
00388 }
00389
00390 driver_ptr->filename = (char*)malloc(strlen(driver_dir) + 1 + strlen(dir_entry->d_name) + 1);
00391
00392 sprintf(driver_ptr->filename, "%s/%s", driver_dir, dir_entry->d_name);
00393
00394 if (!jackctl_load_driver_descriptor(server_ptr, driver_ptr))
00395 {
00396 goto dealloc_driver;
00397 }
00398
00399
00400 for (node_ptr = server_ptr->drivers; node_ptr != NULL; node_ptr = jack_slist_next(node_ptr))
00401 {
00402 other_driver_ptr = (struct jackctl_driver *)node_ptr->data;
00403
00404 if (strcmp(driver_ptr->desc_ptr->name, other_driver_ptr->desc_ptr->name) == 0)
00405 {
00406 jack_error(
00407 "the drivers in '%s' and '%s' both have the name '%s'; using the first",
00408 other_driver_ptr->filename,
00409 driver_ptr->filename,
00410 driver_ptr->desc_ptr->name);
00411 goto dealloc_descriptor;
00412 }
00413 }
00414
00415 driver_ptr->parameters = NULL;
00416 driver_ptr->set_parameters = NULL;
00417
00418 if (!jackctl_add_driver_parameters(driver_ptr))
00419 {
00420 assert(driver_ptr->parameters == NULL);
00421 goto dealloc_descriptor;
00422 }
00423
00424 server_ptr->drivers = jack_slist_append(server_ptr->drivers, driver_ptr);
00425 drivers_count++;
00426
00427 continue;
00428
00429 dealloc_descriptor:
00430 free(driver_ptr->desc_ptr->params);
00431 free(driver_ptr->desc_ptr);
00432
00433 dealloc_driver:
00434 free(driver_ptr->filename);
00435 free(driver_ptr);
00436 }
00437
00438 err = closedir (dir_stream);
00439 if (err) {
00440 jack_error ("error closing driver directory %s: %s",
00441 driver_dir, strerror (errno));
00442 }
00443
00444 if (drivers_count == 0)
00445 {
00446 jack_error ("could not find any drivers in %s!", driver_dir);
00447 return false;
00448 }
00449
00450 return true;
00451 }
00452
00453 static
00454 void
00455 jackctl_server_free_drivers(
00456 jackctl_server_t* server_ptr)
00457 {
00458
00459 }
00460
00461 static
00462 void
00463 jackctl_server_free_parameters(
00464 jackctl_server_t* server_ptr)
00465 {
00466
00467 }
00468
00469
00470 static
00471 int
00472 jackctl_xrun(void *arg)
00473 {
00474 ((struct jackctl_server *)arg)->xruns++;
00475
00476 return 0;
00477 }
00478
00479 jackctl_server_t* jackctl_server_create(const char * name)
00480 {
00481 struct jackctl_server * server_ptr;
00482 union jackctl_parameter_value value;
00483
00484 server_ptr = (struct jackctl_server *) malloc(sizeof(struct jackctl_server));
00485 return (jackctl_server_t*)server_ptr;
00486 }
00487
00488 void jackctl_server_destroy(jackctl_server_t* server)
00489 {
00490 jackctl_server_free_drivers(server);
00491 jackctl_server_free_parameters(server);
00492 free(((struct jackctl_server *)server)->name);
00493 free(server);
00494 }
00495
00496 const JSList * jackctl_server_get_drivers_list(jackctl_server_t* server)
00497 {
00498 return ((struct jackctl_server *)server)->drivers;
00499 }
00500
00501 bool jackctl_server_stop(jackctl_server_t* server)
00502 {
00503 return true;
00504 }
00505
00506 double jackctl_server_get_load(jackctl_server_t* server)
00507 {
00508
00509 return 0;
00510 }
00511
00512 unsigned int jackctl_server_get_sample_rate(jackctl_server_t* server)
00513 {
00514
00515 return 0;
00516 }
00517
00518 double jackctl_server_get_latency(jackctl_server_t* server)
00519 {
00520
00521 return 0;
00522 }
00523
00524 bool jackctl_server_is_realtime(jackctl_server_t* server)
00525 {
00526 return ((struct jackctl_server*)server)->realtime.b;
00527 }
00528
00529 unsigned int jackctl_server_get_xruns(jackctl_server_t* server)
00530 {
00531 return ((struct jackctl_server*)server)->xruns;
00532 }
00533
00534 void jackctl_server_reset_xruns(jackctl_server_t* server)
00535 {
00536 ((struct jackctl_server*)server)->xruns = 0;
00537 }
00538
00539 const JSList * jackctl_server_get_parameters(jackctl_server_t* server)
00540 {
00541 return ((struct jackctl_server*)server)->parameters;
00542 }
00543
00544 bool jackctl_server_start(jackctl_server_t* server, jackctl_driver_t* driver)
00545 {
00546 int rc;
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 return true;
00611
00612
00613 }
00614
00615 const char * jackctl_driver_get_name(jackctl_driver_t* driver)
00616 {
00617 return ((struct jackctl_driver*)driver)->desc_ptr->name;
00618 }
00619
00620 const JSList * jackctl_driver_get_parameters(jackctl_driver_t* driver)
00621 {
00622 return ((struct jackctl_driver*)driver)->parameters;
00623 }
00624
00625 #undef driver_ptr
00626
00627 const char * jackctl_parameter_get_name(jackctl_parameter_t* parameter)
00628 {
00629 return ((struct jackctl_parameter*)parameter)->name;
00630 }
00631
00632 const char * jackctl_parameter_get_short_description(jackctl_parameter_t* parameter)
00633 {
00634 return ((struct jackctl_parameter*)parameter)->short_description;
00635 }
00636
00637 const char * jackctl_parameter_get_long_description(jackctl_parameter_t* parameter)
00638 {
00639 return ((struct jackctl_parameter*)parameter)->long_description;
00640 }
00641
00642 jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter_t* parameter)
00643 {
00644 return ((struct jackctl_parameter*)parameter)->type;
00645 }
00646
00647 bool jackctl_parameter_is_set(jackctl_parameter_t* parameter)
00648 {
00649 return ((struct jackctl_parameter*)parameter)->is_set;
00650 }
00651
00652 union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter_t* parameter)
00653 {
00654 return *((struct jackctl_parameter*)parameter)->value_ptr;
00655 }
00656
00657 bool jackctl_parameter_set_value(jackctl_parameter_t* parameter, const union jackctl_parameter_value * value_ptr)
00658 {
00659 bool new_driver_parameter;
00660
00661
00662 if (((struct jackctl_parameter*)parameter)->driver_ptr != NULL)
00663 {
00664
00665 new_driver_parameter = ((struct jackctl_parameter*)parameter)->driver_parameter_ptr == NULL;
00666 if (new_driver_parameter)
00667 {
00668
00669
00670 ((struct jackctl_parameter*)parameter)->driver_parameter_ptr = (jack_driver_param_t *)malloc(sizeof(jack_driver_param_t));
00671 if (((struct jackctl_parameter*)parameter)->driver_parameter_ptr == NULL)
00672 {
00673 jack_error ("Allocation of jack_driver_param_t structure failed");
00674 return false;
00675 }
00676
00677 ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->character = ((struct jackctl_parameter*)parameter)->id;
00678
00679 ((struct jackctl_parameter*)parameter)->driver_ptr->set_parameters = jack_slist_append(((struct jackctl_parameter*)parameter)->driver_ptr->set_parameters, ((struct jackctl_parameter*)parameter)->driver_parameter_ptr);
00680 }
00681
00682 switch (((struct jackctl_parameter*)parameter)->type)
00683 {
00684 case JackParamInt:
00685 ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.i = value_ptr->i;
00686 break;
00687 case JackParamUInt:
00688 ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.ui = value_ptr->ui;
00689 break;
00690 case JackParamChar:
00691 ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.c = value_ptr->c;
00692 break;
00693 case JackParamString:
00694 strcpy(((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.str, value_ptr->str);
00695 break;
00696 case JackParamBool:
00697 ((struct jackctl_parameter*)parameter)->driver_parameter_ptr->value.i = value_ptr->b;
00698 break;
00699 default:
00700 jack_error("unknown parameter type %i", (int)((struct jackctl_parameter*)parameter)->type);
00701 assert(0);
00702
00703 if (new_driver_parameter)
00704 {
00705 jack_slist_remove(((struct jackctl_parameter*)parameter)->driver_ptr->set_parameters, ((struct jackctl_parameter*)parameter)->driver_parameter_ptr);
00706 }
00707
00708 return false;
00709 }
00710 }
00711
00712 ((struct jackctl_parameter*)parameter)->is_set = true;
00713 *((struct jackctl_parameter*)parameter)->value_ptr = *value_ptr;
00714
00715 return true;
00716 }
00717
00718 union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter_t* parameter)
00719 {
00720 return *((struct jackctl_parameter*)parameter)->default_value_ptr;
00721 }