ServerSession.java revision 0d376053747615ac7c4b45ab7810329ffbdf80d1
1/*
2 * Copyright (c) 2008-2009, Motorola, Inc.
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * - Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * - Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * - Neither the name of the Motorola, Inc. nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33package javax.obex;
34
35import android.util.Log;
36
37import java.io.InputStream;
38import java.io.IOException;
39import java.io.OutputStream;
40
41/**
42 * This class in an implementation of the OBEX ServerSession.
43 * @hide
44 */
45public final class ServerSession extends ObexSession implements Runnable {
46
47    private static final String TAG = "Obex ServerSession";
48
49    private ObexTransport mTransport;
50
51    private InputStream mInput;
52
53    private OutputStream mOutput;
54
55    private ServerRequestHandler mListener;
56
57    private Thread mProcessThread;
58
59    private int mMaxPacketLength;
60
61    private boolean mClosed;
62
63    /**
64     * Creates new ServerSession.
65     * @param trans the connection to the client
66     * @param handler the event listener that will process requests
67     * @param auth the authenticator to use with this connection
68     * @throws IOException if an error occurred while opening the input and
69     *         output streams
70     */
71    public ServerSession(ObexTransport trans, ServerRequestHandler handler, Authenticator auth)
72            throws IOException {
73        mAuthenticator = auth;
74        mTransport = trans;
75        mInput = mTransport.openInputStream();
76        mOutput = mTransport.openOutputStream();
77        mListener = handler;
78        mMaxPacketLength = 256;
79
80        mClosed = false;
81        mProcessThread = new Thread(this);
82        mProcessThread.start();
83    }
84
85    /**
86     * Processes requests made to the server and forwards them to the
87     * appropriate event listener.
88     */
89    public void run() {
90        try {
91
92            boolean done = false;
93            while (!done && !mClosed) {
94                int requestType = mInput.read();
95                switch (requestType) {
96                    case ObexHelper.OBEX_OPCODE_CONNECT:
97                        handleConnectRequest();
98                        break;
99
100                    case ObexHelper.OBEX_OPCODE_DISCONNECT:
101                        handleDisconnectRequest();
102                        done = true;
103                        break;
104
105                    case ObexHelper.OBEX_OPCODE_GET:
106                    case ObexHelper.OBEX_OPCODE_GET_FINAL:
107                        handleGetRequest(requestType);
108                        break;
109
110                    case ObexHelper.OBEX_OPCODE_PUT:
111                    case ObexHelper.OBEX_OPCODE_PUT_FINAL:
112                        handlePutRequest(requestType);
113                        break;
114
115                    case ObexHelper.OBEX_OPCODE_SETPATH:
116                        handleSetPathRequest();
117                        break;
118                    case ObexHelper.OBEX_OPCODE_ABORT:
119                        handleAbortRequest();
120                        break;
121
122                    case -1:
123                        done = true;
124                        break;
125
126                    default:
127
128                        /*
129                         * Received a request type that is not recognized so I am
130                         * just going to read the packet and send a not implemented
131                         * to the client
132                         */
133                        int length = mInput.read();
134                        length = (length << 8) + mInput.read();
135                        for (int i = 3; i < length; i++) {
136                            mInput.read();
137                        }
138                        sendResponse(ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED, null);
139                }
140            }
141
142        } catch (NullPointerException e) {
143            Log.d(TAG, e.toString());
144        } catch (Exception e) {
145            Log.d(TAG, e.toString());
146        }
147        close();
148    }
149
150    /**
151     * Handles a ABORT request from a client. This method will read the rest of
152     * the request from the client. Assuming the request is valid, it will
153     * create a <code>HeaderSet</code> object to pass to the
154     * <code>ServerRequestHandler</code> object. After the handler processes the
155     * request, this method will create a reply message to send to the server.
156     *
157     * @throws IOException if an error occurred at the transport layer
158     */
159    private void handleAbortRequest() throws IOException {
160        int code = ResponseCodes.OBEX_HTTP_OK;
161        HeaderSet request = new HeaderSet();
162        HeaderSet reply = new HeaderSet();
163
164        int length = mInput.read();
165        length = (length << 8) + mInput.read();
166        if (length > ObexHelper.MAX_PACKET_SIZE_INT) {
167            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
168        } else {
169            for (int i = 3; i < length; i++) {
170                mInput.read();
171            }
172            code = mListener.onAbort(request, reply);
173            Log.v(TAG, "onAbort request handler return value- " + code);
174            code = validateResponseCode(code);
175        }
176        sendResponse(code, null);
177    }
178
179    /**
180     * Handles a PUT request from a client. This method will provide a
181     * <code>ServerOperation</code> object to the request handler. The
182     * <code>ServerOperation</code> object will handle the rest of the request.
183     * It will also send replies and receive requests until the final reply
184     * should be sent. When the final reply should be sent, this method will get
185     * the response code to use and send the reply. The
186     * <code>ServerOperation</code> object will always reply with a
187     * OBEX_HTTP_CONTINUE reply. It will only reply if further information is
188     * needed.
189     * @param type the type of request received; either 0x02 or 0x82
190     * @throws IOException if an error occurred at the transport layer
191     */
192    private void handlePutRequest(int type) throws IOException {
193        ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
194        try {
195            int response = -1;
196
197            if ((op.finalBitSet) && !op.isValidBody()) {
198                response = validateResponseCode(mListener
199                        .onDelete(op.requestHeader, op.replyHeader));
200            } else {
201                response = validateResponseCode(mListener.onPut(op));
202            }
203            if (response != ResponseCodes.OBEX_HTTP_OK && !op.isAborted) {
204                op.sendReply(response);
205            } else if (!op.isAborted) {
206                // wait for the final bit
207                while (!op.finalBitSet) {
208                    op.sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
209                }
210                op.sendReply(response);
211            }
212        } catch (Exception e) {
213            /*To fix bugs in aborted cases,
214             *(client abort file transfer prior to the last packet which has the end of body header,
215             *internal error should not be sent because server has already replied with
216             *OK response in "sendReply")
217             */
218            if (!op.isAborted) {
219                sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
220            }
221        }
222    }
223
224    /**
225     * Handles a GET request from a client. This method will provide a
226     * <code>ServerOperation</code> object to the request handler. The
227     * <code>ServerOperation</code> object will handle the rest of the request.
228     * It will also send replies and receive requests until the final reply
229     * should be sent. When the final reply should be sent, this method will get
230     * the response code to use and send the reply. The
231     * <code>ServerOperation</code> object will always reply with a
232     * OBEX_HTTP_CONTINUE reply. It will only reply if further information is
233     * needed.
234     * @param type the type of request received; either 0x03 or 0x83
235     * @throws IOException if an error occurred at the transport layer
236     */
237    private void handleGetRequest(int type) throws IOException {
238        ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
239        try {
240            int response = validateResponseCode(mListener.onGet(op));
241
242            if (!op.isAborted) {
243                op.sendReply(response);
244            }
245        } catch (Exception e) {
246            sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
247        }
248    }
249
250    /**
251     * Send standard response.
252     * @param code the response code to send
253     * @param header the headers to include in the response
254     * @throws IOException if an IO error occurs
255     */
256    public void sendResponse(int code, byte[] header) throws IOException {
257        int totalLength = 3;
258        byte[] data = null;
259        OutputStream op = mOutput;
260        if (op == null) {
261            return;
262        }
263
264        if (header != null) {
265            totalLength += header.length;
266            data = new byte[totalLength];
267            data[0] = (byte)code;
268            data[1] = (byte)(totalLength >> 8);
269            data[2] = (byte)totalLength;
270            System.arraycopy(header, 0, data, 3, header.length);
271        } else {
272            data = new byte[totalLength];
273            data[0] = (byte)code;
274            data[1] = (byte)0x00;
275            data[2] = (byte)totalLength;
276        }
277        op.write(data);
278        op.flush();
279    }
280
281    /**
282     * Handles a SETPATH request from a client. This method will read the rest
283     * of the request from the client. Assuming the request is valid, it will
284     * create a <code>HeaderSet</code> object to pass to the
285     * <code>ServerRequestHandler</code> object. After the handler processes the
286     * request, this method will create a reply message to send to the server
287     * with the response code provided.
288     * @throws IOException if an error occurred at the transport layer
289     */
290    private void handleSetPathRequest() throws IOException {
291        int length;
292        int flags;
293        @SuppressWarnings("unused")
294        int constants;
295        int totalLength = 3;
296        byte[] head = null;
297        int code = -1;
298        int bytesReceived;
299        HeaderSet request = new HeaderSet();
300        HeaderSet reply = new HeaderSet();
301
302        length = mInput.read();
303        length = (length << 8) + mInput.read();
304        flags = mInput.read();
305        constants = mInput.read();
306
307        if (length > ObexHelper.MAX_PACKET_SIZE_INT) {
308            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
309            totalLength = 3;
310        } else {
311            if (length > 5) {
312                byte[] headers = new byte[length - 5];
313                bytesReceived = mInput.read(headers);
314
315                while (bytesReceived != headers.length) {
316                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
317                            - bytesReceived);
318                }
319
320                ObexHelper.updateHeaderSet(request, headers);
321
322                if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
323                    mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
324                } else {
325                    mListener.setConnectionId(1);
326                }
327                // the Auth chan is initiated by the server, client sent back the authResp .
328                if (request.mAuthResp != null) {
329                    if (!handleAuthResp(request.mAuthResp)) {
330                        code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
331                        mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
332                                request.mAuthResp));
333                    }
334                    request.mAuthResp = null;
335                }
336            }
337
338            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
339                // the Auth challenge is initiated by the client
340                // the server will send back the authResp to the client
341                if (request.mAuthChall != null) {
342                    handleAuthChall(request);
343                    reply.mAuthResp = new byte[request.mAuthResp.length];
344                    System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0,
345                            reply.mAuthResp.length);
346                    request.mAuthChall = null;
347                    request.mAuthResp = null;
348                }
349                boolean backup = false;
350                boolean create = true;
351                if (!((flags & 1) == 0)) {
352                    backup = true;
353                }
354                if (!((flags & 2) == 0)) {
355                    create = false;
356                }
357
358                try {
359                    code = mListener.onSetPath(request, reply, backup, create);
360                } catch (Exception e) {
361                    sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
362                    return;
363                }
364
365                code = validateResponseCode(code);
366
367                if (reply.nonce != null) {
368                    mChallengeDigest = new byte[16];
369                    System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16);
370                } else {
371                    mChallengeDigest = null;
372                }
373
374                long id = mListener.getConnectionId();
375                if (id == -1) {
376                    reply.mConnectionID = null;
377                } else {
378                    reply.mConnectionID = ObexHelper.convertToByteArray(id);
379                }
380
381                head = ObexHelper.createHeader(reply, false);
382                totalLength += head.length;
383
384                if (totalLength > mMaxPacketLength) {
385                    totalLength = 3;
386                    head = null;
387                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
388                }
389            }
390        }
391
392        // Compute Length of OBEX SETPATH packet
393        byte[] replyData = new byte[totalLength];
394        replyData[0] = (byte)code;
395        replyData[1] = (byte)(totalLength >> 8);
396        replyData[2] = (byte)totalLength;
397        if (head != null) {
398            System.arraycopy(head, 0, replyData, 3, head.length);
399        }
400        /*
401         * Write the OBEX SETPATH packet to the server. Byte 0: response code
402         * Byte 1&2: Connect Packet Length Byte 3 to n: headers
403         */
404        mOutput.write(replyData);
405        mOutput.flush();
406    }
407
408    /**
409     * Handles a disconnect request from a client. This method will read the
410     * rest of the request from the client. Assuming the request is valid, it
411     * will create a <code>HeaderSet</code> object to pass to the
412     * <code>ServerRequestHandler</code> object. After the handler processes the
413     * request, this method will create a reply message to send to the server.
414     * @throws IOException if an error occurred at the transport layer
415     */
416    private void handleDisconnectRequest() throws IOException {
417        int length;
418        int code = ResponseCodes.OBEX_HTTP_OK;
419        int totalLength = 3;
420        byte[] head = null;
421        int bytesReceived;
422        HeaderSet request = new HeaderSet();
423        HeaderSet reply = new HeaderSet();
424
425        length = mInput.read();
426        length = (length << 8) + mInput.read();
427
428        if (length > ObexHelper.MAX_PACKET_SIZE_INT) {
429            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
430            totalLength = 3;
431        } else {
432            if (length > 3) {
433                byte[] headers = new byte[length - 3];
434                bytesReceived = mInput.read(headers);
435
436                while (bytesReceived != headers.length) {
437                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
438                            - bytesReceived);
439                }
440
441                ObexHelper.updateHeaderSet(request, headers);
442            }
443
444            if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
445                mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
446            } else {
447                mListener.setConnectionId(1);
448            }
449
450            if (request.mAuthResp != null) {
451                if (!handleAuthResp(request.mAuthResp)) {
452                    code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
453                    mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
454                            request.mAuthResp));
455                }
456                request.mAuthResp = null;
457            }
458
459            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
460
461                if (request.mAuthChall != null) {
462                    handleAuthChall(request);
463                    request.mAuthChall = null;
464                }
465
466                try {
467                    mListener.onDisconnect(request, reply);
468                } catch (Exception e) {
469                    sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
470                    return;
471                }
472
473                long id = mListener.getConnectionId();
474                if (id == -1) {
475                    reply.mConnectionID = null;
476                } else {
477                    reply.mConnectionID = ObexHelper.convertToByteArray(id);
478                }
479
480                head = ObexHelper.createHeader(reply, false);
481                totalLength += head.length;
482
483                if (totalLength > mMaxPacketLength) {
484                    totalLength = 3;
485                    head = null;
486                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
487                }
488            }
489        }
490
491        // Compute Length of OBEX CONNECT packet
492        byte[] replyData;
493        if (head != null) {
494            replyData = new byte[3 + head.length];
495        } else {
496            replyData = new byte[3];
497        }
498        replyData[0] = (byte)code;
499        replyData[1] = (byte)(totalLength >> 8);
500        replyData[2] = (byte)totalLength;
501        if (head != null) {
502            System.arraycopy(head, 0, replyData, 3, head.length);
503        }
504        /*
505         * Write the OBEX DISCONNECT packet to the server. Byte 0: response code
506         * Byte 1&2: Connect Packet Length Byte 3 to n: headers
507         */
508        mOutput.write(replyData);
509        mOutput.flush();
510    }
511
512    /**
513     * Handles a connect request from a client. This method will read the rest
514     * of the request from the client. Assuming the request is valid, it will
515     * create a <code>HeaderSet</code> object to pass to the
516     * <code>ServerRequestHandler</code> object. After the handler processes the
517     * request, this method will create a reply message to send to the server
518     * with the response code provided.
519     * @throws IOException if an error occurred at the transport layer
520     */
521    private void handleConnectRequest() throws IOException {
522        int packetLength;
523        @SuppressWarnings("unused")
524        int version;
525        @SuppressWarnings("unused")
526        int flags;
527        int totalLength = 7;
528        byte[] head = null;
529        int code = -1;
530        HeaderSet request = new HeaderSet();
531        HeaderSet reply = new HeaderSet();
532        int bytesReceived;
533
534        /*
535         * Read in the length of the OBEX packet, OBEX version, flags, and max
536         * packet length
537         */
538        packetLength = mInput.read();
539        packetLength = (packetLength << 8) + mInput.read();
540        version = mInput.read();
541        flags = mInput.read();
542        mMaxPacketLength = mInput.read();
543        mMaxPacketLength = (mMaxPacketLength << 8) + mInput.read();
544
545        // should we check it?
546        if (mMaxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) {
547            mMaxPacketLength = ObexHelper.MAX_PACKET_SIZE_INT;
548        }
549
550        if (packetLength > ObexHelper.MAX_PACKET_SIZE_INT) {
551            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
552            totalLength = 7;
553        } else {
554            if (packetLength > 7) {
555                byte[] headers = new byte[packetLength - 7];
556                bytesReceived = mInput.read(headers);
557
558                while (bytesReceived != headers.length) {
559                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
560                            - bytesReceived);
561                }
562
563                ObexHelper.updateHeaderSet(request, headers);
564            }
565
566            if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
567                mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
568            } else {
569                mListener.setConnectionId(1);
570            }
571
572            if (request.mAuthResp != null) {
573                if (!handleAuthResp(request.mAuthResp)) {
574                    code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
575                    mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
576                            request.mAuthResp));
577                }
578                request.mAuthResp = null;
579            }
580
581            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
582                if (request.mAuthChall != null) {
583                    handleAuthChall(request);
584                    reply.mAuthResp = new byte[request.mAuthResp.length];
585                    System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0,
586                            reply.mAuthResp.length);
587                    request.mAuthChall = null;
588                    request.mAuthResp = null;
589                }
590
591                try {
592                    code = mListener.onConnect(request, reply);
593                    code = validateResponseCode(code);
594
595                    if (reply.nonce != null) {
596                        mChallengeDigest = new byte[16];
597                        System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16);
598                    } else {
599                        mChallengeDigest = null;
600                    }
601                    long id = mListener.getConnectionId();
602                    if (id == -1) {
603                        reply.mConnectionID = null;
604                    } else {
605                        reply.mConnectionID = ObexHelper.convertToByteArray(id);
606                    }
607
608                    head = ObexHelper.createHeader(reply, false);
609                    totalLength += head.length;
610
611                    if (totalLength > mMaxPacketLength) {
612                        totalLength = 7;
613                        head = null;
614                        code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
615                    }
616                } catch (Exception e) {
617                    e.printStackTrace();
618                    totalLength = 7;
619                    head = null;
620                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
621                }
622
623            }
624        }
625
626        // Compute Length of OBEX CONNECT packet
627        byte[] length = ObexHelper.convertToByteArray(totalLength);
628
629        /*
630         * Write the OBEX CONNECT packet to the server. Byte 0: response code
631         * Byte 1&2: Connect Packet Length Byte 3: OBEX Version Number
632         * (Presently, 0x10) Byte 4: Flags (For TCP 0x00) Byte 5&6: Max OBEX
633         * Packet Length (Defined in MAX_PACKET_SIZE) Byte 7 to n: headers
634         */
635        byte[] sendData = new byte[totalLength];
636        sendData[0] = (byte)code;
637        sendData[1] = length[2];
638        sendData[2] = length[3];
639        sendData[3] = (byte)0x10;
640        sendData[4] = (byte)0x00;
641        sendData[5] = (byte)(ObexHelper.MAX_PACKET_SIZE_INT >> 8);
642        sendData[6] = (byte)(ObexHelper.MAX_PACKET_SIZE_INT & 0xFF);
643
644        if (head != null) {
645            System.arraycopy(head, 0, sendData, 7, head.length);
646        }
647
648        mOutput.write(sendData);
649        mOutput.flush();
650    }
651
652    /**
653     * Closes the server session - in detail close I/O streams and the
654     * underlying transport layer. Internal flag is also set so that later
655     * attempt to read/write will throw an exception.
656     */
657    public synchronized void close() {
658        if (mListener != null) {
659            mListener.onClose();
660        }
661        try {
662            mInput.close();
663            mOutput.close();
664            mTransport.close();
665            mClosed = true;
666        } catch (Exception e) {
667        }
668        mTransport = null;
669        mInput = null;
670        mOutput = null;
671        mListener = null;
672    }
673
674    /**
675     * Verifies that the response code is valid. If it is not valid, it will
676     * return the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code.
677     * @param code the response code to check
678     * @return the valid response code or <code>OBEX_HTTP_INTERNAL_ERROR</code>
679     *         if <code>code</code> is not valid
680     */
681    private int validateResponseCode(int code) {
682
683        if ((code >= ResponseCodes.OBEX_HTTP_OK) && (code <= ResponseCodes.OBEX_HTTP_PARTIAL)) {
684            return code;
685        }
686        if ((code >= ResponseCodes.OBEX_HTTP_MULT_CHOICE)
687                && (code <= ResponseCodes.OBEX_HTTP_USE_PROXY)) {
688            return code;
689        }
690        if ((code >= ResponseCodes.OBEX_HTTP_BAD_REQUEST)
691                && (code <= ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE)) {
692            return code;
693        }
694        if ((code >= ResponseCodes.OBEX_HTTP_INTERNAL_ERROR)
695                && (code <= ResponseCodes.OBEX_HTTP_VERSION)) {
696            return code;
697        }
698        if ((code >= ResponseCodes.OBEX_DATABASE_FULL)
699                && (code <= ResponseCodes.OBEX_DATABASE_LOCKED)) {
700            return code;
701        }
702        return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
703    }
704
705}
706