Direct-BT
2.3.1
Direct-BT - Direct Bluetooth Programming.
|
Go to the documentation of this file.
25 package org.direct_bt;
28 import java.io.FileInputStream;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.text.SimpleDateFormat;
34 import java.util.Date;
61 public static final short VERSION = (short)0b0101010101010101 + (
short)2;
63 private short version;
65 private long ts_creation_sec;
79 private static final int byte_size_max = 113;
80 private static final int byte_size_min = 23;
85 final private short calcSize() {
179 static public boolean createAndWrite(
final BTDevice device,
final String path,
final boolean overwrite,
final boolean verbose_) {
186 BTUtils.
println(System.err,
"Create SMPKeyBin: Invalid "+smpKeyBin+
", "+device);
210 smpKeyBin.
read( fname );
239 if( smpKeyBin.sec_level.
value < minSecLevel.
value ) {
240 if( smpKeyBin.verbose ) {
241 BTUtils.
fprintf_td(System.err,
"SMPKeyBin::readAndApply: sec_level %s < minimum %s: Key ignored %s, removing file %s\n",
242 smpKeyBin.sec_level.toString(),
243 minSecLevel.toString(),
251 if( smpKeyBin.verbose ) {
252 BTUtils.
println(System.err,
"SMPKeyBin::readAndApply: Apply failed "+res+
", "+device+
", removing file "+fname);
268 this.addrAndType = addrAndType_;
269 this.sec_level = sec_level_;
270 this.io_cap = io_cap_;
281 this.size = calcSize();
347 final public void setVerbose(
final boolean v) { verbose = v; }
362 return r.replace(
':',
'_');
369 return r.replace(
':',
'_');
377 final StringBuilder res =
new StringBuilder();
378 res.append(
"SMPKeyBin[").append(addrAndType.
toString()).append(
", sec ").append(sec_level).append(
", io ").append(io_cap).append(
", ");
390 res.append(
"], Resp[");
402 res.append(
"ver[0x").append(Integer.toHexString(version)).append(
", ok ").append(
isVersionValid()).append(
"], size[").append(size);
404 res.append(
", calc ").append(calcSize());
406 res.append(
", valid ").append(
isSizeValid()).append(
"], ");
408 final SimpleDateFormat sdf =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
409 final Date d =
new Date(ts_creation_sec*1000);
410 res.append(sdf.format(d));
412 res.append(
", valid ").append(
isValid()).append(
"]");
414 return res.toString();
417 final public static boolean remove(
final String path,
final BDAddressAndType addrAndType_) {
418 final String fname =
getFilename(path, addrAndType_);
419 return remove_impl(fname);
421 final private static boolean remove_impl(
final String fname) {
422 final File file =
new File( fname );
424 return file.delete();
425 }
catch (
final Exception ex) {
426 BTUtils.println(System.err,
"Remove SMPKeyBin: Failed "+fname+
": "+ex.getMessage());
427 ex.printStackTrace();
432 final public boolean write(
final String fname,
final boolean overwrite) {
437 final File file =
new File( fname );
438 OutputStream out =
null;
440 if( file.exists() ) {
442 if( !file.delete() ) {
451 final byte[] buffer =
new byte[byte_size_max];
453 out =
new FileOutputStream(file);
454 out.write( (
byte) version );
455 out.write( (
byte)( version >> 8 ) );
456 out.write( (
byte) size );
457 out.write( (
byte)( size >> 8 ) );
459 writeLong(ts_creation_sec, out, buffer);
463 out.write(sec_level.
value);
464 out.write(io_cap.
value);
466 out.write(keys_init.
mask);
467 out.write(keys_resp.
mask);
490 }
catch (
final Exception ex) {
492 ex.printStackTrace();
498 }
catch (
final IOException e) {
505 final public boolean read(
final String fname) {
506 final File file =
new File(fname);
507 InputStream in =
null;
511 if( !file.canRead() ) {
518 final byte[] buffer =
new byte[byte_size_max];
519 in =
new FileInputStream(file);
520 read(in, buffer, byte_size_min, fname);
523 version = (short) ( buffer[i++] | ( buffer[i++] << 8 ) );
524 size = (short) ( buffer[i++] | ( buffer[i++] << 8 ) );
526 remaining = size - 2 - 2 ;
528 if( !err && 8 <= remaining ) {
529 ts_creation_sec = getLong(buffer, i); i+=8;
534 if( !err && 11 <= remaining ) {
540 keys_init.
mask = buffer[i++];
541 keys_resp.
mask = buffer[i++];
588 }
catch (
final Exception ex) {
590 ex.printStackTrace();
597 }
catch (
final IOException e) {
604 BTUtils.
println(System.err,
"Read SMPKeyBin: Failed "+fname+
" (removed): "+
toString()+
", remaining "+remaining);
614 final static private int read(
final InputStream in,
final byte[] buffer,
final int rsize,
final String fname)
throws IOException {
615 final int read_count = in.
read(buffer, 0, rsize);
616 if( read_count != rsize ) {
617 throw new IOException(
"Couldn't read "+rsize+
" bytes, only "+read_count+
" from "+fname);
621 final static private long getLong(
final byte[] buffer,
final int offset)
throws IOException {
623 for (
int j = 0; j < 8; ++j) {
624 res |= ((long) buffer[offset+j] & 0xff) << j*8;
628 final static private void writeLong(
final long value,
final OutputStream out,
final byte[] buffer)
throws IOException {
629 for (
int i = 0; i < 8; ++i) {
630 buffer[i] = (byte) (value >> i*8);
632 out.write(buffer, 0, 8);
705 BTUtils.
println(System.err,
"Apply SMPKeyBin failed: Device Connected/ing: "+res+
", "+
toString()+
", "+device);
ENC_ONLY
Encryption and no authentication (no MITM).
void putStream(final byte[] source, int pos)
Method transfers all bytes representing a SMPLongTermKeyInfo from the given source array at the given...
final boolean isVersionValid()
final BDAddressAndType getAddrAndType()
final boolean hasCSRKResp()
SMPPairingState getPairingState()
Returns the current SMPPairingState.
final void setVerbose(final boolean v)
static HCIStatusCode readAndApply(final String path, final BTDevice device, final BTSecurityLevel minSecLevel, final boolean verbose_)
Create a new SMPKeyBin instance on the fly based upon stored file denoted by path and BTDevice#getAdd...
Bluetooth Security Level.
NO_INPUT_NO_OUTPUT
No input not output, value 3.
static void fprintf_td(final PrintStream out, final String format, final Object ... args)
Convenient PrintStream#printf(String, Object...) invocation, prepending the elapsedTimeMillis() times...
void putStream(final byte[] source, int pos)
Method transfers all bytes representing a SMPLongTermKeyInfo from the given source array at the given...
SMPIOCapability getConnIOCapability()
Return the SMPIOCapability value, determined when the connection is established.
Author: Sven Gothel sgothel@jausoft.com Copyright (c) 2020 Gothel Software e.K.
Bluetooth secure pairing mode.
final boolean write(final String fname, final boolean overwrite)
CONNECTION_ALREADY_EXISTS
static final int byte_size
Size of the byte stream representation in bytes (28)
byte mask
The KeyType bit mask.
SMPLongTermKeyInfo getLongTermKeyInfo(final boolean responder)
Returns a copy of the long term key (LTK) info, valid after connection and SMP pairing has been compl...
final SMPIOCapability getIOCap()
boolean setConnSecurity(final BTSecurityLevel sec_level, final SMPIOCapability io_cap)
Sets the given BTSecurityLevel and SMPIOCapability used to connect to this device on the upcoming con...
static boolean createAndWrite(final BTDevice device, final String path, final boolean overwrite, final boolean verbose_)
Create a new SMPKeyBin instance on the fly based upon given BTDevice's BTSecurityLevel,...
boolean isValid()
Returns whether the device is valid, i.e.
final void getStream(final byte[] sink, int pos)
Method transfers all bytes representing this instance into the given destination array at the given p...
ENCRYPTION_MODE_NOT_ACCEPTED
final String getFileBasename()
Returns the base filename, see SMPKeyBin API doc for naming scheme.
final HCIStatusCode apply(final BTDevice device)
If this instance isValid() and initiator or responder LTK available, i.e.
boolean isSet(final KeyType bit)
Storage for SMP keys including the required connection parameter.
SMP Long Term Key Info, used for platform agnostic persistence.
SMPKeyBin(final BDAddressAndType addrAndType_, final BTSecurityLevel sec_level_, final SMPIOCapability io_cap_)
NONE
No pairing mode, implying no secure connections, no encryption and no MITM protection.
SMP Key Type for Distribution, indicates keys distributed in the Transport Specific Key Distribution ...
final SMPSignatureResolvingKeyInfo getCSRKInit()
void set(final KeyType bit)
final static String getFileBasename(final BDAddressAndType addrAndType_)
Returns the base filename, see SMPKeyBin API doc for naming scheme.
final void putStream(final byte[] source, final int pos)
Method transfers all bytes representing a EUI48 from the given source array at the given position int...
static void println(final PrintStream out, final String msg)
Convenient PrintStream#println(String) invocation, prepending the elapsedTimeMillis() timestamp.
final void setCSRKInit(final SMPSignatureResolvingKeyInfo v)
static final int byte_size
Size of the byte stream representation in bytes.
BTSecurityLevel getConnSecurityLevel()
Return the BTSecurityLevel, determined when the connection is established.
SMPKeyMask getAvailableSMPKeys(final boolean responder)
Returns the available SMPKeyMask.KeyType SMPKeyMask for the responder (LL slave) or initiator (LL mas...
UNSET
Denoting unset value, i.e.
final boolean isSizeValid()
final void setLTKResp(final SMPLongTermKeyInfo v)
NONE
No pairing in process.
SMP Pairing Process state definition.
Unique Bluetooth EUI48 address and BDAddressType tuple.
NEGOTIATING
Pairing mode in negotiating, i.e.
static BTSecurityLevel get(final String name)
Maps the specified name to a constant of BTSecurityLevel.
SIGN_KEY
Indicates that the device shall distribute CSRK using the Signing Information command.
COMPLETED
Phase 3: Key & value distribution completed by responding (slave) device sending SMPIdentInfoMsg (#1)...
UNSET
Security Level not set, value 0.
final byte b[]
The 6 byte EUI48 address.
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
ENC_KEY
LE legacy pairing: Indicates device shall distribute LTK using the Encryption Information command,...
PairingMode getPairingMode()
Returns the current PairingMode used by the device.
final void setCSRKResp(final SMPSignatureResolvingKeyInfo v)
final SMPSignatureResolvingKeyInfo getCSRKResp()
final boolean hasCSRKInit()
static SMPIOCapability get(final String name)
Maps the specified name to a constant of SMPIOCapability.
final static String getFilename(final String path, final BDAddressAndType addrAndType_)
Provides access to Bluetooth adapters.
final boolean hasLTKInit()
static SMPKeyBin read(final String fname, final boolean verbose_)
Create a new SMPKeyBin instance based upon stored file denoted by fname.
final long getCreationTime()
Returns the creation timestamp in seconds since Unix epoch.
BDAddressAndType getAddressAndType()
Returns the unique device EUI48 address and BDAddressType type.
Bluetooth address type constants.
final boolean hasLTKResp()
final boolean read(final String fname)
final BTSecurityLevel getSecLevel()
static native long wallClockSeconds()
Returns current wall-clock system time of day in seconds since Unix Epoch 00:00:00 UTC on 1 January 1...
HCIStatusCode setLongTermKeyInfo(final SMPLongTermKeyInfo ltk)
Sets the long term ket (LTK) info of this device to reuse pre-paired encryption.
static final short VERSION
NONE
No encryption and no authentication.
SMP Signature Resolving Key Info, used for platform agnostic persistence.
static BDAddressType get(final String name)
Maps the specified name to a constant of BDAddressType.
final SMPLongTermKeyInfo getLTKInit()
SMPSignatureResolvingKeyInfo getSignatureResolvingKeyInfo(final boolean responder)
Returns a copy of the Signature Resolving Key (LTK) info, valid after connection and SMP pairing has ...
static SMPKeyBin create(final BTDevice device)
Create a new SMPKeyBin instance based upon given BTDevice's BTSecurityLevel, SMPPairingState,...
final void getStream(final byte[] sink, int pos)
Method transfers all bytes representing this instance into the given destination array at the given p...
final SMPLongTermKeyInfo getLTKResp()
final void setLTKInit(final SMPLongTermKeyInfo v)