static int init(void) {
const char *type;
    if(validateConfigString(&config, "volume.response.type", &type, -1) == EXIT_SUCCESS) {
        if(strcmp(type, "lower_limit"))
            modVolumeResponseCondResize.process = &processLower;
        else
        if(strcmp(type, "upper_limit"))
            modVolumeResponseCondResize.process = &processUpper;
        else
            return EXIT_FAILURE;
    }
    if(validateConfigInt(&config, "volume.response.limit", &responseLimit, -1, 0, 0, -1) == EXIT_FAILURE)
        return EXIT_FAILURE;
    if(validateConfigDouble(&config, "volume.response.divisor", &responseDivisor, -1, 0, 0, -1) == EXIT_FAILURE)
        return EXIT_FAILURE;
#ifdef REDUNDANT // causes segfault, process not yet loaded
    if(strcasecmp(common_data.process->name, "numeric") && (int)responseDivisor != responseDivisor) {
        syslog(LOG_ERR, "[ERROR] Numeric does not 'float'! Setting 'volume.response.divisor'" 
                        " is not an integer: %.2f", responseDivisor);
        return EXIT_FAILURE;
    }
#endif
    if(responseDivisor == 1)
        common_data.mod->volumeResponse = NULL;

    return EXIT_SUCCESS;
}
Exemple #2
0
/* Will validate the data retrieved from the configuration file */
int init(void) {
    int status;
    config_setting_t *conf_setting = NULL;
    const char *conf_value = NULL;
    
    /* Now the configuration file is read, we don't need to know the location
     * of the application anymore. We'll change working directory to root */
    if(chdir("/") < 0) {
        syslog(LOG_ERR, "Unable to change working directory to root: %s", strerror(errno));
        return EXIT_FAILURE;
    }
    
    syslog(LOG_INFO, "Checking presence and validity of required variables:");
    
    validateConfigBool(&config, "sync_2way", &common_data.sync_2way, 0);
    
    validateConfigBool(&config, "diff_commands", &common_data.diff_commands, 0);
    
    common_data.send_query = config_lookup(&config, "query") ? 1:0;
    if(common_data.send_query && ((conf_setting = config_lookup(&config, "query.trigger")) == NULL || 
    config_setting_is_array(conf_setting) == CONFIG_FALSE ||  (common_data.statusQueryLength = 
    config_setting_length(conf_setting)) == 0)) {
        syslog(LOG_ERR, "[ERROR] Setting is not present or not formatted as array: query.trigger");
        return EXIT_FAILURE;
    }
    if(common_data.send_query && validateConfigInt(&config, "query.interval", 
    &common_data.statusQueryInterval, -1, 0, 255, -1) == EXIT_FAILURE)
        return EXIT_FAILURE;
    
    /* Set volume (curve) functions */
    conf_value = NULL;
    config_lookup_string(&config, "volume.curve", &conf_value);
    if(!(common_data.volume = getVolume(&conf_value))) {
        syslog(LOG_ERR, "[Error] Volume curve is not recognised: %s", conf_value);
        return EXIT_FAILURE;
    }
    else {
        syslog(LOG_INFO, "[OK] volume.curve: %s", conf_value);
    }
    /* initialise volume variables */
    if(common_data.volume->init() == EXIT_FAILURE)
        return EXIT_FAILURE;
    
    /* Set and initialise process type */
    conf_value = NULL;
    config_lookup_string(&config, "data_type", &conf_value);
    if(!(common_data.process = getProcessMethod(&conf_value))) {
        syslog(LOG_ERR, "[Error] Setting 'data_type' is not recognised: %s", conf_value);
        return EXIT_FAILURE;
    }
    else {
        syslog(LOG_INFO, "[OK] data_type: %s", conf_value);
    }
    if(common_data.process->init() == EXIT_FAILURE)
        return EXIT_FAILURE;
    
    /* Set and initialise communication interface */
    conf_value = NULL;
    config_lookup_string(&config, "interface", &conf_value);
    if(!(common_data.interface = getInterface(&conf_value))) {
        syslog(LOG_ERR, "[Error] Setting 'interface' is not recognised: %s", conf_value);
        return EXIT_FAILURE;
    }
    else {
        syslog(LOG_INFO, "[OK] interface: %s", conf_value);
    }
    if(common_data.interface->init() == EXIT_FAILURE)
        return EXIT_FAILURE;
        
    /* initialise mixer device */
    if(initMixer() == EXIT_FAILURE)
        return EXIT_FAILURE;

    /* init multipliers */
    common_data.volume->regenerateMultipliers();

#ifndef DISABLE_MSQ
    /* initialise message queue */
    if(initMsQ() == EXIT_FAILURE)
        return EXIT_FAILURE;
#endif
    
    if((status = pthread_mutex_init(&lockConfig, NULL)) != 0) {
        syslog(LOG_ERR, "Failed to create config mutex: %i", status);
        return EXIT_FAILURE;
    }
    
    return EXIT_SUCCESS;
} /* end init */
static int init(void) {
    int count;
    int main_count;
    int int_setting = -1;
    char serial_command[200];
    const char *char_setting = NULL;
    ascii_data.volumeMutationNegative = NULL;
    ascii_data.volumeMutationPositive = NULL;
    
    for(main_count = 0; main_count <= common_data.diff_commands; main_count++)
    {
        if(validateConfigString(&config, "header", &ascii_data.command_header[main_count], main_count) == EXIT_FAILURE)
            return EXIT_FAILURE;
        ascii_data.header_length[main_count] = strlen(ascii_data.command_header[main_count]);
        if(validateConfigString(&config, "tail", &ascii_data.command_tail[main_count], main_count) == EXIT_FAILURE)
            return EXIT_FAILURE;
            
        if(common_data.sync_2way && (ascii_data.tail_length[main_count] = strlen(ascii_data.command_tail[main_count])) < 1) {
            syslog(LOG_ERR, "[Error] Setting 'tail' can not be empty");
            return EXIT_FAILURE;
        }
        if(validateConfigString(&config, "event_delimiter", &ascii_data.event_delimiter[main_count], main_count) == EXIT_FAILURE)
            return EXIT_FAILURE;
        ascii_data.event_delimiter_length[main_count] = strlen(ascii_data.event_delimiter[main_count]);
        if(validateConfigString(&config, "volume.header", &ascii_data.volume_header[main_count], main_count) == EXIT_FAILURE)
            return EXIT_FAILURE;
        if(validateConfigString(&config, "volume.tail", &ascii_data.volume_tail[main_count], main_count) == EXIT_FAILURE)
            return EXIT_FAILURE;
    }
    if(common_data.discrete_volume) {
        if(validateConfigInt(&config, "volume.precision", &ascii_data.volume_precision, -1, 0, 10, 0) == EXIT_FAILURE)
            return EXIT_FAILURE;
        if(validateConfigInt(&config, "volume.length", &ascii_data.volume_length, -1, 0, 10, 0) == EXIT_FAILURE)
            return EXIT_FAILURE;
        if(ascii_data.volume_precision) ascii_data.volume_length += ascii_data.volume_precision+1;
    }
    if(!common_data.discrete_volume) {
        if(validateConfigString(&config, "volume.min", &char_setting, -1) == EXIT_FAILURE)
            return EXIT_FAILURE;
        snprintf(serial_command, 200, "%s%s%s%s%s%s", 
            ascii_data.command_header[0], ascii_data.volume_header[0], 
            ascii_data.event_delimiter[0], char_setting, 
            ascii_data.volume_tail[0], ascii_data.command_tail[0]);
        ascii_data.volumeMutationNegative = calloc(strlen(serial_command)+1, sizeof(char));
        strcpy(ascii_data.volumeMutationNegative, serial_command);
            
        if(validateConfigString(&config, "volume.plus", &char_setting, -1) == EXIT_FAILURE)
            return EXIT_FAILURE;
        snprintf(serial_command, 200, "%s%s%s%s%s%s", 
            ascii_data.command_header[0], ascii_data.volume_header[0], 
            ascii_data.event_delimiter[0], char_setting, 
            ascii_data.volume_tail[0], ascii_data.command_tail[0]);
        ascii_data.volumeMutationPositive = calloc(strlen(serial_command)+1, sizeof(char));
        strcpy(ascii_data.volumeMutationPositive, serial_command);
    }
    
    if(common_data.volume_timeout) {
        if(smoothVolume.init(&sendSmoothVolumeCommand, (char *)ascii_data.volumeMutationNegative, (char *)ascii_data.volumeMutationPositive) == EXIT_FAILURE)
            return EXIT_FAILURE;
    }
    
    if(common_data.send_query && validateConfigString(&config, "query.trigger.[0]", &common_data.statusQuery, -1) == EXIT_FAILURE)
        return EXIT_FAILURE;
        if(common_data.send_query) common_data.statusQueryLength = strlen(common_data.statusQuery);

    if(config_lookup_string(&config, "response.indicator", &ascii_data.requestIndicator)) {
        ascii_data.allowRequests = 1;
        syslog(LOG_INFO, "[OK] response.indicator: %s", ascii_data.requestIndicator);
    } 
    else
        ascii_data.allowRequests = 0;
    
    if(common_data.mod->command) {
        if(common_data.mod->command->init(0) == EXIT_FAILURE)
            return EXIT_FAILURE;
    }
    
    return EXIT_SUCCESS;
} /* end init() */