00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "socket.h"
00023 #include "usbwrap.h"
00024 #include "data.h"
00025 #include "protocol.h"
00026 #include "protostructs.h"
00027 #include "endian.h"
00028 #include "debug.h"
00029 #include "packet.h"
00030 #include "sha1.h"
00031 #include <sstream>
00032 #include <string.h>
00033
00034 using namespace Usb;
00035
00036
00037 namespace Barry {
00038
00039
00040
00041
00042
00043 SocketZero::SocketZero( SocketRoutingQueue &queue,
00044 int writeEndpoint,
00045 uint8_t zeroSocketSequenceStart)
00046 : m_dev(0),
00047 m_queue(&queue),
00048 m_writeEp(writeEndpoint),
00049 m_readEp(0),
00050 m_zeroSocketSequence(zeroSocketSequenceStart),
00051 m_sequenceId(0),
00052 m_halfOpen(false),
00053 m_challengeSeed(0),
00054 m_remainingTries(0),
00055 m_hideSequencePacket(true),
00056 m_resetOnClose(false)
00057 {
00058 }
00059
00060 SocketZero::SocketZero( Device &dev,
00061 int writeEndpoint, int readEndpoint,
00062 uint8_t zeroSocketSequenceStart)
00063 : m_dev(&dev),
00064 m_queue(0),
00065 m_writeEp(writeEndpoint),
00066 m_readEp(readEndpoint),
00067 m_zeroSocketSequence(zeroSocketSequenceStart),
00068 m_sequenceId(0),
00069 m_halfOpen(false),
00070 m_challengeSeed(0),
00071 m_remainingTries(0),
00072 m_hideSequencePacket(true),
00073 m_resetOnClose(false)
00074 {
00075 }
00076
00077 SocketZero::~SocketZero()
00078 {
00079
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 void SocketZero::AppendFragment(Data &whole, const Data &fragment)
00090 {
00091 if( whole.GetSize() == 0 ) {
00092
00093 whole = fragment;
00094 }
00095 else {
00096
00097 int size = whole.GetSize();
00098 unsigned char *buf = whole.GetBuffer(size + fragment.GetSize());
00099 MAKE_PACKET(fpack, fragment);
00100 int fragsize = fragment.GetSize() - SB_FRAG_HEADER_SIZE;
00101
00102 memcpy(buf+size, &fpack->u.db.u.fragment, fragsize);
00103 whole.ReleaseBuffer(size + fragsize);
00104 }
00105
00106
00107 Barry::Protocol::Packet *wpack = (Barry::Protocol::Packet *) whole.GetBuffer();
00108 wpack->size = htobs((uint16_t) whole.GetSize());
00109 wpack->command = SB_COMMAND_DB_DATA;
00110
00111
00112 }
00113
00114
00115
00116
00117 unsigned int SocketZero::MakeNextFragment(const Data &whole, Data &fragment, unsigned int offset)
00118 {
00119
00120 if( whole.GetSize() < SB_FRAG_HEADER_SIZE ) {
00121 eout("Whole packet too short to fragment: " << whole.GetSize());
00122 throw Error("Socket: Whole packet too short to fragment");
00123 }
00124
00125
00126 unsigned int todo = whole.GetSize() - SB_FRAG_HEADER_SIZE - offset;
00127 unsigned int nextOffset = 0;
00128 if( todo > (MAX_PACKET_SIZE - SB_FRAG_HEADER_SIZE) ) {
00129 todo = MAX_PACKET_SIZE - SB_FRAG_HEADER_SIZE;
00130 nextOffset = offset + todo;
00131 }
00132
00133
00134 unsigned char *buf = fragment.GetBuffer(SB_FRAG_HEADER_SIZE + todo);
00135 memcpy(buf, whole.GetData(), SB_FRAG_HEADER_SIZE);
00136
00137
00138 memcpy(buf + SB_FRAG_HEADER_SIZE, whole.GetData() + SB_FRAG_HEADER_SIZE + offset, todo);
00139
00140
00141 Barry::Protocol::Packet *wpack = (Barry::Protocol::Packet *) buf;
00142 wpack->size = htobs((uint16_t) (todo + SB_FRAG_HEADER_SIZE));
00143 if( nextOffset )
00144 wpack->command = SB_COMMAND_DB_FRAGMENTED;
00145 else
00146 wpack->command = SB_COMMAND_DB_DATA;
00147
00148
00149 fragment.ReleaseBuffer(SB_FRAG_HEADER_SIZE + todo);
00150
00151
00152 return nextOffset;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 void SocketZero::CheckSequence(uint16_t socket, const Data &seq)
00165 {
00166 MAKE_PACKET(spack, seq);
00167 if( (unsigned int) seq.GetSize() < SB_SEQUENCE_PACKET_SIZE ) {
00168 eout("Short sequence packet:\n" << seq);
00169 throw Error("Socket: invalid sequence packet");
00170 }
00171
00172
00173
00174 uint32_t sequenceId = btohl(spack->u.sequence.sequenceId);
00175 if( sequenceId == 0 ) {
00176
00177 m_sequenceId = 0;
00178 }
00179 else {
00180 if( sequenceId != m_sequenceId ) {
00181 if( socket != 0 ) {
00182 std::ostringstream oss;
00183 oss << "Socket 0x" << std::hex << (unsigned int)socket
00184 << ": out of sequence. "
00185 << "(Global sequence: " << m_sequenceId
00186 << ". Packet sequence: " << sequenceId
00187 << ")";
00188 eout(oss.str());
00189 throw Error(oss.str());
00190 }
00191 else {
00192 dout("Bad sequence on socket 0: expected: "
00193 << m_sequenceId
00194 << ". Packet sequence: " << sequenceId);
00195 }
00196 }
00197 }
00198
00199
00200 m_sequenceId++;
00201 }
00202
00203 void SocketZero::SendOpen(uint16_t socket, Data &receive)
00204 {
00205
00206 Barry::Protocol::Packet packet;
00207 packet.socket = 0;
00208 packet.size = htobs(SB_SOCKET_PACKET_HEADER_SIZE);
00209 packet.command = SB_COMMAND_OPEN_SOCKET;
00210 packet.u.socket.socket = htobs(socket);
00211 packet.u.socket.sequence = m_zeroSocketSequence;
00212
00213 Data send(&packet, SB_SOCKET_PACKET_HEADER_SIZE);
00214 try {
00215 RawSend(send);
00216 RawReceive(receive);
00217 } catch( Usb::Error & ) {
00218 eeout(send, receive);
00219 throw;
00220 }
00221
00222
00223 Protocol::CheckSize(receive, SB_PACKET_HEADER_SIZE);
00224 if( IS_COMMAND(receive, SB_COMMAND_SEQUENCE_HANDSHAKE) ) {
00225 CheckSequence(0, receive);
00226
00227
00228 RawReceive(receive);
00229 }
00230
00231
00232 }
00233
00234
00235 void SocketZero::SendPasswordHash(uint16_t socket, const char *password, Data &receive)
00236 {
00237 unsigned char pwdigest[SHA_DIGEST_LENGTH];
00238 unsigned char prefixedhash[SHA_DIGEST_LENGTH + 4];
00239
00240
00241 SHA1((unsigned char *) password, strlen(password), pwdigest);
00242
00243
00244 uint32_t seed = htobl(m_challengeSeed);
00245 memcpy(&prefixedhash[0], &seed, sizeof(uint32_t));
00246 memcpy(&prefixedhash[4], pwdigest, SHA_DIGEST_LENGTH);
00247
00248
00249 SHA1((unsigned char *) prefixedhash, SHA_DIGEST_LENGTH + 4, pwdigest);
00250
00251
00252 size_t size = SB_SOCKET_PACKET_HEADER_SIZE + PASSWORD_CHALLENGE_SIZE;
00253
00254
00255 Barry::Protocol::Packet packet;
00256 packet.socket = 0;
00257 packet.size = htobs(size);
00258 packet.command = SB_COMMAND_PASSWORD;
00259 packet.u.socket.socket = htobs(socket);
00260 packet.u.socket.sequence = m_zeroSocketSequence;
00261 packet.u.socket.u.password.remaining_tries = 0;
00262 packet.u.socket.u.password.unknown = 0;
00263 packet.u.socket.u.password.param = htobs(0x14);
00264 memcpy(packet.u.socket.u.password.u.hash, pwdigest,
00265 sizeof(packet.u.socket.u.password.u.hash));
00266
00267
00268 memset(pwdigest, 0, sizeof(pwdigest));
00269 memset(prefixedhash, 0, sizeof(prefixedhash));
00270
00271 Data send(&packet, size);
00272 RawSend(send);
00273 RawReceive(receive);
00274
00275
00276 memset(packet.u.socket.u.password.u.hash, 0,
00277 sizeof(packet.u.socket.u.password.u.hash));
00278 send.Zap();
00279
00280
00281 Protocol::CheckSize(receive, SB_PACKET_HEADER_SIZE);
00282 if( IS_COMMAND(receive, SB_COMMAND_SEQUENCE_HANDSHAKE) ) {
00283 CheckSequence(0, receive);
00284
00285
00286 RawReceive(receive);
00287 }
00288
00289
00290 }
00291
00292 void SocketZero::RawSend(Data &send, int timeout)
00293 {
00294 Usb::Device *dev = m_queue ? m_queue->GetUsbDevice() : m_dev;
00295 if( !dev )
00296 throw Error("SocketZero: No device available for RawSend");
00297
00298
00299
00300
00301
00302
00303
00304
00305 if( (send.GetSize() % 0x40) == 0 ) {
00306 Protocol::SizePacket packet;
00307 packet.size = htobs(send.GetSize());
00308 packet.buffer[2] = 0;
00309 Data sizeCommand(&packet, 3);
00310
00311 dev->BulkWrite(m_writeEp, sizeCommand, timeout);
00312 }
00313
00314 dev->BulkWrite(m_writeEp, send, timeout);
00315 }
00316
00317 void SocketZero::RawReceive(Data &receive, int timeout)
00318 {
00319 do {
00320 if( m_queue ) {
00321 if( !m_queue->DefaultRead(receive, timeout) )
00322 throw Timeout("SocketZero::RawReceive: queue DefaultRead returned false (likely a timeout)");
00323 }
00324 else {
00325 m_dev->BulkRead(m_readEp, receive, timeout);
00326 }
00327 ddout("SocketZero::RawReceive: Endpoint "
00328 << (m_queue ? m_queue->GetReadEp() : m_readEp)
00329 << "\nReceived:\n" << receive);
00330 } while( SequencePacket(receive) );
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 bool SocketZero::SequencePacket(const Data &data)
00348 {
00349
00350 if (m_hideSequencePacket == false) {
00351 return false;
00352 }
00353
00354
00355 if( data.GetSize() >= MIN_PACKET_SIZE ) {
00356 MAKE_PACKET(rpack, data);
00357 if( rpack->socket == 0 &&
00358 rpack->command == SB_COMMAND_SEQUENCE_HANDSHAKE )
00359 {
00360 CheckSequence(0, data);
00361 return true;
00362 }
00363 }
00364 return false;
00365 }
00366
00367
00368
00369
00370
00371 void SocketZero::SetRoutingQueue(SocketRoutingQueue &queue)
00372 {
00373
00374 m_queue = &queue;
00375 }
00376
00377 void SocketZero::UnlinkRoutingQueue()
00378 {
00379 m_queue = 0;
00380 }
00381
00382 void SocketZero::Send(Data &send, int timeout)
00383 {
00384
00385 if( send.GetSize() >= SB_SOCKET_PACKET_HEADER_SIZE ) {
00386 MAKE_PACKETPTR_BUF(spack, send.GetBuffer());
00387 spack->socket = 0;
00388 }
00389
00390
00391
00392 if( send.GetSize() >= SB_SOCKET_PACKET_HEADER_SIZE ) {
00393 MAKE_PACKETPTR_BUF(spack, send.GetBuffer());
00394 spack->u.socket.sequence = m_zeroSocketSequence;
00395 m_zeroSocketSequence++;
00396 }
00397
00398 RawSend(send, timeout);
00399 }
00400
00401 void SocketZero::Send(Data &send, Data &receive, int timeout)
00402 {
00403 Send(send, timeout);
00404 RawReceive(receive, timeout);
00405 }
00406
00407 void SocketZero::Send(Barry::Packet &packet, int timeout)
00408 {
00409 Send(packet.m_send, *packet.m_receive, timeout);
00410 }
00411
00412 void SocketZero::Receive(Data &receive, int timeout)
00413 {
00414 RawReceive(receive, timeout);
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 SocketHandle SocketZero::Open(uint16_t socket, const char *password)
00442 {
00443
00444
00445
00446
00447
00448 Data send, receive;
00449 ZeroPacket packet(send, receive);
00450
00451
00452 uint8_t closeFlag = GetZeroSocketSequence();
00453
00454 if( !m_halfOpen ) {
00455
00456 m_remainingTries = 0;
00457
00458 SendOpen(socket, receive);
00459
00460
00461 if( packet.Command() == SB_COMMAND_PASSWORD_CHALLENGE ) {
00462 m_halfOpen = true;
00463 m_challengeSeed = packet.ChallengeSeed();
00464 m_remainingTries = packet.RemainingTries();
00465 }
00466
00467
00468 }
00469
00470 if( m_halfOpen ) {
00471
00472
00473 if( !password ) {
00474 throw BadPassword("No password specified.", m_remainingTries, false);
00475 }
00476
00477
00478
00479
00480
00481 if( m_remainingTries < BARRY_MIN_PASSWORD_TRIES ) {
00482 throw BadPassword("Fewer than " BARRY_MIN_PASSWORD_TRIES_ASC " password tries remaining in device. Refusing to proceed, to avoid device zapping itself. Use a Windows client, or re-cradle the device.",
00483 m_remainingTries,
00484 true);
00485 }
00486
00487
00488 closeFlag = GetZeroSocketSequence();
00489
00490 SendPasswordHash(socket, password, receive);
00491
00492 if( packet.Command() == SB_COMMAND_PASSWORD_FAILED ) {
00493 m_halfOpen = true;
00494 m_challengeSeed = packet.ChallengeSeed();
00495 m_remainingTries = packet.RemainingTries();
00496 throw BadPassword("Password rejected by device.", m_remainingTries, false);
00497 }
00498
00499
00500
00501 m_halfOpen = false;
00502
00503
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 if( packet.Command() == SB_COMMAND_CLOSE_SOCKET )
00518 {
00519 throw Error("Socket: Device closed socket when trying to open");
00520 }
00521
00522 if( packet.Command() != SB_COMMAND_OPENED_SOCKET ||
00523 packet.SocketResponse() != socket ||
00524 packet.SocketSequence() != closeFlag )
00525 {
00526 eout("Packet:\n" << receive);
00527 throw Error("Socket: Bad OPENED packet in Open");
00528 }
00529
00530
00531 return SocketHandle(new Socket(*this, socket, closeFlag));
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 void SocketZero::Close(Socket &socket)
00545 {
00546 if( socket.GetSocket() == 0 )
00547 return;
00548
00549
00550 Barry::Protocol::Packet packet;
00551 packet.socket = 0;
00552 packet.size = htobs(SB_SOCKET_PACKET_HEADER_SIZE);
00553 packet.command = SB_COMMAND_CLOSE_SOCKET;
00554 packet.u.socket.socket = htobs(socket.GetSocket());
00555 packet.u.socket.sequence = socket.GetCloseFlag();
00556
00557 Data command(&packet, SB_SOCKET_PACKET_HEADER_SIZE);
00558 Data response;
00559 try {
00560 Send(command, response);
00561 }
00562 catch( Usb::Error & ) {
00563
00564 socket.ForceClosed();
00565
00566 eeout(command, response);
00567 throw;
00568 }
00569
00570
00571 Protocol::CheckSize(response, SB_PACKET_HEADER_SIZE);
00572 if( IS_COMMAND(response, SB_COMMAND_SEQUENCE_HANDSHAKE) ) {
00573 CheckSequence(0, response);
00574
00575
00576 RawReceive(response);
00577 }
00578
00579 Protocol::CheckSize(response, SB_SOCKET_PACKET_HEADER_SIZE);
00580 MAKE_PACKET(rpack, response);
00581
00582
00583
00584
00585
00586
00587
00588 if( ( rpack->command != SB_COMMAND_CLOSED_SOCKET &&
00589 rpack->command != SB_COMMAND_REMOTE_CLOSE_SOCKET ) ||
00590 btohs(rpack->u.socket.socket) != socket.GetSocket() ||
00591 rpack->u.socket.sequence != socket.GetCloseFlag() )
00592 {
00593
00594 socket.ForceClosed();
00595
00596 eout("Packet:\n" << response);
00597 throw BadPacket(rpack->command, "Socket: Bad CLOSED packet in Close");
00598 }
00599
00600 if( m_resetOnClose ) {
00601 Data send, receive;
00602 ZeroPacket reset_packet(send, receive);
00603 reset_packet.Reset();
00604
00605 Send(reset_packet);
00606 if( reset_packet.CommandResponse() != SB_COMMAND_RESET_REPLY ) {
00607 throw BadPacket(reset_packet.CommandResponse(),
00608 "Socket: Missing RESET_REPLY in Close");
00609 }
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 socket.ForceClosed();
00622 }
00623
00624
00625
00626
00627
00628
00629 void SocketZero::ClearHalt()
00630 {
00631 Usb::Device *dev = m_queue ? m_queue->GetUsbDevice() : m_dev;
00632 if( !dev )
00633 throw Error("SocketZero: No device available for ClearHalt");
00634
00635
00636 if( m_queue ) {
00637 dev->ClearHalt(m_queue->GetReadEp());
00638 }
00639 else {
00640 dev->ClearHalt(m_readEp);
00641 }
00642
00643
00644 dev->ClearHalt(m_writeEp);
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 Socket::Socket( SocketZero &zero,
00656 uint16_t socket,
00657 uint8_t closeFlag)
00658 : m_zero(&zero)
00659 , m_socket(socket)
00660 , m_closeFlag(closeFlag)
00661 , m_registered(false)
00662 {
00663 }
00664
00665 Socket::~Socket()
00666 {
00667
00668 try {
00669
00670 Close();
00671 }
00672 catch( std::runtime_error &re ) {
00673
00674 dout("Exception caught in ~Socket: " << re.what());
00675 }
00676 }
00677
00678
00679
00680
00681
00682 void Socket::CheckSequence(const Data &seq)
00683 {
00684 m_zero->CheckSequence(m_socket, seq);
00685 }
00686
00687 void Socket::ForceClosed()
00688 {
00689 m_socket = 0;
00690 m_closeFlag = 0;
00691 }
00692
00693
00694
00695
00696
00697 void Socket::Close()
00698 {
00699 UnregisterInterest();
00700 m_zero->Close(*this);
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 void Socket::Send(Data &send, int timeout)
00714 {
00715
00716 if( send.GetSize() >= SB_PACKET_HEADER_SIZE ) {
00717 MAKE_PACKETPTR_BUF(spack, send.GetBuffer());
00718 spack->socket = htobs(m_socket);
00719 }
00720 m_zero->RawSend(send, timeout);
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 void Socket::Send(Data &send, Data &receive, int timeout)
00733 {
00734 Send(send, timeout);
00735 Receive(receive, timeout);
00736 }
00737
00738 void Socket::Send(Barry::Packet &packet, int timeout)
00739 {
00740 Send(packet.m_send, *packet.m_receive, timeout);
00741 }
00742
00743 void Socket::Receive(Data &receive, int timeout)
00744 {
00745 if( m_registered ) {
00746 if( m_zero->m_queue ) {
00747 if( !m_zero->m_queue->SocketRead(m_socket, receive, timeout) )
00748 throw Timeout("Socket::Receive: queue SocketRead returned false (likely a timeout)");
00749 }
00750 else {
00751 throw std::logic_error("NULL queue pointer in a registered socket read.");
00752 }
00753 }
00754 else {
00755 m_zero->RawReceive(receive, timeout);
00756 }
00757 }
00758
00759
00760
00761 void Socket::ReceiveData(Data &receive, int timeout)
00762 {
00763 HideSequencePacket(false);
00764 Receive(receive);
00765 HideSequencePacket(true);
00766 }
00767
00768 void Socket::ClearHalt()
00769 {
00770 m_zero->ClearHalt();
00771 }
00772
00773
00774
00775 void Socket::InitSequence(int timeout)
00776 {
00777 Data receive;
00778 receive.Zap();
00779
00780 HideSequencePacket(false);
00781 Receive(receive);
00782 HideSequencePacket(true);
00783
00784 Protocol::CheckSize(receive, SB_PACKET_HEADER_SIZE);
00785 CheckSequence(receive);
00786 }
00787
00788
00789
00790
00791
00792
00793 void Socket::PacketJVM(Data &send, Data &receive, int timeout)
00794 {
00795 if( ( send.GetSize() < MIN_PACKET_DATA_SIZE ) ||
00796 ( send.GetSize() > MAX_PACKET_DATA_SIZE ) ) {
00797
00798 throw std::logic_error("Socket: unknown send data in PacketJVM()");
00799 }
00800
00801 Data &inFrag = receive;
00802 receive.Zap();
00803
00804
00805 Send(send, inFrag, timeout);
00806
00807 bool done = false;
00808 int blankCount = 0;
00809
00810 while( !done ) {
00811
00812 if( inFrag.GetSize() > 6 ) {
00813 MAKE_PACKET(rpack, inFrag);
00814
00815 blankCount = 0;
00816
00817 Protocol::CheckSize(inFrag, SB_PACKET_HEADER_SIZE);
00818
00819 switch( rpack->command )
00820 {
00821 case SB_COMMAND_SEQUENCE_HANDSHAKE:
00822 CheckSequence(inFrag);
00823 break;
00824
00825 default: {
00826 std::ostringstream oss;
00827 oss << "Socket: (read) unhandled packet in Packet(): 0x" << std::hex << (unsigned int)rpack->command;
00828 eout(oss.str());
00829 throw Error(oss.str());
00830 }
00831 break;
00832 }
00833 }
00834 else if( inFrag.GetSize() == 6 ) {
00835 done = true;
00836 }
00837 else {
00838 blankCount++;
00839
00840
00841 if( blankCount == 10 ) {
00842
00843
00844 throw Error("Socket: 10 blank packets received");
00845 }
00846 }
00847
00848 if( !done ) {
00849
00850 Receive(inFrag);
00851 }
00852 }
00853 }
00854
00855
00856
00857 void Socket::PacketData(Data &send, Data &receive, int timeout)
00858 {
00859 if( ( send.GetSize() < MIN_PACKET_DATA_SIZE ) ||
00860 ( send.GetSize() > MAX_PACKET_DATA_SIZE ) ) {
00861
00862 throw std::logic_error("Socket: unknown send data in PacketData()");
00863 }
00864
00865 Data &inFrag = receive;
00866 receive.Zap();
00867
00868
00869 Send(send, inFrag, timeout);
00870
00871 bool done = false;
00872 int blankCount = 0;
00873
00874 while( !done ) {
00875
00876 if( inFrag.GetSize() > 0 ) {
00877 MAKE_PACKET(rpack, inFrag);
00878
00879 blankCount = 0;
00880
00881 Protocol::CheckSize(inFrag, SB_PACKET_HEADER_SIZE);
00882
00883 switch( rpack->command )
00884 {
00885 case SB_COMMAND_SEQUENCE_HANDSHAKE:
00886 CheckSequence(inFrag);
00887 if (!m_zero->IsSequencePacketHidden())
00888 done = true;
00889 break;
00890
00891 case SB_COMMAND_JL_READY:
00892 case SB_COMMAND_JL_ACK:
00893 case SB_COMMAND_JL_HELLO_ACK:
00894 case SB_COMMAND_JL_RESET_REQUIRED:
00895 done = true;
00896 break;
00897
00898 case SB_COMMAND_JL_GET_DATA_ENTRY:
00899 done = true;
00900 break;
00901
00902 case SB_DATA_JL_INVALID:
00903 throw BadPacket(rpack->command, "file is not a valid Java code file");
00904 break;
00905
00906 case SB_COMMAND_JL_NOT_SUPPORTED:
00907 throw BadPacket(rpack->command, "device does not support requested command");
00908 break;
00909
00910 default:
00911
00912
00913 done = true;
00914 break;
00915 }
00916 }
00917 else {
00918 blankCount++;
00919
00920 if( blankCount == 10 ) {
00921
00922
00923 throw Error("Socket: 10 blank packets received");
00924 }
00925 }
00926
00927 if( !done ) {
00928
00929 Receive(inFrag);
00930 }
00931 }
00932 }
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 void Socket::Packet(Data &send, Data &receive, int timeout)
00943 {
00944 MAKE_PACKET(spack, send);
00945 if( send.GetSize() < MIN_PACKET_SIZE ||
00946 (spack->command != SB_COMMAND_DB_DATA &&
00947 spack->command != SB_COMMAND_DB_DONE) )
00948 {
00949
00950 eout("unknown send data in Packet(): " << send);
00951 throw std::logic_error("Socket: unknown send data in Packet()");
00952 }
00953
00954
00955
00956
00957 Data *inputBuf = &receive;
00958 receive.Zap();
00959
00960 if( send.GetSize() <= MAX_PACKET_SIZE ) {
00961
00962 Send(send, *inputBuf, timeout);
00963 }
00964 else {
00965
00966 unsigned int offset = 0;
00967 Data outFrag;
00968
00969
00970
00971
00972
00973
00974
00975
00976 HideSequencePacket(false);
00977
00978 do {
00979 offset = SocketZero::MakeNextFragment(send, outFrag, offset);
00980
00981
00982 MAKE_PACKET(spack, outFrag);
00983
00984 if (spack->command != SB_COMMAND_DB_FRAGMENTED)
00985 HideSequencePacket(true);
00986
00987 Send(outFrag, *inputBuf, timeout);
00988
00989
00990
00991
00992 if (spack->command != SB_COMMAND_DB_FRAGMENTED) {
00993 MAKE_PACKET(rpack, *inputBuf);
00994
00995 if( offset && inputBuf->GetSize() > 0 ) {
00996 Protocol::CheckSize(*inputBuf, SB_PACKET_HEADER_SIZE);
00997
00998 switch( rpack->command )
00999 {
01000 case SB_COMMAND_SEQUENCE_HANDSHAKE:
01001 CheckSequence(*inputBuf);
01002 break;
01003
01004 default: {
01005 std::ostringstream oss;
01006 oss << "Socket: (send) unhandled packet in Packet(): 0x" << std::hex << (unsigned int)rpack->command;
01007 eout(oss.str());
01008 throw Error(oss.str());
01009 }
01010 break;
01011 }
01012 }
01013 }
01014
01015 } while( offset > 0 );
01016
01017
01018 HideSequencePacket(true);
01019 }
01020
01021 std::auto_ptr<Data> inFrag;
01022 bool done = false, frag = false;
01023 int blankCount = 0;
01024 while( !done ) {
01025 MAKE_PACKET(rpack, *inputBuf);
01026
01027
01028 if( inputBuf->GetSize() > 0 ) {
01029 blankCount = 0;
01030
01031 Protocol::CheckSize(*inputBuf, SB_PACKET_HEADER_SIZE);
01032
01033 switch( rpack->command )
01034 {
01035 case SB_COMMAND_SEQUENCE_HANDSHAKE:
01036 CheckSequence(*inputBuf);
01037 break;
01038
01039 case SB_COMMAND_DB_DATA:
01040 if( frag ) {
01041 SocketZero::AppendFragment(receive, *inputBuf);
01042 }
01043 else {
01044
01045
01046 }
01047 done = true;
01048 break;
01049
01050 case SB_COMMAND_DB_FRAGMENTED:
01051
01052
01053 if( frag ) {
01054 SocketZero::AppendFragment(receive, *inputBuf);
01055 }
01056 frag = true;
01057 break;
01058
01059 case SB_COMMAND_DB_DONE:
01060
01061 done = true;
01062 break;
01063
01064 default: {
01065 std::ostringstream oss;
01066 oss << "Socket: (read) unhandled packet in Packet(): 0x" << std::hex << (unsigned int)rpack->command;
01067 eout(oss.str());
01068 throw Error(oss.str());
01069 }
01070 break;
01071 }
01072 }
01073 else {
01074 blankCount++;
01075
01076 if( blankCount == 10 ) {
01077
01078
01079 throw Error("Socket: 10 blank packets received");
01080 }
01081 }
01082
01083 if( !done ) {
01084
01085
01086 if( !inFrag.get() ) {
01087 inFrag.reset( new Data );
01088 inputBuf = inFrag.get();
01089 }
01090 Receive(*inputBuf);
01091 }
01092 }
01093 }
01094
01095 void Socket::Packet(Barry::Packet &packet, int timeout)
01096 {
01097 Packet(packet.m_send, *packet.m_receive, timeout);
01098 }
01099
01100 void Socket::Packet(Barry::JLPacket &packet, int timeout)
01101 {
01102 if( packet.HasData() ) {
01103 HideSequencePacket(false);
01104 PacketData(packet.m_cmd, *packet.m_receive, timeout);
01105 HideSequencePacket(true);
01106 PacketData(packet.m_data, *packet.m_receive, timeout);
01107 }
01108 else {
01109 PacketData(packet.m_cmd, *packet.m_receive, timeout);
01110 }
01111 }
01112
01113 void Socket::Packet(Barry::JVMPacket &packet, int timeout)
01114 {
01115 HideSequencePacket(false);
01116 PacketJVM(packet.m_cmd, *packet.m_receive, timeout);
01117 HideSequencePacket(true);
01118 }
01119
01120 void Socket::NextRecord(Data &receive)
01121 {
01122 Barry::Protocol::Packet packet;
01123 packet.socket = htobs(GetSocket());
01124 packet.size = htobs(7);
01125 packet.command = SB_COMMAND_DB_DONE;
01126 packet.u.db.tableCmd = 0;
01127 packet.u.db.u.command.operation = 0;
01128
01129 Data command(&packet, 7);
01130 Packet(command, receive);
01131 }
01132
01133 void Socket::RegisterInterest(SocketRoutingQueue::SocketDataHandlerPtr handler)
01134 {
01135 if( !m_zero->m_queue )
01136 throw std::logic_error("SocketRoutingQueue required in SocketZero in order to call Socket::RegisterInterest()");
01137
01138 if( m_registered )
01139 throw std::logic_error("Socket already registered in Socket::RegisterInterest()!");
01140
01141 m_zero->m_queue->RegisterInterest(m_socket, handler);
01142 m_registered = true;
01143 }
01144
01145 void Socket::UnregisterInterest()
01146 {
01147 if( m_registered ) {
01148 if( m_zero->m_queue )
01149 m_zero->m_queue->UnregisterInterest(m_socket);
01150 m_registered = false;
01151 }
01152 }
01153
01154
01155 }
01156