예제 #1
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;
}
예제 #2
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, dummy;
        bool  do_reply = false;

        len = pa_read(fd, buf, 511, NULL);
        if (len < 0) {
            pa_log_error("RFCOMM read error: %s", pa_cstrerror(errno));
            goto fail;
        }
        buf[len] = 0;
        pa_log_debug("RFCOMM << %s", buf);

        /* There are only four HSP AT commands:
         * AT+VGS=value: value between 0 and 15, sent by the HS to AG to set the speaker gain.
         * +VGS=value is sent by AG to HS as a response to an AT+VGS command or when the gain
         * is changed on the AG side.
         * AT+VGM=value: value between 0 and 15, sent by the HS to AG to set the microphone gain.
         * +VGM=value is sent by AG to HS as a response to an AT+VGM command or when the gain
         * is changed on the AG side.
         * AT+CKPD=200: Sent by HS when headset button is pressed.
         * RING: Sent by AG to HS to notify of an incoming call. It can safely be ignored because
         * it does not expect a reply. */
        if (sscanf(buf, "AT+VGS=%d", &gain) == 1 || sscanf(buf, "\r\n+VGM=%d\r\n", &gain) == 1) {
            t->speaker_gain = gain;
            pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED), t);
            do_reply = true;

        } else if (sscanf(buf, "AT+VGM=%d", &gain) == 1 || sscanf(buf, "\r\n+VGS=%d\r\n", &gain) == 1) {
            t->microphone_gain = gain;
            pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED), t);
            do_reply = true;
        } else if (sscanf(buf, "AT+CKPD=%d", &dummy) == 1) {
            do_reply = true;
        } else {
            do_reply = false;
        }

        if (do_reply) {
            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);
}