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
00296
00297
00298
00299
00300
00301
00302
00303 if( (send.GetSize() % 0x40) == 0 ) {
00304 Protocol::SizePacket packet;
00305 packet.size = htobs(send.GetSize());
00306 packet.buffer[2] = 0;
00307 Data sizeCommand(&packet, 3);
00308
00309 dev->BulkWrite(m_writeEp, sizeCommand);
00310 }
00311
00312 dev->BulkWrite(m_writeEp, send);
00313 }
00314
00315 void SocketZero::RawReceive(Data &receive, int timeout)
00316 {
00317 do {
00318 if( m_queue ) {
00319 if( !m_queue->DefaultRead(receive, timeout) )
00320 throw Timeout("SocketZero::RawReceive: queue DefaultRead returned false (likely a timeout)");
00321 }
00322 else {
00323 m_dev->BulkRead(m_readEp, receive, timeout);
00324 }
00325 ddout("SocketZero::RawReceive: Endpoint " << m_readEp
00326 << "\nReceived:\n" << receive);
00327 } while( SequencePacket(receive) );
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 bool SocketZero::SequencePacket(const Data &data)
00345 {
00346
00347 if (m_hideSequencePacket == false) {
00348 return false;
00349 }
00350
00351
00352 if( data.GetSize() >= MIN_PACKET_SIZE ) {
00353 MAKE_PACKET(rpack, data);
00354 if( rpack->socket == 0 &&
00355 rpack->command == SB_COMMAND_SEQUENCE_HANDSHAKE )
00356 {
00357 CheckSequence(0, data);
00358 return true;
00359 }
00360 }
00361 return false;
00362 }
00363
00364
00365
00366
00367
00368 void SocketZero::SetRoutingQueue(SocketRoutingQueue &queue)
00369 {
00370
00371 m_queue = &queue;
00372 }
00373
00374 void SocketZero::UnlinkRoutingQueue()
00375 {
00376 m_queue = 0;
00377 }
00378
00379 void SocketZero::Send(Data &send, int timeout)
00380 {
00381
00382 if( send.GetSize() >= SB_SOCKET_PACKET_HEADER_SIZE ) {
00383 MAKE_PACKETPTR_BUF(spack, send.GetBuffer());
00384 spack->socket = 0;
00385 }
00386
00387
00388
00389 if( send.GetSize() >= SB_SOCKET_PACKET_HEADER_SIZE ) {
00390 MAKE_PACKETPTR_BUF(spack, send.GetBuffer());
00391 spack->u.socket.sequence = m_zeroSocketSequence;
00392 m_zeroSocketSequence++;
00393 }
00394
00395 RawSend(send, timeout);
00396 }
00397
00398 void SocketZero::Send(Data &send, Data &receive, int timeout)
00399 {
00400 Send(send, timeout);
00401 RawReceive(receive, timeout);
00402 }
00403
00404 void SocketZero::Send(Barry::Packet &packet, int timeout)
00405 {
00406 Send(packet.m_send, packet.m_receive, timeout);
00407 }
00408
00409 void SocketZero::Receive(Data &receive, int timeout)
00410 {
00411 RawReceive(receive, timeout);
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 SocketHandle SocketZero::Open(uint16_t socket, const char *password)
00439 {
00440
00441
00442
00443
00444
00445 Data send, receive;
00446 ZeroPacket packet(send, receive);
00447
00448
00449 uint8_t closeFlag = GetZeroSocketSequence();
00450
00451 if( !m_halfOpen ) {
00452
00453 m_remainingTries = 0;
00454
00455 SendOpen(socket, receive);
00456
00457
00458 if( packet.Command() == SB_COMMAND_PASSWORD_CHALLENGE ) {
00459 m_halfOpen = true;
00460 m_challengeSeed = packet.ChallengeSeed();
00461 m_remainingTries = packet.RemainingTries();
00462 }
00463
00464
00465 }
00466
00467 if( m_halfOpen ) {
00468
00469
00470 if( !password ) {
00471 throw BadPassword("No password specified.", m_remainingTries, false);
00472 }
00473
00474
00475
00476
00477
00478 if( m_remainingTries < BARRY_MIN_PASSWORD_TRIES ) {
00479 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.",
00480 m_remainingTries,
00481 true);
00482 }
00483
00484
00485 closeFlag = GetZeroSocketSequence();
00486
00487 SendPasswordHash(socket, password, receive);
00488
00489 if( packet.Command() == SB_COMMAND_PASSWORD_FAILED ) {
00490 m_halfOpen = true;
00491 m_challengeSeed = packet.ChallengeSeed();
00492 m_remainingTries = packet.RemainingTries();
00493 throw BadPassword("Password rejected by device.", m_remainingTries, false);
00494 }
00495
00496
00497
00498 m_halfOpen = false;
00499
00500
00501 }
00502
00503 if( packet.Command() != SB_COMMAND_OPENED_SOCKET ||
00504 packet.SocketResponse() != socket ||
00505 packet.SocketSequence() != closeFlag )
00506 {
00507 eout("Packet:\n" << receive);
00508 throw Error("Socket: Bad OPENED packet in Open");
00509 }
00510
00511
00512 return SocketHandle(new Socket(*this, socket, closeFlag));
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 void SocketZero::Close(Socket &socket)
00526 {
00527 if( socket.GetSocket() == 0 )
00528 return;
00529
00530
00531 Barry::Protocol::Packet packet;
00532 packet.socket = 0;
00533 packet.size = htobs(SB_SOCKET_PACKET_HEADER_SIZE);
00534 packet.command = SB_COMMAND_CLOSE_SOCKET;
00535 packet.u.socket.socket = htobs(socket.GetSocket());
00536 packet.u.socket.sequence = socket.GetCloseFlag();
00537
00538 Data command(&packet, SB_SOCKET_PACKET_HEADER_SIZE);
00539 Data response;
00540 try {
00541 Send(command, response);
00542 }
00543 catch( Usb::Error & ) {
00544
00545 socket.ForceClosed();
00546
00547 eeout(command, response);
00548 throw;
00549 }
00550
00551
00552 Protocol::CheckSize(response, SB_PACKET_HEADER_SIZE);
00553 if( IS_COMMAND(response, SB_COMMAND_SEQUENCE_HANDSHAKE) ) {
00554 CheckSequence(0, response);
00555
00556
00557 RawReceive(response);
00558 }
00559
00560 Protocol::CheckSize(response, SB_SOCKET_PACKET_HEADER_SIZE);
00561 MAKE_PACKET(rpack, response);
00562 if( rpack->command != SB_COMMAND_CLOSED_SOCKET ||
00563 btohs(rpack->u.socket.socket) != socket.GetSocket() ||
00564 rpack->u.socket.sequence != socket.GetCloseFlag() )
00565 {
00566
00567 socket.ForceClosed();
00568
00569 eout("Packet:\n" << response);
00570 throw BadPacket(rpack->command, "Socket: Bad CLOSED packet in Close");
00571 }
00572
00573 if( m_resetOnClose ) {
00574 Data send, receive;
00575 ZeroPacket reset_packet(send, receive);
00576 reset_packet.Reset();
00577
00578 Send(reset_packet);
00579 if( reset_packet.CommandResponse() != SB_COMMAND_RESET_REPLY ) {
00580 throw BadPacket(reset_packet.CommandResponse(),
00581 "Socket: Missing RESET_REPLY in Close");
00582 }
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 socket.ForceClosed();
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 Socket::Socket( SocketZero &zero,
00606 uint16_t socket,
00607 uint8_t closeFlag)
00608 : m_zero(&zero)
00609 , m_socket(socket)
00610 , m_closeFlag(closeFlag)
00611 , m_registered(false)
00612 {
00613 }
00614
00615 Socket::~Socket()
00616 {
00617
00618 try {
00619
00620 Close();
00621 }
00622 catch( std::runtime_error &re ) {
00623
00624 dout("Exception caught in ~Socket: " << re.what());
00625 }
00626 }
00627
00628
00629
00630
00631
00632 void Socket::CheckSequence(const Data &seq)
00633 {
00634 m_zero->CheckSequence(m_socket, seq);
00635 }
00636
00637 void Socket::ForceClosed()
00638 {
00639 m_socket = 0;
00640 m_closeFlag = 0;
00641 }
00642
00643
00644
00645
00646
00647 void Socket::Close()
00648 {
00649 UnregisterInterest();
00650 m_zero->Close(*this);
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 void Socket::Send(Data &send, int timeout)
00664 {
00665
00666 if( send.GetSize() >= SB_PACKET_HEADER_SIZE ) {
00667 MAKE_PACKETPTR_BUF(spack, send.GetBuffer());
00668 spack->socket = htobs(m_socket);
00669 }
00670 m_zero->RawSend(send, timeout);
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 void Socket::Send(Data &send, Data &receive, int timeout)
00683 {
00684 Send(send, timeout);
00685 Receive(receive, timeout);
00686 }
00687
00688 void Socket::Send(Barry::Packet &packet, int timeout)
00689 {
00690 Send(packet.m_send, packet.m_receive, timeout);
00691 }
00692
00693 void Socket::Receive(Data &receive, int timeout)
00694 {
00695 if( m_registered ) {
00696 if( m_zero->m_queue ) {
00697 if( !m_zero->m_queue->SocketRead(m_socket, receive, timeout) )
00698 throw Timeout("Socket::Receive: queue SocketRead returned false (likely a timeout)");
00699 }
00700 else {
00701 throw std::logic_error("NULL queue pointer in a registered socket read.");
00702 }
00703 }
00704 else {
00705 m_zero->RawReceive(receive, timeout);
00706 }
00707 }
00708
00709
00710
00711
00712 void Socket::PacketData(Data &send, Data &receive, int timeout)
00713 {
00714 if( ( send.GetSize() < MIN_PACKET_DATA_SIZE ) ||
00715 ( send.GetSize() > MAX_PACKET_DATA_SIZE ) ) {
00716
00717 throw std::logic_error("Socket: unknown send data in PacketData()");
00718 }
00719
00720 Data &inFrag = receive;
00721 receive.Zap();
00722
00723
00724 Send(send, inFrag, timeout);
00725
00726 bool done = false;
00727 int blankCount = 0;
00728
00729 while( !done ) {
00730
00731 if( inFrag.GetSize() > 0 ) {
00732 MAKE_PACKET(rpack, inFrag);
00733
00734 blankCount = 0;
00735
00736 Protocol::CheckSize(inFrag, SB_PACKET_HEADER_SIZE);
00737
00738 switch( rpack->command )
00739 {
00740 case SB_COMMAND_SEQUENCE_HANDSHAKE:
00741 CheckSequence(inFrag);
00742 if (!m_zero->IsSequencePacketHidden())
00743 done = true;
00744 break;
00745
00746 case SB_COMMAND_JL_READY:
00747 case SB_COMMAND_JL_ACK:
00748 case SB_COMMAND_JL_HELLO_ACK:
00749 case SB_COMMAND_JL_RESET_REQUIRED:
00750 done = true;
00751 break;
00752
00753 case SB_COMMAND_JL_GET_DATA_ENTRY:
00754 done = true;
00755 break;
00756
00757 case SB_DATA_JL_INVALID:
00758 throw BadPacket(rpack->command, "file is not a valid Java code file");
00759 break;
00760
00761 case SB_COMMAND_JL_NOT_SUPPORTED:
00762 throw BadPacket(rpack->command, "device does not support requested command");
00763 break;
00764
00765 default:
00766
00767
00768 done = true;
00769 break;
00770 }
00771 }
00772 else {
00773 blankCount++;
00774
00775 if( blankCount == 10 ) {
00776
00777
00778 throw Error("Socket: 10 blank packets received");
00779 }
00780 }
00781
00782 if( !done ) {
00783
00784 Receive(inFrag);
00785 }
00786 }
00787 }
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 void Socket::Packet(Data &send, Data &receive, int timeout)
00798 {
00799 MAKE_PACKET(spack, send);
00800 if( send.GetSize() < MIN_PACKET_SIZE ||
00801 (spack->command != SB_COMMAND_DB_DATA &&
00802 spack->command != SB_COMMAND_DB_DONE) )
00803 {
00804
00805 eout("unknown send data in Packet(): " << send);
00806 throw std::logic_error("Socket: unknown send data in Packet()");
00807 }
00808
00809 Data inFrag;
00810 receive.Zap();
00811
00812 if( send.GetSize() <= MAX_PACKET_SIZE ) {
00813
00814 Send(send, inFrag, timeout);
00815 }
00816 else {
00817
00818 unsigned int offset = 0;
00819 Data outFrag;
00820
00821
00822
00823
00824
00825
00826
00827
00828 HideSequencePacket(false);
00829
00830 do {
00831 offset = SocketZero::MakeNextFragment(send, outFrag, offset);
00832
00833
00834 MAKE_PACKET(spack, outFrag);
00835
00836 if (spack->command != SB_COMMAND_DB_FRAGMENTED)
00837 HideSequencePacket(true);
00838
00839 Send(outFrag, inFrag, timeout);
00840
00841
00842
00843
00844 if (spack->command != SB_COMMAND_DB_FRAGMENTED) {
00845 MAKE_PACKET(rpack, inFrag);
00846
00847 if( offset && inFrag.GetSize() > 0 ) {
00848 Protocol::CheckSize(inFrag, SB_PACKET_HEADER_SIZE);
00849
00850 switch( rpack->command )
00851 {
00852 case SB_COMMAND_SEQUENCE_HANDSHAKE:
00853 CheckSequence(inFrag);
00854 break;
00855
00856 default: {
00857 std::ostringstream oss;
00858 oss << "Socket: (send) unhandled packet in Packet(): 0x" << std::hex << (unsigned int)rpack->command;
00859 eout(oss.str());
00860 throw Error(oss.str());
00861 }
00862 break;
00863 }
00864 }
00865 }
00866
00867 } while( offset > 0 );
00868
00869
00870 HideSequencePacket(true);
00871 }
00872
00873 bool done = false, frag = false;
00874 int blankCount = 0;
00875 while( !done ) {
00876 MAKE_PACKET(rpack, inFrag);
00877
00878
00879 if( inFrag.GetSize() > 0 ) {
00880 blankCount = 0;
00881
00882 Protocol::CheckSize(inFrag, SB_PACKET_HEADER_SIZE);
00883
00884 switch( rpack->command )
00885 {
00886 case SB_COMMAND_SEQUENCE_HANDSHAKE:
00887 CheckSequence(inFrag);
00888 break;
00889
00890 case SB_COMMAND_DB_DATA:
00891 if( frag ) {
00892 SocketZero::AppendFragment(receive, inFrag);
00893 }
00894 else {
00895 receive = inFrag;
00896 }
00897 done = true;
00898 break;
00899
00900 case SB_COMMAND_DB_FRAGMENTED:
00901 SocketZero::AppendFragment(receive, inFrag);
00902 frag = true;
00903 break;
00904
00905 case SB_COMMAND_DB_DONE:
00906 receive = inFrag;
00907 done = true;
00908 break;
00909
00910 default: {
00911 std::ostringstream oss;
00912 oss << "Socket: (read) unhandled packet in Packet(): 0x" << std::hex << (unsigned int)rpack->command;
00913 eout(oss.str());
00914 throw Error(oss.str());
00915 }
00916 break;
00917 }
00918 }
00919 else {
00920 blankCount++;
00921
00922 if( blankCount == 10 ) {
00923
00924
00925 throw Error("Socket: 10 blank packets received");
00926 }
00927 }
00928
00929 if( !done ) {
00930
00931 Receive(inFrag);
00932 }
00933 }
00934 }
00935
00936 void Socket::Packet(Barry::Packet &packet, int timeout)
00937 {
00938 Packet(packet.m_send, packet.m_receive, timeout);
00939 }
00940
00941 void Socket::Packet(Barry::JLPacket &packet, int timeout)
00942 {
00943 if( packet.HasData() ) {
00944 HideSequencePacket(false);
00945 PacketData(packet.m_cmd, packet.m_receive, timeout);
00946 HideSequencePacket(true);
00947 PacketData(packet.m_data, packet.m_receive, timeout);
00948 }
00949 else {
00950 PacketData(packet.m_cmd, packet.m_receive, timeout);
00951 }
00952 }
00953
00954 void Socket::NextRecord(Data &receive)
00955 {
00956 Barry::Protocol::Packet packet;
00957 packet.socket = htobs(GetSocket());
00958 packet.size = htobs(7);
00959 packet.command = SB_COMMAND_DB_DONE;
00960 packet.u.db.tableCmd = 0;
00961 packet.u.db.u.command.operation = 0;
00962
00963 Data command(&packet, 7);
00964 Packet(command, receive);
00965 }
00966
00967 void Socket::RegisterInterest(SocketRoutingQueue::SocketDataHandler handler,
00968 void *context)
00969 {
00970 if( !m_zero->m_queue )
00971 throw std::logic_error("SocketRoutingQueue required in SocketZero in order to call Socket::RegisterInterest()");
00972
00973 if( m_registered )
00974 throw std::logic_error("Socket already registered in Socket::RegisterInterest()!");
00975
00976 m_zero->m_queue->RegisterInterest(m_socket, handler, context);
00977 m_registered = true;
00978 }
00979
00980 void Socket::UnregisterInterest()
00981 {
00982 if( m_registered ) {
00983 if( m_zero->m_queue )
00984 m_zero->m_queue->UnregisterInterest(m_socket);
00985 m_registered = false;
00986 }
00987 }
00988
00989
00990 }
00991