3 /// Class wrapper to encapsulate the Blackberry USB logical socket
7 Copyright (C) 2005-2013, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
27 #include "protostructs.h"
41 //////////////////////////////////////////////////////////////////////////////
44 SocketZero::SocketZero( SocketRoutingQueue
&queue
,
46 uint8_t zeroSocketSequenceStart
)
49 , m_writeEp(writeEndpoint
)
51 , m_zeroSocketSequence(zeroSocketSequenceStart
)
56 , m_modeSequencePacketSeen(false)
61 SocketZero::SocketZero( Device
&dev
,
62 int writeEndpoint
, int readEndpoint
,
63 uint8_t zeroSocketSequenceStart
)
66 , m_writeEp(writeEndpoint
)
67 , m_readEp(readEndpoint
)
68 , m_zeroSocketSequence(zeroSocketSequenceStart
)
73 , m_modeSequencePacketSeen(false)
78 SocketZero::~SocketZero()
80 // nothing to close for socket zero
84 ///////////////////////////////////////
85 // Socket Zero static calls
87 // appends fragment to whole... if whole is empty, simply copies, and
88 // sets command to DATA instead of FRAGMENTED. Always updates the
89 // packet size of whole, to reflect the total size
90 void SocketZero::AppendFragment(Data
&whole
, const Data
&fragment
)
92 if( whole
.GetSize() == 0 ) {
93 // empty, so just copy
97 // has some data already, so just append
98 int size
= whole
.GetSize();
99 unsigned char *buf
= whole
.GetBuffer(size
+ fragment
.GetSize());
100 MAKE_PACKET(fpack
, fragment
);
101 int fragsize
= fragment
.GetSize() - SB_FRAG_HEADER_SIZE
;
103 memcpy(buf
+size
, &fpack
->u
.db
.u
.fragment
, fragsize
);
104 whole
.ReleaseBuffer(size
+ fragsize
);
107 // update whole's size and command type for future sanity
108 Barry::Protocol::Packet
*wpack
= (Barry::Protocol::Packet
*) whole
.GetBuffer();
109 wpack
->size
= htobs((uint16_t) whole
.GetSize());
110 wpack
->command
= SB_COMMAND_DB_DATA
;
111 // don't need to call ReleaseBuffer here, since we're not changing
112 // the real data size, and ReleaseBuffer was called above during copy
115 // If offset is 0, starts fresh, taking the first fragment packet size chunk
116 // out of whole and creating a sendable packet in fragment. Returns the
117 // next offset if there is still more data, or 0 if finished.
118 unsigned int SocketZero::MakeNextFragment(const Data
&whole
, Data
&fragment
, unsigned int offset
)
121 if( whole
.GetSize() < SB_FRAG_HEADER_SIZE
) {
122 eout("Whole packet too short to fragment: " << whole
.GetSize());
123 throw Error(_("Socket: Whole packet too short to fragment"));
127 unsigned int todo
= whole
.GetSize() - SB_FRAG_HEADER_SIZE
- offset
;
128 unsigned int nextOffset
= 0;
129 if( todo
> (MAX_PACKET_SIZE
- SB_FRAG_HEADER_SIZE
) ) {
130 todo
= MAX_PACKET_SIZE
- SB_FRAG_HEADER_SIZE
;
131 nextOffset
= offset
+ todo
;
134 // create fragment header
135 unsigned char *buf
= fragment
.GetBuffer(SB_FRAG_HEADER_SIZE
+ todo
);
136 memcpy(buf
, whole
.GetData(), SB_FRAG_HEADER_SIZE
);
138 // copy over a fragment size of data
139 memcpy(buf
+ SB_FRAG_HEADER_SIZE
, whole
.GetData() + SB_FRAG_HEADER_SIZE
+ offset
, todo
);
141 // update fragment's size and command type
142 Barry::Protocol::Packet
*wpack
= (Barry::Protocol::Packet
*) buf
;
143 wpack
->size
= htobs((uint16_t) (todo
+ SB_FRAG_HEADER_SIZE
));
145 wpack
->command
= SB_COMMAND_DB_FRAGMENTED
;
147 wpack
->command
= SB_COMMAND_DB_DATA
;
149 // adjust the new fragment size
150 fragment
.ReleaseBuffer(SB_FRAG_HEADER_SIZE
+ todo
);
157 ///////////////////////////////////////
158 // SocketZero private API
161 // FIXME - not sure yet whether sequence ID's are per socket or not... if
162 // they are per socket, then this global sequence behaviour will not work,
163 // and we need to track m_sequenceId on a Socket level.
165 void SocketZero::CheckSequence(uint16_t socket
, const Data
&seq
)
167 MAKE_PACKET(spack
, seq
);
168 if( (unsigned int) seq
.GetSize() < SB_SEQUENCE_PACKET_SIZE
) {
169 eout("Short sequence packet:\n" << seq
);
170 throw Error(_("Socket: invalid sequence packet"));
173 // we'll cheat here... if the packet's sequence is 0, we'll
174 // silently restart, otherwise, fail
175 uint32_t sequenceId
= btohl(spack
->u
.sequence
.sequenceId
);
176 if( sequenceId
== 0 ) {
177 // silently restart (will advance below)
181 if( sequenceId
!= m_sequenceId
) {
183 std::string msg
= string_vprintf(_("Socket 0x%x: out of sequence. (Global sequence: 0x%x. Packet sequence: 0x%x)"),
184 (unsigned int)socket
,
185 (unsigned int)m_sequenceId
,
186 (unsigned int)sequenceId
);
191 dout("Bad sequence on socket 0: expected: "
193 << ". Packet sequence: " << sequenceId
);
202 void SocketZero::SendOpen(uint16_t socket
, Data
&receive
)
204 // build open command
205 Barry::Protocol::Packet packet
;
207 packet
.size
= htobs(SB_SOCKET_PACKET_HEADER_SIZE
);
208 packet
.command
= SB_COMMAND_OPEN_SOCKET
;
209 packet
.u
.socket
.socket
= htobs(socket
);
210 packet
.u
.socket
.sequence
= m_zeroSocketSequence
;// overwritten by Send()
212 Data
send(&packet
, SB_SOCKET_PACKET_HEADER_SIZE
);
216 if( Protocol::IsSequencePacket(receive
) ) {
217 m_modeSequencePacketSeen
= true;
218 // during open, we could get a sequence packet in
219 // the middle, from the SelectMode operation
222 } catch( Usb::Error
& ) {
223 eeout(send
, receive
);
227 // receive now holds the Open response
230 // SHA1 hashing logic based on Rick Scott's XmBlackBerry's send_password()
231 void SocketZero::SendPasswordHash(uint16_t socket
, const char *password
, Data
&receive
)
233 unsigned char pwdigest
[SHA_DIGEST_LENGTH
];
234 unsigned char prefixedhash
[SHA_DIGEST_LENGTH
+ 4];
236 // first, hash the password by itself
237 SHA1((unsigned char *) password
, strlen(password
), pwdigest
);
239 // prefix the resulting hash with the provided seed
240 uint32_t seed
= htobl(m_challengeSeed
);
241 memcpy(&prefixedhash
[0], &seed
, sizeof(uint32_t));
242 memcpy(&prefixedhash
[4], pwdigest
, SHA_DIGEST_LENGTH
);
245 SHA1((unsigned char *) prefixedhash
, SHA_DIGEST_LENGTH
+ 4, pwdigest
);
248 size_t size
= SB_SOCKET_PACKET_HEADER_SIZE
+ PASSWORD_CHALLENGE_SIZE
;
250 // build open command
251 Barry::Protocol::Packet packet
;
253 packet
.size
= htobs(size
);
254 packet
.command
= SB_COMMAND_PASSWORD
;
255 packet
.u
.socket
.socket
= htobs(socket
);
256 packet
.u
.socket
.sequence
= m_zeroSocketSequence
;// overwritten by Send()
257 packet
.u
.socket
.u
.password
.remaining_tries
= 0;
258 packet
.u
.socket
.u
.password
.unknown
= 0;
259 packet
.u
.socket
.u
.password
.param
= htobs(0x14); // FIXME - what does this mean?
260 memcpy(packet
.u
.socket
.u
.password
.u
.hash
, pwdigest
,
261 sizeof(packet
.u
.socket
.u
.password
.u
.hash
));
263 // blank password hashes as we don't need these anymore
264 memset(pwdigest
, 0, sizeof(pwdigest
));
265 memset(prefixedhash
, 0, sizeof(prefixedhash
));
267 Data
send(&packet
, size
);
271 // blank password hash as we don't need this anymore either
272 memset(packet
.u
.socket
.u
.password
.u
.hash
, 0,
273 sizeof(packet
.u
.socket
.u
.password
.u
.hash
));
277 if( Protocol::IsSequencePacket(receive
) ) {
278 m_modeSequencePacketSeen
= true;
280 CheckSequence(0, receive
);
282 // still need our ACK
286 // receive now holds the Password response
289 void SocketZero::RawSend(Data
&send
, int timeout
)
291 Usb::Device
*dev
= m_queue
? m_queue
->GetUsbDevice() : m_dev
;
293 throw Error(_("SocketZero: No device available for RawSend"));
295 // Special case: it seems that sending packets with a size that's an
296 // exact multiple of 0x40 causes the device to get confused.
298 // To get around that, it is observed in the captures that the size
299 // is sent in a special 3 byte packet before the real packet.
300 // Check for this case here.
302 if( (send
.GetSize() % 0x40) == 0 ) {
303 Protocol::SizePacket packet
;
304 packet
.size
= htobs(send
.GetSize());
305 packet
.buffer
[2] = 0; // zero the top byte
306 Data
sizeCommand(&packet
, 3);
308 dev
->BulkWrite(m_writeEp
, sizeCommand
, timeout
);
311 dev
->BulkWrite(m_writeEp
, send
, timeout
);
314 void SocketZero::RawReceive(Data
&receive
, int timeout
)
317 receive
= m_pushback_buffer
;
323 if( !m_queue
->DefaultRead(receive
, timeout
) )
324 throw Timeout(_("SocketZero::RawReceive: queue DefaultRead returned false (likely a timeout)"));
327 m_dev
->BulkRead(m_readEp
, receive
, timeout
);
330 ddout("SocketZero::RawReceive: Endpoint "
331 << (m_queue
? m_queue
->GetReadEp() : m_readEp
)
332 << "\nReceived:\n" << receive
);
335 void SocketZero::Pushback(const Data
&buf
)
338 throw Error(_("Multiple pushbacks in SocketZero!"));
341 m_pushback_buffer
= buf
;
345 ///////////////////////////////////////
346 // SocketZero public API
348 void SocketZero::SetRoutingQueue(SocketRoutingQueue
&queue
)
350 // replace the current queue pointer
354 void SocketZero::UnlinkRoutingQueue()
359 void SocketZero::Send(Data
&send
, int timeout
)
361 // force the socket number to 0
362 if( send
.GetSize() >= SB_SOCKET_PACKET_HEADER_SIZE
) {
363 MAKE_PACKETPTR_BUF(spack
, send
.GetBuffer());
367 // This is a socket 0 packet, so force the send packet data's
368 // socket 0 sequence number to something correct.
369 if( send
.GetSize() >= SB_SOCKET_PACKET_HEADER_SIZE
) {
370 MAKE_PACKETPTR_BUF(spack
, send
.GetBuffer());
371 spack
->u
.socket
.sequence
= m_zeroSocketSequence
;
372 m_zeroSocketSequence
++;
375 RawSend(send
, timeout
);
378 void SocketZero::Send(Data
&send
, Data
&receive
, int timeout
)
381 RawReceive(receive
, timeout
);
384 void SocketZero::Send(Barry::Packet
&packet
, int timeout
)
386 Send(packet
.m_send
, *packet
.m_receive
, timeout
);
389 void SocketZero::Receive(Data
&receive
, int timeout
)
391 RawReceive(receive
, timeout
);
398 /// Open a logical socket on the device.
400 /// Both the socket number and the flag are based on the response to the
401 /// SELECT_MODE command. See Controller::SelectMode() for more info
404 /// The packet sequence is normal for most socket operations.
406 /// - Down: command packet with OPEN_SOCKET
407 /// - Up: optional sequence handshake packet
408 /// - Up: command response, which repeats the socket and flag data
411 /// \exception Barry::Error
412 /// Thrown on protocol error.
414 /// \exception Barry::BadPassword
415 /// Thrown on invalid password, or not enough retries left
418 SocketHandle
SocketZero::Open(uint16_t socket
, const char *password
)
420 return Open(SocketRoutingQueue::SocketDataHandlerPtr(),
426 /// Open a logical socket on the device.
428 /// Both the socket number and the flag are based on the response to the
429 /// SELECT_MODE command. See Controller::SelectMode() for more info
432 /// This version of open includes a socket routing queue handler to
433 /// avoid the race condition with incoming data being lost if
434 /// the handler is only registered after the socket is opened.
436 /// The packet sequence is normal for most socket operations.
438 /// - Down: command packet with OPEN_SOCKET
439 /// - Up: optional sequence handshake packet
440 /// - Up: command response, which repeats the socket and flag data
443 /// \exception Barry::Error
444 /// Thrown on protocol error.
446 /// \exception Barry::BadPassword
447 /// Thrown on invalid password, or not enough retries left
450 SocketHandle
SocketZero::Open(
451 Barry::SocketRoutingQueue::SocketDataHandlerPtr handler
,
452 uint16_t socket
, const char *password
)
454 // Things get a little funky here, as we may be left in an
455 // intermediate state in the case of a failed password.
456 // This function should support being called as many times
457 // as needed to handle the password
461 ZeroPacket
packet(send
, receive
);
463 // save sequence for later close
464 uint8_t closeFlag
= GetZeroSocketSequence();
466 // It's necessary to create the socket before performing any
467 // device IO as the device can start sending packets for a socket
468 // as soon as it's sent a SB_COMMAND_OPENED_SOCKET command.
470 // If something goes wrong and this method throws an error
471 // then the SocketHandle cleanup will destroy the socket,
472 // correctly unregistering it.
473 Socket
*sock
= new Socket(*this, socket
, closeFlag
);
474 SocketHandle
sh(sock
);
476 sock
->Opening(handler
);
480 m_remainingTries
= 0;
482 // this gets set to true if we see a starting sequence packet
483 // during any of our open and password commands... After
484 // a mode command (like "RIM Desktop", etc.) a starting
485 // sequence packet is sent, and may arrive before or after
486 // the socket open handshake.
487 m_modeSequencePacketSeen
= false;
490 SendOpen(socket
, receive
);
492 // check for password challenge, or success
493 if( packet
.Command() == SB_COMMAND_PASSWORD_CHALLENGE
) {
495 m_challengeSeed
= packet
.ChallengeSeed();
496 m_remainingTries
= packet
.RemainingTries();
499 // fall through to challenge code...
503 // half open, device is expecting a password hash... do we
506 throw BadPassword(_("No password specified."), m_remainingTries
, false);
509 // only allow password attempts if there are
510 // BARRY_MIN_PASSWORD_TRIES or more tries remaining...
511 // we want to give the user at least some chance on a
512 // Windows machine before the device commits suicide.
513 if( m_remainingTries
< BARRY_MIN_PASSWORD_TRIES
) {
514 throw BadPassword(string_vprintf(_("Fewer than %d password tries remaining in device. Refusing to proceed, to avoid device zapping itself. Use a Windows client, or re-cradle the device."), BARRY_MIN_PASSWORD_TRIES
),
519 // save sequence for later close (again after SendOpen())
520 closeFlag
= GetZeroSocketSequence();
522 SendPasswordHash(socket
, password
, receive
);
524 if( packet
.Command() == SB_COMMAND_PASSWORD_FAILED
) {
526 m_challengeSeed
= packet
.ChallengeSeed();
527 m_remainingTries
= packet
.RemainingTries();
528 throw BadPassword(_("Password rejected by device."), m_remainingTries
, false);
531 // if we get this far, we are no longer in half-open password
532 // mode, so we can reset our flags
535 // fall through to success check...
538 // If the device thinks that the socket was already open then
539 // it will tell us by sending an SB_COMMAND_CLOSE_SOCKET.
541 // This happens most commonly when using raw channels which
542 // haven't been cleanly closed (such as by killing the process
543 // running Barry) and so the device still thinks the socket
546 // Retrying the open will usually succeed, but relies on the
547 // device software re-creating the channel after it's closed
548 // so return an error here instead of automatically retrying.
549 if( packet
.Command() == SB_COMMAND_CLOSE_SOCKET
)
551 throw SocketCloseOnOpen(_("Socket: Device closed socket when trying to open (can be caused by the wrong password, or if the device thinks the socket is already open... please try again)"));
554 if( packet
.Command() != SB_COMMAND_OPENED_SOCKET
||
555 packet
.SocketResponse() != socket
||
556 packet
.SocketSequence() != closeFlag
)
558 eout("Packet:\n" << receive
);
559 throw Error(_("Socket: Bad OPENED packet in Open"));
562 // if no sequence packet has yet arrived, wait for it here
563 if( !m_modeSequencePacketSeen
) {
565 RawReceive(sequence
);
566 if( !Protocol::IsSequencePacket(sequence
) ) {
567 // if this is not the sequence packet, then it might
568 // just be out of order (some devices do this when
569 // opening the JavaLoader mode), so as a last
570 // ditch effort, do one more read with a short
571 // timeout, and check that as well
573 RawReceive(late_sequence
, 500);
574 if( !Protocol::IsSequencePacket(late_sequence
) ) {
575 throw Error(_("Could not find mode's starting sequence packet"));
578 // ok, so our ditch effort worked, but now we have
579 // a leftover packet on our hands... do a temporary
594 /// Closes a non-default socket (i.e. non-zero socket number)
596 /// The packet sequence is just like Open(), except the command is
599 /// \exception Barry::Error
601 void SocketZero::Close(Socket
&socket
)
603 if( socket
.GetSocket() == 0 )
604 return; // nothing to do
606 // build close command
607 Barry::Protocol::Packet packet
;
609 packet
.size
= htobs(SB_SOCKET_PACKET_HEADER_SIZE
);
610 packet
.command
= SB_COMMAND_CLOSE_SOCKET
;
611 packet
.u
.socket
.socket
= htobs(socket
.GetSocket());
612 packet
.u
.socket
.sequence
= socket
.GetCloseFlag();
614 Data
command(&packet
, SB_SOCKET_PACKET_HEADER_SIZE
);
617 Send(command
, response
);
619 catch( Usb::Error
& ) {
620 // reset so this won't be called again
621 socket
.ForceClosed();
623 eeout(command
, response
);
627 // starting fresh, reset sequence ID
628 if( Protocol::IsSequencePacket(response
) ) {
629 CheckSequence(0, response
);
631 // still need our ACK
632 RawReceive(response
);
635 Protocol::CheckSize(response
, SB_SOCKET_PACKET_HEADER_SIZE
);
636 MAKE_PACKET(rpack
, response
);
637 // The reply will be SB_COMMAND_CLOSED_SOCKET if the device
638 // has closed the socket in response to our request.
640 // It's also possible for the reply to be
641 // SB_COMMAND_REMOTE_CLOSE_SOCKET if the device wanted to
642 // close the socket at the same time, such as if the channel
643 // API is being used by the device.
644 if( ( rpack
->command
!= SB_COMMAND_CLOSED_SOCKET
&&
645 rpack
->command
!= SB_COMMAND_REMOTE_CLOSE_SOCKET
) ||
646 btohs(rpack
->u
.socket
.socket
) != socket
.GetSocket() ||
647 rpack
->u
.socket
.sequence
!= socket
.GetCloseFlag() )
649 // reset so this won't be called again
650 socket
.ForceClosed();
652 eout("Packet:\n" << response
);
653 throw BadPacket(rpack
->command
, _("Socket: Bad CLOSED packet in Close"));
656 if( socket
.IsResetOnClose() ) {
658 ZeroPacket
reset_packet(send
, receive
);
659 reset_packet
.Reset();
662 if( reset_packet
.CommandResponse() != SB_COMMAND_RESET_REPLY
) {
663 throw BadPacket(reset_packet
.CommandResponse(),
664 _("Socket: Missing RESET_REPLY in Close"));
668 // // and finally, there always seems to be an extra read of
669 // // an empty packet at the end... just throw it away
671 // RawReceive(response, 1);
673 // catch( Usb::Timeout & ) {
676 // reset socket and flag
677 socket
.ForceClosed();
684 //////////////////////////////////////////////////////////////////////////////
687 SocketBase::~SocketBase()
691 void SocketBase::CheckSequence(const Data
&seq
)
693 // FIXME - needs implementation
699 /// Sends a fragmented Desktop / Database command packet.
700 /// Assumes that 'send' contains a valid packet, which may or may not
701 /// need fragmentation. If it does, fragmentation will be done
704 void SocketBase::DBFragSend(Data
&send
, int timeout
)
706 MAKE_PACKET(spack
, send
);
707 if( send
.GetSize() < MIN_PACKET_SIZE
||
708 (spack
->command
!= SB_COMMAND_DB_DATA
&&
709 spack
->command
!= SB_COMMAND_DB_DONE
) )
711 // we don't do that around here
712 eout("unknown send data in DBFragSend(): " << send
);
713 throw std::logic_error(_("Socket: unknown send data in DBFragSend()"));
716 if( send
.GetSize() <= MAX_PACKET_SIZE
) {
717 // send non-fragmented
718 SyncSend(send
, timeout
);
722 unsigned int offset
= 0;
726 offset
= SocketZero::MakeNextFragment(send
, outFrag
, offset
);
727 SyncSend(outFrag
, timeout
);
728 } while( offset
> 0 );
736 /// SyncSends 'send' data to device, and waits for response.
740 /// \exception Usb::Error on underlying bus errors.
742 void SocketBase::Send(Data
&send
, Data
&receive
, int timeout
)
744 SyncSend(send
, timeout
);
745 Receive(receive
, timeout
);
748 void SocketBase::Send(Barry::Packet
&packet
, int timeout
)
750 Send(packet
.m_send
, *packet
.m_receive
, timeout
);
753 // sends the send packet down to the device, fragmenting if
754 // necessary, and returns the response in receive, defragmenting
756 // Blocks until response received or timed out in Usb::Device
758 // This is primarily for Desktop Database packets... Javaloader
759 // packets use PacketData().
761 void SocketBase::Packet(Data
&send
, Data
&receive
, int timeout
)
763 // assume the common case of no fragmentation,
764 // and use the receive buffer for input... allocate a frag buffer
765 // later if necessary
766 Data
*inputBuf
= &receive
;
769 DBFragSend(send
, timeout
);
770 Receive(*inputBuf
, timeout
);
772 std::auto_ptr
<Data
> inFrag
;
773 bool done
= false, frag
= false;
776 MAKE_PACKET(rpack
, *inputBuf
);
778 // check the packet's validity
779 if( inputBuf
->GetSize() > 0 ) {
782 Protocol::CheckSize(*inputBuf
, SB_PACKET_HEADER_SIZE
);
784 switch( rpack
->command
)
786 case SB_COMMAND_SEQUENCE_HANDSHAKE
:
787 CheckSequence(*inputBuf
);
790 case SB_COMMAND_DB_DATA
:
792 SocketZero::AppendFragment(receive
, *inputBuf
);
795 // no copy needed, already in receive,
796 // since inputBuf starts out that way
801 case SB_COMMAND_DB_FRAGMENTED
:
802 // only copy if frag is true, since the
803 // first time through, receive == inputBuf
805 SocketZero::AppendFragment(receive
, *inputBuf
);
810 case SB_COMMAND_DB_DONE
:
811 // no copy needed, already in receive
816 std::ostringstream oss
;
817 oss
<< _("Socket: (read) unhandled packet in Packet(): ") << "0x" << std::hex
<< (unsigned int)rpack
->command
;
819 throw Error(oss
.str());
826 //std::cerr << "Blank! " << blankCount << std::endl;
827 if( blankCount
== 10 ) {
828 // only ask for more data on stalled sockets
830 throw Error(_("Socket: 10 blank packets received"));
835 // not done yet, ask for another read, and
836 // create new buffer for fragmented reads
837 if( frag
&& !inFrag
.get() ) {
838 inFrag
.reset( new Data
);
839 inputBuf
= inFrag
.get();
846 void SocketBase::Packet(Barry::Packet
&packet
, int timeout
)
848 Packet(packet
.m_send
, *packet
.m_receive
, timeout
);
851 void SocketBase::Packet(Barry::JLPacket
&packet
, int timeout
)
853 if( packet
.HasData() ) {
854 SyncSend(packet
.m_cmd
);
855 PacketData(packet
.m_data
, *packet
.m_receive
, false, timeout
);
858 PacketData(packet
.m_cmd
, *packet
.m_receive
, false, timeout
);
862 void SocketBase::Packet(Barry::JVMPacket
&packet
, int timeout
)
864 PacketJVM(packet
.m_cmd
, *packet
.m_receive
, timeout
);
867 // sends the send packet down to the device
868 // Blocks until response received or timed out in Usb::Device
870 // This function is used to send packet to JVM
871 void SocketBase::PacketJVM(Data
&send
, Data
&receive
, int timeout
)
873 if( ( send
.GetSize() < MIN_PACKET_DATA_SIZE
) ||
874 ( send
.GetSize() > MAX_PACKET_DATA_SIZE
) ) {
875 // we don't do that around here
876 throw std::logic_error(_("Socket: unknown send data in PacketJVM()"));
879 Data
&inFrag
= receive
;
882 // send non-fragmented
883 RawSend(send
, timeout
);
884 Receive(inFrag
, timeout
);
890 // check the packet's validity
891 if( inFrag
.GetSize() > 6 ) {
892 MAKE_PACKET(rpack
, inFrag
);
896 Protocol::CheckSize(inFrag
, SB_PACKET_HEADER_SIZE
);
898 switch( rpack
->command
)
900 case SB_COMMAND_SEQUENCE_HANDSHAKE
:
901 CheckSequence(inFrag
);
905 std::ostringstream oss
;
906 oss
<< _("Socket: (read) unhandled packet in Packet(): ") << "0x" << std::hex
<< (unsigned int)rpack
->command
;
908 throw Error(oss
.str());
913 else if( inFrag
.GetSize() == 6 ) {
919 //std::cerr << "Blank! " << blankCount << std::endl;
920 if( blankCount
== 10 ) {
921 // only ask for more data on stalled sockets
923 throw Error(_("Socket: 10 blank packets received"));
928 // not done yet, ask for another read
929 Receive(inFrag
, timeout
);
934 // sends the send packet down to the device
935 // Blocks until response received or timed out in Usb::Device
936 void SocketBase::PacketData(Data
&send
,
938 bool done_on_sequence
,
941 if( ( send
.GetSize() < MIN_PACKET_DATA_SIZE
) ||
942 ( send
.GetSize() > MAX_PACKET_DATA_SIZE
) ) {
943 // we don't do that around here
944 throw std::logic_error(_("Socket: unknown send data in PacketData()"));
947 Data
&inFrag
= receive
;
950 // send non-fragmented
951 SyncSend(send
, timeout
);
952 Receive(inFrag
, timeout
);
958 // check the packet's validity
959 if( inFrag
.GetSize() > 0 ) {
960 MAKE_PACKET(rpack
, inFrag
);
964 Protocol::CheckSize(inFrag
, SB_PACKET_HEADER_SIZE
);
966 switch( rpack
->command
)
968 case SB_COMMAND_SEQUENCE_HANDSHAKE
:
969 // CheckSequence(inFrag);
970 if( done_on_sequence
)
974 case SB_COMMAND_JL_READY
:
975 case SB_COMMAND_JL_ACK
:
976 case SB_COMMAND_JL_HELLO_ACK
:
977 case SB_COMMAND_JL_RESET_REQUIRED
:
981 case SB_COMMAND_JL_GET_DATA_ENTRY
: // This response means that the next packet is the stream
985 case SB_DATA_JL_INVALID
:
986 throw BadPacket(rpack
->command
, _("file is not a valid Java code file"));
989 case SB_COMMAND_JL_NOT_SUPPORTED
:
990 throw BadPacket(rpack
->command
, _("device does not support requested command"));
994 // unknown packet, pass it up to the
995 // next higher code layer
1002 //std::cerr << "Blank! " << blankCount << std::endl;
1003 if( blankCount
== 10 ) {
1004 // only ask for more data on stalled sockets
1006 throw Error(_("Socket: 10 blank packets received"));
1011 // not done yet, ask for another read
1017 void SocketBase::NextRecord(Data
&receive
)
1019 Barry::Protocol::Packet packet
;
1020 packet
.size
= htobs(7);
1021 packet
.command
= SB_COMMAND_DB_DONE
;
1022 packet
.u
.db
.tableCmd
= 0;
1023 packet
.u
.db
.u
.command
.operation
= 0;
1025 Data
command(&packet
, 7);
1026 Packet(command
, receive
);
1031 //////////////////////////////////////////////////////////////////////////////
1034 Socket::Socket( SocketZero
&zero
,
1039 , m_closeFlag(closeFlag
)
1040 , m_registered(false)
1041 , m_sequence(new Data
)
1047 // trap exceptions in the destructor
1049 // a non-default socket has been opened, close it
1052 catch( std::runtime_error
&DEBUG_ONLY(re
) ) {
1053 // do nothing... log it?
1054 dout("Exception caught in ~Socket: " << re
.what());
1059 ////////////////////////////////////
1060 // Socket protected API
1062 void Socket::ForceClosed()
1068 void Socket::LocalClose()
1070 LocalUnregisterInterest();
1071 m_zero
->Close(*this);
1074 void Socket::LocalUnregisterInterest()
1076 if( m_registered
) {
1077 if( m_zero
->m_queue
)
1078 m_zero
->m_queue
->UnregisterInterest(m_socket
);
1079 m_registered
= false;
1087 /// Sends 'send' data to device, no receive.
1091 /// \exception Usb::Error on underlying bus errors.
1093 void Socket::RawSend(Data
&send
, int timeout
)
1095 // force the socket number to this socket
1096 if( send
.GetSize() >= SB_PACKET_HEADER_SIZE
) {
1097 MAKE_PACKETPTR_BUF(spack
, send
.GetBuffer());
1098 spack
->socket
= htobs(m_socket
);
1100 m_zero
->RawSend(send
, timeout
);
1103 void Socket::SyncSend(Data
&send
, int timeout
)
1105 RawSend(send
, timeout
);
1106 Receive(*m_sequence
, timeout
);
1107 if( !Protocol::IsSequencePacket(*m_sequence
) )
1108 throw Barry::Error(_("Non-sequence packet in Socket::SyncSend()"));
1109 CheckSequence(*m_sequence
);
1112 void Socket::Receive(Data
&receive
, int timeout
)
1114 if( m_registered
) {
1115 if( m_zero
->m_queue
) {
1116 if( !m_zero
->m_queue
->SocketRead(m_socket
, receive
, timeout
) )
1117 throw Timeout(_("Socket::Receive: queue SocketRead returned false (likely a timeout)"));
1120 throw std::logic_error(_("NULL queue pointer in a registered socket read."));
1122 ddout("Socket::Receive: Endpoint "
1123 << (m_zero
->m_queue
? m_zero
->m_queue
->GetReadEp() : m_zero
->m_readEp
)
1124 << "\nReceived:\n" << receive
);
1127 m_zero
->RawReceive(receive
, timeout
);
1132 void Socket::RegisterInterest(SocketRoutingQueue::SocketDataHandlerPtr handler
)
1134 if( !m_zero
->m_queue
)
1135 throw std::logic_error(_("SocketRoutingQueue required in SocketZero in order to call Socket::RegisterInterest()"));
1137 if( m_registered
) {
1138 throw std::logic_error(string_vprintf(_("Socket (%u) already registered in Socket::RegisterInterest()!"), (unsigned int)m_socket
));
1141 m_zero
->m_queue
->RegisterInterest(m_socket
, handler
);
1142 m_registered
= true;
1145 void Socket::Opening(Barry::SocketRoutingQueue::SocketDataHandlerPtr handler
)
1147 // if we are running with a routing queue, register the
1148 // socket's interest in its own data packets. By default, this
1149 // data will be queued without a callback handler.
1150 // If other application code needs to intercept this with
1151 // its own handler, it must call UnregisterInterest() and
1152 // re-register its own handler
1154 // As opening requires sequence packets to still come in on
1155 // the default queue, only register for data until the socket
1157 if( m_zero
->m_queue
) {
1158 m_zero
->m_queue
->RegisterInterestAndType(m_socket
,
1159 handler
, SocketRoutingQueue::DataPackets
);
1160 m_registered
= true;
1164 void Socket::Opened()
1166 if( m_zero
->m_queue
) {
1167 if( !m_registered
) {
1168 std::ostringstream oss
;
1169 oss
<< "Socket (" << m_socket
<< ") not previously registered in Socket::Opened()!";
1170 throw std::logic_error(oss
.str());
1172 // Need to complete registration and register for
1173 // sequence packets in addition to data packets.
1174 m_zero
->m_queue
->ChangeInterest(m_socket
,
1175 SocketRoutingQueue::SequenceAndDataPackets
);
1180 } // namespace Barry