""" ******************************************************************************* * Ledger Blue * (c) 2016 Ledger * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************** """ import struct from .commException import CommException def wrapCommandAPDU(channel, command, packetSize, ble=False): if packetSize < 3: raise CommException("Can't handle Ledger framing with less than 3 bytes for the report") sequenceIdx = 0 offset = 0 if not ble: result = struct.pack(">H", channel) extraHeaderSize = 2 else: result = "" extraHeaderSize = 0 result += struct.pack(">BHH", 0x05, sequenceIdx, len(command)) sequenceIdx = sequenceIdx + 1 if len(command) > packetSize - 5 - extraHeaderSize: blockSize = packetSize - 5 - extraHeaderSize else: blockSize = len(command) result += command[offset : offset + blockSize] offset = offset + blockSize while offset <> len(command): if not ble: result += struct.pack(">H", channel) result += struct.pack(">BH", 0x05, sequenceIdx) sequenceIdx = sequenceIdx + 1 if (len(command) - offset) > packetSize - 3 - extraHeaderSize: blockSize = packetSize - 3 - extraHeaderSize else: blockSize = len(command) - offset result += command[offset : offset + blockSize] offset = offset + blockSize if not ble: while (len(result) % packetSize) <> 0: result += "\x00" return bytearray(result) def unwrapResponseAPDU(channel, data, packetSize, ble=False): sequenceIdx = 0 offset = 0 if not ble: extraHeaderSize = 2 else: extraHeaderSize = 0 if ((data is None) or (len(data) < 5 + extraHeaderSize + 5)): return None if not ble: if struct.unpack(">H", str(data[offset : offset + 2]))[0] <> channel: raise CommException("Invalid channel") offset += 2 if data[offset] <> 0x05: raise CommException("Invalid tag") offset += 1 if struct.unpack(">H", str(data[offset : offset + 2]))[0] <> sequenceIdx: raise CommException("Invalid sequence") offset += 2 responseLength = struct.unpack(">H", str(data[offset : offset + 2]))[0] offset += 2 if len(data) < 5 + extraHeaderSize + responseLength: return None if responseLength > packetSize - 5 - extraHeaderSize: blockSize = packetSize - 5 - extraHeaderSize else: blockSize = responseLength result = data[offset : offset + blockSize] offset += blockSize while (len(result) <> responseLength): sequenceIdx = sequenceIdx + 1 if (offset == len(data)): return None if not ble: if struct.unpack(">H", str(data[offset : offset + 2]))[0] <> channel: raise CommException("Invalid channel") offset += 2 if data[offset] <> 0x05: raise CommException("Invalid tag") offset += 1 if struct.unpack(">H", str(data[offset : offset + 2]))[0] <> sequenceIdx: raise CommException("Invalid sequence") offset += 2 if (responseLength - len(result)) > packetSize - 3 - extraHeaderSize: blockSize = packetSize - 3 - extraHeaderSize else: blockSize = responseLength - len(result) result += data[offset : offset + blockSize] offset += blockSize return bytearray(result)