diff options
50 files changed, 283 insertions, 2789 deletions
diff --git a/api/direct_bt/ATTPDUTypes.hpp b/api/direct_bt/ATTPDUTypes.hpp index 78b68cd9..b56d8ac4 100644 --- a/api/direct_bt/ATTPDUTypes.hpp +++ b/api/direct_bt/ATTPDUTypes.hpp @@ -36,11 +36,11 @@ #include <atomic> #include <jau/basic_types.hpp> +#include <jau/octets.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" #include "BTTypes0.hpp" -#include "OctetTypes.hpp" /** * - - - - - - - - - - - - - - - @@ -432,7 +432,7 @@ namespace direct_bt { public: /** actual received PDU */ - POctets pdu; + jau::POctets pdu; /** flags a request PDU, i.e. a command etc, initiated by a GATT client */ const bool is_request; @@ -753,7 +753,7 @@ namespace direct_bt { class AttReadRsp: public AttPDUMsg { private: - const TOctetSlice view; + const jau::TOctetSlice view; constexpr static jau::nsize_t pdu_value_offset = 1; @@ -770,7 +770,7 @@ namespace direct_bt { constexpr uint8_t const * getValuePtr() const noexcept { return pdu.get_ptr_nc( pdu_value_offset ); } - constexpr TOctetSlice const & getValue() const noexcept { return view; } + constexpr jau::TOctetSlice const & getValue() const noexcept { return view; } constexpr_cxx20 std::string getName() const noexcept override { return "AttReadRsp"; @@ -836,7 +836,7 @@ namespace direct_bt { class AttReadBlobRsp: public AttPDUMsg { private: - const TOctetSlice view; + const jau::TOctetSlice view; constexpr static jau::nsize_t pdu_value_offset = 1; @@ -853,7 +853,7 @@ namespace direct_bt { constexpr uint8_t const * getValuePtr() const noexcept { return pdu.get_ptr_nc( pdu_value_offset ); } - constexpr TOctetSlice const & getValue() const noexcept { return view; } + constexpr jau::TOctetSlice const & getValue() const noexcept { return view; } constexpr_cxx20 std::string getName() const noexcept override { return "AttReadBlobRsp"; @@ -881,12 +881,12 @@ namespace direct_bt { class AttWriteReq : public AttPDUMsg { private: - const TOctetSlice view; + const jau::TOctetSlice view; constexpr static jau::nsize_t pdu_value_offset = 1 + 2; public: - AttWriteReq(const uint16_t handle, const TROOctets & value) + AttWriteReq(const uint16_t handle, const jau::TROOctets & value) : AttPDUMsg(Opcode::WRITE_REQ, 1+2+value.getSize()), view(pdu, getPDUValueOffset(), getPDUValueSize()) { pdu.put_uint16_nc(1, handle); @@ -902,7 +902,7 @@ namespace direct_bt { constexpr uint8_t const * getValuePtr() const noexcept { return pdu.get_ptr_nc( pdu_value_offset ); } - constexpr TOctetSlice const & getValue() const noexcept { return view; } + constexpr jau::TOctetSlice const & getValue() const noexcept { return view; } constexpr_cxx20 std::string getName() const noexcept override { return "AttWriteReq"; @@ -953,12 +953,12 @@ namespace direct_bt { class AttWriteCmd : public AttPDUMsg { private: - const TOctetSlice view; + const jau::TOctetSlice view; constexpr static jau::nsize_t pdu_value_offset = 1 + 2; public: - AttWriteCmd(const uint16_t handle, const TROOctets & value) + AttWriteCmd(const uint16_t handle, const jau::TROOctets & value) : AttPDUMsg(Opcode::WRITE_CMD, 1+2+value.getSize()), view(pdu, getPDUValueOffset(), getPDUValueSize()) { pdu.put_uint16_nc(1, handle); @@ -974,7 +974,7 @@ namespace direct_bt { constexpr uint8_t const * getValuePtr() const noexcept { return pdu.get_ptr_nc( pdu_value_offset ); } - constexpr TOctetSlice const & getValue() const noexcept { return view; } + constexpr jau::TOctetSlice const & getValue() const noexcept { return view; } constexpr_cxx20 std::string getName() const noexcept override { return "AttWriteCmd"; @@ -1005,7 +1005,7 @@ namespace direct_bt { class AttHandleValueRcv: public AttPDUMsg { private: - const TOctetSlice view; + const jau::TOctetSlice view; constexpr static jau::nsize_t pdu_value_offset = 1 + 2; @@ -1022,7 +1022,7 @@ namespace direct_bt { constexpr uint8_t const * getValuePtr() const noexcept { return pdu.get_ptr_nc( pdu_value_offset ); } - TOctetSlice const & getValue() const noexcept { return view; } + jau::TOctetSlice const & getValue() const noexcept { return view; } bool isNotification() const noexcept { return Opcode::HANDLE_VALUE_NTF == getOpcode(); @@ -1136,15 +1136,15 @@ namespace direct_bt { class AttReadByNTypeReq : public AttPDUMsg { private: - constexpr_cxx20 uuid_t::TypeSize getUUIFormat() const { - return uuid_t::toTypeSize(this->getPDUValueSize()); + constexpr_cxx20 jau::uuid_t::TypeSize getUUIFormat() const { + return jau::uuid_t::toTypeSize(this->getPDUValueSize()); } public: - AttReadByNTypeReq(const bool groupTypeReq, const uint16_t startHandle, const uint16_t endHandle, const uuid_t & uuid) + AttReadByNTypeReq(const bool groupTypeReq, const uint16_t startHandle, const uint16_t endHandle, const jau::uuid_t & uuid) : AttPDUMsg(groupTypeReq ? Opcode::READ_BY_GROUP_TYPE_REQ : Opcode::READ_BY_TYPE_REQ, 1+2+2+uuid.getTypeSizeInt()) { - if( uuid.getTypeSize() != uuid_t::TypeSize::UUID16_SZ && uuid.getTypeSize()!= uuid_t::TypeSize::UUID128_SZ ) { + if( uuid.getTypeSize() != jau::uuid_t::TypeSize::UUID16_SZ && uuid.getTypeSize()!= jau::uuid_t::TypeSize::UUID128_SZ ) { throw jau::IllegalArgumentException("Only UUID16 and UUID128 allowed: "+uuid.toString(), E_FILE_LINE); } pdu.put_uint16_nc(1, startHandle); @@ -1163,7 +1163,7 @@ namespace direct_bt { return "AttReadByNTypeReq"; } - std::unique_ptr<const uuid_t> getNType() const { + std::unique_ptr<const jau::uuid_t> getNType() const { return pdu.get_uuid( getPDUValueOffset(), getUUIFormat() ); } @@ -1202,7 +1202,7 @@ namespace direct_bt { */ class Element { private: - const TOctetSlice view; + const jau::TOctetSlice view; public: Element(const AttReadByTypeRsp & p, const jau::nsize_t idx) @@ -1301,7 +1301,7 @@ namespace direct_bt { */ class Element { private: - const TOctetSlice view; + const jau::TOctetSlice view; public: Element(const AttReadByGroupTypeRsp & p, const jau::nsize_t idx) @@ -1436,12 +1436,12 @@ namespace direct_bt { class AttFindInfoRsp: public AttElementList { private: - uuid_t::TypeSize getUUIFormat() const { + jau::uuid_t::TypeSize getUUIFormat() const { const int f = pdu.get_uint8_nc(1); if( 0x01 == f ) { - return uuid_t::TypeSize::UUID16_SZ; + return jau::uuid_t::TypeSize::UUID16_SZ; } else if( 0x02 == f ) { - return uuid_t::TypeSize::UUID128_SZ; + return jau::uuid_t::TypeSize::UUID128_SZ; } throw AttValueException("PDUFindInfoRsp: Invalid format "+std::to_string(f)+", not UUID16 (1) or UUID128 (2)", E_FILE_LINE); } @@ -1453,7 +1453,7 @@ namespace direct_bt { class Element { public: const uint16_t handle; - const std::unique_ptr<const uuid_t> uuid; + const std::unique_ptr<const jau::uuid_t> uuid; Element(const AttFindInfoRsp & p, const jau::nsize_t idx) : handle( p.getElementHandle(idx) ), uuid( p.getElementValue(idx) ) @@ -1483,7 +1483,7 @@ namespace direct_bt { * </p> */ jau::nsize_t getElementValueSize() const override { - return uuid_t::number(getUUIFormat()); + return jau::uuid_t::number(getUUIFormat()); } jau::nsize_t getElementCount() const override { @@ -1498,7 +1498,7 @@ namespace direct_bt { return pdu.get_uint16( getElementPDUOffset(elementIdx) ); } - std::unique_ptr<const uuid_t> getElementValue(const jau::nsize_t elementIdx) const { + std::unique_ptr<const jau::uuid_t> getElementValue(const jau::nsize_t elementIdx) const { return pdu.get_uuid( getElementPDUOffset(elementIdx) + 2, getUUIFormat() ); } diff --git a/api/direct_bt/BTAddress.hpp b/api/direct_bt/BTAddress.hpp index ec094d1a..593ee254 100644 --- a/api/direct_bt/BTAddress.hpp +++ b/api/direct_bt/BTAddress.hpp @@ -33,6 +33,10 @@ #include <jau/packed_attribute.hpp> #include <jau/ordered_atomic.hpp> +#include <jau/eui48.hpp> + +using jau::EUI48; +using jau::EUI48Sub; namespace direct_bt { @@ -154,263 +158,6 @@ namespace direct_bt { HCILEOwnAddressType to_HCILEOwnAddressType(const BDAddressType addrType) noexcept; std::string to_string(const HCILEOwnAddressType type) noexcept; - /** - * A 48 bit EUI-48 sub-identifier, see EUI48. - */ - struct EUI48Sub { - /** EUI48 MAC address matching any device, i.e. `0:0:0:0:0:0`. */ - static const EUI48Sub ANY_DEVICE; - /** EUI48 MAC address matching all device, i.e. `ff:ff:ff:ff:ff:ff`. */ - static const EUI48Sub ALL_DEVICE; - /** EUI48 MAC address matching local device, i.e. `0:0:0:ff:ff:ff`. */ - static const EUI48Sub LOCAL_DEVICE; - - /** - * The <= 6 byte EUI48 sub-address. - */ - uint8_t b[6]; // == sizeof(EUI48) - - /** - * The actual length in bytes of the EUI48 sub-address, less or equal 6 bytes. - */ - jau::nsize_t length; - - constexpr EUI48Sub() noexcept : b{0}, length{0} { } - EUI48Sub(const uint8_t * b_, const jau::nsize_t len_) noexcept; - - /** - * Fills given EUI48Sub instance via given string representation. - * <p> - * Implementation is consistent with EUI48Sub::toString(). - * </p> - * @param str a string of less or equal of 17 characters representing less or equal of 6 bytes as hexadecimal numbers separated via colon, - * e.g. `01:02:03:0A:0B:0C`, `01:02:03:0A`, `:`, (empty). - * @param dest EUI48Sub to set its value - * @param errmsg error parsing message if returning false - * @return true if successful, otherwise false - * @see EUI48Sub::EUI48Sub - * @see EUI48Sub::toString() - */ - static bool scanEUI48Sub(const std::string& str, EUI48Sub& dest, std::string& errmsg); - - /** - * Construct a sub EUI48 via given string representation. - * <p> - * Implementation is consistent with EUI48Sub::toString(). - * </p> - * @param str a string of less or equal of 17 characters representing less or equal of 6 bytes as hexadecimal numbers separated via colon, - * e.g. `01:02:03:0A:0B:0C`, `01:02:03:0A`, `:`, (empty). - * @see EUI48Sub::scanEUI48Sub() - * @see EUI48Sub::toString() - * @throws jau::IllegalArgumentException if given string doesn't comply with EUI48 - */ - EUI48Sub(const std::string& str); - - constexpr EUI48Sub(const EUI48Sub &o) noexcept = default; - EUI48Sub(EUI48Sub &&o) noexcept = default; - constexpr EUI48Sub& operator=(const EUI48Sub &o) noexcept = default; - EUI48Sub& operator=(EUI48Sub &&o) noexcept = default; - - constexpr std::size_t hash_code() const noexcept { - // 31 * x == (x << 5) - x - std::size_t h = length; - for(jau::nsize_t i=0; i<length; i++) { - h = ( ( h << 5 ) - h ) + b[i]; - } - return h; - } - - /** - * Method clears the underlying byte array {@link #b} and sets length to zero. - */ - void clear() { - b[0] = 0; b[1] = 0; b[2] = 0; - b[3] = 0; b[4] = 0; b[5] = 0; - length = 0; - } - - /** - * Find index of needle within haystack. - * @param haystack_b haystack data - * @param haystack_length haystack length - * @param needle_b needle data - * @param needle_length needle length - * @return index of first element of needle within haystack or -1 if not found. If the needle length is zero, 0 (found) is returned. - */ - static jau::snsize_t indexOf(const uint8_t haystack_b[], const jau::nsize_t haystack_length, - const uint8_t needle_b[], const jau::nsize_t needle_length) noexcept; - - /** - * Finds the index of given EUI48Sub needle within this instance haystack. - * @param needle - * @return index of first element of needle within this instance haystack or -1 if not found. If the needle length is zero, 0 (found) is returned. - */ - jau::snsize_t indexOf(const EUI48Sub& needle) const noexcept { - return indexOf(b, length, needle.b, needle.length); - } - - /** - * Returns true, if given EUI48Sub needle is contained in this instance haystack. - * <p> - * If the sub is zero, true is returned. - * </p> - */ - bool contains(const EUI48Sub& needle) const noexcept { - return 0 <= indexOf(needle); - } - - /** - * Returns the EUI48 sub-string representation, - * less or equal 17 characters representing less or equal 6 bytes as upper case hexadecimal numbers separated via colon, - * e.g. `01:02:03:0A:0B:0C`, `01:02:03:0A`, `:`, (empty). - */ - std::string toString() const noexcept; - }; - inline std::string to_string(const EUI48Sub& a) noexcept { return a.toString(); } - - inline bool operator==(const EUI48Sub& lhs, const EUI48Sub& rhs) noexcept { - if( &lhs == &rhs ) { - return true; - } - if( lhs.length != rhs.length ) { - return false; - } - return !memcmp(&lhs.b, &rhs.b, lhs.length); - } - - inline bool operator!=(const EUI48Sub& lhs, const EUI48Sub& rhs) noexcept - { return !(lhs == rhs); } - - - /** - * A packed 48 bit EUI-48 identifier, formerly known as MAC-48 - * or simply network device MAC address (Media Access Control address). - */ - __pack ( struct EUI48 { - /** EUI48 MAC address matching any device, i.e. `0:0:0:0:0:0`. */ - static const EUI48 ANY_DEVICE; - /** EUI48 MAC address matching all device, i.e. `ff:ff:ff:ff:ff:ff`. */ - static const EUI48 ALL_DEVICE; - /** EUI48 MAC address matching local device, i.e. `0:0:0:ff:ff:ff`. */ - static const EUI48 LOCAL_DEVICE; - - /** - * The 6 byte EUI48 address. - */ - uint8_t b[6]; // == sizeof(EUI48) - - constexpr EUI48() noexcept : b{0} { } - EUI48(const uint8_t * b_) noexcept; - - /** - * Fills given EUI48 instance via given string representation. - * <p> - * Implementation is consistent with EUI48::toString(). - * </p> - * @param str a string of exactly 17 characters representing 6 bytes as hexadecimal numbers separated via colon `01:02:03:0A:0B:0C`. - * @param dest EUI48 to set its value - * @param errmsg error parsing message if returning false - * @return true if successful, otherwise false - * @see EUI48::EUI48 - * @see EUI48::toString() - */ - static bool scanEUI48(const std::string& str, EUI48& dest, std::string& errmsg); - - /** - * Construct instance via given string representation. - * <p> - * Implementation is consistent with EUI48::toString(). - * </p> - * @param str a string of exactly 17 characters representing 6 bytes as hexadecimal numbers separated via colon `01:02:03:0A:0B:0C`. - * @see EUI48::scanEUI48() - * @see EUI48::toString() - * @throws jau::IllegalArgumentException if given string doesn't comply with EUI48 - */ - EUI48(const std::string& str); - - constexpr EUI48(const EUI48 &o) noexcept = default; - EUI48(EUI48 &&o) noexcept = default; - constexpr EUI48& operator=(const EUI48 &o) noexcept = default; - EUI48& operator=(EUI48 &&o) noexcept = default; - - constexpr std::size_t hash_code() const noexcept { - // 31 * x == (x << 5) - x - std::size_t h = b[0]; - h = ( ( h << 5 ) - h ) + b[1]; - h = ( ( h << 5 ) - h ) + b[2]; - h = ( ( h << 5 ) - h ) + b[3]; - h = ( ( h << 5 ) - h ) + b[4]; - h = ( ( h << 5 ) - h ) + b[5]; - return h; - } - - /** - * Method clears the underlying byte array {@link #b}. - */ - void clear() { - b[0] = 0; b[1] = 0; b[2] = 0; - b[3] = 0; b[4] = 0; b[5] = 0; - } - - /** - * Returns the BLERandomAddressType. - * <p> - * If ::BDAddressType is ::BDAddressType::BDADDR_LE_RANDOM, - * method shall return a valid value other than ::BLERandomAddressType::UNDEFINED. - * </p> - * <p> - * If BDAddressType is not ::BDAddressType::BDADDR_LE_RANDOM, - * method shall return ::BLERandomAddressType::UNDEFINED. - * </p> - * @since 2.2.0 - */ - BLERandomAddressType getBLERandomAddressType(const BDAddressType addressType) const noexcept; - - /** - * Finds the index of given EUI48Sub needle within this instance haystack. - * @param needle - * @return index of first element of needle within this instance haystack or -1 if not found. If the needle length is zero, 0 (found) is returned. - */ - jau::snsize_t indexOf(const EUI48Sub& needle) const noexcept { - return EUI48Sub::indexOf(b, sizeof(b), needle.b, needle.length); - } - - /** - * Returns true, if given EUI48Sub needle is contained in this instance haystack. - * <p> - * If the sub is zero, true is returned. - * </p> - */ - bool contains(const EUI48Sub& needle) const noexcept { - return 0 <= indexOf(needle); - } - - /** - * Returns the EUI48 string representation, - * exactly 17 characters representing 6 bytes as upper case hexadecimal numbers separated via colon `01:02:03:0A:0B:0C`. - * @see EUI48::EUI48() - */ - std::string toString() const noexcept; - } ); - inline std::string to_string(const EUI48& a) noexcept { return a.toString(); } - - inline bool operator==(const EUI48& lhs, const EUI48& rhs) noexcept { - if( &lhs == &rhs ) { - return true; - } - //return !memcmp(&lhs, &rhs, sizeof(EUI48)); - const uint8_t * a = lhs.b; - const uint8_t * b = rhs.b; - return a[0] == b[0] && - a[1] == b[1] && - a[2] == b[2] && - a[3] == b[3] && - a[4] == b[4] && - a[5] == b[5]; - } - - inline bool operator!=(const EUI48& lhs, const EUI48& rhs) noexcept - { return !(lhs == rhs); } /** * Unique Bluetooth EUI48 address and ::BDAddressType tuple. @@ -431,14 +178,14 @@ namespace direct_bt { */ static const BDAddressAndType ANY_DEVICE; - EUI48 address; + jau::EUI48 address; BDAddressType type; private: jau::relaxed_atomic_size_t hash = 0; // default 0, cache public: - BDAddressAndType(const EUI48 & address_, BDAddressType type_) + BDAddressAndType(const jau::EUI48 & address_, BDAddressType type_) : address(address_), type(type_) {} constexpr BDAddressAndType() noexcept : address(), type{BDAddressType::BDADDR_UNDEFINED} { } @@ -473,6 +220,20 @@ namespace direct_bt { /** * Returns the BLERandomAddressType. * <p> + * If ::BDAddressType is ::BDAddressType::BDADDR_LE_RANDOM, + * method shall return a valid value other than ::BLERandomAddressType::UNDEFINED. + * </p> + * <p> + * If BDAddressType is not ::BDAddressType::BDADDR_LE_RANDOM, + * method shall return ::BLERandomAddressType::UNDEFINED. + * </p> + * @since 2.2.0 + */ + static BLERandomAddressType getBLERandomAddressType(const jau::EUI48& address, const BDAddressType addressType) noexcept; + + /** + * Returns the BLERandomAddressType. + * <p> * If type is ::BDAddressType::BDADDR_LE_RANDOM}, * method shall return a valid value other than ::BLERandomAddressType::UNDEFINED. * </p> @@ -483,9 +244,10 @@ namespace direct_bt { * @since 2.0.0 */ BLERandomAddressType getBLERandomAddressType() const noexcept { - return address.getBLERandomAddressType(type); + return getBLERandomAddressType(address, type); } + /** * Returns true if both devices match, i.e. equal address * and equal type or at least one type is {@link BDAddressType#BDADDR_UNDEFINED}. @@ -549,18 +311,6 @@ namespace direct_bt { // injecting specialization of std::hash to namespace std of our types above namespace std { - template<> struct hash<direct_bt::EUI48Sub> { - std::size_t operator()(direct_bt::EUI48Sub const& a) const noexcept { - return a.hash_code(); - } - }; - - template<> struct hash<direct_bt::EUI48> { - std::size_t operator()(direct_bt::EUI48 const& a) const noexcept { - return a.hash_code(); - } - }; - template<> struct hash<direct_bt::BDAddressAndType> { std::size_t operator()(direct_bt::BDAddressAndType const& a) const noexcept { return a.hash_code(); diff --git a/api/direct_bt/BTDevice.hpp b/api/direct_bt/BTDevice.hpp index 3e306238..eecf0c1d 100644 --- a/api/direct_bt/BTDevice.hpp +++ b/api/direct_bt/BTDevice.hpp @@ -88,7 +88,7 @@ namespace direct_bt { jau::relaxed_atomic_uint16 hciConnHandle; jau::ordered_atomic<LE_Features, std::memory_order_relaxed> le_features; std::shared_ptr<ManufactureSpecificData> advMSD = nullptr; - jau::darray<std::shared_ptr<const uuid_t>> advServices; + jau::darray<std::shared_ptr<const jau::uuid_t>> advServices; #if SMP_SUPPORTED_BY_OS std::shared_ptr<SMPHandler> smpHandler = nullptr; std::recursive_mutex mtx_smpHandler; @@ -144,14 +144,14 @@ namespace direct_bt { } /** Add advertised service (GAP discovery) */ - bool addAdvService(std::shared_ptr<const uuid_t> const &uuid) noexcept; + bool addAdvService(std::shared_ptr<const jau::uuid_t> const &uuid) noexcept; /** Add advertised service (GAP discovery) */ - bool addAdvServices(jau::darray<std::shared_ptr<const uuid_t>> const & services) noexcept; + bool addAdvServices(jau::darray<std::shared_ptr<const jau::uuid_t>> const & services) noexcept; /** * Find advertised service (GAP discovery) index * @return index >= 0 if found, otherwise -1 */ - int findAdvService(std::shared_ptr<const uuid_t> const &uuid) const noexcept; + int findAdvService(const jau::uuid_t& uuid) const noexcept; EIRDataType update(EInfoReport const & data) noexcept; EIRDataType update(GattGenericAccessSvc const &data, const uint64_t timestamp) noexcept; @@ -332,7 +332,7 @@ namespace direct_bt { * use {@link #getGattService()}. * </p> */ - jau::darray<std::shared_ptr<const uuid_t>> getAdvertisedServices() const noexcept; + jau::darray<std::shared_ptr<const jau::uuid_t>> getAdvertisedServices() const noexcept; std::string toString() const noexcept override { return toString(false); } @@ -905,7 +905,7 @@ namespace direct_bt { * Implementation calls getGattService(). * </p> */ - std::shared_ptr<BTGattService> findGattService(std::shared_ptr<uuid_t> const &uuid); + std::shared_ptr<BTGattService> findGattService(const jau::uuid_t& uuid); /** Returns the shared GenericAccess instance, retrieved by {@link #getGattService()} or nullptr if not available. */ std::shared_ptr<GattGenericAccessSvc> getGattGenericAccess(); diff --git a/api/direct_bt/BTGattChar.hpp b/api/direct_bt/BTGattChar.hpp index 44dd48b3..944ecceb 100644 --- a/api/direct_bt/BTGattChar.hpp +++ b/api/direct_bt/BTGattChar.hpp @@ -35,10 +35,10 @@ #include <atomic> #include <jau/java_uplink.hpp> +#include <jau/octets.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" #include "BTTypes0.hpp" -#include "OctetTypes.hpp" #include "ATTPDUTypes.hpp" #include "BTTypes1.hpp" @@ -129,7 +129,7 @@ namespace direct_bt { * @param timestamp the indication monotonic timestamp, see getCurrentMilliseconds() */ virtual void notificationReceived(BTGattCharRef charDecl, - const TROOctets& charValue, const uint64_t timestamp) = 0; + const jau::TROOctets& charValue, const uint64_t timestamp) = 0; /** * Called from native BLE stack, initiated by a received indication associated @@ -140,7 +140,7 @@ namespace direct_bt { * @param confirmationSent if true, the native stack has sent the confirmation, otherwise user is required to do so. */ virtual void indicationReceived(BTGattCharRef charDecl, - const TROOctets& charValue, const uint64_t timestamp, + const jau::TROOctets& charValue, const uint64_t timestamp, const bool confirmationSent) = 0; virtual ~Listener() noexcept {} @@ -186,7 +186,7 @@ namespace direct_bt { const uint16_t value_handle; /* Characteristics Value Type UUID */ - std::unique_ptr<const uuid_t> value_type; + std::unique_ptr<const jau::uuid_t> value_type; /** List of Characteristic Descriptions as shared reference */ jau::darray<BTGattDescRef> descriptorList; @@ -195,7 +195,7 @@ namespace direct_bt { int clientCharConfigIndex = -1; BTGattChar(const BTGattServiceRef & service_, const uint16_t service_handle_, const uint16_t handle_, - const PropertyBitVal properties_, const uint16_t value_handle_, std::unique_ptr<const uuid_t> && value_type_) noexcept + const PropertyBitVal properties_, const uint16_t value_handle_, std::unique_ptr<const jau::uuid_t> && value_type_) noexcept : wbr_service(service_), service_handle(service_handle_), handle(handle_), properties(properties_), value_handle(value_handle_), value_type(std::move(value_type_)) {} @@ -382,7 +382,7 @@ namespace direct_bt { * If the BTDevice's BTGattHandler is null, i.e. not connected, an IllegalStateException is thrown. * </p> */ - bool readValue(POctets & res, int expectedLength=-1); + bool readValue(jau::POctets & res, int expectedLength=-1); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value @@ -393,7 +393,7 @@ namespace direct_bt { * If the BTDevice's BTGattHandler is null, i.e. not connected, an IllegalStateException is thrown. * </p> */ - bool writeValue(const TROOctets & value); + bool writeValue(const jau::TROOctets & value); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response @@ -404,7 +404,7 @@ namespace direct_bt { * If the BTDevice's BTGattHandler is null, i.e. not connected, an IllegalStateException is thrown. * </p> */ - bool writeValueNoResp(const TROOctets & value); + bool writeValueNoResp(const jau::TROOctets & value); }; typedef std::shared_ptr<BTGattChar> BTGattCharRef; @@ -458,7 +458,7 @@ namespace direct_bt { * @param timestamp the indication monotonic timestamp, see getCurrentMilliseconds() */ virtual void notificationReceived(BTGattCharRef charDecl, - const TROOctets& charValue, const uint64_t timestamp) = 0; + const jau::TROOctets& charValue, const uint64_t timestamp) = 0; /** * Called from native BLE stack, initiated by a received indication associated @@ -469,7 +469,7 @@ namespace direct_bt { * @param confirmationSent if true, the native stack has sent the confirmation, otherwise user is required to do so. */ virtual void indicationReceived(BTGattCharRef charDecl, - const TROOctets& charValue, const uint64_t timestamp, + const jau::TROOctets& charValue, const uint64_t timestamp, const bool confirmationSent) = 0; virtual ~BTGattCharListener() noexcept {} diff --git a/api/direct_bt/BTGattDesc.hpp b/api/direct_bt/BTGattDesc.hpp index 81e11145..24667782 100644 --- a/api/direct_bt/BTGattDesc.hpp +++ b/api/direct_bt/BTGattDesc.hpp @@ -26,6 +26,8 @@ #ifndef BT_GATT_DESCRIPTOR_HPP_ #define BT_GATT_DESCRIPTOR_HPP_ +#include <jau/octets.hpp> +#include <jau/uuid.hpp> #include <cstring> #include <string> #include <memory> @@ -34,9 +36,7 @@ #include <mutex> #include <atomic> -#include "UUID.hpp" #include "BTTypes0.hpp" -#include "OctetTypes.hpp" #include "ATTPDUTypes.hpp" #include "BTTypes1.hpp" @@ -67,9 +67,9 @@ namespace direct_bt { std::string toShortString() const noexcept; public: - static const uuid16_t TYPE_EXT_PROP; - static const uuid16_t TYPE_USER_DESC; - static const uuid16_t TYPE_CCC_DESC; + static const jau::uuid16_t TYPE_EXT_PROP; + static const jau::uuid16_t TYPE_USER_DESC; + static const jau::uuid16_t TYPE_CCC_DESC; /** * Following UUID16 GATT profile attribute types are listed under: @@ -99,7 +99,7 @@ namespace direct_bt { }; /** Type of descriptor */ - std::unique_ptr<const uuid_t> type; + std::unique_ptr<const jau::uuid_t> type; /** * Characteristic Descriptor Handle @@ -110,9 +110,9 @@ namespace direct_bt { const uint16_t handle; /* Characteristics Descriptor's Value */ - POctets value; + jau::POctets value; - BTGattDesc(const BTGattCharRef & characteristic, std::unique_ptr<const uuid_t> && type_, + BTGattDesc(const BTGattCharRef & characteristic, std::unique_ptr<const jau::uuid_t> && type_, const uint16_t handle_) noexcept : wbr_char(characteristic), type(std::move(type_)), handle(handle_), value(/* intentional zero sized */) {} diff --git a/api/direct_bt/BTGattHandler.hpp b/api/direct_bt/BTGattHandler.hpp index 14258a3e..16c8d8ac 100644 --- a/api/direct_bt/BTGattHandler.hpp +++ b/api/direct_bt/BTGattHandler.hpp @@ -38,8 +38,8 @@ #include <jau/environment.hpp> #include <jau/ringbuffer.hpp> #include <jau/cow_darray.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" #include "BTTypes0.hpp" #include "L2CAPComm.hpp" #include "ATTPDUTypes.hpp" @@ -170,7 +170,7 @@ namespace direct_bt { const std::string deviceString; std::recursive_mutex mtx_command; - POctets rbuffer; + jau::POctets rbuffer; jau::sc_atomic_bool is_connected; // reflects state jau::relaxed_atomic_bool has_ioerror; // reflects state @@ -383,7 +383,7 @@ namespace direct_bt { * if required until the response returns zero. * </p> */ - bool readValue(const uint16_t handle, POctets & res, int expectedLength=-1); + bool readValue(const uint16_t handle, jau::POctets & res, int expectedLength=-1); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.8.1 Read Characteristic Value @@ -402,7 +402,7 @@ namespace direct_bt { * if required until the response returns zero. * </p> */ - bool readCharacteristicValue(const BTGattChar & c, POctets & res, int expectedLength=-1); + bool readCharacteristicValue(const BTGattChar & c, jau::POctets & res, int expectedLength=-1); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.12.1 Read Characteristic Descriptor @@ -426,7 +426,7 @@ namespace direct_bt { /** * Generic write GATT value and long value */ - bool writeValue(const uint16_t handle, const TROOctets & value, const bool withResponse); + bool writeValue(const uint16_t handle, const jau::TROOctets & value, const bool withResponse); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.12.3 Write Characteristic Descriptors @@ -442,12 +442,12 @@ namespace direct_bt { /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value */ - bool writeCharacteristicValue(const BTGattChar & c, const TROOctets & value); + bool writeCharacteristicValue(const BTGattChar & c, const jau::TROOctets & value); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response */ - bool writeCharacteristicValueNoResp(const BTGattChar & c, const TROOctets & value); + bool writeCharacteristicValueNoResp(const BTGattChar & c, const jau::TROOctets & value); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration diff --git a/api/direct_bt/BTGattService.hpp b/api/direct_bt/BTGattService.hpp index cfbe090f..17dcef51 100644 --- a/api/direct_bt/BTGattService.hpp +++ b/api/direct_bt/BTGattService.hpp @@ -36,10 +36,10 @@ #include <jau/java_uplink.hpp> #include <jau/darray.hpp> +#include <jau/octets.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" #include "BTTypes0.hpp" -#include "OctetTypes.hpp" #include "ATTPDUTypes.hpp" #include "BTTypes1.hpp" @@ -91,13 +91,13 @@ namespace direct_bt { const uint16_t endHandle; /** Service type UUID */ - std::unique_ptr<const uuid_t> type; + std::unique_ptr<const jau::uuid_t> type; /** List of Characteristic Declarations as shared reference */ jau::darray<BTGattCharRef> characteristicList; BTGattService(const std::shared_ptr<BTGattHandler> &handler_, const bool isPrimary_, - const uint16_t startHandle_, const uint16_t endHandle_, std::unique_ptr<const uuid_t> && type_) noexcept + const uint16_t startHandle_, const uint16_t endHandle_, std::unique_ptr<const jau::uuid_t> && type_) noexcept : wbr_handler(handler_), isPrimary(isPrimary_), startHandle(startHandle_), endHandle(endHandle_), type(std::move(type_)), characteristicList() { characteristicList.reserve(10); } diff --git a/api/direct_bt/BTManager.hpp b/api/direct_bt/BTManager.hpp index d0c621ff..313571b0 100644 --- a/api/direct_bt/BTManager.hpp +++ b/api/direct_bt/BTManager.hpp @@ -39,10 +39,10 @@ #include <jau/java_uplink.hpp> #include <jau/darray.hpp> #include <jau/cow_darray.hpp> +#include <jau/octets.hpp> #include "BTTypes0.hpp" #include "BTIoctl.hpp" -#include "OctetTypes.hpp" #include "HCIComm.hpp" #include "MgmtTypes.hpp" #include "BTAdapter.hpp" @@ -219,7 +219,7 @@ namespace direct_bt { const MgmtEnv & env; - POctets rbuffer; + jau::POctets rbuffer; HCIComm comm; jau::ringbuffer<std::unique_ptr<MgmtEvent>, std::nullptr_t, jau::nsize_t> mgmtEventRing; diff --git a/api/direct_bt/BTTypes0.hpp b/api/direct_bt/BTTypes0.hpp index 6e07cc9f..73643d8d 100644 --- a/api/direct_bt/BTTypes0.hpp +++ b/api/direct_bt/BTTypes0.hpp @@ -33,10 +33,10 @@ #include <jau/basic_types.hpp> #include <jau/darray.hpp> +#include <jau/octets.hpp> +#include <jau/uuid.hpp> -#include "OctetTypes.hpp" #include "BTAddress.hpp" -#include "UUID.hpp" namespace direct_bt { @@ -755,7 +755,7 @@ namespace direct_bt { private: uint16_t company; std::string companyName; - POctets data; + jau::POctets data; public: ManufactureSpecificData(uint16_t const company) noexcept; @@ -769,7 +769,7 @@ namespace direct_bt { constexpr uint16_t getCompany() const noexcept { return company; } const std::string& getCompanyName() const noexcept { return companyName; } - const TROOctets& getData() const noexcept { return data; } + const jau::TROOctets& getData() const noexcept { return data; } std::string toString() const noexcept; }; @@ -885,7 +885,7 @@ namespace direct_bt { EAD_Event_Type ead_type = EAD_Event_Type::NONE; uint8_t ad_address_type = 0; BDAddressType addressType = BDAddressType::BDADDR_UNDEFINED; - EUI48 address; + jau::EUI48 address; GAPFlags flags = GAPFlags::NONE; std::string name; @@ -893,11 +893,11 @@ namespace direct_bt { int8_t rssi = 127; // The core spec defines 127 as the "not available" value int8_t tx_power = 127; // The core spec defines 127 as the "not available" value std::shared_ptr<ManufactureSpecificData> msd = nullptr; - jau::darray<std::shared_ptr<const uuid_t>> services; + jau::darray<std::shared_ptr<const jau::uuid_t>> services; uint32_t device_class = 0; AppearanceCat appearance = AppearanceCat::UNKNOWN; - POctets hash; - POctets randomizer; + jau::POctets hash; + jau::POctets randomizer; uint16_t did_source = 0; uint16_t did_vendor = 0; uint16_t did_product = 0; @@ -921,7 +921,7 @@ namespace direct_bt { void setEvtType(AD_PDU_Type et) noexcept { evt_type = et; set(EIRDataType::EVT_TYPE); } void setExtEvtType(EAD_Event_Type eadt) noexcept { ead_type = eadt; set(EIRDataType::EXT_EVT_TYPE); } void setAddressType(BDAddressType at) noexcept; - void setAddress(EUI48 const &a) noexcept { address = a; set(EIRDataType::BDADDR); } + void setAddress(jau::EUI48 const &a) noexcept { address = a; set(EIRDataType::BDADDR); } void setRSSI(int8_t v) noexcept { rssi = v; set(EIRDataType::RSSI); } void setFlags(GAPFlags f) noexcept { flags = f; set(EIRDataType::FLAGS); } @@ -929,8 +929,8 @@ namespace direct_bt { void setShortName(const std::string& name_short_) noexcept; void setManufactureSpecificData(const ManufactureSpecificData& msd_) noexcept; - void addService(const std::shared_ptr<const uuid_t>& uuid) noexcept; - void addService(const uuid_t& uuid) noexcept; + void addService(const std::shared_ptr<const jau::uuid_t>& uuid) noexcept; + void addService(const jau::uuid_t& uuid) noexcept; void setDeviceClass(uint32_t c) noexcept { device_class= c; set(EIRDataType::DEVICE_CLASS); } void setAppearance(AppearanceCat a) noexcept { appearance= a; set(EIRDataType::APPEARANCE); } void setHash(const uint8_t * h) noexcept { hash.resize(16); memcpy(hash.get_wptr(), h, 16); set(EIRDataType::HASH); } @@ -1037,19 +1037,19 @@ namespace direct_bt { GAPFlags getFlags() const noexcept { return flags; } uint8_t getADAddressType() const noexcept { return ad_address_type; } BDAddressType getAddressType() const noexcept { return addressType; } - EUI48 const & getAddress() const noexcept { return address; } + jau::EUI48 const & getAddress() const noexcept { return address; } std::string const & getName() const noexcept { return name; } std::string const & getShortName() const noexcept{ return name_short; } int8_t getRSSI() const noexcept { return rssi; } int8_t getTxPower() const noexcept { return tx_power; } std::shared_ptr<ManufactureSpecificData> getManufactureSpecificData() const noexcept { return msd; } - jau::darray<std::shared_ptr<const uuid_t>> getServices() const noexcept { return services; } + jau::darray<std::shared_ptr<const jau::uuid_t>> getServices() const noexcept { return services; } uint32_t getDeviceClass() const noexcept { return device_class; } AppearanceCat getAppearance() const noexcept { return appearance; } - const TROOctets & getHash() const noexcept { return hash; } - const TROOctets & getRandomizer() const noexcept { return randomizer; } + const jau::TROOctets & getHash() const noexcept { return hash; } + const jau::TROOctets & getRandomizer() const noexcept { return randomizer; } uint16_t getDeviceIDSource() const noexcept { return did_source; } uint16_t getDeviceIDVendor() const noexcept { return did_vendor; } uint16_t getDeviceIDProduct() const noexcept { return did_product; } diff --git a/api/direct_bt/BTTypes1.hpp b/api/direct_bt/BTTypes1.hpp index d2336b6f..2c2adf83 100644 --- a/api/direct_bt/BTTypes1.hpp +++ b/api/direct_bt/BTTypes1.hpp @@ -31,8 +31,8 @@ #include <jau/java_uplink.hpp> #include <jau/basic_types.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" #include "BTAddress.hpp" #include "BTTypes0.hpp" @@ -74,7 +74,7 @@ namespace direct_bt { class ConnectionInfo { private: - EUI48 address; + jau::EUI48 address; BDAddressType addressType; int8_t rssi; int8_t tx_power; @@ -83,10 +83,10 @@ namespace direct_bt { public: static jau::nsize_t minimumDataSize() noexcept { return 6 + 1 + 1 + 1 + 1; } - ConnectionInfo(const EUI48 &address_, BDAddressType addressType_, int8_t rssi_, int8_t tx_power_, int8_t max_tx_power_) noexcept + ConnectionInfo(const jau::EUI48 &address_, BDAddressType addressType_, int8_t rssi_, int8_t tx_power_, int8_t max_tx_power_) noexcept : address(address_), addressType(addressType_), rssi(rssi_), tx_power(tx_power_), max_tx_power(max_tx_power_) {} - const EUI48 getAddress() const noexcept { return address; } + const jau::EUI48 getAddress() const noexcept { return address; } BDAddressType getAddressType() const noexcept { return addressType; } int8_t getRSSI() const noexcept { return rssi; } int8_t getTxPower() const noexcept { return tx_power; } diff --git a/api/direct_bt/GattNumbers.hpp b/api/direct_bt/GattNumbers.hpp index 97726ff3..e5fea80b 100644 --- a/api/direct_bt/GattNumbers.hpp +++ b/api/direct_bt/GattNumbers.hpp @@ -30,9 +30,9 @@ #include <jau/basic_types.hpp> #include <jau/darray.hpp> +#include <jau/octets.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" -#include "OctetTypes.hpp" #include "BTTypes0.hpp" #include "ieee11073/DataTypes.hpp" @@ -230,7 +230,7 @@ const GattCharacteristicSpec * findGattCharSpec(const uint16_t uuid16) noexcept; /** * Converts a GATT Name (not null-terminated) UTF8 to a null-terminated C++ string */ -std::string GattNameToString(const TROOctets &v) noexcept; +std::string GattNameToString(const jau::TROOctets &v) noexcept; /** * <i>Peripheral Preferred Connection Parameters</i> is a GATT Characteristic. @@ -248,9 +248,9 @@ struct GattPeriphalPreferredConnectionParameters { /** mandatory [10..3200] */ const uint16_t connectionSupervisionTimeoutMultiplier; - static std::shared_ptr<GattPeriphalPreferredConnectionParameters> get(const TROOctets &source) noexcept; + static std::shared_ptr<GattPeriphalPreferredConnectionParameters> get(const jau::TROOctets &source) noexcept; - GattPeriphalPreferredConnectionParameters(const TROOctets &source) noexcept; + GattPeriphalPreferredConnectionParameters(const jau::TROOctets &source) noexcept; std::string toString() const noexcept; }; @@ -293,12 +293,12 @@ struct GattPnP_ID { const uint16_t product_id; const uint16_t product_version; - static std::shared_ptr<GattPnP_ID> get(const TROOctets &source) noexcept; + static std::shared_ptr<GattPnP_ID> get(const jau::TROOctets &source) noexcept; GattPnP_ID() noexcept : vendor_id_source(0), vendor_id(0), product_id(0), product_version(0) {} - GattPnP_ID(const TROOctets &source) noexcept; + GattPnP_ID(const jau::TROOctets &source) noexcept; GattPnP_ID(const uint8_t vendor_id_source_, const uint16_t vendor_id_, const uint16_t product_id_, const uint16_t product_version_) noexcept : vendor_id_source(vendor_id_source_), vendor_id(vendor_id_), product_id(product_id_), product_version(product_version_) {} @@ -315,7 +315,7 @@ struct GattPnP_ID { class GattDeviceInformationSvc { public: /** Optional */ - const POctets systemID; + const jau::POctets systemID; /** Optional */ const std::string modelNumber; /** Optional */ @@ -329,13 +329,13 @@ class GattDeviceInformationSvc { /** Optional */ const std::string manufacturer; /** Optional */ - const POctets regulatoryCertDataList; + const jau::POctets regulatoryCertDataList; /** Optional */ const std::shared_ptr<GattPnP_ID> pnpID; - GattDeviceInformationSvc(const POctets &systemID_, const std::string &modelNumber_, const std::string &serialNumber_, + GattDeviceInformationSvc(const jau::POctets &systemID_, const std::string &modelNumber_, const std::string &serialNumber_, const std::string &firmwareRevision_, const std::string &hardwareRevision_, const std::string &softwareRevision_, - const std::string &manufacturer_, const POctets ®ulatoryCertDataList_, const std::shared_ptr<GattPnP_ID> &pnpID_) noexcept + const std::string &manufacturer_, const jau::POctets ®ulatoryCertDataList_, const std::shared_ptr<GattPnP_ID> &pnpID_) noexcept : systemID(systemID_), modelNumber(modelNumber_), serialNumber(serialNumber_), firmwareRevision(firmwareRevision_), hardwareRevision(hardwareRevision_), softwareRevision(softwareRevision_), manufacturer(manufacturer_), regulatoryCertDataList(regulatoryCertDataList_), pnpID(pnpID_) {} @@ -371,10 +371,10 @@ class GattTemperatureMeasurement { /** Temperature Type, if HAS_TEMP_TYPE is set: Format ????. 1 byte (!?). */ const uint8_t temperature_type; - static std::shared_ptr<GattTemperatureMeasurement> get(const TROOctets &source) noexcept; + static std::shared_ptr<GattTemperatureMeasurement> get(const jau::TROOctets &source) noexcept; - static std::shared_ptr<GattTemperatureMeasurement> get(const TOctetSlice &source) noexcept { - const TROOctets o(source.get_ptr(0), source.getSize()); + static std::shared_ptr<GattTemperatureMeasurement> get(const jau::TOctetSlice &source) noexcept { + const jau::TROOctets o(source.get_ptr(0), source.getSize()); return get(o); } diff --git a/api/direct_bt/GattTypes.hpp b/api/direct_bt/GattTypes.hpp index 6b681c81..6703e7ec 100644 --- a/api/direct_bt/GattTypes.hpp +++ b/api/direct_bt/GattTypes.hpp @@ -35,10 +35,10 @@ #include <atomic> #include <jau/java_uplink.hpp> +#include <jau/octets.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" #include "BTTypes0.hpp" -#include "OctetTypes.hpp" #include "ATTPDUTypes.hpp" /* Only to resolve high level service and characteristic names */ diff --git a/api/direct_bt/HCIHandler.hpp b/api/direct_bt/HCIHandler.hpp index d1b5138c..5d435f88 100644 --- a/api/direct_bt/HCIHandler.hpp +++ b/api/direct_bt/HCIHandler.hpp @@ -38,10 +38,10 @@ #include <jau/environment.hpp> #include <jau/ringbuffer.hpp> #include <jau/java_uplink.hpp> +#include <jau/octets.hpp> #include "BTTypes0.hpp" #include "BTIoctl.hpp" -#include "OctetTypes.hpp" #include "HCIComm.hpp" #include "HCITypes.hpp" #include "MgmtTypes.hpp" @@ -225,7 +225,7 @@ namespace direct_bt { static MgmtEvent::Opcode translate(HCIEventType evt, HCIMetaEventType met) noexcept; const uint16_t dev_id; - POctets rbuffer; + jau::POctets rbuffer; HCIComm comm; hci_ufilter filter_mask; std::atomic<uint32_t> metaev_filter_mask; diff --git a/api/direct_bt/HCITypes.hpp b/api/direct_bt/HCITypes.hpp index 7a7df001..d65dfd57 100644 --- a/api/direct_bt/HCITypes.hpp +++ b/api/direct_bt/HCITypes.hpp @@ -34,10 +34,10 @@ #include <mutex> #include <jau/basic_types.hpp> +#include <jau/octets.hpp> #include "BTTypes0.hpp" #include "BTIoctl.hpp" -#include "OctetTypes.hpp" #include "HCIIoctl.hpp" #include "SMPTypes.hpp" @@ -489,7 +489,7 @@ namespace direct_bt { template<typename T> friend class HCIStructCmdCompleteMetaEvtWrap; protected: - POctets pdu; + jau::POctets pdu; inline static void checkPacketType(const HCIPacketType type) { switch(type) { @@ -545,7 +545,7 @@ namespace direct_bt { constexpr jau::nsize_t getTotalSize() const noexcept { return pdu.getSize(); } /** Return the underlying octets read only */ - TROOctets & getPDU() noexcept { return pdu; } + jau::TROOctets & getPDU() noexcept { return pdu; } HCIPacketType getPacketType() noexcept { return static_cast<HCIPacketType>(pdu.get_uint8_nc(0)); } diff --git a/api/direct_bt/L2CAPComm.hpp b/api/direct_bt/L2CAPComm.hpp index 40e9a85e..f05a8446 100644 --- a/api/direct_bt/L2CAPComm.hpp +++ b/api/direct_bt/L2CAPComm.hpp @@ -35,8 +35,8 @@ #include <atomic> #include <jau/environment.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" #include "BTTypes0.hpp" /** diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp index 5c66e307..475791d2 100644 --- a/api/direct_bt/MgmtTypes.hpp +++ b/api/direct_bt/MgmtTypes.hpp @@ -34,11 +34,11 @@ #include <jau/function_def.hpp> #include <jau/cow_darray.hpp> +#include <jau/octets.hpp> #include <jau/packed_attribute.hpp> #include "BTTypes0.hpp" #include "BTIoctl.hpp" -#include "OctetTypes.hpp" #include "HCIComm.hpp" #include "BTTypes1.hpp" @@ -304,7 +304,7 @@ namespace direct_bt { class MgmtMsg { protected: - POctets pdu; + jau::POctets pdu; uint64_t ts_creation; virtual std::string baseString() const noexcept { @@ -358,7 +358,7 @@ namespace direct_bt { jau::nsize_t getTotalSize() const noexcept { return pdu.getSize(); } /** Return the underlying octets read only */ - TROOctets & getPDU() noexcept { return pdu; } + jau::TROOctets & getPDU() noexcept { return pdu; } uint16_t getIntOpcode() const noexcept { return pdu.get_uint16_nc(0); } uint16_t getDevID() const noexcept { return pdu.get_uint16_nc(2); } @@ -802,7 +802,7 @@ namespace direct_bt { public: MgmtPinCodeReplyCmd(const uint16_t dev_id, const BDAddressAndType& addressAndType, - const uint8_t pin_len, const TROOctets &pin_code) + const uint8_t pin_len, const jau::TROOctets &pin_code) : MgmtCommand(Opcode::PIN_CODE_REPLY, dev_id, 6+1+1+16) { pdu.put_eui48_nc(MGMT_HEADER_SIZE, addressAndType.address); @@ -813,7 +813,7 @@ namespace direct_bt { const EUI48& getAddress() const noexcept { return *reinterpret_cast<const EUI48 *>( pdu.get_ptr_nc(MGMT_HEADER_SIZE + 0) ); } // mgmt_addr_info BDAddressType getAddressType() const noexcept { return static_cast<BDAddressType>(pdu.get_uint8_nc(MGMT_HEADER_SIZE+6)); } // mgmt_addr_info uint8_t getPinLength() const noexcept { return pdu.get_uint8_nc(MGMT_HEADER_SIZE+6+1); } - TROOctets getPinCode() const noexcept { return POctets(pdu.get_ptr_nc(MGMT_HEADER_SIZE+6+1+1), getPinLength()); } + jau::TROOctets getPinCode() const noexcept { return jau::POctets(pdu.get_ptr_nc(MGMT_HEADER_SIZE+6+1+1), getPinLength()); } }; /** diff --git a/api/direct_bt/OctetTypes.hpp b/api/direct_bt/OctetTypes.hpp deleted file mode 100644 index 96ab6a49..00000000 --- a/api/direct_bt/OctetTypes.hpp +++ /dev/null @@ -1,675 +0,0 @@ -/* - * Author: Sven Gothel <[email protected]> - * Copyright (c) 2020 Gothel Software e.K. - * Copyright (c) 2020 ZAFENA AB - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef OCTET_TYPES_HPP_ -#define OCTET_TYPES_HPP_ - -#include <cstring> -#include <string> -#include <memory> -#include <cstdint> -#include <algorithm> - -#include <mutex> -#include <atomic> - -#include <jau/basic_types.hpp> - -#include "UUID.hpp" -#include "BTAddress.hpp" - -// #define TRACE_MEM 1 -#ifdef TRACE_MEM - #define TRACE_PRINT(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); } -#else - #define TRACE_PRINT(...) -#endif - -namespace direct_bt { - - /** - * Transient read only octet data, i.e. non persistent passthrough, owned by caller. - * <p> - * Either ATT value (Vol 3, Part F 3.2.4) or PDU data. - * </p> - */ - class TROOctets - { - private: - /** Used memory size <= capacity, maybe zero. */ - jau::nsize_t _size; - /** Non-null memory pointer. Actual capacity known by owner. */ - uint8_t * _data; - - protected: - static inline void checkPtr(uint8_t *d, jau::nsize_t s) { - if( nullptr == d && 0 < s ) { - throw jau::IllegalArgumentException("TROOctets::setData: nullptr with size "+std::to_string(s)+" > 0", E_FILE_LINE); - } - } - - constexpr uint8_t * data() noexcept { return _data; } - - /** - * @param d a non nullptr memory, otherwise throws exception - * @param s used memory size, may be zero - */ - inline void setData(uint8_t *d, jau::nsize_t s) { - TRACE_PRINT("POctets setData: %d bytes @ %p -> %d bytes @ %p", - _size, _data, s, d); - checkPtr(d, s); - _size = s; - _data = d; - } - constexpr void setSize(jau::nsize_t s) noexcept { _size = s; } - - public: - /** - * Transient passthrough read-only memory, w/o ownership .. - * @param source a non nullptr memory, otherwise throws exception. Actual capacity known by owner. - * @param len readable size of the memory, may be zero - */ - TROOctets(const uint8_t *source, const jau::nsize_t len) - : _size( len ), _data( const_cast<uint8_t *>(source) ) { - checkPtr(_data, _size); - } - - TROOctets(const TROOctets &o) noexcept = default; - TROOctets(TROOctets &&o) noexcept = default; - TROOctets& operator=(const TROOctets &o) noexcept = default; - TROOctets& operator=(TROOctets &&o) noexcept = default; - - virtual ~TROOctets() noexcept {} - - inline void check_range(const jau::nsize_t i, const jau::nsize_t count, const char *file, int line) const { - if( i+count > _size ) { - throw jau::IndexOutOfBoundsException(i, count, _size, file, line); - } - } - #define check_range(I,C) check_range((I), (C), E_FILE_LINE) - - constexpr bool is_range_valid(const jau::nsize_t i, const jau::nsize_t count) const noexcept { - return i+count <= _size; - } - - /** Returns the used memory size for read and write operations, may be zero. */ - constexpr jau::nsize_t getSize() const noexcept { return _size; } - - uint8_t get_uint8(const jau::nsize_t i) const { - check_range(i, 1); - return _data[i]; - } - constexpr uint8_t get_uint8_nc(const jau::nsize_t i) const noexcept { - return _data[i]; - } - - int8_t get_int8(const jau::nsize_t i) const { - check_range(i, 1); - return jau::get_int8(_data, i); - } - constexpr int8_t get_int8_nc(const jau::nsize_t i) const noexcept { - return jau::get_int8(_data, i); - } - - uint16_t get_uint16(const jau::nsize_t i) const { - check_range(i, 2); - return jau::get_uint16(_data, i, true /* littleEndian */); - } - constexpr uint16_t get_uint16_nc(const jau::nsize_t i) const noexcept { - return jau::get_uint16(_data, i, true /* littleEndian */); - } - - uint32_t get_uint32(const jau::nsize_t i) const { - check_range(i, 4); - return jau::get_uint32(_data, i, true /* littleEndian */); - } - constexpr uint32_t get_uint32_nc(const jau::nsize_t i) const noexcept { - return jau::get_uint32(_data, i, true /* littleEndian */); - } - - EUI48 get_eui48(const jau::nsize_t i) const { - check_range(i, sizeof(EUI48)); - return EUI48(_data+i); - } - inline EUI48 get_eui48_nc(const jau::nsize_t i) const noexcept { - return EUI48(_data+i); - } - - uint64_t get_uint64(const jau::nsize_t i) const { - check_range(i, 8); - return jau::get_uint64(_data, i, true /* littleEndian */); - } - constexpr uint64_t get_uint64_nc(const jau::nsize_t i) const noexcept { - return jau::get_uint64(_data, i, true /* littleEndian */); - } - - jau::uint128_t get_uint128(const jau::nsize_t i) const { - check_range(i, 8); - return jau::get_uint128(_data, i, true /* littleEndian */); - } - constexpr jau::uint128_t get_uint128_nc(const jau::nsize_t i) const noexcept { - return jau::get_uint128(_data, i, true /* littleEndian */); - } - - jau::uint192_t get_uint192(const jau::nsize_t i) const { - check_range(i, 8); - return jau::get_uint192(_data, i, true /* littleEndian */); - } - constexpr jau::uint192_t get_uint192_nc(const jau::nsize_t i) const noexcept { - return jau::get_uint192(_data, i, true /* littleEndian */); - } - - jau::uint256_t get_uint256(const jau::nsize_t i) const { - check_range(i, 8); - return jau::get_uint256(_data, i, true /* littleEndian */); - } - constexpr jau::uint256_t get_uint256_nc(const jau::nsize_t i) const noexcept { - return jau::get_uint256(_data, i, true /* littleEndian */); - } - - /** Assumes a null terminated string */ - std::string get_string(const jau::nsize_t i) const { - check_range(i, 1); // minimum size - return std::string( (const char*)(_data+i) ); - } - /** Assumes a null terminated string */ - constexpr_cxx20 std::string get_string_nc(const jau::nsize_t i) const noexcept { - return std::string( (const char*)(_data+i) ); - } - - /** Assumes a string with defined length, not necessarily null terminated */ - inline std::string get_string(const jau::nsize_t i, const jau::nsize_t length) const { - check_range(i, length); - return std::string( (const char*)(_data+i), length ); - } - - uuid16_t get_uuid16(const jau::nsize_t i) const { - return uuid16_t(get_uint16(i)); - } - inline uuid16_t get_uuid16_nc(const jau::nsize_t i) const noexcept { - return uuid16_t(get_uint16_nc(i)); - } - - uuid128_t get_uuid128(const jau::nsize_t i) const { - check_range(i, uuid_t::number(uuid_t::TypeSize::UUID128_SZ)); - return direct_bt::get_uuid128(_data, i, true /* littleEndian */); - } - inline uuid128_t get_uuid128_nc(const jau::nsize_t i) const noexcept { - return direct_bt::get_uuid128(_data, i, true /* littleEndian */); - } - - std::unique_ptr<const uuid_t> get_uuid(const jau::nsize_t i, const uuid_t::TypeSize tsize) const { - check_range(i, uuid_t::number(tsize)); - return uuid_t::create(tsize, _data, i, true /* littleEndian */); - } - - constexpr uint8_t const * get_ptr() const noexcept { return _data; } - uint8_t const * get_ptr(const jau::nsize_t i) const { - check_range(i, 1); - return _data + i; - } - constexpr uint8_t const * get_ptr_nc(const jau::nsize_t i) const noexcept { - return _data + i; - } - - bool operator==(const TROOctets& rhs) const noexcept { - return _size == rhs._size && 0 == std::memcmp(_data, rhs._data, _size); - } - bool operator!=(const TROOctets& rhs) const noexcept { - return !(*this == rhs); - } - - std::string toString() const noexcept { - return "size "+std::to_string(_size)+", ro: "+jau::bytesHexString(_data, 0, _size, true /* lsbFirst */); - } - }; - - /** - * Transient octet data, i.e. non persistent passthrough, owned by caller. - * <p> - * Either ATT value (Vol 3, Part F 3.2.4) or PDU data. - * </p> - */ - class TOctets : public TROOctets - { - public: - /** Transient passthrough r/w memory, w/o ownership ..*/ - TOctets(uint8_t *source, const jau::nsize_t len) - : TROOctets(source, len) {} - - TOctets(const TOctets &o) noexcept = default; - TOctets(TOctets &&o) noexcept = default; - TOctets& operator=(const TOctets &o) noexcept = default; - TOctets& operator=(TOctets &&o) noexcept = default; - - virtual ~TOctets() noexcept override {} - - void put_int8(const jau::nsize_t i, const int8_t v) { - check_range(i, 1); - data()[i] = static_cast<uint8_t>(v); - } - constexpr void put_int8_nc(const jau::nsize_t i, const int8_t v) noexcept { - data()[i] = static_cast<uint8_t>(v); - } - - void put_uint8(const jau::nsize_t i, const uint8_t v) { - check_range(i, 1); - data()[i] = v; - } - constexpr void put_uint8_nc(const jau::nsize_t i, const uint8_t v) noexcept { - data()[i] = v; - } - - void put_uint16(const jau::nsize_t i, const uint16_t v) { - check_range(i, 2); - jau::put_uint16(data(), i, v, true /* littleEndian */); - } - constexpr void put_uint16_nc(const jau::nsize_t i, const uint16_t v) noexcept { - jau::put_uint16(data(), i, v, true /* littleEndian */); - } - - void put_uint32(const jau::nsize_t i, const uint32_t v) { - check_range(i, 4); - jau::put_uint32(data(), i, v, true /* littleEndian */); - } - constexpr void put_uint32_nc(const jau::nsize_t i, const uint32_t v) noexcept { - jau::put_uint32(data(), i, v, true /* littleEndian */); - } - - void put_eui48(const jau::nsize_t i, const EUI48 & v) { - check_range(i, sizeof(v.b)); - memcpy(data() + i, v.b, sizeof(v.b)); - } - void put_eui48_nc(const jau::nsize_t i, const EUI48 & v) noexcept { - memcpy(data() + i, v.b, sizeof(v.b)); - } - - void put_uint64(const jau::nsize_t i, const uint64_t & v) { - check_range(i, 8); - jau::put_uint64(data(), i, v, true /* littleEndian */); - } - constexpr void put_uint64_nc(const jau::nsize_t i, const uint64_t & v) noexcept { - jau::put_uint64(data(), i, v, true /* littleEndian */); - } - - void put_uint128(const jau::nsize_t i, const jau::uint128_t & v) { - check_range(i, 8); - jau::put_uint128(data(), i, v, true /* littleEndian */); - } - constexpr void put_uint128_nc(const jau::nsize_t i, const jau::uint128_t & v) noexcept { - jau::put_uint128(data(), i, v, true /* littleEndian */); - } - - void put_uint192(const jau::nsize_t i, const jau::uint192_t & v) { - check_range(i, 8); - jau::put_uint192(data(), i, v, true /* littleEndian */); - } - constexpr void put_uint192_nc(const jau::nsize_t i, const jau::uint192_t & v) noexcept { - jau::put_uint192(data(), i, v, true /* littleEndian */); - } - - void put_uint256(const jau::nsize_t i, const jau::uint256_t & v) { - check_range(i, 8); - jau::put_uint256(data(), i, v, true /* littleEndian */); - } - constexpr void put_uint256_nc(const jau::nsize_t i, const jau::uint256_t & v) noexcept { - jau::put_uint256(data(), i, v, true /* littleEndian */); - } - - void put_octets(const jau::nsize_t i, const TROOctets & v) { - check_range(i, v.getSize()); - memcpy(data() + i, v.get_ptr(), v.getSize()); - } - void put_octets_nc(const jau::nsize_t i, const TROOctets & v) noexcept { - memcpy(data() + i, v.get_ptr(), v.getSize()); - } - - void put_bytes(const jau::nsize_t i, const uint8_t *source, const jau::nsize_t byte_count) { - check_range(i, byte_count); - memcpy(data() + i, source, byte_count); - } - void put_bytes_nc(const jau::nsize_t i, const uint8_t *source, const jau::nsize_t byte_count) noexcept { - memcpy(data() + i, source, byte_count); - } - - void put_string(const jau::nsize_t i, const std::string & v, const jau::nsize_t max_len, const bool includeEOS) { - const jau::nsize_t size1 = v.size() + ( includeEOS ? 1 : 0 ); - const jau::nsize_t size = std::min(size1, max_len); - check_range(i, size); - memcpy(data() + i, v.c_str(), size); - if( size < size1 && includeEOS ) { - *(data() + i + size - 1) = 0; // ensure EOS - } - } - void put_string_nc(const jau::nsize_t i, const std::string & v, const jau::nsize_t max_len, const bool includeEOS) noexcept { - const jau::nsize_t size1 = v.size() + ( includeEOS ? 1 : 0 ); - const jau::nsize_t size = std::min(size1, max_len); - memcpy(data() + i, v.c_str(), size); - if( size < size1 && includeEOS ) { - *(data() + i + size - 1) = 0; // ensure EOS - } - } - - void put_uuid(const jau::nsize_t i, const uuid_t & v) { - check_range(i, v.getTypeSizeInt()); - v.put(data(), i, true /* littleEndian */); - } - void put_uuid_nc(const jau::nsize_t i, const uuid_t & v) noexcept { - v.put(data(), i, true /* littleEndian */); - } - - inline uint8_t * get_wptr() noexcept { return data(); } - - uint8_t * get_wptr(const jau::nsize_t i) { - check_range(i, 1); - return data() + i; - } - inline uint8_t * get_wptr_nc(const jau::nsize_t i) noexcept { - return data() + i; - } - - std::string toString() const noexcept { - return "size "+std::to_string(getSize())+", rw: "+jau::bytesHexString(get_ptr(), 0, getSize(), true /* lsbFirst */); - } - }; - - class TOctetSlice - { - private: - const TOctets & parent; - jau::nsize_t const offset; - jau::nsize_t const size; - - public: - TOctetSlice(const TOctets &buffer_, const jau::nsize_t offset_, const jau::nsize_t size_) - : parent(buffer_), offset(offset_), size(size_) - { - if( offset_+size > buffer_.getSize() ) { - throw jau::IndexOutOfBoundsException(offset_, size, buffer_.getSize(), E_FILE_LINE); - } - } - - constexpr jau::nsize_t getSize() const noexcept { return size; } - constexpr jau::nsize_t getOffset() const noexcept { return offset; } - const TOctets& getParent() const noexcept { return parent; } - - uint8_t get_uint8(const jau::nsize_t i) const { - return parent.get_uint8(offset+i); - } - constexpr uint8_t get_uint8_nc(const jau::nsize_t i) const noexcept { - return parent.get_uint8_nc(offset+i); - } - - uint16_t get_uint16(const jau::nsize_t i) const { - return parent.get_uint16(offset+i); - } - constexpr uint16_t get_uint16_nc(const jau::nsize_t i) const noexcept { - return parent.get_uint16_nc(offset+i); - } - - uint8_t const * get_ptr(const jau::nsize_t i) const { - return parent.get_ptr(offset+i); - } - constexpr uint8_t const * get_ptr_nc(const jau::nsize_t i) const noexcept { - return parent.get_ptr_nc(offset+i); - } - - std::string toString() const noexcept { - return "offset "+std::to_string(offset)+", size "+std::to_string(size)+": "+jau::bytesHexString(parent.get_ptr(), offset, size, true /* lsbFirst */); - } - }; - - /** - * Persistent octet data, i.e. owned memory allocation. - * <p> - * GATT value (Vol 3, Part F 3.2.4) - * </p> - */ - class POctets : public TOctets - { - private: - jau::nsize_t capacity; - - void freeData() { - uint8_t * ptr = data(); - if( nullptr != ptr ) { - TRACE_PRINT("POctets release: %p", ptr); - free(ptr); - } // else: zero sized POctets w/ nullptr are supported - } - - static uint8_t * allocData(const jau::nsize_t size) { - if( size <= 0 ) { - return nullptr; - } - uint8_t * m = static_cast<uint8_t*>( std::malloc(size) ); - if( nullptr == m ) { - throw jau::OutOfMemoryError("allocData size "+std::to_string(size)+" -> nullptr", E_FILE_LINE); - } - return m; - } - - public: - /** Returns the memory capacity, never zero, greater or equal {@link #getSize()}. */ - constexpr jau::nsize_t getCapacity() const noexcept { return capacity; } - - /** Intentional zero sized POctets instance. */ - POctets() - : TOctets(nullptr, 0), capacity(0) - { - TRACE_PRINT("POctets ctor0: zero-sized"); - } - - /** Takes ownership (malloc and copy, free) ..*/ - POctets(const uint8_t *_source, const jau::nsize_t size_) - : TOctets( allocData(size_), size_), - capacity( size_ ) - { - std::memcpy(data(), _source, size_); - TRACE_PRINT("POctets ctor1: %p", data()); - } - - /** New buffer (malloc, free) */ - POctets(const jau::nsize_t _capacity, const jau::nsize_t size_) - : TOctets( allocData(_capacity), size_), - capacity( _capacity ) - { - if( capacity < getSize() ) { - throw jau::IllegalArgumentException("capacity "+std::to_string(capacity)+" < size "+std::to_string(getSize()), E_FILE_LINE); - } - TRACE_PRINT("POctets ctor2: %p", data()); - } - - /** New buffer (malloc, free) */ - POctets(const jau::nsize_t size) - : POctets(size, size) - { - TRACE_PRINT("POctets ctor3: %p", data()); - } - - POctets(const POctets &_source) - : TOctets( allocData(_source.getSize()), _source.getSize()), - capacity( _source.getSize() ) - { - std::memcpy(data(), _source.get_ptr(), _source.getSize()); - TRACE_PRINT("POctets ctor-cpy0: %p", data()); - } - - POctets(POctets &&o) noexcept - : TOctets( o.data(), o.getSize() ), - capacity( o.getCapacity() ) - { - // moved origin data references - // purge origin - o.setData(nullptr, 0); - o.capacity = 0; - TRACE_PRINT("POctets ctor-move0: %p", data()); - } - - POctets& operator=(const POctets &_source) { - if( this == &_source ) { - return *this; - } - freeData(); - setData(allocData(_source.getSize()), _source.getSize()); - capacity = _source.getSize(); - std::memcpy(data(), _source.get_ptr(), _source.getSize()); - TRACE_PRINT("POctets assign0: %p", data()); - return *this; - } - - POctets& operator=(POctets &&o) noexcept { - // move origin data references - setData(o.data(), o.getSize()); - capacity = o.capacity; - // purge origin - o.setData(nullptr, 0); - o.capacity = 0; - TRACE_PRINT("POctets assign-move0: %p", data()); - return *this; - } - - virtual ~POctets() noexcept override { - freeData(); - setData(nullptr, 0); - capacity=0; - } - - /** Makes a persistent POctets by copying the data from TROOctets. */ - POctets(const TROOctets & _source) - : TOctets( allocData(_source.getSize()), _source.getSize()), - capacity( _source.getSize() ) - { - std::memcpy(data(), _source.get_ptr(), _source.getSize()); - TRACE_PRINT("POctets ctor-cpy1: %p", data()); - } - - POctets& operator=(const TROOctets &_source) { - if( static_cast<TROOctets *>(this) == &_source ) { - return *this; - } - freeData(); - setData(allocData(_source.getSize()), _source.getSize()); - capacity = _source.getSize(); - std::memcpy(data(), _source.get_ptr(), _source.getSize()); - TRACE_PRINT("POctets assign1: %p", data()); - return *this; - } - - /** Makes a persistent POctets by copying the data from TOctetSlice. */ - POctets(const TOctetSlice & _source) - : TOctets( allocData(_source.getSize()), _source.getSize()), - capacity( _source.getSize() ) - { - std::memcpy(data(), _source.getParent().get_ptr() + _source.getOffset(), _source.getSize()); - TRACE_PRINT("POctets ctor-cpy2: %p", data()); - } - - POctets& operator=(const TOctetSlice &_source) { - freeData(); - setData(allocData(_source.getSize()), _source.getSize()); - capacity = _source.getSize(); - std::memcpy(data(), _source.get_ptr(0), _source.getSize()); - TRACE_PRINT("POctets assign2: %p", data()); - return *this; - } - - POctets & resize(const jau::nsize_t newSize, const jau::nsize_t newCapacity) { - if( newCapacity < newSize ) { - throw jau::IllegalArgumentException("newCapacity "+std::to_string(newCapacity)+" < newSize "+std::to_string(newSize), E_FILE_LINE); - } - if( newCapacity != capacity ) { - if( newSize > getSize() ) { - recapacity(newCapacity); - setSize(newSize); - } else { - setSize(newSize); - recapacity(newCapacity); - } - } else { - setSize(newSize); - } - return *this; - } - - POctets & resize(const jau::nsize_t newSize) { - if( capacity < newSize ) { - throw jau::IllegalArgumentException("capacity "+std::to_string(capacity)+" < newSize "+std::to_string(newSize), E_FILE_LINE); - } - setSize(newSize); - return *this; - } - - POctets & recapacity(const jau::nsize_t newCapacity) { - if( newCapacity < getSize() ) { - throw jau::IllegalArgumentException("newCapacity "+std::to_string(newCapacity)+" < size "+std::to_string(getSize()), E_FILE_LINE); - } - if( newCapacity == capacity ) { - return *this; - } - uint8_t* data2 = allocData(newCapacity); - if( getSize() > 0 ) { - memcpy(data2, get_ptr(), getSize()); - } - TRACE_PRINT("POctets recapacity: %p -> %p", data(), data2); - free(data()); - setData(data2, getSize()); - capacity = newCapacity; - return *this; - } - - POctets & operator+=(const TROOctets &b) { - if( 0 < b.getSize() ) { - const jau::nsize_t newSize = getSize() + b.getSize(); - if( capacity < newSize ) { - recapacity( newSize ); - } - memcpy(data()+getSize(), b.get_ptr(), b.getSize()); - setSize(newSize); - } - return *this; - } - POctets & operator+=(const TOctetSlice &b) { - if( 0 < b.getSize() ) { - const jau::nsize_t newSize = getSize() + b.getSize(); - if( capacity < newSize ) { - recapacity( newSize ); - } - memcpy(data()+getSize(), b.getParent().get_ptr()+b.getOffset(), b.getSize()); - setSize(newSize); - } - return *this; - } - - std::string toString() const { - return "size "+std::to_string(getSize())+", capacity "+std::to_string(getCapacity())+", "+jau::bytesHexString(get_ptr(), 0, getSize(), true /* lsbFirst */); - } - }; - - -} - - -#endif /* OCTET_TYPES_HPP_ */ diff --git a/api/direct_bt/SMPHandler.hpp b/api/direct_bt/SMPHandler.hpp index 06f14420..2ffaa7b8 100644 --- a/api/direct_bt/SMPHandler.hpp +++ b/api/direct_bt/SMPHandler.hpp @@ -39,8 +39,8 @@ #include <jau/function_def.hpp> #include <jau/darray.hpp> #include <jau/cow_darray.hpp> +#include <jau/uuid.hpp> -#include "UUID.hpp" #include "BTTypes0.hpp" #include "L2CAPComm.hpp" #include "SMPTypes.hpp" @@ -192,7 +192,7 @@ namespace direct_bt { const std::string deviceString; std::recursive_mutex mtx_command; - POctets rbuffer; + jau::POctets rbuffer; L2CAPComm l2cap; jau::sc_atomic_bool is_connected; // reflects state diff --git a/api/direct_bt/SMPTypes.hpp b/api/direct_bt/SMPTypes.hpp index dc472c12..cc5e6d03 100644 --- a/api/direct_bt/SMPTypes.hpp +++ b/api/direct_bt/SMPTypes.hpp @@ -34,8 +34,8 @@ #include <mutex> #include <jau/basic_types.hpp> +#include <jau/octets.hpp> -#include "OctetTypes.hpp" #include "BTTypes0.hpp" /** @@ -700,7 +700,7 @@ namespace direct_bt { } /** actual received PDU */ - POctets pdu; + jau::POctets pdu; /** creation timestamp in milliseconds */ uint64_t ts_creation; diff --git a/api/direct_bt/UUID.hpp b/api/direct_bt/UUID.hpp deleted file mode 100644 index 01c29a50..00000000 --- a/api/direct_bt/UUID.hpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Author: Sven Gothel <[email protected]> - * Copyright (c) 2020 Gothel Software e.K. - * Copyright (c) 2020 ZAFENA AB - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef UUID_HPP_ -#define UUID_HPP_ - -#include <cstring> -#include <string> -#include <memory> -#include <cstdint> -#include <vector> - -#include <jau/basic_types.hpp> - -namespace direct_bt { - -class uuid128_t; // forward - -/** - * Bluetooth UUID <https://www.bluetooth.com/specifications/assigned-numbers/service-discovery/> - * <p> - * Bluetooth is LSB or Little-Endian! - * </p> - * <p> - * BASE_UUID '00000000-0000-1000-8000-00805F9B34FB' - * </p> - */ -extern uuid128_t BT_BASE_UUID; - -class uuid_t { -public: - /** Underlying integer value present octet count */ - enum class TypeSize : jau::nsize_t { - UUID16_SZ=2, UUID32_SZ=4, UUID128_SZ=16 - }; - static constexpr jau::nsize_t number(const TypeSize rhs) noexcept { - return static_cast<jau::nsize_t>(rhs); - } - -private: - TypeSize type; - -protected: - uuid_t(TypeSize const type_) : type(type_) {} - -public: - static TypeSize toTypeSize(const jau::nsize_t size); - static std::unique_ptr<uuid_t> create(TypeSize const t, uint8_t const * const buffer, jau::nsize_t const byte_offset, bool const littleEndian); - static std::unique_ptr<uuid_t> create(const std::string& str); - - virtual ~uuid_t() noexcept {} - - uuid_t(const uuid_t &o) noexcept = default; - uuid_t(uuid_t &&o) noexcept = default; - uuid_t& operator=(const uuid_t &o) noexcept = default; - uuid_t& operator=(uuid_t &&o) noexcept = default; - - std::unique_ptr<uuid_t> clone() const noexcept; - - virtual bool operator==(uuid_t const &o) const noexcept { - if( this == &o ) { - return true; - } - return type == o.type; - } - bool operator!=(uuid_t const &o) const noexcept - { return !(*this == o); } - - TypeSize getTypeSize() const noexcept { return type; } - jau::nsize_t getTypeSizeInt() const noexcept { return uuid_t::number(type); } - - uuid128_t toUUID128(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid32_le_octet_index=12) const noexcept; - - /** returns the pointer to the uuid data of size getTypeSize() */ - virtual const uint8_t * data() const noexcept = 0; - virtual std::string toString() const noexcept = 0; - virtual std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept = 0; - virtual jau::nsize_t put(uint8_t * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) const noexcept = 0; -}; - -class uuid16_t : public uuid_t { -public: - uint16_t value; - - uuid16_t(uint16_t const v) noexcept - : uuid_t(TypeSize::UUID16_SZ), value(v) { } - - uuid16_t(const std::string& str); - - uuid16_t(uint8_t const * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept - : uuid_t(TypeSize::UUID16_SZ), value(jau::get_uint16(buffer, byte_offset, littleEndian)) { } - - uuid16_t(const uuid16_t &o) noexcept = default; - uuid16_t(uuid16_t &&o) noexcept = default; - uuid16_t& operator=(const uuid16_t &o) noexcept = default; - uuid16_t& operator=(uuid16_t &&o) noexcept = default; - - bool operator==(uuid_t const &o) const noexcept override { - if( this == &o ) { - return true; - } - return getTypeSize() == o.getTypeSize() && value == static_cast<uuid16_t const *>(&o)->value; - } - - const uint8_t * data() const noexcept override { return static_cast<uint8_t*>(static_cast<void*>(const_cast<uint16_t*>(&value))); } - std::string toString() const noexcept override; - std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override; - - jau::nsize_t put(uint8_t * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) const noexcept override { - jau::put_uint16(buffer, byte_offset, value, littleEndian); - return 2; - } -}; - -class uuid32_t : public uuid_t { -public: - uint32_t value; - - uuid32_t(uint32_t const v) noexcept - : uuid_t(TypeSize::UUID32_SZ), value(v) {} - - uuid32_t(const std::string& str); - - uuid32_t(uint8_t const * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept - : uuid_t(TypeSize::UUID32_SZ), value(jau::get_uint32(buffer, byte_offset, littleEndian)) { } - - uuid32_t(const uuid32_t &o) noexcept = default; - uuid32_t(uuid32_t &&o) noexcept = default; - uuid32_t& operator=(const uuid32_t &o) noexcept = default; - uuid32_t& operator=(uuid32_t &&o) noexcept = default; - - bool operator==(uuid_t const &o) const noexcept override { - if( this == &o ) { - return true; - } - return getTypeSize() == o.getTypeSize() && value == static_cast<uuid32_t const *>(&o)->value; - } - - const uint8_t * data() const noexcept override { return static_cast<uint8_t*>(static_cast<void*>(const_cast<uint32_t*>(&value))); } - std::string toString() const noexcept override; - std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override; - - jau::nsize_t put(uint8_t * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) const noexcept override { - jau::put_uint32(buffer, byte_offset, value, littleEndian); - return 4; - } -}; - -class uuid128_t : public uuid_t { -public: - jau::uint128_t value; - - uuid128_t() noexcept : uuid_t(TypeSize::UUID128_SZ) { bzero(value.data, sizeof(value)); } - - uuid128_t(jau::uint128_t const v) noexcept - : uuid_t(TypeSize::UUID128_SZ), value(v) {} - - uuid128_t(const std::string& str); - - uuid128_t(uint8_t const * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) noexcept - : uuid_t(TypeSize::UUID128_SZ), value(jau::get_uint128(buffer, byte_offset, littleEndian)) { } - - uuid128_t(uuid16_t const & uuid16, uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid16_le_octet_index=12) noexcept; - - uuid128_t(uuid32_t const & uuid32, uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const uuid32_le_octet_index=12) noexcept; - - uuid128_t(const uuid128_t &o) noexcept = default; - uuid128_t(uuid128_t &&o) noexcept = default; - uuid128_t& operator=(const uuid128_t &o) noexcept = default; - uuid128_t& operator=(uuid128_t &&o) noexcept = default; - - bool operator==(uuid_t const &o) const noexcept override { - if( this == &o ) { - return true; - } - return getTypeSize() == o.getTypeSize() && value == static_cast<uuid128_t const *>(&o)->value; - } - - const uint8_t * data() const noexcept override { return value.data; } - std::string toString() const noexcept override; - std::string toUUID128String(uuid128_t const & base_uuid=BT_BASE_UUID, jau::nsize_t const le_octet_index=12) const noexcept override { - (void)base_uuid; - (void)le_octet_index; - return toString(); - } - - jau::nsize_t put(uint8_t * const buffer, jau::nsize_t const byte_offset, bool const littleEndian) const noexcept override { - jau::put_uint128(buffer, byte_offset, value, littleEndian); - return 16; - } -}; - -inline uuid16_t get_uuid16(uint8_t const * buffer, jau::nsize_t const byte_offset) noexcept -{ - return uuid16_t(jau::get_uint16(buffer, byte_offset)); -} -inline uuid16_t get_uuid16(uint8_t const * buffer, jau::nsize_t const byte_offset, bool littleEndian) noexcept -{ - return uuid16_t(jau::get_uint16(buffer, byte_offset, littleEndian)); -} -inline uuid32_t get_uuid32(uint8_t const * buffer, jau::nsize_t const byte_offset) noexcept -{ - return uuid32_t(jau::get_uint32(buffer, byte_offset)); -} -inline uuid32_t get_uuid32(uint8_t const * buffer, jau::nsize_t const byte_offset, bool littleEndian) noexcept -{ - return uuid32_t(jau::get_uint32(buffer, byte_offset, littleEndian)); -} -inline uuid128_t get_uuid128(uint8_t const * buffer, jau::nsize_t const byte_offset) noexcept -{ - return uuid128_t(jau::get_uint128(buffer, byte_offset)); -} -inline uuid128_t get_uuid128(uint8_t const * buffer, jau::nsize_t const byte_offset, bool littleEndian) noexcept -{ - return uuid128_t(jau::get_uint128(buffer, byte_offset, littleEndian)); -} - -} /* namespace direct_bt */ - -#endif /* UUID_HPP_ */ diff --git a/api/direct_bt/linux_kernel_types.hpp b/api/direct_bt/linux_kernel_types.hpp index 247fddb3..6bc88680 100644 --- a/api/direct_bt/linux_kernel_types.hpp +++ b/api/direct_bt/linux_kernel_types.hpp @@ -27,8 +27,7 @@ #define LINUX_KERNEL_TYPES_HPP_ #include <jau/packed_attribute.hpp> - -#include "BTAddress.hpp" +#include <jau/eui48.hpp> #if defined(__linux__) /* <sys/param.h> defines __u64 _le64 and _be64 on aarch64 */ @@ -52,6 +51,6 @@ typedef uint32_t __be32; typedef uint64_t __be64; #endif -typedef direct_bt::EUI48 bdaddr_t; +typedef jau::EUI48 bdaddr_t; #endif /* LINUX_KERNEL_TYPES_HPP_ */ diff --git a/cmake/modules/DirCopy.cmake b/cmake/modules/DirCopy.cmake new file mode 100644 index 00000000..49e89ec2 --- /dev/null +++ b/cmake/modules/DirCopy.cmake @@ -0,0 +1 @@ +file(COPY ${_srcdir} DESTINATION ${_dstdir}) diff --git a/examples/java/DBTPeripheral00.java b/examples/java/DBTPeripheral00.java index da2746e3..527b69d5 100644 --- a/examples/java/DBTPeripheral00.java +++ b/examples/java/DBTPeripheral00.java @@ -40,12 +40,12 @@ import org.direct_bt.BTManager; import org.direct_bt.BTSecurityRegistry; import org.direct_bt.BTUtils; import org.direct_bt.EIRDataTypeSet; -import org.direct_bt.EUI48; import org.direct_bt.HCIStatusCode; import org.direct_bt.PairingMode; import org.direct_bt.SMPKeyBin; import org.direct_bt.SMPPairingState; import org.direct_bt.ScanType; +import org.jau.net.EUI48; /** * This Java peripheral {@link BTRole::Slave} example uses the Direct-BT fully event driven workflow. diff --git a/examples/java/DBTScanner10.java b/examples/java/DBTScanner10.java index 0ab22585..184309d1 100644 --- a/examples/java/DBTScanner10.java +++ b/examples/java/DBTScanner10.java @@ -52,7 +52,6 @@ import org.direct_bt.BTSecurityRegistry; import org.direct_bt.BTType; import org.direct_bt.BTUtils; import org.direct_bt.EIRDataTypeSet; -import org.direct_bt.EUI48; import org.direct_bt.GattCharPropertySet; import org.direct_bt.HCIStatusCode; import org.direct_bt.HCIWhitelistConnectType; @@ -61,6 +60,7 @@ import org.direct_bt.SMPIOCapability; import org.direct_bt.SMPKeyBin; import org.direct_bt.SMPPairingState; import org.direct_bt.ScanType; +import org.jau.net.EUI48; import jau.direct_bt.DBTManager; diff --git a/jaulib b/jaulib -Subproject 9e2ac8b761c82dcd6165d7228a2ab6cefba4f6f +Subproject c7173473ed59d5b32743c6fea834ba2c339b4b2 diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index c88e9f08..8c52088c 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -8,6 +8,9 @@ file(GLOB_RECURSE JAVA_SOURCES "*.java") add_jar(direct_bt_jar ${JAVA_SOURCES} + ${PROJECT_SOURCE_DIR}/jaulib/java_base/org/jau/util/BasicTypes.java + ${PROJECT_SOURCE_DIR}/jaulib/java_net/org/jau/net/EUI48.java + ${PROJECT_SOURCE_DIR}/jaulib/java_net/org/jau/net/EUI48Sub.java INCLUDE_JARS ${jaulib_fat_jar_file} MANIFEST ${CMAKE_CURRENT_BINARY_DIR}/manifest.txt OUTPUT_NAME direct_bt diff --git a/java/jau/direct_bt/DBTAdapter.java b/java/jau/direct_bt/DBTAdapter.java index edf97e24..56139e14 100644 --- a/java/jau/direct_bt/DBTAdapter.java +++ b/java/jau/direct_bt/DBTAdapter.java @@ -50,12 +50,12 @@ import org.direct_bt.BTRole; import org.direct_bt.BTType; import org.direct_bt.BTUtils; import org.direct_bt.EIRDataTypeSet; -import org.direct_bt.EUI48; import org.direct_bt.HCIStatusCode; import org.direct_bt.HCIWhitelistConnectType; import org.direct_bt.PairingMode; import org.direct_bt.SMPPairingState; import org.direct_bt.ScanType; +import org.jau.net.EUI48; public class DBTAdapter extends DBTObject implements BTAdapter { diff --git a/java/jau/direct_bt/DBTDevice.java b/java/jau/direct_bt/DBTDevice.java index f31395c3..1dc5bb9e 100644 --- a/java/jau/direct_bt/DBTDevice.java +++ b/java/jau/direct_bt/DBTDevice.java @@ -45,7 +45,6 @@ import org.direct_bt.BTRole; import org.direct_bt.BTType; import org.direct_bt.BTUtils; import org.direct_bt.EIRDataTypeSet; -import org.direct_bt.EUI48; import org.direct_bt.BTGattCharListener; import org.direct_bt.HCIStatusCode; import org.direct_bt.PairingMode; @@ -54,6 +53,7 @@ import org.direct_bt.SMPKeyMask; import org.direct_bt.SMPLongTermKeyInfo; import org.direct_bt.SMPPairingState; import org.direct_bt.SMPSignatureResolvingKeyInfo; +import org.jau.net.EUI48; public class DBTDevice extends DBTObject implements BTDevice { diff --git a/java/org/direct_bt/BDAddressAndType.java b/java/org/direct_bt/BDAddressAndType.java index edcc8fb9..c924d4b9 100644 --- a/java/org/direct_bt/BDAddressAndType.java +++ b/java/org/direct_bt/BDAddressAndType.java @@ -25,6 +25,8 @@ package org.direct_bt; +import org.jau.net.EUI48; + /** * Unique Bluetooth {@link EUI48} address and {@link BDAddressType} tuple. * <p> @@ -73,6 +75,26 @@ public class BDAddressAndType { /** * Returns the {@link BLERandomAddressType}. * <p> + * If {@link BDAddressType} is {@link BDAddressType::BDADDR_LE_RANDOM}, + * method shall return a valid value other than {@link BLERandomAddressType::UNDEFINED}. + * </p> + * <p> + * If {@link BDAddressType} is not {@link BDAddressType::BDADDR_LE_RANDOM}, + * method shall return {@link BLERandomAddressType::UNDEFINED}. + * </p> + * @since 2.2.0 + */ + public static BLERandomAddressType getBLERandomAddressType(final EUI48 address, final BDAddressType addressType) { + if( BDAddressType.BDADDR_LE_RANDOM != addressType ) { + return BLERandomAddressType.UNDEFINED; + } + final byte high2 = (byte) ( ( address.b[5] >> 6 ) & 0x03 ); + return BLERandomAddressType.get(high2); + } + + /** + * Returns the {@link BLERandomAddressType}. + * <p> * If {@link #type} is {@link BDAddressType::BDADDR_LE_RANDOM}, * method shall return a valid value other than {@link BLERandomAddressType::UNDEFINED}. * </p> @@ -83,7 +105,7 @@ public class BDAddressAndType { * @since 2.0.0 */ public BLERandomAddressType getBLERandomAddressType() { - return address.getBLERandomAddressType(type); + return getBLERandomAddressType(address, type); } /** diff --git a/java/org/direct_bt/BTDeviceRegistry.java b/java/org/direct_bt/BTDeviceRegistry.java index 82bdd0cd..553c5413 100644 --- a/java/org/direct_bt/BTDeviceRegistry.java +++ b/java/org/direct_bt/BTDeviceRegistry.java @@ -33,6 +33,9 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import org.jau.net.EUI48; +import org.jau.net.EUI48Sub; + /** * Application toolkit providing BT device registration of processed and awaited devices. * The latter on a pattern matching basis, i.e. EUI48Sub or name-sub. diff --git a/java/org/direct_bt/BTSecurityRegistry.java b/java/org/direct_bt/BTSecurityRegistry.java index 01e1b6b8..fe34e85b 100644 --- a/java/org/direct_bt/BTSecurityRegistry.java +++ b/java/org/direct_bt/BTSecurityRegistry.java @@ -30,6 +30,9 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; +import org.jau.net.EUI48; +import org.jau.net.EUI48Sub; + /** * Application toolkit providing BT security setup and its device association * on a pattern matching basis, i.e. EUI48Sub or name-sub. diff --git a/java/org/direct_bt/BTUtils.java b/java/org/direct_bt/BTUtils.java index 23870f23..15e54345 100644 --- a/java/org/direct_bt/BTUtils.java +++ b/java/org/direct_bt/BTUtils.java @@ -26,6 +26,8 @@ package org.direct_bt; import java.io.PrintStream; +import org.jau.util.BasicTypes; + public class BTUtils { private static long t0; static { @@ -123,40 +125,8 @@ public class BTUtils { public static String bytesHexString(final byte[] bytes, final int offset, final int length, final boolean lsbFirst) { - final int byte_len = 0 <= length ? length : bytes.length - offset; - if( byte_len > ( bytes.length - offset ) ) { - throw new IllegalArgumentException("byte[] ( "+bytes.length+" - "+offset+" ) < "+length+" bytes"); - } - // final char[] hex_array = lowerCase ? HEX_ARRAY_LOW : HEX_ARRAY_BIG; - final char[] hex_array = HEX_ARRAY_LOW; - final char[] hexChars; - final int char_offset; - - if( lsbFirst ) { - // LSB left -> MSB right, no leading `0x` - char_offset = 0; - hexChars = new char[byte_len * 2]; - for (int j = 0; j < byte_len; j++) { - final int v = bytes[offset + j] & 0xFF; - hexChars[char_offset + j * 2] = hex_array[v >>> 4]; - hexChars[char_offset + j * 2 + 1] = hex_array[v & 0x0F]; - } - } else { - // MSB left -> LSB right, with leading `0x` - char_offset = 2; - hexChars = new char[2 + byte_len * 2]; - hexChars[0] = '0'; - hexChars[1] = 'x'; - for (int j = byte_len-1; j >= 0; j--) { - final int v = bytes[offset + j] & 0xFF; - hexChars[char_offset + j * 2] = hex_array[v >>> 4]; - hexChars[char_offset + j * 2 + 1] = hex_array[v & 0x0F]; - } - } - return new String(hexChars); + return BasicTypes.bytesHexString(bytes, offset, length, lsbFirst); } - private static final char[] HEX_ARRAY_LOW = "0123456789abcdef".toCharArray(); - private static final char[] HEX_ARRAY_BIG = "0123456789ABCDEF".toCharArray(); /** * Produce a hexadecimal string representation of the given byte value. @@ -167,11 +137,7 @@ public class BTUtils { */ public static StringBuilder byteHexString(final StringBuilder sb, final byte value, final boolean lowerCase) { - final char[] hex_array = lowerCase ? HEX_ARRAY_LOW : HEX_ARRAY_BIG; - final int v = value & 0xFF; - sb.append(hex_array[v >>> 4]); - sb.append(hex_array[v & 0x0F]); - return sb; + return BasicTypes.byteHexString(sb, value, lowerCase); } /** diff --git a/java/org/direct_bt/EUI48.java b/java/org/direct_bt/EUI48.java deleted file mode 100644 index af23eed7..00000000 --- a/java/org/direct_bt/EUI48.java +++ /dev/null @@ -1,288 +0,0 @@ -/** - * Author: Sven Gothel <[email protected]> - * Copyright (c) 2021 Gothel Software e.K. - * Copyright (c) 2020 ZAFENA AB - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -package org.direct_bt; - -/** - * A packed 48 bit EUI-48 identifier, formerly known as MAC-48 - * or simply network device MAC address (Media Access Control address). - * <p> - * Implementation caches the hash value {@link #hashCode()}, - * hence users shall take special care when mutating the - * underlying data {@link #b}, read its API notes. - * </p> - */ -public class EUI48 { - /** EUI48 MAC address matching any device, i.e. '0:0:0:0:0:0'. */ - public static final EUI48 ANY_DEVICE = new EUI48( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 } ); - /** EUI48 MAC address matching all device, i.e. 'ff:ff:ff:ff:ff:ff'. */ - public static final EUI48 ALL_DEVICE = new EUI48( new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff } ); - /** EUI48 MAC address matching local device, i.e. '0:0:0:ff:ff:ff'. */ - public static final EUI48 LOCAL_DEVICE = new EUI48( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0xff } ); - - /** - * The 6 byte EUI48 address. - * <p> - * If modifying, it is the user's responsibility to avoid data races.<br> - * Further, call {@link #clearHash()} after mutation is complete. - * </p> - */ - public final byte b[/* 6 octets */]; - - private volatile int hash; // default 0, cache - - /** - * Size of the byte stream representation in bytes - * @see #getStream(byte[], int) - */ - /* pp */ static final int byte_size = 6; - - /** - * Fills given EUI48 instance via given string representation. - * <p> - * Implementation is consistent with {@link #toString()}. - * </p> - * @param str a string of exactly 17 characters representing 6 bytes as hexadecimal numbers separated via colon {@code "01:02:03:0A:0B:0C"}. - * @param dest EUI48 to set its value - * @param errmsg error parsing message if returning false - * @return true if successful, otherwise false - * @see #EUI48(String) - * @see #toString() - */ - public static boolean scanEUI48(final String str, final EUI48 dest, final StringBuilder errmsg) { - if( 17 != str.length() ) { - errmsg.append("EUI48 string not of length 17 but "+str.length()+": "+str); - return false; - } - try { - for(int i=0; i<byte_size; i++) { - dest.b[byte_size-1-i] = Integer.valueOf(str.substring(i*2+i, i*2+i+2), 16).byteValue(); - } - } catch (final NumberFormatException e) { - errmsg.append("EUI48 string not in format '01:02:03:0A:0B:0C' but "+str+"; "+e.getMessage()); - return false; - } - return true; - } - - /** - * Construct instance via given string representation. - * <p> - * Implementation is consistent with {@link #toString()}. - * </p> - * @param str a string of exactly 17 characters representing 6 bytes as hexadecimal numbers separated via colon {@code "01:02:03:0A:0B:0C"}. - * @see #scanEUI48(String, byte[], StringBuilder) - * @see #toString() - * @throws IllegalArgumentException if given string doesn't comply with EUI48 - */ - public EUI48(final String str) throws IllegalArgumentException { - final StringBuilder errmsg = new StringBuilder(); - b = new byte[byte_size]; - if( !scanEUI48(str, this, errmsg) ) { - throw new IllegalArgumentException(errmsg.toString()); - } - } - - /** Construct instance via given source byte array */ - public EUI48(final byte stream[], final int pos) { - if( byte_size > ( stream.length - pos ) ) { - throw new IllegalArgumentException("EUI48 stream ( "+stream.length+" - "+pos+" ) < "+byte_size+" bytes"); - } - b = new byte[byte_size]; - System.arraycopy(stream, pos, b, 0, byte_size); - } - - /** Construct instance using the given address of the byte array */ - public EUI48(final byte address[]) { - if( byte_size != address.length ) { - throw new IllegalArgumentException("EUI48 stream "+address.length+" != "+byte_size+" bytes"); - } - b = address; - } - - /** Construct empty unset instance. */ - public EUI48() { - b = new byte[byte_size]; - } - - @Override - public final boolean equals(final Object obj) { - if(this == obj) { - return true; - } - if (obj == null || !(obj instanceof EUI48)) { - return false; - } - final byte[] b2 = ((EUI48)obj).b; - return b[0] == b2[0] && - b[1] == b2[1] && - b[2] == b2[2] && - b[3] == b2[3] && - b[4] == b2[4] && - b[5] == b2[5]; - } - - /** - * {@inheritDoc} - * <p> - * Implementation uses a lock-free volatile cache. - * </p> - * @see #clearHash() - */ - @Override - public final int hashCode() { - int h = hash; - if( 0 == h ) { - /** - // final int p = 92821; // alternative with less collisions? - final int p = 31; // traditional prime - h = b[0]; - h = p * h + b[1]; - h = p * h + b[2]; - h = p * h + b[3]; - h = p * h + b[4]; - h = p * h + b[5]; - */ - // 31 * x == (x << 5) - x - h = b[0]; - h = ( ( h << 5 ) - h ) + b[1]; - h = ( ( h << 5 ) - h ) + b[2]; - h = ( ( h << 5 ) - h ) + b[3]; - h = ( ( h << 5 ) - h ) + b[4]; - h = ( ( h << 5 ) - h ) + b[5]; - hash = h; - } - return h; - } - - /** - * Method clears the cached hash value. - * @see #clear() - */ - public void clearHash() { hash = 0; } - - /** - * Method clears the underlying byte array {@link #b} and cached hash value. - * @see #clearHash() - */ - public void clear() { - hash = 0; - b[0] = 0; b[1] = 0; b[2] = 0; - b[3] = 0; b[4] = 0; b[5] = 0; - } - - /** - * Method transfers all bytes representing a EUI48 from the given - * source array at the given position into this instance and clears its cached hash value. - * <p> - * Implementation is consistent with {@link #EUI48(byte[], int)}. - * </p> - * @param source the source array - * @param pos starting position in the source array - * @see #EUI48(byte[], int) - * @see #clearHash() - */ - public final void putStream(final byte[] source, final int pos) { - if( byte_size > ( source.length - pos ) ) { - throw new IllegalArgumentException("Stream ( "+source.length+" - "+pos+" ) < "+byte_size+" bytes"); - } - hash = 0; - System.arraycopy(source, pos, b, 0, byte_size); - } - - /** - * Method transfers all bytes representing this instance into the given - * destination array at the given position. - * <p> - * Implementation is consistent with {@link #EUI48(byte[], int)}. - * </p> - * @param sink the destination array - * @param pos starting position in the destination array - * @see #EUI48(byte[], int) - */ - public final void getStream(final byte[] sink, final int pos) { - if( byte_size > ( sink.length - pos ) ) { - throw new IllegalArgumentException("Stream ( "+sink.length+" - "+pos+" ) < "+byte_size+" bytes"); - } - System.arraycopy(b, 0, sink, pos, byte_size); - } - - /** - * Returns the {@link BLERandomAddressType}. - * <p> - * If {@link BDAddressType} is {@link BDAddressType::BDADDR_LE_RANDOM}, - * method shall return a valid value other than {@link BLERandomAddressType::UNDEFINED}. - * </p> - * <p> - * If {@link BDAddressType} is not {@link BDAddressType::BDADDR_LE_RANDOM}, - * method shall return {@link BLERandomAddressType::UNDEFINED}. - * </p> - * @since 2.2.0 - */ - public BLERandomAddressType getBLERandomAddressType(final BDAddressType addressType) { - if( BDAddressType.BDADDR_LE_RANDOM != addressType ) { - return BLERandomAddressType.UNDEFINED; - } - final byte high2 = (byte) ( ( b[5] >> 6 ) & 0x03 ); - return BLERandomAddressType.get(high2); - } - - /** - * Finds the index of given EUI48Sub. - */ - public int indexOf(final EUI48Sub needle) { - return EUI48Sub.indexOf(b, 6, needle.b, needle.length); - } - - /** - * Returns true, if given EUI48Sub is contained in here. - * <p> - * If the sub is zero, true is returned. - * </p> - */ - public boolean contains(final EUI48Sub needle) { - return 0 <= indexOf(needle); - } - - /** - * {@inheritDoc} - * <p> - * Returns the EUI48 string representation, - * exactly 17 characters representing 6 bytes as upper case hexadecimal numbers separated via colon {@code "01:02:03:0A:0B:0C"}. - * </p> - * @see #EUI48(String) - */ - @Override - public final String toString() { - final StringBuilder sb = new StringBuilder(17); - for(int i=byte_size-1; 0 <= i; i--) { - BTUtils.byteHexString(sb, b[i], false /* lowerCase */); - if( 0 < i ) { - sb.append(":"); - } - } - return sb.toString(); - } -} diff --git a/java/org/direct_bt/EUI48Sub.java b/java/org/direct_bt/EUI48Sub.java deleted file mode 100644 index c8bd7f72..00000000 --- a/java/org/direct_bt/EUI48Sub.java +++ /dev/null @@ -1,276 +0,0 @@ -/** - * Author: Sven Gothel <[email protected]> - * Copyright (c) 2021 Gothel Software e.K. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package org.direct_bt; - -import java.util.Arrays; - -/** - * A 48 bit EUI-48 sub-identifier, see {@link EUI48}. - */ -public class EUI48Sub { - /** EUI48Sub MAC address matching any device, i.e. '0:0:0:0:0:0'. */ - public static final EUI48Sub ANY_DEVICE = new EUI48Sub( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, 0, 6 ); - /** EUI48Sub MAC address matching all device, i.e. 'ff:ff:ff:ff:ff:ff'. */ - public static final EUI48Sub ALL_DEVICE = new EUI48Sub( new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }, 0, 6 ); - /** EUI48Sub MAC address matching local device, i.e. '0:0:0:ff:ff:ff'. */ - public static final EUI48Sub LOCAL_DEVICE = new EUI48Sub( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0xff }, 0, 6 ); - - /** - * The EUI48 sub-address, always 6 bytes reserved. - */ - public final byte b[/* 6 octets */]; - - private volatile int hash; // default 0, cache - - /** - * The actual length in bytes of the EUI48 sub-address, less or equal 6 bytes. - */ - public int length; - - /** - * Fills given EUI48Sub instance via given string representation. - * <p> - * Implementation is consistent with {@link #toString()}. - * </p> - * @param str a string of less or equal of 17 characters representing less or equal of 6 bytes as hexadecimal numbers separated via colon, - * e.g. {@code "01:02:03:0A:0B:0C"}, {@code "01:02:03:0A"}, {@code ":"}, {@code ""}. - * @param dest EUI48Sub to set its value - * @param errmsg error parsing message if returning false - * @return true if successful, otherwise false - * @see #EUI48Sub(String) - * @see #toString() - */ - public static boolean scanEUI48Sub(final String str, final EUI48Sub dest, final StringBuilder errmsg) { - final int str_len = str.length(); - dest.clear(); - - if( 17 < str_len ) { // not exceeding EUI48.byte_size - errmsg.append("EUI48 sub-string must be less or equal length 17 but "+str.length()+": "+str); - return false; - } - final byte b_[] = new byte[ 6 ]; // intermediate result high -> low - int len_ = 0; - int j=0; - try { - boolean exp_colon = false; - while( j+1 < str_len /* && byte_count_ < byte_size */ ) { // min 2 chars left - final boolean is_colon = ':' == str.charAt(j); - if( exp_colon && !is_colon ) { - errmsg.append("EUI48Sub sub-string not in format '01:02:03:0A:0B:0C', but '"+str+"', colon missing, pos "+j+", len "+str_len); - return false; - } else if( is_colon ) { - ++j; - exp_colon = false; - } else { - b_[len_] = Integer.valueOf(str.substring(j, j+2), 16).byteValue(); // b_: high->low - j += 2; - ++len_; - exp_colon = true; - } - } - dest.length = len_; - for(j=0; j<len_; ++j) { // swap low->high - dest.b[j] = b_[len_-1-j]; - } - } catch (final NumberFormatException e) { - errmsg.append("EUI48 sub-string not in format '01:02:03:0A:0B:0C' but "+str+", pos "+j+", len "+str_len); - return false; - } - return true; - } - - /** Construct empty unset instance. */ - public EUI48Sub() { - b = new byte[6]; - length = 0; - } - - /** - * Construct a sub EUI48 via given string representation. - * <p> - * Implementation is consistent with {@link #toString()}. - * </p> - * @param str a string of less or equal of 17 characters representing less or equal of 6 bytes as hexadecimal numbers separated via colon, - * e.g. {@code "01:02:03:0A:0B:0C"}, {@code "01:02:03:0A"}, {@code ":"}, {@code ""}. - * @see #toString() - * @throws IllegalArgumentException if given string doesn't comply with EUI48 - */ - public EUI48Sub(final String str) throws IllegalArgumentException { - final StringBuilder errmsg = new StringBuilder(); - b = new byte[ 6 ]; - if( !scanEUI48Sub(str, this, errmsg) ) { - throw new IllegalArgumentException(errmsg.toString()); - } - } - - /** Construct instance via given source byte array */ - public EUI48Sub(final byte stream[], final int pos, final int len_) { - if( len_ > EUI48.byte_size || pos + len_ > stream.length ) { - throw new IllegalArgumentException("EUI48 stream ( pos "+pos+", len "+len_+" > EUI48 size "+EUI48.byte_size+" or stream.length "+stream.length); - } - b = new byte[6]; - System.arraycopy(stream, pos, b, 0, len_); - length = len_; - } - - @Override - public final boolean equals(final Object obj) { - if(this == obj) { - return true; - } - if (obj == null || !(obj instanceof EUI48Sub)) { - return false; - } - final int length2 = ((EUI48Sub)obj).length; - if( length != length2 ) { - return false; - } - final byte[] b2 = ((EUI48Sub)obj).b; - return Arrays.equals(b, 0, length, b2, 0, length2); - } - - /** - * {@inheritDoc} - * <p> - * Implementation uses a lock-free volatile cache. - * </p> - * @see #clearHash() - */ - @Override - public final int hashCode() { - int h = hash; - if( 0 == h ) { - // 31 * x == (x << 5) - x - h = length; - for(int i=0; i<length; i++) { - h = ( ( h << 5 ) - h ) + b[i]; - } - hash = h; - } - return h; - } - - /** - * Method clears the cached hash value. - * @see #clear() - */ - public void clearHash() { hash = 0; } - - /** - * Method clears the underlying byte array {@link #b} and sets length to zero. The cached hash value is also cleared. - * @see #clearHash() - */ - public void clear() { - hash = 0; - b[0] = 0; b[1] = 0; b[2] = 0; - b[3] = 0; b[4] = 0; b[5] = 0; - length = 0; - } - - /** - * Find index of needle within haystack. - * @param haystack_b haystack data - * @param haystack_length haystack length - * @param needle_b needle data - * @param needle_length needle length - * @return index of first element of needle within haystack or -1 if not found. If the needle length is zero, 0 (found) is returned. - */ - public static int indexOf(final byte haystack_b[], final int haystack_length, - final byte needle_b[], final int needle_length) { - if( 0 == needle_length ) { - return 0; - } - if( haystack_length < needle_length ) { - return -1; - } - final byte first = needle_b[0]; - final int outerEnd = haystack_length - needle_length + 1; // exclusive - - for (int i = 0; i < outerEnd; i++) { - // find first char of other - while( haystack_b[i] != first ) { - if( ++i == outerEnd ) { - return -1; - } - } - if( i < outerEnd ) { // otherLen chars left to match? - // continue matching other chars - final int innerEnd = i + needle_length; // exclusive - int j = i, k=0; - do { - if( ++j == innerEnd ) { - return i; // gotcha - } - } while( haystack_b[j] == needle_b[++k] ); - } - } - return -1; - } - - /** - * Finds the index of given EUI48Sub needle within this instance haystack. - * @param needle - * @return index of first element of needle within this instance haystack or -1 if not found. If the needle length is zero, 0 (found) is returned. - */ - public int indexOf(final EUI48Sub needle) { - return indexOf(b, length, needle.b, needle.length); - } - - /** - * Returns true, if given EUI48Sub needle is contained in this instance haystack. - * <p> - * If the sub is zero, true is returned. - * </p> - */ - public boolean contains(final EUI48Sub needle) { - return 0 <= indexOf(needle); - } - - /** - * {@inheritDoc} - * <p> - * Returns the EUI48 sub-string representation, - * less or equal 17 characters representing less or equal 6 bytes as upper case hexadecimal numbers separated via colon, - * e.g. {@code "01:02:03:0A:0B:0C"}, {@code "01:02:03:0A"}, {@code ":"}, {@code ""}. - * </p> - */ - @Override - public final String toString() { - // str_len = 2 * len + ( len - 1 ) - // str_len = 3 * len - 1 - // len = ( str_len + 1 ) / 3 - if( 0 < length ) { - final StringBuilder sb = new StringBuilder(3 * length - 1); - for(int i=length-1; 0 <= i; i--) { - BTUtils.byteHexString(sb, b[i], false /* lowerCase */); - if( 0 < i ) { - sb.append(":"); - } - } - return sb.toString(); - } else { - return new String(":"); - } - } -} diff --git a/java_fat/CMakeLists.txt b/java_fat/CMakeLists.txt index c09c97b2..11d4c02c 100644 --- a/java_fat/CMakeLists.txt +++ b/java_fat/CMakeLists.txt @@ -32,14 +32,21 @@ add_custom_command (OUTPUT ${direct_bt_fat_jar_file} ${direct_bt_java_src_file} -D _archives:FILEPATH="${jaulib_fat_jar_file}" -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/ExtractArchiveList.cmake + COMMAND ${CMAKE_COMMAND} + -D_srcdir=${CMAKE_CURRENT_BINARY_DIR}/../java/${CMAKE_FILES_DIRECTORY}/direct_bt_jar.dir/jau + -D_dstdir=${CMAKE_CURRENT_BINARY_DIR}/temp + -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/DirCopy.cmake + COMMAND ${CMAKE_COMMAND} + -D_srcdir=${CMAKE_CURRENT_BINARY_DIR}/../java/${CMAKE_FILES_DIRECTORY}/direct_bt_jar.dir/org + -D_dstdir=${CMAKE_CURRENT_BINARY_DIR}/temp + -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/DirCopy.cmake + COMMAND ${JAR} --create --file ${direct_bt_fat_jar_file} --manifest ${CMAKE_CURRENT_BINARY_DIR}/manifest-fat.txt -C ${CMAKE_CURRENT_BINARY_DIR}/temp/ jau -C ${CMAKE_CURRENT_BINARY_DIR}/temp/ org -C ${CMAKE_CURRENT_BINARY_DIR}/temp/ natives - -C ${CMAKE_CURRENT_BINARY_DIR}/../java/${CMAKE_FILES_DIRECTORY}/direct_bt_jar.dir/ jau - -C ${CMAKE_CURRENT_BINARY_DIR}/../java/${CMAKE_FILES_DIRECTORY}/direct_bt_jar.dir/ org -C ${CMAKE_CURRENT_BINARY_DIR}/ natives COMMAND ${JAR} diff --git a/scripts/rebuild.sh b/scripts/rebuild.sh index 7155f58f..06538b16 100644 --- a/scripts/rebuild.sh +++ b/scripts/rebuild.sh @@ -26,7 +26,7 @@ buildit() { echo CPU_COUNT $CPU_COUNT cd $rootdir/build-$archabi - make -j $CPU_COUNT install test + make -j $CPU_COUNT install if [ $? -eq 0 ] ; then echo "REBUILD SUCCESS $bname $archabi" cp -a examples/* $rootdir/dist-$archabi/bin diff --git a/src/direct_bt/BTDevice.cpp b/src/direct_bt/BTDevice.cpp index 843f137c..cde13a01 100644 --- a/src/direct_bt/BTDevice.cpp +++ b/src/direct_bt/BTDevice.cpp @@ -99,30 +99,30 @@ GATTRole BTDevice::getLocalGATTRole() const noexcept { } } -bool BTDevice::addAdvService(std::shared_ptr<const uuid_t> const &uuid) noexcept +bool BTDevice::addAdvService(std::shared_ptr<const jau::uuid_t> const &uuid) noexcept { - if( 0 > findAdvService(uuid) ) { + if( 0 > findAdvService(*uuid) ) { advServices.push_back(uuid); return true; } return false; } -bool BTDevice::addAdvServices(jau::darray<std::shared_ptr<const uuid_t>> const & services) noexcept +bool BTDevice::addAdvServices(jau::darray<std::shared_ptr<const jau::uuid_t>> const & services) noexcept { bool res = false; for(size_t j=0; j<services.size(); j++) { - const std::shared_ptr<const uuid_t> uuid = services.at(j); + const std::shared_ptr<const jau::uuid_t> uuid = services.at(j); res = addAdvService(uuid) || res; } return res; } -int BTDevice::findAdvService(std::shared_ptr<const uuid_t> const &uuid) const noexcept +int BTDevice::findAdvService(const jau::uuid_t& uuid) const noexcept { const size_t size = advServices.size(); for (size_t i = 0; i < size; i++) { - const std::shared_ptr<const uuid_t> & e = advServices[i]; - if ( nullptr != e && *uuid == *e ) { + const std::shared_ptr<const jau::uuid_t> & e = advServices[i]; + if ( nullptr != e && uuid == *e ) { return i; } } @@ -141,9 +141,9 @@ std::shared_ptr<ManufactureSpecificData> const BTDevice::getManufactureSpecificD return res; } -jau::darray<std::shared_ptr<const uuid_t>> BTDevice::getAdvertisedServices() const noexcept { +jau::darray<std::shared_ptr<const jau::uuid_t>> BTDevice::getAdvertisedServices() const noexcept { jau::sc_atomic_critical sync(sync_data); - jau::darray<std::shared_ptr<const uuid_t>> res = advServices; + jau::darray<std::shared_ptr<const jau::uuid_t>> res = advServices; return res; } @@ -161,12 +161,12 @@ std::string BTDevice::toString(bool includeDiscoveredServices) const noexcept { "), gap "+direct_bt::to_string(gap_flags)+ ", "+msdstr+", "+javaObjectToString()+"]"); if( includeDiscoveredServices ) { - jau::darray<std::shared_ptr<const uuid_t>> _advServices = getAdvertisedServices(); + jau::darray<std::shared_ptr<const jau::uuid_t>> _advServices = getAdvertisedServices(); if( _advServices.size() > 0 ) { out.append("\n"); const size_t size = _advServices.size(); for (size_t i = 0; i < size; i++) { - const std::shared_ptr<const uuid_t> & e = _advServices[i]; + const std::shared_ptr<const jau::uuid_t> & e = _advServices[i]; if( 0 < i ) { out.append("\n"); } @@ -1571,12 +1571,12 @@ jau::darray<std::shared_ptr<BTGattService>> BTDevice::getGattServices() noexcept return gattServices; } -std::shared_ptr<BTGattService> BTDevice::findGattService(std::shared_ptr<uuid_t> const &uuid) { +std::shared_ptr<BTGattService> BTDevice::findGattService(const jau::uuid_t& uuid) { const jau::darray<std::shared_ptr<BTGattService>> & gattServices = getGattServices(); // reference of the GATTHandler's list const size_t size = gattServices.size(); for (size_t i = 0; i < size; i++) { const std::shared_ptr<BTGattService> & e = gattServices[i]; - if ( nullptr != e && *uuid == *(e->type) ) { + if ( nullptr != e && uuid == *(e->type) ) { return e; } } diff --git a/src/direct_bt/BTGattHandler.cpp b/src/direct_bt/BTGattHandler.cpp index 223a875d..a5c3b3ec 100644 --- a/src/direct_bt/BTGattHandler.cpp +++ b/src/direct_bt/BTGattHandler.cpp @@ -207,8 +207,8 @@ void BTGattHandler::l2capReaderThreadImpl() { const AttHandleValueRcv * a = static_cast<const AttHandleValueRcv*>(attPDU.get()); COND_PRINT(env.DEBUG_DATA, "GATTHandler::reader: NTF: %s, listener %zd", a->toString().c_str(), characteristicListenerList.size()); BTGattCharRef decl = findCharacterisicsByValueHandle(a->getHandle()); - const TOctetSlice& a_value_view = a->getValue(); - const TROOctets data_view(a_value_view.get_ptr_nc(0), a_value_view.getSize()); // just a view, still owned by attPDU + const jau::TOctetSlice& a_value_view = a->getValue(); + const jau::TROOctets data_view(a_value_view.get_ptr_nc(0), a_value_view.getSize()); // just a view, still owned by attPDU // const std::shared_ptr<TROOctets> data( std::make_shared<POctets>(a->getValue()) ); const uint64_t timestamp = a->ts_creation; int i=0; @@ -235,8 +235,8 @@ void BTGattHandler::l2capReaderThreadImpl() { cfmSent = true; } BTGattCharRef decl = findCharacterisicsByValueHandle(a->getHandle()); - const TOctetSlice& a_value_view = a->getValue(); - const TROOctets data_view(a_value_view.get_ptr_nc(0), a_value_view.getSize()); // just a view, still owned by attPDU + const jau::TOctetSlice& a_value_view = a->getValue(); + const jau::TROOctets data_view(a_value_view.get_ptr_nc(0), a_value_view.getSize()); // just a view, still owned by attPDU // const std::shared_ptr<TROOctets> data( std::make_shared<POctets>(a->getValue()) ); const uint64_t timestamp = a->ts_creation; int i=0; @@ -550,7 +550,7 @@ bool BTGattHandler::discoverPrimaryServices(std::shared_ptr<BTGattHandler> share * and the error code is set to Attribute Not Found or when the End Group Handle * in the Read by Type Group Response is 0xFFFF. */ - const uuid16_t groupType = uuid16_t(GattAttributeType::PRIMARY_SERVICE); + const jau::uuid16_t groupType = jau::uuid16_t(GattAttributeType::PRIMARY_SERVICE); const std::lock_guard<std::recursive_mutex> lock(mtx_command); // RAII-style acquire and relinquish via destructor PERF_TS_T0(); @@ -574,7 +574,7 @@ bool BTGattHandler::discoverPrimaryServices(std::shared_ptr<BTGattHandler> share result.push_back( BTGattServiceRef( new BTGattService( shared_this, true, p->pdu.get_uint16(ePDUOffset), // start-handle p->pdu.get_uint16(ePDUOffset + 2), // end-handle - p->pdu.get_uuid( ePDUOffset + 2 + 2, uuid_t::toTypeSize(esz-2-2) ) // uuid + p->pdu.get_uuid( ePDUOffset + 2 + 2, jau::uuid_t::toTypeSize(esz-2-2) ) // uuid ) ) ); COND_PRINT(env.DEBUG_DATA, "GATT PRIM SRV discovered[%d/%d]: %s on %s", i, count, result.at(result.size()-1)->toString().c_str(), toString().c_str()); @@ -608,7 +608,7 @@ bool BTGattHandler::discoverCharacteristics(BTGattServiceRef & service) { * BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration * </p> */ - const uuid16_t characteristicTypeReq = uuid16_t(GattAttributeType::CHARACTERISTIC); + const jau::uuid16_t characteristicTypeReq = jau::uuid16_t(GattAttributeType::CHARACTERISTIC); const std::lock_guard<std::recursive_mutex> lock(mtx_command); // RAII-style acquire and relinquish via destructor COND_PRINT(env.DEBUG_DATA, "GATT discoverCharacteristics Service: %s on %s", service->toString().c_str(), toString().c_str()); @@ -639,7 +639,7 @@ bool BTGattHandler::discoverCharacteristics(BTGattServiceRef & service) { p->getElementHandle(e_iter), // Characteristic Handle static_cast<BTGattChar::PropertyBitVal>(p->pdu.get_uint8(ePDUOffset + 2)), // Characteristics Property p->pdu.get_uint16(ePDUOffset + 2 + 1), // Characteristics Value Handle - p->pdu.get_uuid(ePDUOffset + 2 + 1 + 2, uuid_t::toTypeSize(esz-2-1-2) ) ) ) ); // Characteristics Value Type UUID + p->pdu.get_uuid(ePDUOffset + 2 + 1 + 2, jau::uuid_t::toTypeSize(esz-2-1-2) ) ) ) ); // Characteristics Value Type UUID COND_PRINT(env.DEBUG_DATA, "GATT C discovered[%d/%d]: char%s on %s", e_iter, e_count, service->characteristicList.at(service->characteristicList.size()-1)->toString().c_str(), toString().c_str()); } @@ -705,7 +705,7 @@ bool BTGattHandler::discoverDescriptors(BTGattServiceRef & service) { // handle: handle of Characteristic Descriptor. // value: Characteristic Descriptor UUID. const uint16_t cd_handle = p->getElementHandle(e_iter); - std::unique_ptr<const uuid_t> cd_uuid = p->getElementValue(e_iter); + std::unique_ptr<const jau::uuid_t> cd_uuid = p->getElementValue(e_iter); std::shared_ptr<BTGattDesc> cd( std::make_shared<BTGattDesc>(charDecl, std::move(cd_uuid), cd_handle) ); if( cd_handle <= charDecl->value_handle || cd_handle > cd_handle_end ) { // should never happen! @@ -759,7 +759,7 @@ bool BTGattHandler::readDescriptorValue(BTGattDesc & desc, int expectedLength) { return res; } -bool BTGattHandler::readCharacteristicValue(const BTGattChar & decl, POctets & resValue, int expectedLength) { +bool BTGattHandler::readCharacteristicValue(const BTGattChar & decl, jau::POctets & resValue, int expectedLength) { COND_PRINT(env.DEBUG_DATA, "GATTHandler::readCharacteristicValue expLen %d, decl %s", expectedLength, decl.toString().c_str()); const bool res = readValue(decl.value_handle, resValue, expectedLength); if( !res ) { @@ -768,7 +768,7 @@ bool BTGattHandler::readCharacteristicValue(const BTGattChar & decl, POctets & r return res; } -bool BTGattHandler::readValue(const uint16_t handle, POctets & res, int expectedLength) { +bool BTGattHandler::readValue(const uint16_t handle, jau::POctets & res, int expectedLength) { /* BT Core Spec v5.2: Vol 3, Part G GATT: 4.8.1 Read Characteristic Value */ /* BT Core Spec v5.2: Vol 3, Part G GATT: 4.8.3 Read Long Characteristic Value */ const std::lock_guard<std::recursive_mutex> lock(mtx_command); // RAII-style acquire and relinquish via destructor @@ -797,7 +797,7 @@ bool BTGattHandler::readValue(const uint16_t handle, POctets & res, int expected COND_PRINT(env.DEBUG_DATA, "GATT RV recv: %s from %s", pdu->toString().c_str(), toString().c_str()); if( pdu->getOpcode() == AttPDUMsg::Opcode::READ_RSP ) { const AttReadRsp * p = static_cast<const AttReadRsp*>(pdu.get()); - const TOctetSlice & v = p->getValue(); + const jau::TOctetSlice & v = p->getValue(); res += v; offset += v.getSize(); if( p->getPDUValueSize() < p->getMaxPDUValueSize(usedMTU) ) { @@ -805,7 +805,7 @@ bool BTGattHandler::readValue(const uint16_t handle, POctets & res, int expected } } else if( pdu->getOpcode() == AttPDUMsg::Opcode::READ_BLOB_RSP ) { const AttReadBlobRsp * p = static_cast<const AttReadBlobRsp*>(pdu.get()); - const TOctetSlice & v = p->getValue(); + const jau::TOctetSlice & v = p->getValue(); if( 0 == v.getSize() ) { done = true; // OK by spec: No more data - end of communication } else { @@ -855,7 +855,7 @@ bool BTGattHandler::writeDescriptorValue(const BTGattDesc & cd) { return res; } -bool BTGattHandler::writeCharacteristicValue(const BTGattChar & c, const TROOctets & value) { +bool BTGattHandler::writeCharacteristicValue(const BTGattChar & c, const jau::TROOctets & value) { /* BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value */ COND_PRINT(env.DEBUG_DATA, "GATTHandler::writeCharacteristicValue desc %s, value %s", c.toString().c_str(), value.toString().c_str()); const bool res = writeValue(c.value_handle, value, true); @@ -865,13 +865,13 @@ bool BTGattHandler::writeCharacteristicValue(const BTGattChar & c, const TROOcte return res; } -bool BTGattHandler::writeCharacteristicValueNoResp(const BTGattChar & c, const TROOctets & value) { +bool BTGattHandler::writeCharacteristicValueNoResp(const BTGattChar & c, const jau::TROOctets & value) { /* BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response */ COND_PRINT(env.DEBUG_DATA, "GATT writeCharacteristicValueNoResp decl %s, value %s", c.toString().c_str(), value.toString().c_str()); return writeValue(c.value_handle, value, false); // complete or exception } -bool BTGattHandler::writeValue(const uint16_t handle, const TROOctets & value, const bool withResponse) { +bool BTGattHandler::writeValue(const uint16_t handle, const jau::TROOctets & value, const bool withResponse) { /* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration */ /* BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value */ /* BT Core Spec v5.2: Vol 3, Part G GATT: 4.11 Characteristic Value Indication */ @@ -941,25 +941,25 @@ bool BTGattHandler::configNotificationIndication(BTGattDesc & cccd, const bool e /*********************************************************************************************************************/ /*********************************************************************************************************************/ -static const uuid16_t _GENERIC_ACCESS(GattServiceType::GENERIC_ACCESS); -static const uuid16_t _DEVICE_NAME(GattCharacteristicType::DEVICE_NAME); -static const uuid16_t _APPEARANCE(GattCharacteristicType::APPEARANCE); -static const uuid16_t _PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS(GattCharacteristicType::PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS); - -static const uuid16_t _DEVICE_INFORMATION(GattServiceType::DEVICE_INFORMATION); -static const uuid16_t _SYSTEM_ID(GattCharacteristicType::SYSTEM_ID); -static const uuid16_t _MODEL_NUMBER_STRING(GattCharacteristicType::MODEL_NUMBER_STRING); -static const uuid16_t _SERIAL_NUMBER_STRING(GattCharacteristicType::SERIAL_NUMBER_STRING); -static const uuid16_t _FIRMWARE_REVISION_STRING(GattCharacteristicType::FIRMWARE_REVISION_STRING); -static const uuid16_t _HARDWARE_REVISION_STRING(GattCharacteristicType::HARDWARE_REVISION_STRING); -static const uuid16_t _SOFTWARE_REVISION_STRING(GattCharacteristicType::SOFTWARE_REVISION_STRING); -static const uuid16_t _MANUFACTURER_NAME_STRING(GattCharacteristicType::MANUFACTURER_NAME_STRING); -static const uuid16_t _REGULATORY_CERT_DATA_LIST(GattCharacteristicType::REGULATORY_CERT_DATA_LIST); -static const uuid16_t _PNP_ID(GattCharacteristicType::PNP_ID); +static const jau::uuid16_t _GENERIC_ACCESS(GattServiceType::GENERIC_ACCESS); +static const jau::uuid16_t _DEVICE_NAME(GattCharacteristicType::DEVICE_NAME); +static const jau::uuid16_t _APPEARANCE(GattCharacteristicType::APPEARANCE); +static const jau::uuid16_t _PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS(GattCharacteristicType::PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS); + +static const jau::uuid16_t _DEVICE_INFORMATION(GattServiceType::DEVICE_INFORMATION); +static const jau::uuid16_t _SYSTEM_ID(GattCharacteristicType::SYSTEM_ID); +static const jau::uuid16_t _MODEL_NUMBER_STRING(GattCharacteristicType::MODEL_NUMBER_STRING); +static const jau::uuid16_t _SERIAL_NUMBER_STRING(GattCharacteristicType::SERIAL_NUMBER_STRING); +static const jau::uuid16_t _FIRMWARE_REVISION_STRING(GattCharacteristicType::FIRMWARE_REVISION_STRING); +static const jau::uuid16_t _HARDWARE_REVISION_STRING(GattCharacteristicType::HARDWARE_REVISION_STRING); +static const jau::uuid16_t _SOFTWARE_REVISION_STRING(GattCharacteristicType::SOFTWARE_REVISION_STRING); +static const jau::uuid16_t _MANUFACTURER_NAME_STRING(GattCharacteristicType::MANUFACTURER_NAME_STRING); +static const jau::uuid16_t _REGULATORY_CERT_DATA_LIST(GattCharacteristicType::REGULATORY_CERT_DATA_LIST); +static const jau::uuid16_t _PNP_ID(GattCharacteristicType::PNP_ID); std::shared_ptr<GattGenericAccessSvc> BTGattHandler::getGenericAccess(jau::darray<BTGattCharRef> & genericAccessCharDeclList) { std::shared_ptr<GattGenericAccessSvc> res = nullptr; - POctets value(number(Defaults::MAX_ATT_MTU), 0); + jau::POctets value(number(Defaults::MAX_ATT_MTU), 0); std::string deviceName = ""; AppearanceCat appearance = AppearanceCat::UNKNOWN; std::shared_ptr<GattPeriphalPreferredConnectionParameters> prefConnParam = nullptr; @@ -1008,7 +1008,7 @@ bool BTGattHandler::ping() { for(size_t i=0; isOK && i<services.size(); i++) { jau::darray<BTGattCharRef> & genericAccessCharDeclList = services.at(i)->characteristicList; - POctets value(32, 0); + jau::POctets value(32, 0); for(size_t j=0; isOK && j<genericAccessCharDeclList.size(); j++) { const BTGattChar & charDecl = *genericAccessCharDeclList.at(j); @@ -1036,16 +1036,16 @@ bool BTGattHandler::ping() { std::shared_ptr<GattDeviceInformationSvc> BTGattHandler::getDeviceInformation(jau::darray<BTGattCharRef> & characteristicDeclList) { std::shared_ptr<GattDeviceInformationSvc> res = nullptr; - POctets value(number(Defaults::MAX_ATT_MTU), 0); + jau::POctets value(number(Defaults::MAX_ATT_MTU), 0); - POctets systemID(8, 0); + jau::POctets systemID(8, 0); std::string modelNumber; std::string serialNumber; std::string firmwareRevision; std::string hardwareRevision; std::string softwareRevision; std::string manufacturer; - POctets regulatoryCertDataList(128, 0); + jau::POctets regulatoryCertDataList(128, 0); std::shared_ptr<GattPnP_ID> pnpID = nullptr; bool found = false; diff --git a/src/direct_bt/BTManager.cpp b/src/direct_bt/BTManager.cpp index 4a5ab1db..73bc6208 100644 --- a/src/direct_bt/BTManager.cpp +++ b/src/direct_bt/BTManager.cpp @@ -191,7 +191,7 @@ static void mgmthandler_sigaction(int sig, siginfo_t *info, void *ucontext) noex bool BTManager::send(MgmtCommand &req) noexcept { const std::lock_guard<std::recursive_mutex> lock(mtx_sendReply); // RAII-style acquire and relinquish via destructor COND_PRINT(env.DEBUG_EVENT, "DBTManager-IO SENT %s", req.toString().c_str()); - TROOctets & pdu = req.getPDU(); + jau::TROOctets & pdu = req.getPDU(); if ( comm.write( pdu.get_ptr(), pdu.getSize() ) < 0 ) { ERR_PRINT("DBTManager::sendWithReply: HCIComm write error, req %s", req.toString().c_str()); return false; diff --git a/src/direct_bt/BTTypes0.cpp b/src/direct_bt/BTTypes0.cpp index ce750439..43ee8322 100644 --- a/src/direct_bt/BTTypes0.cpp +++ b/src/direct_bt/BTTypes0.cpp @@ -149,11 +149,11 @@ std::string direct_bt::to_string(const BLERandomAddressType type) noexcept { return "Unknown BLERandomAddressType "+jau::to_hexstring(number(type)); } -BLERandomAddressType EUI48::getBLERandomAddressType(const BDAddressType addressType) const noexcept { +BLERandomAddressType BDAddressAndType::getBLERandomAddressType(const jau::EUI48& address, const BDAddressType addressType) noexcept { if( BDAddressType::BDADDR_LE_RANDOM != addressType ) { return BLERandomAddressType::UNDEFINED; } - const uint8_t high2 = ( b[5] >> 6 ) & 0x03; + const uint8_t high2 = ( address.b[5] >> 6 ) & 0x03; switch( high2 ) { case 0x00: return BLERandomAddressType::UNRESOLVABLE_PRIVAT; case 0x01: return BLERandomAddressType::RESOLVABLE_PRIVAT; @@ -163,172 +163,8 @@ BLERandomAddressType EUI48::getBLERandomAddressType(const BDAddressType addressT } } -std::string EUI48Sub::toString() const noexcept { - // str_len = 2 * len + ( len - 1 ) - // str_len = 3 * len - 1 - // len = ( str_len + 1 ) / 3 - std::string str; - if( 0 < length ) { - str.reserve(3 * length - 1); - - for(int i=length-1; 0 <= i; i--) { - jau::byteHexString(str, b[i], false /* lowerCase */); - if( 0 < i ) { - str.push_back(':'); - } - } - } else { - str.push_back(':'); - } - return str; -} - -bool EUI48Sub::scanEUI48Sub(const std::string& str, EUI48Sub& dest, std::string& errmsg) { - const jau::nsize_t str_len = static_cast<jau::nsize_t>( str.length() ); - dest.clear(); - - if( 17 < str_len ) { // not exceeding byte_size - errmsg.append("EUI48 sub-string must be less or equal length 17 but "+std::to_string(str_len)+": "+str); - return false; - } - const char * str_ptr = str.c_str(); - jau::nsize_t j=0; - bool exp_colon = false; - uint8_t b_[6]; // intermediate result high -> low - while( j+1 < str_len /* && byte_count_ < byte_size */ ) { // min 2 chars left - const bool is_colon = ':' == str[j]; - if( exp_colon && !is_colon ) { - errmsg.append("EUI48Sub sub-string not in format '01:02:03:0A:0B:0C', but '"+str+"', colon missing, pos "+std::to_string(j)+", len "+std::to_string(str_len)); - return false; - } else if( is_colon ) { - ++j; - exp_colon = false; - } else { - if ( sscanf(str_ptr+j, "%02hhx", &b_[dest.length]) != 1 ) // b_: high->low - { - errmsg.append("EUI48Sub sub-string not in format '01:02:03:0A:0B:0C' but '"+str+"', pos "+std::to_string(j)+", len "+std::to_string(str_len)); - return false; - } - j += 2; - ++dest.length; - exp_colon = true; - } - } - for(j=0; j<dest.length; ++j) { // swap low->high - dest.b[j] = b_[dest.length-1-j]; - } - // sscanf provided host data type, in which we store the values, - // hence no endian conversion - return true; -} - -EUI48Sub::EUI48Sub(const std::string& str) { - std::string errmsg; - if( !scanEUI48Sub(str, *this, errmsg) ) { - throw jau::IllegalArgumentException(errmsg, E_FILE_LINE); - } -} - -EUI48Sub::EUI48Sub(const uint8_t * b_, const jau::nsize_t len_) noexcept { - length = len_; - const jau::nsize_t cpsz = std::max<jau::nsize_t>(sizeof(b), len_); - const jau::nsize_t bzsz = sizeof(b) - cpsz; - memcpy(b, b_, cpsz); - if( bzsz > 0 ) { - bzero(b+cpsz, bzsz); - } -} - -jau::snsize_t EUI48Sub::indexOf(const uint8_t haystack_b[], const jau::nsize_t haystack_length, - const uint8_t needle_b[], const jau::nsize_t needle_length) noexcept { - if( 0 == needle_length ) { - return 0; - } - if( haystack_length < needle_length ) { - return -1; - } - const uint8_t first = needle_b[0]; - const jau::nsize_t outerEnd = haystack_length - needle_length + 1; // exclusive - - for (jau::nsize_t i = 0; i < outerEnd; i++) { - // find first char of other - while( haystack_b[i] != first ) { - if( ++i == outerEnd ) { - return -1; - } - } - if( i < outerEnd ) { // otherLen chars left to match? - // continue matching other chars - const jau::nsize_t innerEnd = i + needle_length; // exclusive - jau::nsize_t j = i, k=0; - do { - if( ++j == innerEnd ) { - return i; // gotcha - } - } while( haystack_b[j] == needle_b[++k] ); - } - } - return -1; -} - -std::string EUI48::toString() const noexcept { - // str_len = 2 * len + ( len - 1 ) - // str_len = 3 * len - 1 - // len = ( str_len + 1 ) / 3 - std::string str; - str.reserve(17); // 6 * 2 + ( 6 - 1 ) - - for(int i=6-1; 0 <= i; i--) { - jau::byteHexString(str, b[i], false /* lowerCase */); - if( 0 < i ) { - str.push_back(':'); - } - } - return str; -} - -bool EUI48::scanEUI48(const std::string& str, EUI48& dest, std::string& errmsg) { - if( 17 != str.length() ) { - errmsg.append("EUI48 string not of length 17 but "); - errmsg.append(std::to_string(str.length())); - errmsg.append(": "+str); - return false; - } - if ( sscanf(str.c_str(), "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", - &dest.b[5], &dest.b[4], &dest.b[3], &dest.b[2], &dest.b[1], &dest.b[0]) != 6 ) - { - errmsg.append("EUI48 string not in format '01:02:03:0A:0B:0C' but '"+str+"'"); - return false; - } - // sscanf provided host data type, in which we store the values, - // hence no endian conversion - return true; -} - -EUI48::EUI48(const std::string& str) { - std::string errmsg; - if( !scanEUI48(str, *this, errmsg) ) { - throw jau::IllegalArgumentException(errmsg, E_FILE_LINE); - } -} - -EUI48::EUI48(const uint8_t * b_) noexcept { - memcpy(b, b_, sizeof(b)); -} - -static uint8_t _EUI48_ALL_DEVICE[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -static uint8_t _EUI48_LOCAL_DEVICE[] = {0x00, 0x00, 0x00, 0xff, 0xff, 0xff}; - -const EUI48Sub direct_bt::EUI48Sub::ANY_DEVICE; // default ctor is zero bytes! -const EUI48Sub direct_bt::EUI48Sub::ALL_DEVICE( _EUI48_ALL_DEVICE, 6 ); -const EUI48Sub direct_bt::EUI48Sub::LOCAL_DEVICE( _EUI48_LOCAL_DEVICE, 6 ); - -const EUI48 direct_bt::EUI48::ANY_DEVICE; // default ctor is zero bytes! -const EUI48 direct_bt::EUI48::ALL_DEVICE( _EUI48_ALL_DEVICE ); -const EUI48 direct_bt::EUI48::LOCAL_DEVICE( _EUI48_LOCAL_DEVICE ); - -const BDAddressAndType direct_bt::BDAddressAndType::ANY_BREDR_DEVICE(EUI48::ANY_DEVICE, BDAddressType::BDADDR_BREDR); -const BDAddressAndType direct_bt::BDAddressAndType::ANY_DEVICE(EUI48::ANY_DEVICE, BDAddressType::BDADDR_UNDEFINED); +const BDAddressAndType direct_bt::BDAddressAndType::ANY_BREDR_DEVICE(jau::EUI48::ANY_DEVICE, BDAddressType::BDADDR_BREDR); +const BDAddressAndType direct_bt::BDAddressAndType::ANY_DEVICE(jau::EUI48::ANY_DEVICE, BDAddressType::BDADDR_UNDEFINED); std::string BDAddressAndType::toString() const noexcept { const BLERandomAddressType leRandomAddressType = getBLERandomAddressType(); @@ -924,10 +760,10 @@ void EInfoReport::setDeviceID(const uint16_t source_, const uint16_t vendor, con set(EIRDataType::DEVICE_ID); } -void EInfoReport::addService(const std::shared_ptr<const uuid_t>& uuid) noexcept +void EInfoReport::addService(const std::shared_ptr<const jau::uuid_t>& uuid) noexcept { auto begin = services.begin(); - auto it = std::find_if(begin, services.end(), [&](std::shared_ptr<const uuid_t> const& p) { + auto it = std::find_if(begin, services.end(), [&](std::shared_ptr<const jau::uuid_t> const& p) { return *p == *uuid; }); if ( it == std::end(services) ) { @@ -935,7 +771,7 @@ void EInfoReport::addService(const std::shared_ptr<const uuid_t>& uuid) noexcept set(EIRDataType::SERVICE_UUID); } } -void EInfoReport::addService(const uuid_t& uuid) noexcept { +void EInfoReport::addService(const jau::uuid_t& uuid) noexcept { addService( uuid.clone() ); } @@ -964,7 +800,7 @@ std::string EInfoReport::toString(const bool includeServices) const noexcept { if( includeServices && services.size() > 0 ) { out.append("\n"); for(auto it = services.begin(); it != services.end(); it++) { - std::shared_ptr<const uuid_t> p = *it; + std::shared_ptr<const jau::uuid_t> p = *it; out.append(" ").append(p->toUUID128String()).append(", ").append(std::to_string(static_cast<int>(p->getTypeSize()))).append(" bytes\n"); } } @@ -998,7 +834,7 @@ bool EInfoReport::operator==(const EInfoReport& o) const noexcept { o.did_version == did_version && o.services.size() == services.size() && std::equal( o.services.cbegin(), o.services.cend(), services.cbegin(), - [](const std::shared_ptr<const uuid_t>&a, const std::shared_ptr<const uuid_t>&b) + [](const std::shared_ptr<const jau::uuid_t>&a, const std::shared_ptr<const jau::uuid_t>&b) -> bool { return *a == *b; } ); } @@ -1077,7 +913,7 @@ int EInfoReport::read_data(uint8_t const * data, uint8_t const data_length) noex [[fallthrough]]; case GAP_T::UUID16_COMPLETE: for(int j=0; j<elem_len/2; j++) { - const std::shared_ptr<const uuid_t> uuid( std::make_shared<const uuid16_t>(elem_data, j*2, true) ); + const std::shared_ptr<const jau::uuid_t> uuid( std::make_shared<const jau::uuid16_t>(elem_data, j*2, true) ); addService( uuid ); } break; @@ -1086,7 +922,7 @@ int EInfoReport::read_data(uint8_t const * data, uint8_t const data_length) noex [[fallthrough]]; case GAP_T::UUID32_COMPLETE: for(int j=0; j<elem_len/4; j++) { - const std::shared_ptr<const uuid_t> uuid( std::make_shared<const uuid32_t>(elem_data, j*4, true) ); + const std::shared_ptr<const jau::uuid_t> uuid( std::make_shared<const jau::uuid32_t>(elem_data, j*4, true) ); addService( uuid ); } break; @@ -1095,7 +931,7 @@ int EInfoReport::read_data(uint8_t const * data, uint8_t const data_length) noex [[fallthrough]]; case GAP_T::UUID128_COMPLETE: for(int j=0; j<elem_len/16; j++) { - const std::shared_ptr<const uuid_t> uuid( std::make_shared<const uuid128_t>(elem_data, j*16, true) ); + const std::shared_ptr<const jau::uuid_t> uuid( std::make_shared<const jau::uuid128_t>(elem_data, j*16, true) ); addService( uuid ); } break; @@ -1247,9 +1083,9 @@ jau::nsize_t EInfoReport::write_data(EIRDataType write_mask, uint8_t * data, jau } } if( isEIRDataTypeSet(mask, EIRDataType::SERVICE_UUID) ) { - jau::darray<std::shared_ptr<const uuid_t>> uuid16s, uuid32s, uuid128s; + jau::darray<std::shared_ptr<const jau::uuid_t>> uuid16s, uuid32s, uuid128s; for(auto it = services.begin(); it != services.end(); it++) { - std::shared_ptr<const uuid_t> p = *it; + std::shared_ptr<const jau::uuid_t> p = *it; switch( p->getTypeSizeInt() ) { case 2: uuid16s.push_back(p); @@ -1274,7 +1110,7 @@ jau::nsize_t EInfoReport::write_data(EIRDataType write_mask, uint8_t * data, jau *data_i++ = ad_sz; *data_i++ = direct_bt::number(GAP_T::UUID16_COMPLETE); for(auto it = uuid16s.begin(); it != uuid16s.end(); it++) { - std::shared_ptr<const uuid_t> p = *it; + std::shared_ptr<const jau::uuid_t> p = *it; data_i += p->put(data_i, 0, true /* le */); } } @@ -1288,7 +1124,7 @@ jau::nsize_t EInfoReport::write_data(EIRDataType write_mask, uint8_t * data, jau *data_i++ = ad_sz; *data_i++ = direct_bt::number(GAP_T::UUID32_COMPLETE); for(auto it = uuid32s.begin(); it != uuid32s.end(); it++) { - std::shared_ptr<const uuid_t> p = *it; + std::shared_ptr<const jau::uuid_t> p = *it; data_i += p->put(data_i, 0, true /* le */); } } @@ -1302,7 +1138,7 @@ jau::nsize_t EInfoReport::write_data(EIRDataType write_mask, uint8_t * data, jau *data_i++ = ad_sz; *data_i++ = direct_bt::number(GAP_T::UUID128_COMPLETE); for(auto it = uuid128s.begin(); it != uuid128s.end(); it++) { - std::shared_ptr<const uuid_t> p = *it; + std::shared_ptr<const jau::uuid_t> p = *it; data_i += p->put(data_i, 0, true /* le */); } } @@ -1352,7 +1188,7 @@ jau::darray<std::unique_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t c read_segments++; } for(i = 0; i < num_reports && i_octets + 5 < limes; i++) { - ad_reports[i]->setAddress( *((EUI48 const *)i_octets) ); + ad_reports[i]->setAddress( *((jau::EUI48 const *)i_octets) ); i_octets += 6; read_segments++; } @@ -1436,7 +1272,7 @@ jau::darray<std::unique_ptr<EInfoReport>> EInfoReport::read_ext_ad_reports(uint8 read_segments++; } for(i = 0; i < num_reports && i_octets + 5 < limes; i++) { - ad_reports[i]->setAddress( *((EUI48 const *)i_octets) ); + ad_reports[i]->setAddress( *((jau::EUI48 const *)i_octets) ); i_octets += 6; read_segments++; } diff --git a/src/direct_bt/CMakeLists.txt b/src/direct_bt/CMakeLists.txt index 37b42194..dbad2d71 100644 --- a/src/direct_bt/CMakeLists.txt +++ b/src/direct_bt/CMakeLists.txt @@ -15,6 +15,8 @@ set (direct_bt_LIB_SRCS ${PROJECT_SOURCE_DIR}/jaulib/src/environment.cpp ${PROJECT_SOURCE_DIR}/jaulib/src/debug.cpp ${PROJECT_SOURCE_DIR}/jaulib/src/basic_types.cpp + ${PROJECT_SOURCE_DIR}/jaulib/src/eui48.cpp + ${PROJECT_SOURCE_DIR}/jaulib/src/uuid.cpp ${PROJECT_SOURCE_DIR}/src/direct_bt/ieee11073/DataTypes.cpp ${PROJECT_SOURCE_DIR}/src/direct_bt/ATTPDUTypes.cpp ${PROJECT_SOURCE_DIR}/src/direct_bt/BTAdapter.cpp @@ -37,7 +39,6 @@ set (direct_bt_LIB_SRCS ${PROJECT_SOURCE_DIR}/src/direct_bt/SMPHandler.cpp ${PROJECT_SOURCE_DIR}/src/direct_bt/SMPTypes.cpp ${PROJECT_SOURCE_DIR}/src/direct_bt/SMPKeyBin.cpp - ${PROJECT_SOURCE_DIR}/src/direct_bt/UUID.cpp # autogenerated files ${CMAKE_CURRENT_BINARY_DIR}/../version.c ) diff --git a/src/direct_bt/GATTNumbers.cpp b/src/direct_bt/GATTNumbers.cpp index e73ad315..e9464085 100644 --- a/src/direct_bt/GATTNumbers.cpp +++ b/src/direct_bt/GATTNumbers.cpp @@ -346,24 +346,24 @@ const GattCharacteristicSpec * direct_bt::findGattCharSpec(const uint16_t uuid16 /********************************************************/ /********************************************************/ -std::string direct_bt::GattNameToString(const TROOctets &v) noexcept { +std::string direct_bt::GattNameToString(const jau::TROOctets &v) noexcept { const jau::nsize_t str_len = v.getSize(); if( 0 == str_len ) { return std::string(); // empty } - POctets s(str_len+1); // dtor releases chunk + jau::POctets s(str_len+1); // dtor releases chunk memcpy(s.get_wptr(), v.get_ptr(), str_len); s.put_uint8_nc(str_len, 0); // EOS return std::string((const char*)s.get_ptr()); } -GattPeriphalPreferredConnectionParameters::GattPeriphalPreferredConnectionParameters(const TROOctets &source) noexcept +GattPeriphalPreferredConnectionParameters::GattPeriphalPreferredConnectionParameters(const jau::TROOctets &source) noexcept : minConnectionInterval(source.get_uint16(0)), maxConnectionInterval(source.get_uint16(2)), slaveLatency(source.get_uint16(4)), connectionSupervisionTimeoutMultiplier(source.get_uint16(6)) { } -std::shared_ptr<GattPeriphalPreferredConnectionParameters> GattPeriphalPreferredConnectionParameters::get(const TROOctets &source) noexcept { +std::shared_ptr<GattPeriphalPreferredConnectionParameters> GattPeriphalPreferredConnectionParameters::get(const jau::TROOctets &source) noexcept { const jau::nsize_t reqSize = 8; if( source.getSize() < reqSize ) { ERR_PRINT("GattPeriphalPreferredConnectionParameters: Insufficient data, less than %d bytes in %s", reqSize, source.toString().c_str()); @@ -384,11 +384,11 @@ std::string GattGenericAccessSvc::toString() const noexcept { return "'"+deviceName+"'[appearance "+jau::to_hexstring(static_cast<uint16_t>(appearance))+" ("+to_string(appearance)+"), "+pcp+"]"; } -GattPnP_ID::GattPnP_ID(const TROOctets &source) noexcept +GattPnP_ID::GattPnP_ID(const jau::TROOctets &source) noexcept : vendor_id_source(source.get_uint8(0)), vendor_id(source.get_uint16(1)), product_id(source.get_uint16(3)), product_version(source.get_uint16(5)) {} -std::shared_ptr<GattPnP_ID> GattPnP_ID::get(const TROOctets &source) noexcept { +std::shared_ptr<GattPnP_ID> GattPnP_ID::get(const jau::TROOctets &source) noexcept { const jau::nsize_t reqSize = 7; if( source.getSize() < reqSize ) { ERR_PRINT("GattPnP_ID: Insufficient data, less than %d bytes in %s", reqSize, source.toString().c_str()); @@ -411,7 +411,7 @@ std::string GattDeviceInformationSvc::toString() const noexcept { "'], pnpID["+pnp+"], regCertData '"+regulatoryCertDataList.toString()+"']"; } -std::shared_ptr<GattTemperatureMeasurement> GattTemperatureMeasurement::get(const TROOctets &source) noexcept { +std::shared_ptr<GattTemperatureMeasurement> GattTemperatureMeasurement::get(const jau::TROOctets &source) noexcept { const jau::nsize_t size = source.getSize(); jau::nsize_t reqSize = 1 + 4; // max size = 13 if( reqSize > size ) { diff --git a/src/direct_bt/HCIHandler.cpp b/src/direct_bt/HCIHandler.cpp index 0f33afec..1b9bb0c7 100644 --- a/src/direct_bt/HCIHandler.cpp +++ b/src/direct_bt/HCIHandler.cpp @@ -508,7 +508,7 @@ void HCIHandler::sendMgmtEvent(const MgmtEvent& event) noexcept { bool HCIHandler::sendCommand(HCICommand &req, const bool quiet) noexcept { COND_PRINT(env.DEBUG_EVENT, "HCIHandler-IO SENT %s", req.toString().c_str()); - TROOctets & pdu = req.getPDU(); + jau::TROOctets & pdu = req.getPDU(); if ( comm.write( pdu.get_ptr(), pdu.getSize() ) < 0 ) { if( !quiet || jau::environment::get().verbose ) { ERR_PRINT("HCIHandler::sendCommand: HCIComm write error, req %s - %s", req.toString().c_str(), toString().c_str()); diff --git a/src/direct_bt/UUID.cpp b/src/direct_bt/UUID.cpp deleted file mode 100644 index 8e8fd361..00000000 --- a/src/direct_bt/UUID.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Author: Sven Gothel <[email protected]> - * Copyright (c) 2020 Gothel Software e.K. - * Copyright (c) 2020 ZAFENA AB - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <jau/debug.hpp> - -#include "UUID.hpp" - - -using namespace direct_bt; - -// BASE_UUID '00000000-0000-1000-8000-00805F9B34FB' -static uint8_t bt_base_uuid_be[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; -uuid128_t direct_bt::BT_BASE_UUID( bt_base_uuid_be, 0, false ); - -uuid_t::TypeSize uuid_t::toTypeSize(const jau::nsize_t size) { - switch( static_cast<TypeSize>(size) ) { - case TypeSize::UUID16_SZ: return TypeSize::UUID16_SZ; - case TypeSize::UUID32_SZ: return TypeSize::UUID32_SZ; - case TypeSize::UUID128_SZ: return TypeSize::UUID128_SZ; - } - throw jau::IllegalArgumentException("Given size "+std::to_string(size)+", not matching uuid16_t, uuid32_t or uuid128_t", E_FILE_LINE); -} - -std::unique_ptr<uuid_t> uuid_t::create(TypeSize t, uint8_t const * const buffer, jau::nsize_t const byte_offset, bool littleEndian) { - if( TypeSize::UUID16_SZ == t ) { - return std::unique_ptr<uuid_t>(new uuid16_t(buffer, byte_offset, littleEndian)); - } else if( TypeSize::UUID32_SZ == t ) { - return std::unique_ptr<uuid_t>(new uuid32_t(buffer, byte_offset, littleEndian)); - } else if( TypeSize::UUID128_SZ == t ) { - return std::unique_ptr<uuid_t>(new uuid128_t(buffer, byte_offset, littleEndian)); - } - throw jau::IllegalArgumentException("Unknown Type "+std::to_string(static_cast<jau::nsize_t>(t)), E_FILE_LINE); -} -std::unique_ptr<uuid_t> uuid_t::create(const std::string& str) { - const size_t len = str.length(); - switch( len ) { - case 4: // 16 - return std::unique_ptr<uuid_t>(new uuid16_t(str)); - case 8: // 32 - return std::unique_ptr<uuid_t>(new uuid32_t(str)); - case 36: // 128 - return std::unique_ptr<uuid_t>(new uuid128_t(str)); - default: { - std::string msg("UUID string not of length 4, 8 or 36 but "); - msg.append(std::to_string(str.length())); - msg.append(": "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); - } - } -} - -std::unique_ptr<uuid_t> uuid_t::clone() const noexcept { - switch(type) { - case TypeSize::UUID16_SZ: return std::make_unique<uuid16_t>( *( static_cast<const uuid16_t*>(this) ) ); - case TypeSize::UUID32_SZ: return std::make_unique<uuid32_t>( *( static_cast<const uuid32_t*>(this) ) ); - case TypeSize::UUID128_SZ: return std::make_unique<uuid128_t>( *( static_cast<const uuid128_t*>(this) ) ); - } - ABORT("Unknown Type %d", static_cast<jau::nsize_t>(type)); - abort(); // never reached -} - -uuid128_t uuid_t::toUUID128(uuid128_t const & base_uuid, jau::nsize_t const uuid32_le_octet_index) const noexcept { - switch(type) { - case TypeSize::UUID16_SZ: return uuid128_t( *( static_cast<const uuid16_t*>(this) ), base_uuid, uuid32_le_octet_index); - case TypeSize::UUID32_SZ: return uuid128_t( *( static_cast<const uuid32_t*>(this) ), base_uuid, uuid32_le_octet_index); - case TypeSize::UUID128_SZ: return uuid128_t( *( static_cast<const uuid128_t*>(this) ) ); - } - ABORT("Unknown Type %d", static_cast<jau::nsize_t>(type)); - abort(); // never reached -} - -uuid128_t::uuid128_t(uuid16_t const & uuid16, uuid128_t const & base_uuid, jau::nsize_t const uuid16_le_octet_index) noexcept -: uuid_t(TypeSize::UUID128_SZ), value(merge_uint128(uuid16.value, base_uuid.value, uuid16_le_octet_index)) {} - -uuid128_t::uuid128_t(uuid32_t const & uuid32, uuid128_t const & base_uuid, jau::nsize_t const uuid32_le_octet_index) noexcept -: uuid_t(TypeSize::UUID128_SZ), value(merge_uint128(uuid32.value, base_uuid.value, uuid32_le_octet_index)) {} - -std::string uuid16_t::toString() const noexcept { - const jau::nsize_t length = 4; - std::string str; - str.reserve(length+1); // including EOS for snprintf - str.resize(length); - - const jau::nsize_t count = snprintf(&str[0], str.capacity(), "%.4x", value); - if( length != count ) { - ABORT("UUID16 string not of length %d but %d", length, count); - } - return str; -} - -std::string uuid16_t::toUUID128String(uuid128_t const & base_uuid, jau::nsize_t const le_octet_index) const noexcept -{ - uuid128_t u128(*this, base_uuid, le_octet_index); - return u128.toString(); -} - -std::string uuid32_t::toString() const noexcept { - const jau::nsize_t length = 8; - std::string str; - str.reserve(length+1); // including EOS for snprintf - str.resize(length); - - const jau::nsize_t count = snprintf(&str[0], str.capacity(), "%.8x", value); - if( length != count ) { - ABORT("UUID32 string not of length %d but %d", length, count); - } - return str; -} - -std::string uuid32_t::toUUID128String(uuid128_t const & base_uuid, jau::nsize_t const le_octet_index) const noexcept -{ - uuid128_t u128(*this, base_uuid, le_octet_index); - return u128.toString(); -} - -std::string uuid128_t::toString() const noexcept { - // 87654321-0000-1000-8000-00805F9B34FB - // 0 1 2 3 4 5 - // LE: low-mem - FB349B5F0800-0080-0010-0000-12345678 - high-mem - // 5 4 3 2 1 0 - // - // BE: low-mem - 87654321-0000-1000-8000-00805F9B34FB - high-mem - // 0 1 2 3 4 5 - // - const jau::nsize_t length = 36; - std::string str; - str.reserve(length+1); // including EOS for snprintf - str.resize(length); - uint32_t part0, part4; - uint16_t part1, part2, part3, part5; - - // snprintf uses host data type, in which values are stored, - // hence no endian conversion -#if __BYTE_ORDER == __BIG_ENDIAN - part0 = jau::get_uint32(value.data, 0); - part1 = jau::get_uint16(value.data, 4); - part2 = jau::get_uint16(value.data, 6); - part3 = jau::get_uint16(value.data, 8); - part4 = jau::get_uint32(value.data, 10); - part5 = jau::get_uint16(value.data, 14); -#elif __BYTE_ORDER == __LITTLE_ENDIAN - part5 = jau::get_uint16(value.data, 0); - part4 = jau::get_uint32(value.data, 2); - part3 = jau::get_uint16(value.data, 6); - part2 = jau::get_uint16(value.data, 8); - part1 = jau::get_uint16(value.data, 10); - part0 = jau::get_uint32(value.data, 12); -#else -#error "Unexpected __BYTE_ORDER" -#endif - const jau::nsize_t count = snprintf(&str[0], str.capacity(), "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", - part0, part1, part2, part3, part4, part5); - if( length != count ) { - ABORT("UUID128 string not of length %d but %d", length, count); - } - return str; -} - -uuid16_t::uuid16_t(const std::string& str) -: uuid_t(TypeSize::UUID16_SZ), value(0) -{ - uint16_t part0; - - if( 4 != str.length() ) { - std::string msg("UUID16 string not of length 4 but "); - msg.append(std::to_string(str.length())); - msg.append(": "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); - } - if ( sscanf(str.c_str(), "%04hx", &part0) != 1 ) { - std::string msg("UUID16 string not in format '0000' but "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); - } - // sscanf provided host data type, in which we store the values, - // hence no endian conversion - value = part0; -} - -uuid32_t::uuid32_t(const std::string& str) -: uuid_t(TypeSize::UUID32_SZ) -{ - uint32_t part0; - - if( 8 != str.length() ) { - std::string msg("UUID32 string not of length 8 but "); - msg.append(std::to_string(str.length())); - msg.append(": "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); - } - // if ( sscanf(str.c_str(), "%08x-%04hx-%04hx-%04hx-%08x%04hx", - if ( sscanf(str.c_str(), "%08x", &part0) != 1 ) { - std::string msg("UUID32 string not in format '00000000' but "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); - } - // sscanf provided host data type, in which we store the values, - // hence no endian conversion - value = part0; -} - -uuid128_t::uuid128_t(const std::string& str) -: uuid_t(TypeSize::UUID128_SZ) -{ - uint32_t part0, part4; - uint16_t part1, part2, part3, part5; - - if( 36 != str.length() ) { - std::string msg("UUID128 string not of length 36 but "); - msg.append(std::to_string(str.length())); - msg.append(": "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); - } - if ( sscanf(str.c_str(), "%08x-%04hx-%04hx-%04hx-%08x%04hx", - &part0, &part1, &part2, &part3, &part4, &part5) != 6 ) - { - std::string msg("UUID128 string not in format '00000000-0000-1000-8000-00805F9B34FB' but "+str); - throw jau::IllegalArgumentException(msg, E_FILE_LINE); - } - - // sscanf provided host data type, in which we store the values, - // hence no endian conversion -#if __BYTE_ORDER == __BIG_ENDIAN - jau::put_uint32(value.data, 0, part0); - jau::put_uint16(value.data, 4, part1); - jau::put_uint16(value.data, 6, part2); - jau::put_uint16(value.data, 8, part3); - jau::put_uint32(value.data, 10, part4); - jau::put_uint16(value.data, 14, part5); -#elif __BYTE_ORDER == __LITTLE_ENDIAN - jau::put_uint16(value.data, 0, part5); - jau::put_uint32(value.data, 2, part4); - jau::put_uint16(value.data, 6, part3); - jau::put_uint16(value.data, 8, part2); - jau::put_uint16(value.data, 10, part1); - jau::put_uint32(value.data, 12, part0); -#else -#error "Unexpected __BYTE_ORDER" -#endif -} - diff --git a/test/direct_bt/CMakeLists.txt b/test/direct_bt/CMakeLists.txt index abf7c151..b2005e01 100644 --- a/test/direct_bt/CMakeLists.txt +++ b/test/direct_bt/CMakeLists.txt @@ -7,9 +7,7 @@ include_directories( set( SOURCES_IDIOMATIC_EXAMPLES test_adeir01.cpp test_attpdu01.cpp - test_btaddress01.cpp test_misc_types.cpp - test_uuid.cpp ) string( REPLACE ".cpp" "" BASENAMES_IDIOMATIC_EXAMPLES "${SOURCES_IDIOMATIC_EXAMPLES}" ) diff --git a/test/direct_bt/test_adeir01.cpp b/test/direct_bt/test_adeir01.cpp index 981f5f14..8b4123e1 100644 --- a/test/direct_bt/test_adeir01.cpp +++ b/test/direct_bt/test_adeir01.cpp @@ -8,7 +8,7 @@ #include <catch2/catch_amalgamated.hpp> #include <jau/test/catch2_ext.hpp> -#include <direct_bt/UUID.hpp> +#include <jau/uuid.hpp> // #include <direct_bt/BTAddress.hpp> // #include <direct_bt/BTTypes1.hpp> #include <direct_bt/ATTPDUTypes.hpp> @@ -24,11 +24,11 @@ TEST_CASE( "AD EIR PDU Test 01", "[datatype][AD][EIR]" ) { const std::vector<uint8_t> msd_data = { 0x01, 0x02 }; ManufactureSpecificData msd(0x0001, msd_data.data(), msd_data.size()); - const uuid16_t uuid_01 = uuid16_t(0x1234); - const uuid16_t uuid_02 = uuid16_t(0x0a0b); + const jau::uuid16_t uuid_01 = jau::uuid16_t(0x1234); + const jau::uuid16_t uuid_02 = jau::uuid16_t(0x0a0b); { - std::shared_ptr<const uuid_t> const p1 = std::make_shared<uuid16_t>( uuid_01 ); - std::shared_ptr<const uuid_t> const p2 = uuid_02.clone(); + std::shared_ptr<const jau::uuid_t> const p1 = std::make_shared<jau::uuid16_t>( uuid_01 ); + std::shared_ptr<const jau::uuid_t> const p2 = uuid_02.clone(); std::cout << "uuid_01: " << uuid_01.toString() << ", [" << p1->toString() << "]" << std::endl; std::cout << "uuid_02: " << uuid_02.toString() << ", [" << p2->toString() << "]" << std::endl; } @@ -67,12 +67,12 @@ TEST_CASE( "AD EIR PDU Test 02", "[datatype][AD][EIR]" ) { const std::vector<uint8_t> msd_data = { 0x01, 0x02, 0x03, 0x04, 0x05 }; ManufactureSpecificData msd(0x0001, msd_data.data(), msd_data.size()); - const uuid16_t uuid_01(0x1234); - const uuid16_t uuid_02(0x0a0b); - const uuid32_t uuid_11(0xabcd1234); - const uuid128_t uuid_21("00001234-5678-100a-8000-00805F9B34FB"); + const jau::uuid16_t uuid_01(0x1234); + const jau::uuid16_t uuid_02(0x0a0b); + const jau::uuid32_t uuid_11(0xabcd1234); + const jau::uuid128_t uuid_21("00001234-5678-100a-8000-00805F9B34FB"); { - std::shared_ptr<const uuid_t> const p1 = uuid_21.clone(); + std::shared_ptr<const jau::uuid_t> const p1 = uuid_21.clone(); std::cout << "uuid_21: " << uuid_21.toString() << ", [" << p1->toString() << "]" << std::endl; } diff --git a/test/direct_bt/test_attpdu01.cpp b/test/direct_bt/test_attpdu01.cpp index 955f98c2..baa48c0f 100644 --- a/test/direct_bt/test_attpdu01.cpp +++ b/test/direct_bt/test_attpdu01.cpp @@ -8,7 +8,7 @@ #include <catch2/catch_amalgamated.hpp> #include <jau/test/catch2_ext.hpp> -#include <direct_bt/UUID.hpp> +#include <jau/uuid.hpp> // #include <direct_bt/BTAddress.hpp> // #include <direct_bt/BTTypes1.hpp> #include <direct_bt/ATTPDUTypes.hpp> @@ -18,10 +18,10 @@ using namespace direct_bt; TEST_CASE( "ATT PDU Test 01", "[datatype][attpdu]" ) { - const uuid16_t uuid16 = uuid16_t(uuid16_t(0x1234)); + const jau::uuid16_t uuid16 = jau::uuid16_t(0x1234); const AttReadByNTypeReq req(true /* group */, 1, 0xffff, uuid16); - std::shared_ptr<const uuid_t> uuid16_2 = req.getNType(); + std::shared_ptr<const jau::uuid_t> uuid16_2 = req.getNType(); REQUIRE(uuid16.getTypeSizeInt() == 2); REQUIRE(uuid16_2->getTypeSizeInt() == 2); REQUIRE( 0 == memcmp(uuid16.data(), uuid16_2->data(), 2) ); diff --git a/test/direct_bt/test_btaddress01.cpp b/test/direct_bt/test_btaddress01.cpp deleted file mode 100644 index 6cad6582..00000000 --- a/test/direct_bt/test_btaddress01.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include <iostream> -#include <cassert> -#include <cinttypes> -#include <cstring> - -#define CATCH_CONFIG_RUNNER -// #define CATCH_CONFIG_MAIN -#include <catch2/catch_amalgamated.hpp> -#include <jau/test/catch2_ext.hpp> - -#include <jau/basic_types.hpp> -#include <jau/darray.hpp> -#include <direct_bt/BTAddress.hpp> - -using namespace direct_bt; -using namespace jau; - -static void test_sub(const std::string& mac_str, const jau::darray<std::string>& mac_sub_strs, const jau::darray<jau::snsize_t>& indices) { - const EUI48 mac(mac_str); - printf("Test EUI48 mac: '%s' -> '%s'\n", mac_str.c_str(), mac.toString().c_str()); - REQUIRE(mac_str == mac.toString()); - - int i=0; - jau::for_each_const(mac_sub_strs, [&i, &mac, &indices](const std::string &mac_sub_str) { - const EUI48Sub mac_sub(mac_sub_str); - printf("EUI48Sub mac02_sub: '%s' -> '%s'\n", mac_sub_str.c_str(), mac_sub.toString().c_str()); - // cut-off pre- and post-colon in test string, but leave single colon - std::string sub_str(mac_sub_str); - if( sub_str.size() == 0 ) { - sub_str = ":"; - } else if( sub_str != ":" ) { - if( sub_str.size() > 0 && sub_str[0] == ':' ) { - sub_str = sub_str.substr(1, sub_str.size()); - } - if( sub_str.size() > 0 && sub_str[sub_str.size()-1] == ':' ) { - sub_str = sub_str.substr(0, sub_str.size()-1); - } - } - REQUIRE(sub_str == mac_sub.toString()); - - jau::snsize_t idx = mac.indexOf(mac_sub); - REQUIRE( idx == indices.at(i)); - if( idx >= 0 ) { - REQUIRE( mac.contains(mac_sub) ); - } else { - REQUIRE( !mac.contains(mac_sub) ); - } - - ++i; - } ); - (void) indices; -} - -static void test_sub(const std::string& mac_sub_str_exp, const std::string& mac_sub_str, const bool expected_result) { - std::string errmsg; - EUI48Sub mac_sub; - const bool res = EUI48Sub::scanEUI48Sub(mac_sub_str, mac_sub, errmsg); - if( res ) { - printf("EUI48Sub mac_sub: '%s' -> '%s'\n", mac_sub_str.c_str(), mac_sub.toString().c_str()); - if( expected_result ) { - REQUIRE(mac_sub_str_exp == mac_sub.toString()); - } - } else { - printf("EUI48Sub mac_sub: '%s' -> Error '%s'\n", mac_sub_str.c_str(), errmsg.c_str()); - } - REQUIRE( expected_result == res ); -} - -TEST_CASE( "EUI48 Test 01", "[datatype][eui48]" ) { - EUI48 mac01; - INFO_STR("EUI48 size: whole0 "+std::to_string(sizeof(EUI48))); - INFO_STR("EUI48 size: whole1 "+std::to_string(sizeof(mac01))); - INFO_STR("EUI48 size: data1 "+std::to_string(sizeof(mac01.b))); - REQUIRE_MSG("EUI48 struct and data size match", sizeof(EUI48) == sizeof(mac01)); - REQUIRE_MSG("EUI48 struct and data size match", sizeof(mac01) == sizeof(mac01.b)); - - { - // index [high=5 ... low=0] - const std::string mac02_str = "C0:10:22:A0:10:00"; - const jau::darray<std::string> mac02_sub_strs = { "C0", "C0:10", ":10:22", "10:22", ":10:22:", "10:22:", "10", "10:00", "00", ":", "", "00:10", mac02_str}; - const jau::darray<jau::snsize_t> mac02_sub_idxs = { 5, 4, 3, 3, 3, 3, 1, 0, 0, 0, 0, -1, 0}; - test_sub(mac02_str, mac02_sub_strs, mac02_sub_idxs); - } - - { - // index [high=5 ... low=0] - const std::string mac03_str = "01:02:03:04:05:06"; - const jau::darray<std::string> mac03_sub_strs = { "01", "01:02", ":03:04", "03:04", ":04:05:", "04:05:", "04", "05:06", "06", ":", "", "06:05", mac03_str}; - const jau::darray<jau::snsize_t> mac03_sub_idxs = { 5, 4, 2, 2, 1, 1, 2, 0, 0, 0, 0, -1, 0}; - test_sub(mac03_str, mac03_sub_strs, mac03_sub_idxs); - } - { - const std::string mac_sub_str = "C0:10:22:A0:10:00"; - test_sub(mac_sub_str, mac_sub_str, true /* expected_result */); - } - { - const std::string mac_sub_str = "0600106"; - const std::string dummy; - test_sub(dummy, mac_sub_str, false /* expected_result */); - } -} diff --git a/test/direct_bt/test_uuid.cpp b/test/direct_bt/test_uuid.cpp deleted file mode 100644 index 46d06d9a..00000000 --- a/test/direct_bt/test_uuid.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include <iostream> -#include <cassert> -#include <cinttypes> -#include <cstring> - -#define CATCH_CONFIG_RUNNER -// #define CATCH_CONFIG_MAIN -#include <catch2/catch_amalgamated.hpp> -#include <jau/test/catch2_ext.hpp> - -#include <direct_bt/UUID.hpp> - -using namespace direct_bt; - -TEST_CASE( "UUID Test 01", "[datatype][uuid]" ) { - std::cout << "Hello COUT" << std::endl; - std::cerr << "Hello CERR" << std::endl; - - uint8_t buffer[100]; - static uint8_t uuid128_bytes[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; - - { - const uuid128_t v01 = uuid128_t(uuid128_bytes, 0, true); - REQUIRE(v01.getTypeSizeInt() == 16); - REQUIRE(v01.getTypeSizeInt() == sizeof(v01.value)); - REQUIRE(v01.getTypeSizeInt() == sizeof(v01.value.data)); - REQUIRE( 0 == memcmp(uuid128_bytes, v01.data(), 16) ); - - v01.put(buffer, 0, true /* littleEndian */); - std::shared_ptr<const uuid_t> v02 = uuid_t::create(uuid_t::TypeSize::UUID128_SZ, buffer, 0, true); - REQUIRE(v02->getTypeSizeInt() == 16); - REQUIRE( 0 == memcmp(v01.data(), v02->data(), 16) ); - REQUIRE( v01.toString() == v02->toString() ); - } - - { - const uuid32_t v01 = uuid32_t(uuid32_t(0x12345678)); - REQUIRE(v01.getTypeSizeInt() == 4); - REQUIRE(v01.getTypeSizeInt() == sizeof(v01.value)); - REQUIRE(0x12345678 == v01.value); - - v01.put(buffer, 0, true /* littleEndian */); - std::shared_ptr<const uuid_t> v02 = uuid_t::create(uuid_t::TypeSize::UUID32_SZ, buffer, 0, true); - REQUIRE(v02->getTypeSizeInt() == 4); - REQUIRE( 0 == memcmp(v01.data(), v02->data(), 4) ); - REQUIRE( v01.toString() == v02->toString() ); - } - - { - const uuid16_t v01 = uuid16_t(uuid16_t(0x1234)); - REQUIRE(v01.getTypeSizeInt() == 2); - REQUIRE(v01.getTypeSizeInt() == sizeof(v01.value)); - REQUIRE(0x1234 == v01.value); - - v01.put(buffer, 0, true /* littleEndian */); - std::shared_ptr<const uuid_t> v02 = uuid_t::create(uuid_t::TypeSize::UUID16_SZ, buffer, 0, true); - REQUIRE(v02->getTypeSizeInt() == 2); - REQUIRE( 0 == memcmp(v01.data(), v02->data(), 2) ); - REQUIRE( v01.toString() == v02->toString() ); - } - - - - { - const uuid16_t v01("1234"); - REQUIRE(v01.getTypeSizeInt() == uuid_t::number( uuid_t::TypeSize::UUID16_SZ )); - REQUIRE(v01.getTypeSizeInt() == sizeof(v01.value)); - REQUIRE(0x1234 == v01.value); - REQUIRE("1234" == v01.toString()); - } - { - const uuid32_t v01("12345678"); - REQUIRE(v01.getTypeSizeInt() == uuid_t::number( uuid_t::TypeSize::UUID32_SZ )); - REQUIRE(v01.getTypeSizeInt() == sizeof(v01.value)); - REQUIRE(0x12345678 == v01.value); - REQUIRE("12345678" == v01.toString()); - } - { - const uuid128_t v01("00001234-5678-100A-800B-00805F9B34FB"); - REQUIRE(v01.getTypeSizeInt() == uuid_t::number( uuid_t::TypeSize::UUID128_SZ) ); - REQUIRE(v01.getTypeSizeInt() == sizeof(v01.value)); - REQUIRE("00001234-5678-100a-800b-00805f9b34fb" == v01.toString()); - } - - - - { - std::shared_ptr<const uuid_t> v01 = uuid_t::create("1234"); - REQUIRE(v01->getTypeSizeInt() == uuid_t::number( uuid_t::TypeSize::UUID16_SZ )); - REQUIRE("1234" == v01->toString()); - } - { - std::shared_ptr<const uuid_t> v01 = uuid_t::create("12345678"); - REQUIRE(v01->getTypeSizeInt() == uuid_t::number( uuid_t::TypeSize::UUID32_SZ)); - REQUIRE("12345678" == v01->toString()); - } - { - std::shared_ptr<const uuid_t> v01 = uuid_t::create("00001234-5678-100A-800B-00805F9B34FB"); - REQUIRE(v01->getTypeSizeInt() == uuid_t::number( uuid_t::TypeSize::UUID128_SZ )); - REQUIRE("00001234-5678-100a-800b-00805f9b34fb" == v01->toString()); - } -} diff --git a/test/java/test/org/direct_bt/TestEUI48.java b/test/java/test/org/direct_bt/TestEUI48.java deleted file mode 100644 index 93d3c40d..00000000 --- a/test/java/test/org/direct_bt/TestEUI48.java +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Copyright 2015 JogAmp Community. 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. - * - * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of JogAmp Community. - */ - -package test.org.direct_bt; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import jau.test.junit.util.JunitTracer; - -import org.direct_bt.BTException; -import org.direct_bt.BTFactory; -import org.direct_bt.BTManager; -import org.direct_bt.EUI48; -import org.direct_bt.EUI48Sub; -import org.junit.Assert; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -/** - * Test basic EUI48 functionality - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class TestEUI48 extends JunitTracer { - - static { - final BTManager manager; - try { - manager = BTFactory.getDirectBTManager(); - } catch (BTException | NoSuchMethodException | SecurityException - | IllegalAccessException | IllegalArgumentException - | InvocationTargetException | ClassNotFoundException e) { - System.err.println("Unable to instantiate DirectBT BluetoothManager"); - e.printStackTrace(); - System.exit(-1); - } - } - static void test_sub(final String mac_str, final List<String> mac_sub_strs, final List<Integer> indices) { - final EUI48 mac = new EUI48(mac_str); - - System.out.printf("Test EUI48 mac: '%s' -> '%s'\n", mac_str, mac.toString()); - Assert.assertEquals(mac_str, mac.toString()); - - int i=0; - for(final Iterator<String> iter=mac_sub_strs.iterator(); iter.hasNext(); ++i) { - final String mac_sub_str = iter.next(); - final EUI48Sub mac_sub = new EUI48Sub(mac_sub_str); - System.out.printf("EUI48Sub mac02_sub: '%s' -> '%s'\n", mac_sub_str, mac_sub.toString()); - // cut-off pre- and post-colon in test string, but leave single colon - String sub_str = new String(mac_sub_str); - if( sub_str.isEmpty() ) { - sub_str = ":"; - } else if( !sub_str.equals(":") ) { - if( sub_str.length() > 0 && sub_str.charAt(0) == ':' ) { - sub_str = sub_str.substring(1, sub_str.length()); - } - if( sub_str.length() > 0 && sub_str.charAt(sub_str.length()-1) == ':' ) { - sub_str = sub_str.substring(0, sub_str.length()-1); - } - } - Assert.assertEquals(sub_str, mac_sub.toString()); - - final int idx = mac.indexOf(mac_sub); - Assert.assertEquals( idx, indices.get(i).intValue()); - if( idx >= 0 ) { - Assert.assertTrue( mac.contains(mac_sub) ); - } else { - Assert.assertFalse( mac.contains(mac_sub) ); - } - } - } - static void test_sub(final String mac_sub_str_exp, final String mac_sub_str, final boolean expected_result) { - final StringBuilder errmsg = new StringBuilder(); - final EUI48Sub mac_sub = new EUI48Sub (); - final boolean res = EUI48Sub.scanEUI48Sub(mac_sub_str, mac_sub, errmsg); - if( res ) { - System.out.printf("EUI48Sub mac_sub: '%s' -> '%s'\n", mac_sub_str, mac_sub.toString()); - if( expected_result ) { - Assert.assertEquals(mac_sub_str_exp, mac_sub.toString()); - } - } else { - System.out.printf("EUI48Sub mac_sub: '%s' -> Error '%s'\n", mac_sub_str, errmsg.toString()); - } - Assert.assertEquals(expected_result, res); - } - - @Test - public void test01_EUI48AndSub() { - { - // index [high=5 ... low=0] - final String mac02_str = "C0:10:22:A0:10:00"; - final String[] mac02_sub_strs = { "C0", "C0:10", ":10:22", "10:22", ":10:22:", "10:22:", "10", "10:00", "00", ":", "", "00:10", mac02_str}; - final Integer[] mac02_sub_idxs = { 5, 4, 3, 3, 3, 3, 1, 0, 0, 0, 0, -1, 0}; - test_sub(mac02_str, Arrays.asList(mac02_sub_strs), Arrays.asList(mac02_sub_idxs)); - } - - { - // index [high=5 ... low=0] - final String mac03_str = "01:02:03:04:05:06"; - final String[] mac03_sub_strs = { "01", "01:02", ":03:04", "03:04", ":04:05:", "04:05:", "04", "05:06", "06", ":", "", "06:05", mac03_str}; - final Integer[] mac03_sub_idxs = { 5, 4, 2, 2, 1, 1, 2, 0, 0, 0, 0, -1, 0}; - test_sub(mac03_str, Arrays.asList(mac03_sub_strs), Arrays.asList(mac03_sub_idxs)); - } - { - final String mac_sub_str = "C0:10:22:A0:10:00"; - test_sub(mac_sub_str, mac_sub_str, true /* expected_result */); - } - { - final String mac_sub_str = "0600106"; - test_sub(null, mac_sub_str, false /* expected_result */); - } - } - - public static void main(final String args[]) throws IOException { - final String tstname = TestEUI48.class.getName(); - org.junit.runner.JUnitCore.main(tstname); - } - -} |