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
260        if (header != null) {
261            totalLength += header.length;
262            data = new byte[totalLength];
263            data[0] = (byte)code;
264            data[1] = (byte)(totalLength >> 8);
265            data[2] = (byte)totalLength;
266            System.arraycopy(header, 0, data, 3, header.length);
267        } else {
268            data = new byte[totalLength];
269            data[0] = (byte)code;
270            data[1] = (byte)0x00;
271            data[2] = (byte)totalLength;
272        }
273        mOutput.write(data);
274        mOutput.flush();
275    }
276
277    /**
278     * Handles a SETPATH request from a client. This method will read the rest
279     * of the request from the client. Assuming the request is valid, it will
280     * create a <code>HeaderSet</code> object to pass to the
281     * <code>ServerRequestHandler</code> object. After the handler processes the
282     * request, this method will create a reply message to send to the server
283     * with the response code provided.
284     * @throws IOException if an error occurred at the transport layer
285     */
286    private void handleSetPathRequest() throws IOException {
287        int length;
288        int flags;
289        @SuppressWarnings("unused")
290        int constants;
291        int totalLength = 3;
292        byte[] head = null;
293        int code = -1;
294        int bytesReceived;
295        HeaderSet request = new HeaderSet();
296        HeaderSet reply = new HeaderSet();
297
298        length = mInput.read();
299        length = (length << 8) + mInput.read();
300        flags = mInput.read();
301        constants = mInput.read();
302
303        if (length > ObexHelper.MAX_PACKET_SIZE_INT) {
304            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
305            totalLength = 3;
306        } else {
307            if (length > 5) {
308                byte[] headers = new byte[length - 5];
309                bytesReceived = mInput.read(headers);
310
311                while (bytesReceived != headers.length) {
312                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
313                            - bytesReceived);
314                }
315
316                ObexHelper.updateHeaderSet(request, headers);
317
318                if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
319                    mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
320                } else {
321                    mListener.setConnectionId(1);
322                }
323                // the Auth chan is initiated by the server, client sent back the authResp .
324                if (request.mAuthResp != null) {
325                    if (!handleAuthResp(request.mAuthResp)) {
326                        code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
327                        mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
328                                request.mAuthResp));
329                    }
330                    request.mAuthResp = null;
331                }
332            }
333
334            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
335                // the Auth challenge is initiated by the client
336                // the server will send back the authResp to the client
337                if (request.mAuthChall != null) {
338                    handleAuthChall(request);
339                    reply.mAuthResp = new byte[request.mAuthResp.length];
340                    System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0,
341                            reply.mAuthResp.length);
342                    request.mAuthChall = null;
343                    request.mAuthResp = null;
344                }
345                boolean backup = false;
346                boolean create = true;
347                if (!((flags & 1) == 0)) {
348                    backup = true;
349                }
350                if (!((flags & 2) == 0)) {
351                    create = false;
352                }
353
354                try {
355                    code = mListener.onSetPath(request, reply, backup, create);
356                } catch (Exception e) {
357                    sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
358                    return;
359                }
360
361                code = validateResponseCode(code);
362
363                if (reply.nonce != null) {
364                    mChallengeDigest = new byte[16];
365                    System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16);
366                } else {
367                    mChallengeDigest = null;
368                }
369
370                long id = mListener.getConnectionId();
371                if (id == -1) {
372                    reply.mConnectionID = null;
373                } else {
374                    reply.mConnectionID = ObexHelper.convertToByteArray(id);
375                }
376
377                head = ObexHelper.createHeader(reply, false);
378                totalLength += head.length;
379
380                if (totalLength > mMaxPacketLength) {
381                    totalLength = 3;
382                    head = null;
383                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
384                }
385            }
386        }
387
388        // Compute Length of OBEX SETPATH packet
389        byte[] replyData = new byte[totalLength];
390        replyData[0] = (byte)code;
391        replyData[1] = (byte)(totalLength >> 8);
392        replyData[2] = (byte)totalLength;
393        if (head != null) {
394            System.arraycopy(head, 0, replyData, 3, head.length);
395        }
396        /*
397         * Write the OBEX SETPATH packet to the server. Byte 0: response code
398         * Byte 1&2: Connect Packet Length Byte 3 to n: headers
399         */
400        mOutput.write(replyData);
401        mOutput.flush();
402    }
403
404    /**
405     * Handles a disconnect request from a client. This method will read the
406     * rest of the request from the client. Assuming the request is valid, it
407     * will create a <code>HeaderSet</code> object to pass to the
408     * <code>ServerRequestHandler</code> object. After the handler processes the
409     * request, this method will create a reply message to send to the server.
410     * @throws IOException if an error occurred at the transport layer
411     */
412    private void handleDisconnectRequest() throws IOException {
413        int length;
414        int code = ResponseCodes.OBEX_HTTP_OK;
415        int totalLength = 3;
416        byte[] head = null;
417        int bytesReceived;
418        HeaderSet request = new HeaderSet();
419        HeaderSet reply = new HeaderSet();
420
421        length = mInput.read();
422        length = (length << 8) + mInput.read();
423
424        if (length > ObexHelper.MAX_PACKET_SIZE_INT) {
425            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
426            totalLength = 3;
427        } else {
428            if (length > 3) {
429                byte[] headers = new byte[length - 3];
430                bytesReceived = mInput.read(headers);
431
432                while (bytesReceived != headers.length) {
433                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
434                            - bytesReceived);
435                }
436
437                ObexHelper.updateHeaderSet(request, headers);
438            }
439
440            if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
441                mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
442            } else {
443                mListener.setConnectionId(1);
444            }
445
446            if (request.mAuthResp != null) {
447                if (!handleAuthResp(request.mAuthResp)) {
448                    code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
449                    mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
450                            request.mAuthResp));
451                }
452                request.mAuthResp = null;
453            }
454
455            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
456
457                if (request.mAuthChall != null) {
458                    handleAuthChall(request);
459                    request.mAuthChall = null;
460                }
461
462                try {
463                    mListener.onDisconnect(request, reply);
464                } catch (Exception e) {
465                    sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
466                    return;
467                }
468
469                long id = mListener.getConnectionId();
470                if (id == -1) {
471                    reply.mConnectionID = null;
472                } else {
473                    reply.mConnectionID = ObexHelper.convertToByteArray(id);
474                }
475
476                head = ObexHelper.createHeader(reply, false);
477                totalLength += head.length;
478
479                if (totalLength > mMaxPacketLength) {
480                    totalLength = 3;
481                    head = null;
482                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
483                }
484            }
485        }
486
487        // Compute Length of OBEX CONNECT packet
488        byte[] replyData;
489        if (head != null) {
490            replyData = new byte[3 + head.length];
491        } else {
492            replyData = new byte[3];
493        }
494        replyData[0] = (byte)code;
495        replyData[1] = (byte)(totalLength >> 8);
496        replyData[2] = (byte)totalLength;
497        if (head != null) {
498            System.arraycopy(head, 0, replyData, 3, head.length);
499        }
500        /*
501         * Write the OBEX DISCONNECT packet to the server. Byte 0: response code
502         * Byte 1&2: Connect Packet Length Byte 3 to n: headers
503         */
504        mOutput.write(replyData);
505        mOutput.flush();
506    }
507
508    /**
509     * Handles a connect request from a client. This method will read the rest
510     * of the request from the client. Assuming the request is valid, it will
511     * create a <code>HeaderSet</code> object to pass to the
512     * <code>ServerRequestHandler</code> object. After the handler processes the
513     * request, this method will create a reply message to send to the server
514     * with the response code provided.
515     * @throws IOException if an error occurred at the transport layer
516     */
517    private void handleConnectRequest() throws IOException {
518        int packetLength;
519        @SuppressWarnings("unused")
520        int version;
521        @SuppressWarnings("unused")
522        int flags;
523        int totalLength = 7;
524        byte[] head = null;
525        int code = -1;
526        HeaderSet request = new HeaderSet();
527        HeaderSet reply = new HeaderSet();
528        int bytesReceived;
529
530        /*
531         * Read in the length of the OBEX packet, OBEX version, flags, and max
532         * packet length
533         */
534        packetLength = mInput.read();
535        packetLength = (packetLength << 8) + mInput.read();
536        version = mInput.read();
537        flags = mInput.read();
538        mMaxPacketLength = mInput.read();
539        mMaxPacketLength = (mMaxPacketLength << 8) + mInput.read();
540
541        // should we check it?
542        if (mMaxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) {
543            mMaxPacketLength = ObexHelper.MAX_PACKET_SIZE_INT;
544        }
545
546        if (packetLength > ObexHelper.MAX_PACKET_SIZE_INT) {
547            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
548            totalLength = 7;
549        } else {
550            if (packetLength > 7) {
551                byte[] headers = new byte[packetLength - 7];
552                bytesReceived = mInput.read(headers);
553
554                while (bytesReceived != headers.length) {
555                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
556                            - bytesReceived);
557                }
558
559                ObexHelper.updateHeaderSet(request, headers);
560            }
561
562            if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
563                mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
564            } else {
565                mListener.setConnectionId(1);
566            }
567
568            if (request.mAuthResp != null) {
569                if (!handleAuthResp(request.mAuthResp)) {
570                    code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
571                    mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
572                            request.mAuthResp));
573                }
574                request.mAuthResp = null;
575            }
576
577            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
578                if (request.mAuthChall != null) {
579                    handleAuthChall(request);
580                    reply.mAuthResp = new byte[request.mAuthResp.length];
581                    System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0,
582                            reply.mAuthResp.length);
583                    request.mAuthChall = null;
584                    request.mAuthResp = null;
585                }
586
587                try {
588                    code = mListener.onConnect(request, reply);
589                    code = validateResponseCode(code);
590
591                    if (reply.nonce != null) {
592                        mChallengeDigest = new byte[16];
593                        System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16);
594                    } else {
595                        mChallengeDigest = null;
596                    }
597                    long id = mListener.getConnectionId();
598                    if (id == -1) {
599                        reply.mConnectionID = null;
600                    } else {
601                        reply.mConnectionID = ObexHelper.convertToByteArray(id);
602                    }
603
604                    head = ObexHelper.createHeader(reply, false);
605                    totalLength += head.length;
606
607                    if (totalLength > mMaxPacketLength) {
608                        totalLength = 7;
609                        head = null;
610                        code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
611                    }
612                } catch (Exception e) {
613                    e.printStackTrace();
614                    totalLength = 7;
615                    head = null;
616                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
617                }
618
619            }
620        }
621
622        // Compute Length of OBEX CONNECT packet
623        byte[] length = ObexHelper.convertToByteArray(totalLength);
624
625        /*
626         * Write the OBEX CONNECT packet to the server. Byte 0: response code
627         * Byte 1&2: Connect Packet Length Byte 3: OBEX Version Number
628         * (Presently, 0x10) Byte 4: Flags (For TCP 0x00) Byte 5&6: Max OBEX
629         * Packet Length (Defined in MAX_PACKET_SIZE) Byte 7 to n: headers
630         */
631        byte[] sendData = new byte[totalLength];
632        sendData[0] = (byte)code;
633        sendData[1] = length[2];
634        sendData[2] = length[3];
635        sendData[3] = (byte)0x10;
636        sendData[4] = (byte)0x00;
637        sendData[5] = (byte)(ObexHelper.MAX_PACKET_SIZE_INT >> 8);
638        sendData[6] = (byte)(ObexHelper.MAX_PACKET_SIZE_INT & 0xFF);
639
640        if (head != null) {
641            System.arraycopy(head, 0, sendData, 7, head.length);
642        }
643
644        mOutput.write(sendData);
645        mOutput.flush();
646    }
647
648    /**
649     * Closes the server session - in detail close I/O streams and the
650     * underlying transport layer. Internal flag is also set so that later
651     * attempt to read/write will throw an exception.
652     */
653    public synchronized void close() {
654        if (mListener != null) {
655            mListener.onClose();
656        }
657        try {
658            mInput.close();
659            mOutput.close();
660            mTransport.close();
661            mClosed = true;
662        } catch (Exception e) {
663        }
664        mTransport = null;
665        mInput = null;
666        mOutput = null;
667        mListener = null;
668    }
669
670    /**
671     * Verifies that the response code is valid. If it is not valid, it will
672     * return the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code.
673     * @param code the response code to check
674     * @return the valid response code or <code>OBEX_HTTP_INTERNAL_ERROR</code>
675     *         if <code>code</code> is not valid
676     */
677    private int validateResponseCode(int code) {
678
679        if ((code >= ResponseCodes.OBEX_HTTP_OK) && (code <= ResponseCodes.OBEX_HTTP_PARTIAL)) {
680            return code;
681        }
682        if ((code >= ResponseCodes.OBEX_HTTP_MULT_CHOICE)
683                && (code <= ResponseCodes.OBEX_HTTP_USE_PROXY)) {
684            return code;
685        }
686        if ((code >= ResponseCodes.OBEX_HTTP_BAD_REQUEST)
687                && (code <= ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE)) {
688            return code;
689        }
690        if ((code >= ResponseCodes.OBEX_HTTP_INTERNAL_ERROR)
691                && (code <= ResponseCodes.OBEX_HTTP_VERSION)) {
692            return code;
693        }
694        if ((code >= ResponseCodes.OBEX_DATABASE_FULL)
695                && (code <= ResponseCodes.OBEX_DATABASE_LOCKED)) {
696            return code;
697        }
698        return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
699    }
700
701}
702