int cmtspeech_create_source_output(struct userdata *u)
{
    pa_source_output_new_data data;
    char t[256];

    pa_assert(u);
    pa_assert(!u->source);
    ENTER();

    if (u->source_output) {
        pa_log_info("Create called but output already exists");
        return 1;
    }

    if (!(u->source = pa_namereg_get(u->core, u->source_name, PA_NAMEREG_SOURCE))) {
        pa_log_error("Couldn't find source %s", u->source_name);
        return 2;
    }

    if (cmtspeech_check_source_api(u->source))
        return 3;

    pa_source_output_new_data_init(&data);
    data.driver = __FILE__;
    data.module = u->module;
    data.source = u->source;
    snprintf(t, sizeof(t), "Cellular call up link");
    pa_proplist_sets(data.proplist, PA_PROP_MEDIA_NAME, t);
    snprintf(t, sizeof(t), "phone");
    pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, t);
    snprintf(t, sizeof(t), "cmtspeech module");
    pa_proplist_sets(data.proplist, PA_PROP_APPLICATION_NAME, t);
    pa_source_output_new_data_set_sample_spec(&data, &u->ss);
    pa_source_output_new_data_set_channel_map(&data, &u->map);
    data.flags = PA_SOURCE_OUTPUT_DONT_MOVE|PA_SOURCE_OUTPUT_START_CORKED;

    pa_source_output_new(&u->source_output, u->core, &data);
    pa_source_output_new_data_done(&data);

    if (!u->source_output) {
        pa_log("Creating cmtspeech source output failed");
        return -1;
    }

    u->source_output->push = cmtspeech_source_output_push_cb;
    u->source_output->kill = cmtspeech_source_output_kill_cb;
    u->source_output->attach = cmtspeech_source_output_attach_cb;
    u->source_output->detach = cmtspeech_source_output_detach_cb;
    u->source_output->moving = cmtspeech_source_output_moving_cb;
    u->source_output->state_change = cmtspeech_source_output_state_change_cb;
    u->source_output->may_move_to = cmtspeech_source_output_may_move_to_cb;
    u->source_output->userdata = u;

    pa_source_output_put(u->source_output);

    pa_log_info("cmtspeech source-output created");

    return 0;
}
pa_source *voice_get_original_master_source(struct userdata *u) {
    const char *om_name;
    pa_source *om_source;
    pa_assert(u);
    pa_assert(u->modargs);
    pa_assert(u->core);
    om_name = pa_modargs_get_value(u->modargs, "master_source", NULL);
    if (!om_name) {
        pa_log_error("Master source name not found from modargs!");
        return NULL;
    }
    if (!(om_source = pa_namereg_get(u->core, om_name, PA_NAMEREG_SOURCE))) {
        pa_log_error("Original master source \"%s\" not found", om_name);
        return NULL;
    }
    return om_source;
}
Example #3
0
int main(int argc, char *argv[]) {
    struct sockaddr_in sa;
#ifdef HAVE_IPV6
    struct sockaddr_in6 sa6;
#endif
    int fd;
    int r;

    if (!getenv("MAKE_CHECK"))
        pa_log_set_level(PA_LOG_DEBUG);

    fd = socket(PF_INET, SOCK_STREAM, 0);
    pa_assert(fd >= 0);

    sa.sin_family = AF_INET;
    sa.sin_port = htons(22);
    sa.sin_addr.s_addr = inet_addr("127.0.0.1");

    r = connect(fd, (struct sockaddr*) &sa, sizeof(sa));
    pa_assert(r >= 0);

    do_ip_acl_check("127.0.0.1", fd, 1);
    do_ip_acl_check("127.0.0.2/0", fd, 1);
    do_ip_acl_check("127.0.0.1/32", fd, 1);
    do_ip_acl_check("127.0.0.1/7", fd, 1);
    do_ip_acl_check("127.0.0.2", fd, 0);
    do_ip_acl_check("127.0.0.0/8;0.0.0.0/32", fd, 1);
    do_ip_acl_check("128.0.0.2/9", fd, 0);
    do_ip_acl_check("::1/9", fd, 0);

    close(fd);

#ifdef HAVE_IPV6
    if ( (fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0 ) {
      pa_log_error("Unable to open IPv6 socket, IPv6 tests ignored");
      return 0;
    }

    memset(&sa6, 0, sizeof(sa6));
    sa6.sin6_family = AF_INET6;
    sa6.sin6_port = htons(22);
    pa_assert_se(inet_pton(AF_INET6, "::1", &sa6.sin6_addr) == 1);

    r = connect(fd, (struct sockaddr*) &sa6, sizeof(sa6));
    pa_assert(r >= 0);

    do_ip_acl_check("::1", fd, 1);
    do_ip_acl_check("::1/9", fd, 1);
    do_ip_acl_check("::/0", fd, 1);
    do_ip_acl_check("::2/128", fd, 0);
    do_ip_acl_check("::2/127", fd, 0);
    do_ip_acl_check("::2/126", fd, 1);

    close(fd);
#endif

    return 0;
}
int cmtspeech_dbus_init(struct userdata *u, const char *dbus_type)
{
    struct cmtspeech_dbus_conn *e = &u->dbus_conn;
    DBusConnection          *dbusconn;
    DBusError                error;
    char                     rule[512];

    if (0 == strcasecmp(dbus_type, "system"))
	e->dbus_type = DBUS_BUS_SYSTEM;
    else
	e->dbus_type = DBUS_BUS_SESSION;

#define STRBUSTYPE(DBusType) ((DBusType) == DBUS_BUS_SYSTEM ? "system" : "session")

    pa_log_info("DBus connection to %s bus.", STRBUSTYPE(e->dbus_type));

    dbus_error_init(&error);
    e->dbus_conn = pa_dbus_bus_get(u->core, e->dbus_type, &error);

    if (e->dbus_conn == NULL || dbus_error_is_set(&error)) {
        pa_log_error("Failed to get %s Bus: %s: %s", STRBUSTYPE(e->dbus_type), error.name, error.message);
        goto fail;
    }

    memset(&e->dbus_match_rules, 0, sizeof(e->dbus_match_rules));
    dbusconn = pa_dbus_connection_get(e->dbus_conn);

    if (!dbus_connection_add_filter(dbusconn, cmtspeech_dbus_filter, u, NULL)) {
        pa_log("failed to add filter function");
        goto fail;
    }

    snprintf(rule, sizeof(rule), "type='signal',interface='%s'", CMTSPEECH_DBUS_CSCALL_CONNECT_IF);
    if (add_dbus_match(e, dbusconn, rule)) {
	goto fail;
    }

    snprintf(rule, sizeof(rule), "type='signal',interface='%s'", CMTSPEECH_DBUS_CSCALL_STATUS_IF);
    if (add_dbus_match(e, dbusconn, rule)) {
	goto fail;
    }

    snprintf(rule, sizeof(rule), "type='signal',interface='%s'", CMTSPEECH_DBUS_PHONE_SSC_STATE_IF);
    if (add_dbus_match(e, dbusconn, rule)) {
	goto fail;
    }

    snprintf(rule, sizeof(rule), "type='signal',interface='%s'", OFONO_DBUS_VOICECALL_IF);
    if (add_dbus_match(e, dbusconn, rule))
        goto fail;

    return 0;

 fail:
    cmtspeech_dbus_unload(u);
    dbus_error_free(&error);
    return -1;
}
static int detect_alsa(pa_core *c, int just_one) {
    FILE *f;
    int n = 0, n_sink = 0, n_source = 0;

    if (!(f = pa_fopen_cloexec("/proc/asound/devices", "r"))) {

        if (errno != ENOENT)
            pa_log_error("open(\"/proc/asound/devices\") failed: %s", pa_cstrerror(errno));

        return -1;
    }

    while (!feof(f)) {
        char line[64], args[64];
        unsigned device, subdevice;
        int is_sink;

        if (!fgets(line, sizeof(line), f))
            break;

        line[strcspn(line, "\r\n")] = 0;

        if (pa_endswith(line, "digital audio playback"))
            is_sink = 1;
        else if (pa_endswith(line, "digital audio capture"))
            is_sink = 0;
        else
            continue;

        if (just_one && is_sink && n_sink >= 1)
            continue;

        if (just_one && !is_sink && n_source >= 1)
            continue;

        if (sscanf(line, " %*i: [%u- %u]: ", &device, &subdevice) != 2)
            continue;

        /* Only one sink per device */
        if (subdevice != 0)
            continue;

        pa_snprintf(args, sizeof(args), "device_id=%u", device);
        if (!pa_module_load(c, is_sink ? "module-alsa-sink" : "module-alsa-source", args))
            continue;

        n++;

        if (is_sink)
            n_sink++;
        else
            n_source++;
    }

    fclose(f);

    return n;
}
int voice_parse_aep_steps(struct userdata *u, const char *steps)
{
    char *token;
    const char *state;
    int i = -1;
    int32_t step;
    int32_t old = 0;

    for (token = pa_split(steps, ",", &state); token; i ++)
    {
        if (i > (int)ARRAY_SIZE(u->aep_volume_steps.steps) - 1)
        {
            pa_log_error("Too many elements in aep volume steps table: %d > %d",
                         i + 1, ARRAY_SIZE(u->aep_volume_steps.steps));
            pa_xfree(token);
            goto error;
        }

        if (pa_atoi(token, &step))
        {
            pa_xfree(token);
            goto error;
        }

        if (i < 0)
            old = step;
        else
            u->aep_volume_steps.steps[i] = (old + step) / 2;

        pa_xfree(token);
    }

    u->aep_volume_steps.count = i;
    pa_log_info("AEP volume steps table read, %d steps found", i + 1);

    return 0;

error:

    pa_log_error("Error near token '%s' when parsing parameter %s: %s", token,
                 PA_NOKIA_PROP_AUDIO_AEP_mB_STEPS, steps);
    u->aep_volume_steps.count = 0;

    return -1;
}
Example #7
0
static int sco_listen(pa_bluetooth_transport *t) {
    struct transport_data *trd = t->userdata;
    struct sockaddr_sco addr;
    int sock, i;
    bdaddr_t src;
    const char *src_addr;

    sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO);
    if (sock < 0) {
        pa_log_error("socket(SEQPACKET, SCO) %s", pa_cstrerror(errno));
        return -1;
    }

    src_addr = t->device->adapter->address;

    /* don't use ba2str to avoid -lbluetooth */
    for (i = 5; i >= 0; i--, src_addr += 3)
        src.b[i] = strtol(src_addr, NULL, 16);

    /* Bind to local address */
    memset(&addr, 0, sizeof(addr));
    addr.sco_family = AF_BLUETOOTH;
    bacpy(&addr.sco_bdaddr, &src);

    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        pa_log_error("bind(): %s", pa_cstrerror(errno));
        goto fail_close;
    }

    pa_log_info ("doing listen");
    if (listen(sock, 1) < 0) {
        pa_log_error("listen(): %s", pa_cstrerror(errno));
        goto fail_close;
    }

    trd->sco_fd = sock;
    trd->sco_io = trd->mainloop->io_new(trd->mainloop, sock, PA_IO_EVENT_INPUT,
        sco_io_callback, t);

    return sock;

fail_close:
    close(sock);
    return -1;
}
static int detect_oss(pa_core *c, int just_one) {
    FILE *f;
    int n = 0, b = 0;

    if (!(f = pa_fopen_cloexec("/dev/sndstat", "r")) &&
        !(f = pa_fopen_cloexec("/proc/sndstat", "r")) &&
        !(f = pa_fopen_cloexec("/proc/asound/oss/sndstat", "r"))) {

        if (errno != ENOENT)
            pa_log_error("failed to open OSS sndstat device: %s", pa_cstrerror(errno));

        return -1;
    }

    while (!feof(f)) {
        char line[256], args[64];
        unsigned device;

        if (!fgets(line, sizeof(line), f))
            break;

        line[strcspn(line, "\r\n")] = 0;

        if (!b) {
            b = pa_streq(line, "Audio devices:") || pa_streq(line, "Installed devices:");
            continue;
        }

        if (line[0] == 0)
            break;

        if (sscanf(line, "%u: ", &device) == 1) {
            if (device == 0)
                pa_snprintf(args, sizeof(args), "device=/dev/dsp");
            else
                pa_snprintf(args, sizeof(args), "device=/dev/dsp%u", device);

            if (!pa_module_load(c, "module-oss", args))
                continue;

        } else if (sscanf(line, "pcm%u: ", &device) == 1) {
            /* FreeBSD support, the devices are named /dev/dsp0.0, dsp0.1 and so on */
            pa_snprintf(args, sizeof(args), "device=/dev/dsp%u.0", device);

            if (!pa_module_load(c, "module-oss", args))
                continue;
        }

        n++;

        if (just_one)
            break;
    }

    fclose(f);
    return n;
}
Example #9
0
OpusEncoder *tc_opus_create_encoder(int sample_rate, int channels, int bitrate)
{
   int err;

   OpusEncoder *encoder = opus_encoder_create(sample_rate, channels, OPUS_APPLICATION_AUDIO, &err);
   if (err<0){
      pa_log_error("failed to create an encoder: %s", opus_strerror(err));
      return NULL;
   }

   err = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(bitrate));
   if (err<0)
   {
      pa_log_error("failed to set bitrate: %s", opus_strerror(err));
      return NULL;
   }

   return encoder;
}
Example #10
0
void pa_fdsem_post(pa_fdsem *f) {
    pa_assert(f);

    if (pa_atomic_cmpxchg(&f->data->signalled, 0, 1)) {

        if (pa_atomic_load(&f->data->waiting)) {
            ssize_t r;
            char x = 'x';

            pa_atomic_inc(&f->data->in_pipe);

            for (;;) {

#ifdef HAVE_SYS_EVENTFD_H
                if (f->efd >= 0) {
                    uint64_t u = 1;

                    if ((r = pa_write(f->efd, &u, sizeof(u), NULL)) != sizeof(u)) {
                        if (r >= 0 || errno != EINTR) {
                            pa_log_error("Invalid write to eventfd: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
                            pa_assert_not_reached();
                        }

                        continue;
                    }
                } else
#endif

                    if ((r = pa_write(f->fds[1], &x, 1, NULL)) != 1) {
                        if (r >= 0 || errno != EINTR) {
                            pa_log_error("Invalid write to pipe: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
                            pa_assert_not_reached();
                        }

                        continue;
                    }

                break;
            }
        }
    }
}
int cmtspeech_check_source_api(pa_source *s) {
    if (strcmp(PA_PROP_SOURCE_API_EXTENSION_PROPERTY_VALUE,
                pa_strnull(pa_proplist_gets(s->proplist, PA_PROP_SOURCE_API_EXTENSION_PROPERTY_NAME)))) {
        pa_log_error("Source \"%s\" does not support %s version %s", s->name,
                     PA_PROP_SOURCE_API_EXTENSION_PROPERTY_NAME,
                     PA_PROP_SOURCE_API_EXTENSION_PROPERTY_VALUE);
        pa_log_debug("'%s' != '%s'", PA_PROP_SOURCE_API_EXTENSION_PROPERTY_VALUE,
                     pa_strnull(pa_proplist_gets(s->proplist, PA_PROP_SOURCE_API_EXTENSION_PROPERTY_NAME)));
        return -1;
    }
    return 0;
}
Example #12
0
OpusDecoder *tc_opus_create_decoder(int sample_rate, int channels)
{
   int err;

   OpusDecoder * decoder = opus_decoder_create(sample_rate, channels, &err);
   if (err<0) {
      pa_log_error("failed to create decoder: %s", opus_strerror(err));
      return NULL;
   }

   return decoder;
}
Example #13
0
int pa_sndfile_read_sample_spec(SNDFILE *sf, pa_sample_spec *ss) {
    SF_INFO sfi;
    int sf_errno;

    pa_assert(sf);
    pa_assert(ss);

    pa_zero(sfi);
    if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
        pa_log_error("sndfile: %s", sf_error_number(sf_errno));
        return -1;
    }

    switch (sfi.format & SF_FORMAT_SUBMASK) {

        case SF_FORMAT_PCM_16:
        case SF_FORMAT_PCM_U8:
        case SF_FORMAT_PCM_S8:
            ss->format = PA_SAMPLE_S16NE;
            break;

        case SF_FORMAT_PCM_24:
            ss->format = PA_SAMPLE_S24NE;
            break;

        case SF_FORMAT_PCM_32:
            ss->format = PA_SAMPLE_S32NE;
            break;

        case SF_FORMAT_ULAW:
            ss->format = PA_SAMPLE_ULAW;
            break;

        case SF_FORMAT_ALAW:
            ss->format = PA_SAMPLE_ALAW;
            break;

        case SF_FORMAT_FLOAT:
        case SF_FORMAT_DOUBLE:
        default:
            ss->format = PA_SAMPLE_FLOAT32NE;
            break;
    }

    ss->rate = (uint32_t) sfi.samplerate;
    ss->channels = (uint8_t) sfi.channels;

    if (!pa_sample_spec_valid(ss))
        return -1;

    return 0;
}
Example #14
0
int pa_iochannel_creds_enable(pa_iochannel *io) {
    int t = 1;

    pa_assert(io);
    pa_assert(io->ifd >= 0);

    if (setsockopt(io->ifd, SOL_SOCKET, SO_PASSCRED, &t, sizeof(t)) < 0) {
        pa_log_error("setsockopt(SOL_SOCKET, SO_PASSCRED): %s", pa_cstrerror(errno));
        return -1;
    }

    return 0;
}
Example #15
0
static void flush(pa_fdsem *f) {
    ssize_t r;
    pa_assert(f);

    if (pa_atomic_load(&f->data->in_pipe) <= 0)
        return;

    do {
        char x[10];

#ifdef HAVE_SYS_EVENTFD_H
        if (f->efd >= 0) {
            uint64_t u;

            if ((r = pa_read(f->efd, &u, sizeof(u), NULL)) != sizeof(u)) {

                if (r >= 0 || errno != EINTR) {
                    pa_log_error("Invalid read from eventfd: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
                    pa_assert_not_reached();
                }

                continue;
            }
            r = (ssize_t) u;
        } else
#endif

            if ((r = pa_read(f->fds[0], &x, sizeof(x), NULL)) <= 0) {

                if (r >= 0 || errno != EINTR) {
                    pa_log_error("Invalid read from pipe: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
                    pa_assert_not_reached();
                }

                continue;
            }

    } while (pa_atomic_sub(&f->data->in_pipe, (int) r) > (int) r);
}
static char *card_get_sysattr(const char *card_idx, const char *name) {
    struct udev *udev;
    struct udev_device *card = NULL;
    char *t, *r = NULL;
    const char *v;

    pa_assert(card_idx);
    pa_assert(name);

    if (!(udev = udev_new())) {
        pa_log_error("Failed to allocate udev context.");
        goto finish;
    }

    t = pa_sprintf_malloc("/sys/class/sound/card%s", card_idx);
    card = udev_device_new_from_syspath(udev, t);
    pa_xfree(t);

    if (!card) {
        pa_log_error("Failed to get card object.");
        goto finish;
    }

    if ((v = udev_device_get_sysattr_value(card, name)) && *v)
        r = pa_xstrdup(v);

finish:

    if (card)
        udev_device_unref(card);

    if (udev)
        udev_unref(udev);

    return r;
}
Example #17
0
static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
    pa_bluetooth_transport *t = userdata;

    pa_assert(io);
    pa_assert(t);

    if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) {
        pa_log_info("Lost RFCOMM connection.");
        goto fail;
    }

    if (events & PA_IO_EVENT_INPUT) {
        char buf[512];
        ssize_t len;
        int gain;

        len = read(fd, buf, 511);
        buf[len] = 0;
        pa_log_debug("RFCOMM << %s", buf);

        if (sscanf(buf, "AT+VGS=%d", &gain) == 1) {
          t->speaker_gain = gain;
          pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED), t);

        } else if (sscanf(buf, "AT+VGM=%d", &gain) == 1) {
          t->microphone_gain = gain;
          pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED), t);
        }

        pa_log_debug("RFCOMM >> OK");

        len = write(fd, "\r\nOK\r\n", 6);

        /* we ignore any errors, it's not critical and real errors should
         * be caught with the HANGUP and ERROR events handled above */
        if (len < 0)
            pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
    }

    return;

fail:
    pa_bluetooth_transport_unlink(t);
    pa_bluetooth_transport_free(t);
    return;
}
Example #18
0
static void set_microphone_gain(pa_bluetooth_transport *t, uint16_t gain) {
    struct transport_rfcomm *trfc = t->userdata;
    char buf[512];
    ssize_t len, written;

    if (t->microphone_gain == gain)
      return;

    t->microphone_gain = gain;

    len = sprintf(buf, "\r\n+VGM=%d\r\n", gain);
    pa_log_debug("RFCOMM >> +VGM=%d", gain);

    written = write (trfc->rfcomm_fd, buf, len);

    if (written != len)
        pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
}
/* parse sidetone configuration file parameters */
sidetone_args* sidetone_args_new(const char *args) {

    pa_modargs* ma = NULL;
    sidetone_args* st_args = NULL;
    int count = 0 ;

    st_args = pa_xnew0(sidetone_args, 1);
    st_args->steps=pa_xnew0(struct mv_volume_steps, 1);
    ma = pa_modargs_new(args, valid_modargs);
    if(!ma) {
        pa_log_error("Failed to parse module arguments");
        goto fail;
    }

    st_args->modargs = ma;

    if(!(st_args->mixer = pa_modargs_get_value(ma, "mixer", NULL))) {
        pa_log_error("Failed to read mixer name");
        goto fail;
    }


    if(!(st_args->control_element = pa_modargs_get_value(ma, "control_element", NULL))) {
        pa_log_error("Failed to parse control element");
        goto fail;
    }


    if( !(st_args->master_sink = pa_modargs_get_value(ma, "master_sink", NULL))) {
        pa_log_error("Failed to parse master sink name");
        goto fail;
    }


    if(!(st_args->mainvolume = pa_modargs_get_value(ma, "mainvolume", NULL))) {
        pa_log_error("failed to search volume string");
    }

    count = parse_volume_steps(st_args->steps, st_args->mainvolume);
    if (count < 1) {
        pa_log_error("failed to parse call steps; %s", st_args->mainvolume);
        goto fail;
    }

    return st_args;

fail:

    sidetone_args_free(st_args);

    return NULL;
}
int voice_init_voip_sink(struct userdata *u, const char *name) {
    pa_sink_new_data sink_data;
    pa_assert(u);
    pa_assert(u->core);
    pa_assert(u->master_sink);
    ENTER();

    pa_sink_new_data_init(&sink_data);
    sink_data.module = u->module;
    sink_data.driver = __FILE__;
    pa_sink_new_data_set_name(&sink_data, name);
    pa_sink_new_data_set_sample_spec(&sink_data, &u->aep_sample_spec);
    pa_sink_new_data_set_channel_map(&sink_data, &u->aep_channel_map);
    pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "%s connected conceptually to %s", name, u->raw_sink->name);
    pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, u->raw_sink->name);
    pa_proplist_sets(sink_data.proplist, "module-suspend-on-idle.timeout", "1");

    pa_proplist_sets(sink_data.proplist, PA_PROP_SINK_API_EXTENSION_PROPERTY_NAME,
                     PA_PROP_SINK_API_EXTENSION_PROPERTY_VALUE);

    u->voip_sink = pa_sink_new(u->core, &sink_data,
                               (u->master_sink->flags & (PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY)) | PA_SINK_SHARE_VOLUME_WITH_MASTER);

    pa_sink_new_data_done(&sink_data);

    /* Create sink */
    if (!u->voip_sink) {
        pa_log_error("Failed to create sink.");
        return -1;
    }

    u->voip_sink->parent.process_msg = voip_sink_process_msg;
    u->voip_sink->set_state = voip_sink_set_state;
    u->voip_sink->update_requested_latency = voip_sink_update_requested_latency;
    u->voip_sink->request_rewind = voip_sink_request_rewind;
    u->voip_sink->userdata = u;
    pa_memblock_ref(u->aep_silence_memchunk.memblock);
    u->voip_sink->silence = u->aep_silence_memchunk;

    pa_sink_set_asyncmsgq(u->voip_sink, u->master_sink->asyncmsgq);
    pa_sink_set_rtpoll(u->voip_sink, u->master_sink->thread_info.rtpoll);

    return 0;
}
Example #21
0
static void sco_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
    pa_bluetooth_transport *t = userdata;

    pa_assert(io);
    pa_assert(t);

    if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) {
        pa_log_error("error listening SCO connection: %s", pa_cstrerror(errno));
        goto fail;
    }

    if (t->state != PA_BLUETOOTH_TRANSPORT_STATE_PLAYING) {
        pa_log_info("SCO incoming connection: changing state to PLAYING");
        pa_bluetooth_transport_set_state (t, PA_BLUETOOTH_TRANSPORT_STATE_PLAYING);
    }

fail:
    return;
}
Example #22
0
int tc_opus_encode(OpusEncoder *encoder, unsigned char *pcm_bytes, unsigned char *cbits, int channels, int frame_size)
{
      int i;
      int nbBytes;
      opus_int16 in[frame_size*channels];

      /* Convert from little-endian ordering. */
      for (i=0;i<channels*frame_size;i++)
         in[i]=pcm_bytes[2*i+1]<<8|pcm_bytes[2*i];


      nbBytes = opus_encode(encoder, in, frame_size, cbits, frame_size*channels*2);
      if (nbBytes<0)
      {
         pa_log_error("encode failed: %s", opus_strerror(nbBytes));
         return EXIT_FAILURE;
      }

      return nbBytes;
}
int pa__init(pa_module *m) {
    struct userdata *u = NULL;

    u = pa_xnew0(struct userdata, 1);
    m->userdata = u;

    u->mode_sink = pa_namereg_get(m->core, "sink.hw0", PA_NAMEREG_SINK);
    if (!u->mode_sink) {
        pa_log_error("sink.hw0 not found");
        pa_xfree(u);
        m->userdata = NULL;
        return -1;
    }

    run_basic_tests(u);
    run_modifier_tests(u);

    pa_module_unload_request(m, TRUE);
    return 0;
}
Example #24
0
int tc_opus_decode(OpusDecoder *decoder, unsigned char *cbits, int nbBytes, unsigned char *pcm_bytes, int channels, int max_frame_size)
{
      int err=0, i;
      opus_int16 out[max_frame_size*channels];

      int frame_size = opus_decode(decoder, cbits, nbBytes, out, max_frame_size, 0);
      if (frame_size<0)
      {
         pa_log_error("decoder failed: %s", opus_strerror(err));
         return EXIT_FAILURE;
      }

      /* Convert to little-endian ordering. */
      for(i=0;i<channels*frame_size;i++)
      {
         pcm_bytes[2*i]=out[i]&0xFF;
         pcm_bytes[2*i+1]=(out[i]>>8)&0xFF;
      }

      return frame_size;
}
Example #25
0
static int sco_do_accept(pa_bluetooth_transport *t) {
    struct transport_data *trd = t->userdata;
    struct sockaddr_sco addr;
    socklen_t optlen;
    int sock;

    memset(&addr, 0, sizeof(addr));
    optlen = sizeof(addr);

    pa_log_info ("doing accept");
    sock = accept(trd->sco_fd, (struct sockaddr *) &addr, &optlen);
    if (sock < 0) {
        if (errno != EAGAIN)
            pa_log_error("accept(): %s", pa_cstrerror(errno));
        goto fail;
    }
    return sock;

fail:
    return -1;
}
/* Called from I/O thread context */
static int voip_sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
    struct userdata *u = PA_SINK(o)->userdata;

    switch (code) {

    case VOICE_SINK_GET_SIDE_INFO_QUEUE_PTR: {
        /* TODO: Make sure there is only one client (or multiple queues) */
        if (!u->dl_sideinfo_queue) {
            pa_log_warn("Side info queue not set");
        }
        *((pa_queue **) data) = u->dl_sideinfo_queue;
        pa_log_debug("Side info queue (%p) passed to client", (void *) u->dl_sideinfo_queue);
        return 0;
    }

    case PA_SINK_MESSAGE_GET_LATENCY: {
        pa_usec_t usec = 0;

        if (PA_MSGOBJECT(u->raw_sink)->process_msg(PA_MSGOBJECT(u->raw_sink), PA_SINK_MESSAGE_GET_LATENCY, &usec, (int64_t)0, NULL) < 0)
            usec = 0;

        *((pa_usec_t*) data) = usec;
        return 0;
    }

    case PA_SINK_MESSAGE_ADD_INPUT: {
        pa_sink_input *i = PA_SINK_INPUT(data);
        if (i == u->hw_sink_input) {
            pa_log_error("Denied loop connection");
            // TODO: How to deny connection...
            return -1;
        }
        // Pass trough to pa_sink_process_msg
        break;
    }

    }

    return pa_sink_process_msg(o, code, data, offset, chunk);
}
static int add_dbus_match(struct cmtspeech_dbus_conn *e, DBusConnection *dbusconn, char *match)
{
    DBusError error;
    uint i;

    dbus_error_init(&error);

    for(i = 0; i < PA_ELEMENTSOF(e->dbus_match_rules) && e->dbus_match_rules[i] != NULL; i++);

    pa_return_val_if_fail (i < PA_ELEMENTSOF(e->dbus_match_rules), -1);

    dbus_bus_add_match(dbusconn, match, &error);
    if (dbus_error_is_set(&error)) {
        pa_log_error("Unable to add dbus match:\"%s\": %s: %s", match, error.name, error.message);
        return -1;;
    }

    e->dbus_match_rules[i] = pa_xstrdup(match);
    pa_log_debug("added dbus match \"%s\"", match);

    return 0;
}
Example #28
0
void pa_ltdl_init(void) {

#ifdef PA_BIND_NOW
    const lt_dlvtable *dlopen_loader;
#endif

    pa_assert_se(lt_dlinit() == 0);

#ifdef PA_BIND_NOW
    /* Already initialised */
    if (bindnow_loader)
        return;

    if (!(dlopen_loader = lt_dlloader_find((char*) "lt_dlopen"))) {
        pa_log_warn(_("Failed to find original lt_dlopen loader."));
        return;
    }

    if (!(bindnow_loader = malloc(sizeof(lt_dlvtable)))) {
        pa_log_error(_("Failed to allocate new dl loader."));
        return;
    }

    memcpy(bindnow_loader, dlopen_loader, sizeof(*bindnow_loader));
    bindnow_loader->name = "bind-now-loader";
    bindnow_loader->module_open = bind_now_open;
    bindnow_loader->module_close = bind_now_close;
    bindnow_loader->find_sym = bind_now_find_sym;
    bindnow_loader->priority = LT_DLLOADER_PREPEND;

    /* Add our BIND_NOW loader as the default module loader. */
    if (lt_dlloader_add(bindnow_loader) != 0) {
        pa_log_warn(_("Failed to add bind-now-loader."));
        free(bindnow_loader);
        bindnow_loader = NULL;
    }
#endif
}
int voice_init_raw_source(struct userdata *u, const char *name) {
    pa_source_new_data data;
    ENTER();

    pa_assert(u);
    pa_assert(u->master_source);

    pa_source_new_data_init(&data);
    data.driver = __FILE__;
    data.module = u->module;
    pa_source_new_data_set_name(&data, name);
    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "%s source connected to %s", name, u->master_source->name);
    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, u->master_source->name);
    pa_proplist_sets(data.proplist, "module-suspend-on-idle.timeout", "1");

    pa_source_new_data_set_sample_spec(&data, &u->hw_sample_spec);
    pa_source_new_data_set_channel_map(&data, &u->stereo_map);

    u->raw_source = pa_source_new(u->core, &data, u->master_source->flags &
                                  (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY));
    pa_source_new_data_done(&data);

    if (!u->raw_source) {
        pa_log_error("Failed to create source.");
        return -1;
    }

    u->raw_source->parent.process_msg = raw_source_process_msg;
    u->raw_source->set_state = raw_source_set_state;
    u->raw_source->update_requested_latency = raw_source_update_requested_latency;
    u->raw_source->userdata = u;
    pa_source_set_asyncmsgq(u->raw_source, u->master_source->asyncmsgq);
    pa_source_set_rtpoll(u->raw_source, u->master_source->thread_info.rtpoll);

    return 0;
}
Example #30
0
int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
    int r = -1;
    FILE *f = NULL;
    struct channel_conf_info ci;
    pa_config_item table[] = {
        { "daemonize",                  pa_config_parse_bool,     &c->daemonize, NULL },
        { "fail",                       pa_config_parse_bool,     &c->fail, NULL },
        { "high-priority",              pa_config_parse_bool,     &c->high_priority, NULL },
        { "realtime-scheduling",        pa_config_parse_bool,     &c->realtime_scheduling, NULL },
        { "disallow-module-loading",    pa_config_parse_bool,     &c->disallow_module_loading, NULL },
        { "allow-module-loading",       pa_config_parse_not_bool, &c->disallow_module_loading, NULL },
        { "disallow-exit",              pa_config_parse_bool,     &c->disallow_exit, NULL },
        { "allow-exit",                 pa_config_parse_not_bool, &c->disallow_exit, NULL },
        { "use-pid-file",               pa_config_parse_bool,     &c->use_pid_file, NULL },
        { "system-instance",            pa_config_parse_bool,     &c->system_instance, NULL },
#ifdef HAVE_DBUS
        { "local-server-type",          parse_server_type,        c, NULL },
#endif
        { "no-cpu-limit",               pa_config_parse_bool,     &c->no_cpu_limit, NULL },
        { "cpu-limit",                  pa_config_parse_not_bool, &c->no_cpu_limit, NULL },
        { "disable-shm",                pa_config_parse_bool,     &c->disable_shm, NULL },
        { "enable-shm",                 pa_config_parse_not_bool, &c->disable_shm, NULL },
        { "enable-memfd",               pa_config_parse_not_bool, &c->disable_memfd, NULL },
        { "flat-volumes",               pa_config_parse_bool,     &c->flat_volumes, NULL },
        { "lock-memory",                pa_config_parse_bool,     &c->lock_memory, NULL },
        { "enable-deferred-volume",     pa_config_parse_bool,     &c->deferred_volume, NULL },
        { "exit-idle-time",             pa_config_parse_int,      &c->exit_idle_time, NULL },
        { "scache-idle-time",           pa_config_parse_int,      &c->scache_idle_time, NULL },
        { "realtime-priority",          parse_rtprio,             c, NULL },
        { "dl-search-path",             pa_config_parse_string,   &c->dl_search_path, NULL },
        { "default-script-file",        pa_config_parse_string,   &c->default_script_file, NULL },
        { "log-target",                 parse_log_target,         c, NULL },
        { "log-level",                  parse_log_level,          c, NULL },
        { "verbose",                    parse_log_level,          c, NULL },
        { "resample-method",            parse_resample_method,    c, NULL },
        { "default-sample-format",      parse_sample_format,      c, NULL },
        { "default-sample-rate",        parse_sample_rate,        c, NULL },
        { "alternate-sample-rate",      parse_alternate_sample_rate, c, NULL },
        { "default-sample-channels",    parse_sample_channels,    &ci,  NULL },
        { "default-channel-map",        parse_channel_map,        &ci,  NULL },
        { "default-fragments",          parse_fragments,          c, NULL },
        { "default-fragment-size-msec", parse_fragment_size_msec, c, NULL },
        { "deferred-volume-safety-margin-usec",
                                        pa_config_parse_unsigned, &c->deferred_volume_safety_margin_usec, NULL },
        { "deferred-volume-extra-delay-usec",
                                        pa_config_parse_int,      &c->deferred_volume_extra_delay_usec, NULL },
        { "nice-level",                 parse_nice_level,         c, NULL },
        { "avoid-resampling",           pa_config_parse_bool,     &c->avoid_resampling, NULL },
        { "disable-remixing",           pa_config_parse_bool,     &c->disable_remixing, NULL },
        { "enable-remixing",            pa_config_parse_not_bool, &c->disable_remixing, NULL },
        { "remixing-use-all-sink-channels",
                                        pa_config_parse_bool,     &c->remixing_use_all_sink_channels, NULL },
        { "disable-lfe-remixing",       pa_config_parse_bool,     &c->disable_lfe_remixing, NULL },
        { "enable-lfe-remixing",        pa_config_parse_not_bool, &c->disable_lfe_remixing, NULL },
        { "lfe-crossover-freq",         pa_config_parse_unsigned, &c->lfe_crossover_freq, NULL },
        { "load-default-script-file",   pa_config_parse_bool,     &c->load_default_script_file, NULL },
        { "shm-size-bytes",             pa_config_parse_size,     &c->shm_size, NULL },
        { "log-meta",                   pa_config_parse_bool,     &c->log_meta, NULL },
        { "log-time",                   pa_config_parse_bool,     &c->log_time, NULL },
        { "log-backtrace",              pa_config_parse_unsigned, &c->log_backtrace, NULL },
#ifdef HAVE_SYS_RESOURCE_H
        { "rlimit-fsize",               parse_rlimit,             &c->rlimit_fsize, NULL },
        { "rlimit-data",                parse_rlimit,             &c->rlimit_data, NULL },
        { "rlimit-stack",               parse_rlimit,             &c->rlimit_stack, NULL },
        { "rlimit-core",                parse_rlimit,             &c->rlimit_core, NULL },
#ifdef RLIMIT_RSS
        { "rlimit-rss",                 parse_rlimit,             &c->rlimit_rss, NULL },
#endif
#ifdef RLIMIT_NOFILE
        { "rlimit-nofile",              parse_rlimit,             &c->rlimit_nofile, NULL },
#endif
#ifdef RLIMIT_AS
        { "rlimit-as",                  parse_rlimit,             &c->rlimit_as, NULL },
#endif
#ifdef RLIMIT_NPROC
        { "rlimit-nproc",               parse_rlimit,             &c->rlimit_nproc, NULL },
#endif
#ifdef RLIMIT_MEMLOCK
        { "rlimit-memlock",             parse_rlimit,             &c->rlimit_memlock, NULL },
#endif
#ifdef RLIMIT_LOCKS
        { "rlimit-locks",               parse_rlimit,             &c->rlimit_locks, NULL },
#endif
#ifdef RLIMIT_SIGPENDING
        { "rlimit-sigpending",          parse_rlimit,             &c->rlimit_sigpending, NULL },
#endif
#ifdef RLIMIT_MSGQUEUE
        { "rlimit-msgqueue",            parse_rlimit,             &c->rlimit_msgqueue, NULL },
#endif
#ifdef RLIMIT_NICE
        { "rlimit-nice",                parse_rlimit,             &c->rlimit_nice, NULL },
#endif
#ifdef RLIMIT_RTPRIO
        { "rlimit-rtprio",              parse_rlimit,             &c->rlimit_rtprio, NULL },
#endif
#ifdef RLIMIT_RTTIME
        { "rlimit-rttime",              parse_rlimit,             &c->rlimit_rttime, NULL },
#endif
#endif
        { NULL,                         NULL,                     NULL, NULL },
    };

    pa_xfree(c->config_file);
    c->config_file = NULL;

    f = filename ?
        pa_fopen_cloexec(c->config_file = pa_xstrdup(filename), "r") :
        pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file);

    if (!f && errno != ENOENT) {
        pa_log_warn(_("Failed to open configuration file: %s"), pa_cstrerror(errno));
        goto finish;
    }

    ci.default_channel_map_set = ci.default_sample_spec_set = false;
    ci.conf = c;

    r = f ? pa_config_parse(c->config_file, f, table, NULL, true, NULL) : 0;

    if (r >= 0) {

        /* Make sure that channel map and sample spec fit together */

        if (ci.default_sample_spec_set &&
            ci.default_channel_map_set &&
            c->default_channel_map.channels != c->default_sample_spec.channels) {
            pa_log_error(_("The specified default channel map has a different number of channels than the specified default number of channels."));
            r = -1;
            goto finish;
        } else if (ci.default_sample_spec_set)
            pa_channel_map_init_extend(&c->default_channel_map, c->default_sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
        else if (ci.default_channel_map_set)
            c->default_sample_spec.channels = c->default_channel_map.channels;
    }

finish:
    if (f)
        fclose(f);

    return r;
}