Share via


Escenario de RFCOMM: Enviar un archivo como cliente (HTML)

[ Este artículo está destinado a desarrolladores de Windows 8.x y Windows Phone 8.x que escriben aplicaciones de Windows en tiempo de ejecución. Si estás desarrollando para Windows 10, consulta la documentación más reciente

El escenario de aplicación básico consiste en conectarse a un dispositivo emparejado según el dispositivo que se desee. En este escenario, el desarrollador puede usar las funciones RfcommDeviceService.GetDeviceSelector* para generar una consulta AQS que puede servir para enumerar las instancias de dispositivo emparejado del servicio que se desee. A partir de ahí, el desarrollador de la aplicación elige uno de los dispositivos enumerados, crea un RfcommDeviceService y lee los atributos SDP según sea necesario (utilizando established data helpers para analizar los datos del atributo). Luego, el desarrollador de la aplicación puede crear un socket y usar las propiedades ConnectionHostName y ConnectionServiceName de RfcommDeviceService para conectarse de forma asincrónica (ConnectAsync) al servicio de dispositivo remoto con los parámetros correspondientes. Cuando llegue el momento de enviar un archivo, el desarrollador de la aplicación puede seguir los patrones establecidos de flujo de datos para leer fragmentos de datos del archivo y enviarlo al dispositivo en el OutputStream del socket.

var _service;    // Windows.Devices.Bluetooth.RfcommDeviceService
var _socket;     // Windows.Networking.Sockets.StreamSocket

function Initialize() {
    // Enumerate devices with the object push service
    Windows.Devices.Enumeration.DeviceInformation.findAllAsync(
        RfcommDeviceService.getDeviceSelector(
            RfcommServiceId.obexObjectPush))
    .done(function(services) {
        if (services.length > 0) {
            // Initialize the target Bluetooth BR device
            RfcommDeviceService.fromIdAsync(services[0].id)
            .done(function(service) {
                // Check that the service meets this App’s minimum
                // requirement
                if (SupportsProtection(service)
                    && IsCompatibleVersion(service))
                {
                    _service = service;

                    // Create a socket and connect to the target
                    _socket = new StreamSocket();
                    _socket.connectAsync(
                        _service.connectionHostName,
                        _service.connectionServiceName,
                        SocketProtectionLevel
                            .bluetoothEncryptionAllowNullAuthentication)
                    .done(function () {
                        // The socket is connected. At this point the App can
                        // wait for the user to take some action, e.g. click
                        // a button to send a file to the device, which could
                        // invoke the Picker and then send the picked file.
                        // The transfer itself would use the Sockets API and
                        // not the Rfcomm API, and so is omitted here for
                        // brevity.
                    });
                }
            });
        }
    });
}

// This App requires a connection that is encrypted but does not care about
// whether its authenticated.
function SupportsProtection(service)
{
    switch (service.protectionLevel)
    {
    case SocketProtectionLevel.plainSocket:
        if ((service.maximumProtectionLevel == SocketProtectionLevel
                .bluetoothEncryptionWithAuthentication)
            || (service.maximumProtectionLevel == SocketProtectionLevel
                .bluetoothEncryptionAllowNullAuthentication)
        {
            // The connection can be upgraded when opening the socket so the
            // App may offer UI here to notify the user that Windows may
            // prompt for a PIN exchange.
            return true;
        }
        else
        {
            // The connection cannot be upgraded so an App may offer UI here
            // to explain why a connection won’t be made.
            return false;
        }
    case SocketProtectionLevel.bluetoothEncryptionWithAuthentication:
        return true;
    case SocketProtectionLevel.bluetoothEncryptionAllowNullAuthentication:
        return true;
    }
    return false;
}

// This App relies on CRC32 checking available in version 2.0 of the service.
var SERVICE_VERSION_ATTRIBUTE_ID = 0x0300;
var byte SERVICE_VERSION_ATTRIBUTE_TYPE = 0x0A;   // UINT32
var MINIMUM_SERVICE_VERSION = 200;
function IsCompatibleVersion(service)
{
    service.getSdpRawAttributesAsync(BluetoothCacheMode.Uncached)
    .done(function(attributes) {
        var attribute = attributes[SERVICE_VERSION_ATTRIBUTE_ID];
        var reader = DataReader.fromBuffer(attribute);

        // The first byte contains the attribute's type
        var attributeType = reader.readByte();
        if (attributeType == SERVICE_VERSION_ATTRIBUTE_TYPE)
        {
            // The remainder is the data
            var version = reader.uint32();
            return version >= MINIMUM_SERVICE_VERSION;
        }
    });
}