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