mirror of https://github.com/m2049r/xmrwallet.git
new Ledger interface
This commit is contained in:
parent
f01a8eac5d
commit
3e90f2e22e
|
@ -37,7 +37,8 @@ android {
|
|||
abi {
|
||||
enable true
|
||||
reset()
|
||||
include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
//include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
include 'arm64-v8a'
|
||||
universalApk true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright (c) 2017-2018, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#if defined(HAVE_MONERUJO)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LedgerFind - find Ledger Device and return it's name
|
||||
* @param buffer - buffer for name of found device
|
||||
* @param len - length of buffer
|
||||
* @return 0 - success
|
||||
* -1 - no device connected / found
|
||||
* -2 - JVM not found
|
||||
*/
|
||||
int LedgerFind(char *buffer, size_t len);
|
||||
|
||||
/**
|
||||
* @brief LedgerExchange - exchange data with Ledger Device
|
||||
* @param command - buffer for data to send
|
||||
* @param cmd_len - length of send to send
|
||||
* @param response - buffer for received data
|
||||
* @param max_resp_len - size of receive buffer
|
||||
*
|
||||
* @return length of received data in response or -1 if error
|
||||
*/
|
||||
int LedgerExchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "device_io.hpp"
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace hw {
|
||||
namespace io {
|
||||
class device_io_monerujo: device_io {
|
||||
public:
|
||||
device_io_monerujo() {};
|
||||
~device_io_monerujo() {};
|
||||
|
||||
void init() {};
|
||||
void release() {};
|
||||
|
||||
void connect(void *params) {};
|
||||
void disconnect() {};
|
||||
bool connected() const {return true;}; // monerujo is always connected before it gets here
|
||||
|
||||
// returns number of bytes read or -1 on error
|
||||
int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len) {
|
||||
return LedgerExchange(command, cmd_len, response, max_resp_len);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif //#if defined(HAVE_MONERUJO)
|
|
@ -1386,24 +1386,22 @@ Java_com_m2049r_xmrwallet_model_WalletManager_setLogLevel(JNIEnv *env, jobject i
|
|||
// Ledger Stuff
|
||||
//
|
||||
|
||||
#include "monerujo_ledger.h"
|
||||
#include "device_io_monerujo.hpp"
|
||||
|
||||
/**
|
||||
* @brief LedgerExchange - exchange data with Ledger Device
|
||||
* @param pbSendBuffer - buffer for data to send
|
||||
* @param cbSendLength - length of send buffer
|
||||
* @param pbRecvBuffer - buffer for received data
|
||||
* @param pcbRecvLength - pointer to size of receive buffer
|
||||
* gets set with length of received data on successful return
|
||||
* @return SCARD_S_SUCCESS - success
|
||||
* SCARD_E_NO_READERS_AVAILABLE - no device connected / found
|
||||
* SCARD_E_INSUFFICIENT_BUFFER - pbRecvBuffer is too small for the response
|
||||
* @param command - buffer for data to send
|
||||
* @param cmd_len - length of send to send
|
||||
* @param response - buffer for received data
|
||||
* @param max_resp_len - size of receive buffer
|
||||
*
|
||||
* @return length of received data in response or -1 if error
|
||||
*/
|
||||
LONG LedgerExchange(
|
||||
LPCBYTE pbSendBuffer,
|
||||
DWORD cbSendLength,
|
||||
LPBYTE pbRecvBuffer,
|
||||
LPDWORD pcbRecvLength) {
|
||||
int LedgerExchange(
|
||||
unsigned char *command,
|
||||
unsigned int cmd_len,
|
||||
unsigned char *response,
|
||||
unsigned int max_resp_len) {
|
||||
LOGD("LedgerExchange");
|
||||
JNIEnv *jenv;
|
||||
int envStat = attachJVM(&jenv);
|
||||
|
@ -1411,30 +1409,29 @@ LONG LedgerExchange(
|
|||
|
||||
jmethodID exchangeMethod = jenv->GetStaticMethodID(class_Ledger, "Exchange", "([B)[B");
|
||||
|
||||
jsize sendLen = static_cast<jsize>(cbSendLength);
|
||||
jsize sendLen = static_cast<jsize>(cmd_len);
|
||||
jbyteArray dataSend = jenv->NewByteArray(sendLen);
|
||||
jenv->SetByteArrayRegion(dataSend, 0, sendLen, (jbyte *) pbSendBuffer);
|
||||
jenv->SetByteArrayRegion(dataSend, 0, sendLen, (jbyte *) command);
|
||||
jbyteArray dataRecv = (jbyteArray) jenv->CallStaticObjectMethod(class_Ledger, exchangeMethod,
|
||||
dataSend);
|
||||
jenv->DeleteLocalRef(dataSend);
|
||||
if (dataRecv == nullptr) {
|
||||
detachJVM(jenv, envStat);
|
||||
LOGD("LedgerExchange SCARD_E_NO_READERS_AVAILABLE");
|
||||
return SCARD_E_NO_READERS_AVAILABLE;
|
||||
return -1;
|
||||
}
|
||||
jsize len = jenv->GetArrayLength(dataRecv);
|
||||
LOGD("LedgerExchange SCARD_S_SUCCESS %ld/%d", cbSendLength, len);
|
||||
if (len <= *pcbRecvLength) {
|
||||
*pcbRecvLength = static_cast<DWORD>(len);
|
||||
jenv->GetByteArrayRegion(dataRecv, 0, len, (jbyte *) pbRecvBuffer);
|
||||
LOGD("LedgerExchange SCARD_S_SUCCESS %ld/%d", cmd_len, len);
|
||||
if (len <= max_resp_len) {
|
||||
jenv->GetByteArrayRegion(dataRecv, 0, len, (jbyte *) response);
|
||||
jenv->DeleteLocalRef(dataRecv);
|
||||
detachJVM(jenv, envStat);
|
||||
return SCARD_S_SUCCESS;
|
||||
return static_cast<int>(len);;
|
||||
} else {
|
||||
jenv->DeleteLocalRef(dataRecv);
|
||||
detachJVM(jenv, envStat);
|
||||
LOGE("LedgerExchange SCARD_E_INSUFFICIENT_BUFFER");
|
||||
return SCARD_E_INSUFFICIENT_BUFFER;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2018 m2049r
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef XMRWALLET_LEDGER_H
|
||||
#define XMRWALLET_LEDGER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define SCARD_S_SUCCESS ((LONG)0x00000000) /**< No error was encountered. */
|
||||
#define SCARD_E_INSUFFICIENT_BUFFER ((LONG)0x80100008) /**< The data buffer to receive returned data is too small for the returned data. */
|
||||
#define SCARD_E_NO_READERS_AVAILABLE ((LONG)0x8010002E) /**< Cannot find a smart card reader. */
|
||||
|
||||
typedef long LONG;
|
||||
typedef unsigned long DWORD;
|
||||
typedef DWORD *LPDWORD;
|
||||
typedef unsigned char BYTE;
|
||||
typedef BYTE *LPBYTE;
|
||||
typedef const BYTE *LPCBYTE;
|
||||
|
||||
typedef char CHAR;
|
||||
typedef CHAR *LPSTR;
|
||||
|
||||
int LedgerFind(char *buffer, size_t len);
|
||||
LONG LedgerExchange(LPCBYTE pbSendBuffer, DWORD cbSendLength, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //XMRWALLET_LEDGER_H
|
|
@ -1177,6 +1177,8 @@ public class LoginActivity extends BaseActivity
|
|||
case Device_Ledger:
|
||||
if (!hasLedger()) {
|
||||
toast(R.string.open_wallet_ledger_missing);
|
||||
} else {
|
||||
startWallet(walletName, password, fingerprintUsed);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -529,16 +529,23 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onWalletStarted(final boolean success) {
|
||||
public void onWalletStarted(final Wallet.ConnectionStatus connStatus) {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
dismissProgressDialog();
|
||||
if (!success) {
|
||||
Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_connect_failed), Toast.LENGTH_LONG).show();
|
||||
switch (connStatus) {
|
||||
case ConnectionStatus_Disconnected:
|
||||
Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_connect_failed), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case ConnectionStatus_WrongVersion:
|
||||
Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_connect_wrongversion), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case ConnectionStatus_Connected:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!success) {
|
||||
if (connStatus != Wallet.ConnectionStatus.ConnectionStatus_Connected) {
|
||||
finish();
|
||||
} else {
|
||||
haveWallet = true;
|
||||
|
|
|
@ -34,11 +34,9 @@ import java.io.IOException;
|
|||
import timber.log.Timber;
|
||||
|
||||
public class Ledger {
|
||||
// lookahead parameters as suggest on
|
||||
// https://monero.stackexchange.com/a/9902/8977 (Step 8)
|
||||
// by dEBRUYNE
|
||||
static public final int LOOKAHEAD_ACCOUNTS = 3;
|
||||
static public final int LOOKAHEAD_SUBADDRESSES = 100;
|
||||
// 5:20 is same as wallet2.cpp::restore()
|
||||
static public final int LOOKAHEAD_ACCOUNTS = 5;
|
||||
static public final int LOOKAHEAD_SUBADDRESSES = 20;
|
||||
static public final String SUBADDRESS_LOOKAHEAD = LOOKAHEAD_ACCOUNTS + ":" + LOOKAHEAD_SUBADDRESSES;
|
||||
|
||||
public static final int SW_OK = 0x9000;
|
||||
|
|
|
@ -226,7 +226,7 @@ public class WalletService extends Service {
|
|||
|
||||
void onSetNotes(boolean success);
|
||||
|
||||
void onWalletStarted(boolean success);
|
||||
void onWalletStarted(Wallet.ConnectionStatus walletStatus);
|
||||
|
||||
void onWalletOpen(Wallet.Device device);
|
||||
}
|
||||
|
@ -293,9 +293,9 @@ public class WalletService extends Service {
|
|||
if (walletId != null) {
|
||||
showProgress(getString(R.string.status_wallet_loading));
|
||||
showProgress(10);
|
||||
boolean success = start(walletId, walletPw);
|
||||
if (observer != null) observer.onWalletStarted(success);
|
||||
if (!success) {
|
||||
Wallet.ConnectionStatus connStatus = start(walletId, walletPw);
|
||||
if (observer != null) observer.onWalletStarted(connStatus);
|
||||
if (connStatus != Wallet.ConnectionStatus.ConnectionStatus_Connected) {
|
||||
errorState = true;
|
||||
stop();
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ public class WalletService extends Service {
|
|||
return true; // true is important so that onUnbind is also called next time
|
||||
}
|
||||
|
||||
private boolean start(String walletName, String walletPassword) {
|
||||
private Wallet.ConnectionStatus start(String walletName, String walletPassword) {
|
||||
Timber.d("start()");
|
||||
startNotfication();
|
||||
showProgress(getString(R.string.status_wallet_loading));
|
||||
|
@ -498,9 +498,11 @@ public class WalletService extends Service {
|
|||
if (listener == null) {
|
||||
Timber.d("start() loadWallet");
|
||||
Wallet aWallet = loadWallet(walletName, walletPassword);
|
||||
if ((aWallet == null) || (aWallet.getConnectionStatus() != Wallet.ConnectionStatus.ConnectionStatus_Connected)) {
|
||||
Wallet.ConnectionStatus connStatus = Wallet.ConnectionStatus.ConnectionStatus_Disconnected;
|
||||
if (aWallet != null) connStatus = aWallet.getConnectionStatus();
|
||||
if (connStatus != Wallet.ConnectionStatus.ConnectionStatus_Connected) {
|
||||
if (aWallet != null) aWallet.close();
|
||||
return false;
|
||||
return connStatus;
|
||||
}
|
||||
listener = new MyWalletListener();
|
||||
listener.start();
|
||||
|
@ -511,7 +513,7 @@ public class WalletService extends Service {
|
|||
// if we try to refresh the history here we get occasional segfaults!
|
||||
// doesnt matter since we update as soon as we get a new block anyway
|
||||
Timber.d("start() done");
|
||||
return true;
|
||||
return Wallet.ConnectionStatus.ConnectionStatus_Connected;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
|
@ -551,6 +553,7 @@ public class WalletService extends Service {
|
|||
if (walletMgr.walletExists(path)) {
|
||||
Timber.d("open wallet %s", path);
|
||||
Wallet.Device device = WalletManager.getInstance().queryWalletDevice(path + ".keys", walletPassword);
|
||||
Timber.d("device is %s", device.toString());
|
||||
if (observer != null) observer.onWalletOpen(device);
|
||||
wallet = walletMgr.openWallet(path, walletPassword);
|
||||
showProgress(60);
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
<string name="status_wallet_unload_failed">Wallet save failed!</string>
|
||||
<string name="status_wallet_connecting">Connecting …</string>
|
||||
<string name="status_wallet_connect_failed">Node connection failed!\nCheck username/password</string>
|
||||
<string name="status_wallet_connect_wrongversion">Node version incompatible!</string>
|
||||
<string name="status_wallet_connect_timeout">Node connection timed out!\nTry again or another.</string>
|
||||
<string name="status_wallet_node_invalid">Node invalid!\nTry another.</string>
|
||||
<string name="status_wallet_connect_ioex">Cannot reach node!\nTry again or another.</string>
|
||||
|
|
|
@ -7,7 +7,7 @@ set -e
|
|||
orig_path=$PATH
|
||||
|
||||
packages=(boost openssl monero)
|
||||
archs=(arm arm64 x86 x86_64)
|
||||
archs=(arm64 x86_64)
|
||||
|
||||
for arch in ${archs[@]}; do
|
||||
case ${arch} in
|
||||
|
@ -32,11 +32,11 @@ for arch in ${archs[@]}; do
|
|||
OUTPUT_DIR=`pwd`/$package/lib/$xarch
|
||||
mkdir -p $OUTPUT_DIR
|
||||
rm -f $OUTPUT_DIR/*.a
|
||||
cp -a /opt/android/build/$package/$arch/lib/*.a $OUTPUT_DIR
|
||||
cp -a /media/m2049r/DATA/android/external-libs/build/$package/$arch/lib/*.a $OUTPUT_DIR
|
||||
|
||||
if [ $package = "monero" -a -d "/opt/android/build/$package/include" ]; then
|
||||
rm -rf $OUTPUT_DIR/../../include
|
||||
cp -a /opt/android/build/$package/include $OUTPUT_DIR/../..
|
||||
cp -a /media/m2049r/DATA/android/external-libs/build/$package/include $OUTPUT_DIR/../..
|
||||
fi
|
||||
|
||||
done
|
||||
|
|
Loading…
Reference in New Issue