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 33 package javax.obex; 34 35 import android.util.Log; 36 37 import java.io.InputStream; 38 import java.io.IOException; 39 import java.io.OutputStream; 40 41 /** 42 * This class in an implementation of the OBEX ServerSession. 43 * @hide 44 */ 45 public 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