0

I'm using the Bluecove library to devolep an Obex ftp client/server on android 2.X. So far i managed to connect as a client from android to a pc. I tried the bluecove example code for a server but doesn't work. Is it possible to develop a server on android 2.X. Does any one have the code to do it. Thank you.

1 Answer 1

0
public class OBEXServer implements Runnable {

    private SessionNotifier serverConnection;

    private boolean isStoped = false;

    private boolean isRunning = false;

    public final UUID OBEX_OBJECT_PUSH = new UUID(0x1105);

    public static final String SERVER_NAME = "OBEX Object Push";

    private UserInteraction interaction;

    private OBEXServer(UserInteraction interaction) {
        this.interaction = interaction;
    }

    public static OBEXServer startServer(UserInteraction interaction) {
        OBEXServer srv = new OBEXServer(interaction);
        Thread thread = new Thread(srv);
        thread.start();
        while (!srv.isRunning && !srv.isStoped) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new Error(e);
            }
        }
        if (!srv.isRunning) {
            throw new Error("Can't start server");
        }
        return srv;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    public void run() {
        isStoped = false;
        LocalDevice localDevice;
        try {
            localDevice = LocalDevice.getLocalDevice();
            if (!localDevice.setDiscoverable(DiscoveryAgent.GIAC)) {
                Logger.error("Fail to set LocalDevice Discoverable");
            }
            serverConnection = (SessionNotifier) Connector.open("btgoep://localhost:" + OBEX_OBJECT_PUSH + ";name="
                    + SERVER_NAME);
        } catch (Throwable e) {
            Logger.error("OBEX Server start error", e);
            isStoped = true;
            return;
        }

        try {
            ServiceRecord record = localDevice.getRecord(serverConnection);
            String url = record.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
            Logger.debug("BT server url: " + url);

            final int OBJECT_TRANSFER_SERVICE = 0x100000;

            try {
                record.setDeviceServiceClasses(OBJECT_TRANSFER_SERVICE);
            } catch (Throwable e) {
                Logger.debug("setDeviceServiceClasses", e);
            }

            DataElement bluetoothProfileDescriptorList = new DataElement(DataElement.DATSEQ);
            DataElement obbexPushProfileDescriptor = new DataElement(DataElement.DATSEQ);
            obbexPushProfileDescriptor.addElement(new DataElement(DataElement.UUID, OBEX_OBJECT_PUSH));
            obbexPushProfileDescriptor.addElement(new DataElement(DataElement.U_INT_2, 0x100));
            bluetoothProfileDescriptorList.addElement(obbexPushProfileDescriptor);
            record.setAttributeValue(0x0009, bluetoothProfileDescriptorList);

            final short ATTR_SUPPORTED_FORMAT_LIST_LIST = 0x0303;
            DataElement supportedFormatList = new DataElement(DataElement.DATSEQ);
            // any type of object.
            supportedFormatList.addElement(new DataElement(DataElement.U_INT_1, 0xFF));
            record.setAttributeValue(ATTR_SUPPORTED_FORMAT_LIST_LIST, supportedFormatList);

            final short UUID_PUBLICBROWSE_GROUP = 0x1002;
            final short ATTR_BROWSE_GRP_LIST = 0x0005;
            DataElement browseClassIDList = new DataElement(DataElement.DATSEQ);
            UUID browseClassUUID = new UUID(UUID_PUBLICBROWSE_GROUP);
            browseClassIDList.addElement(new DataElement(DataElement.UUID, browseClassUUID));
            record.setAttributeValue(ATTR_BROWSE_GRP_LIST, browseClassIDList);

            localDevice.updateRecord(record);
        } catch (Throwable e) {
            Logger.error("Updating SDP", e);
        }

        try {
            int errorCount = 0;
            int count = 0;
            isRunning = true;
            while (!isStoped) {
                RequestHandler handler = new RequestHandler();
                try {
                    count++;
                    Logger.debug("Accepting OBEX connections");
                    handler.connectionAccepted(serverConnection.acceptAndOpen(handler));
                } catch (InterruptedIOException e) {
                    isStoped = true;
                    break;
                } catch (Throwable e) {
                    if ("Stack closed".equals(e.getMessage())) {
                        isStoped = true;
                    }
                    if (isStoped) {
                        return;
                    }
                    errorCount++;
                    Logger.error("acceptAndOpen ", e);
                    continue;
                }
                errorCount = 0;
            }
        } finally {
            close();
            Logger.debug("OBEX Server finished!");
            isRunning = false;
        }
    }

    public void close() {
        isStoped = true;
        try {
            if (serverConnection != null) {
                serverConnection.close();
            }
            Logger.debug("OBEX ServerConnection closed");
        } catch (Throwable e) {
            Logger.error("OBEX Server stop error", e);
        }
    }

    private static File homePath() {
        String path = "bluetooth";
        boolean isWindows = false;
        String sysName = System.getProperty("os.name");
        if (sysName != null) {
            sysName = sysName.toLowerCase();
            if (sysName.indexOf("windows") != -1) {
                isWindows = true;
                path = "My Documents";
            }
        }
        File dir;
        try {
            dir = new File(System.getProperty("user.home"), path);
            if (!dir.exists()) {
                if (!dir.mkdirs()) {
                    throw new SecurityException();
                }
            }
        } catch (SecurityException e) {
            dir = new File(new File(System.getProperty("java.io.tmpdir"), System.getProperty("user.name")), path);
        }
        if (isWindows) {
            dir = new File(dir, "Bluetooth Exchange Folder");
        }
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                return null;
            }
        } else if (!dir.isDirectory()) {
            dir.delete();
            if (!dir.mkdirs()) {
                return null;
            }
        }
        return dir;
    }

    private void showStatus(final String message) {
        interaction.showStatus(message);
    }

    private class RequestHandler extends ServerRequestHandler {

        Timer notConnectedTimer = new Timer();

        boolean isConnected = false;

        boolean receivedOk = false;

        Connection cconn;

        void connectionAccepted(Connection cconn) {
            Logger.debug("Received OBEX connection");
            showStatus("Client connected");
            this.cconn = cconn;
            if (!isConnected) {
                notConnectedTimer.schedule(new TimerTask() {
                    public void run() {
                        notConnectedClose();
                    }
                }, 1000 * 30);
            }
        }

        void notConnectedClose() {
            if (!isConnected) {
                Logger.debug("OBEX connection timeout");
                try {
                    cconn.close();
                } catch (IOException e) {
                }
                if (!receivedOk) {
                    showStatus("Disconnected");
                }
            }
        }

        public int onConnect(HeaderSet request, HeaderSet reply) {
            isConnected = true;
            notConnectedTimer.cancel();
            Logger.debug("OBEX onConnect");
            return ResponseCodes.OBEX_HTTP_OK;
        }

        public void onDisconnect(HeaderSet request, HeaderSet reply) {
            Logger.debug("OBEX onDisconnect");
            if (!receivedOk) {
                showStatus("Disconnected");
            }
        }

        public int onSetPath(HeaderSet request, HeaderSet reply, boolean backup, boolean create) {
            Logger.debug("OBEX onSetPath");
            return super.onSetPath(request, reply, backup, create);
        }

        public int onDelete(HeaderSet request, HeaderSet reply) {
            Logger.debug("OBEX onDelete");
            return super.onDelete(request, reply);
        }

        public int onPut(Operation op) {
            Logger.debug("OBEX onPut");
            try {
                HeaderSet hs = op.getReceivedHeaders();
                String name = (String) hs.getHeader(HeaderSet.NAME);
                if (name != null) {
                    Logger.debug("name:" + name);
                    showStatus("Receiving " + name);
                } else {
                    name = "xxx.xx";
                    showStatus("Receiving file");
                }
                Long len = (Long) hs.getHeader(HeaderSet.LENGTH);
                if (len != null) {
                    Logger.debug("file lenght:" + len);
                    interaction.setProgressValue(0);
                    interaction.setProgressMaximum(len.intValue());
                }
                File f = new File(homePath(), name);
                FileOutputStream out = new FileOutputStream(f);
                InputStream is = op.openInputStream();

                int received = 0;

                while (!isStoped) {
                    int data = is.read();
                    if (data == -1) {
                        Logger.debug("EOS received");
                        break;
                    }
                    out.write(data);
                    received++;
                    if ((len != null) && (received % 100 == 0)) {
                        interaction.setProgressValue(received);
                    }
                }
                op.close();
                out.close();
                Logger.debug("file saved:" + f.getAbsolutePath());
                showStatus("Received " + name);
                receivedOk = true;
                return ResponseCodes.OBEX_HTTP_OK;
            } catch (IOException e) {
                Logger.error("OBEX Server onPut error", e);
                return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
            } finally {
                Logger.debug("OBEX onPut ends");
                interaction.setProgressDone();
            }
        }

        public int onGet(Operation op) {
            Logger.debug("OBEX onGet");
            try {
                HeaderSet hs = op.getReceivedHeaders();
                String name = (String) hs.getHeader(HeaderSet.NAME);

                return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;

            } catch (IOException e) {
                Logger.error("OBEX Server onGet error", e);
                return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
            } finally {
                Logger.debug("OBEX onGet ends");
            }
        }

        public void onAuthenticationFailure(byte[] userName) {
            Logger.debug("OBEX AuthFailure " + new String(userName));
        }

    }
}
1
  • Just need to implement the specific methods as shown in the specification of the Bluetooth GOEP profile. Simple Commented Nov 22, 2011 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.