Преглед изворни кода

basic libnfc operations

develop
Robin Thoni пре 8 година
родитељ
комит
017bc8715f

+ 1
- 0
CMakeLists.txt Прегледај датотеку

@@ -3,6 +3,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeMod
3 3
 set(PROJECT_NAME mifare-tools)
4 4
 project(${PROJECT_NAME})
5 5
 find_package(GTest)
6
+set(LIBS ${LIBS} nfc)
6 7
 add_subdirectory(src)
7 8
 if (GTEST_FOUND)
8 9
     enable_testing()

+ 4
- 1
src/CMakeLists.txt Прегледај датотеку

@@ -10,7 +10,10 @@ set(SOURCE_FILES
10 10
   DBO/CommandLineOption.h
11 11
   DBO/Result.hxx
12 12
   DBO/Result.h
13
-  )
13
+  DataAccess/LibNfc.cpp
14
+  DataAccess/LibNfc.h
15
+        DataAccess/NfcDevice.cpp
16
+        DataAccess/NfcDevice.h DataAccess/FreeFareDevice.cpp DataAccess/FreeFareDevice.h)
14 17
 
15 18
 add_executable(${PROJECT_NAME} ${SOURCE_FILES})
16 19
 target_link_libraries(${PROJECT_NAME} ${LIBS})

+ 29
- 23
src/DBO/Result.h Прегледај датотеку

@@ -2,51 +2,57 @@
2 2
 // Created by robin on 8/9/15.
3 3
 //
4 4
 
5
-#ifndef PDNS_SLAVE_RESULT_H
6
-#define PDNS_SLAVE_RESULT_H
5
+#ifndef RESULT_H
6
+#define RESULT_H
7 7
 
8 8
 # include <string>
9 9
 # include <vector>
10
+# include <iostream>
10 11
 
11 12
 template <class T> class Result
12 13
 {
13 14
 public:
14
-    Result();
15
-
16
-    Result(const T& data);
17
-
18
-    virtual ~Result();
19
-
20
-    Result<T>& ok(const T& data);
15
+    static const Result<T> ok(const T& data);
16
+    static const Result<T> strerror();
17
+    static const Result<T> error(const std::string& error);
18
+    template <class U> static const Result<T> error(const Result<U>& other);
21 19
 
22 20
     T& getData();
23
-
24
-    bool isSuccess() const;
25
-
26
-    Result<T>& addWarning(const std::string& warning);
27
-
28
-    const std::vector<std::string>& getWarnings() const;
29
-
30
-    Result<T>& error(const std::string& error);
31
-
21
+    const bool isSuccess() const;
32 22
     const std::string& getError() const;
33 23
 
34 24
     bool operator !() const;
35
-
36 25
     operator bool() const;
37 26
 
27
+    template<class U>
28
+    friend std::ostream& operator<<(std::ostream& os, const Result<U>& res);
29
+
38 30
     const Result<T>& print() const;
39 31
 
40 32
 private:
41
-    T _data;
33
+    Result();
42 34
 
43
-    std::vector<std::string> _warnings;
35
+    T _data;
44 36
 
45 37
     std::string _error;
38
+
39
+    bool _success;
46 40
 };
47 41
 
48
-typedef Result<bool> BResult;
42
+typedef Result<bool> ResultBool;
43
+
44
+typedef Result<int> ResultInt;
45
+
46
+typedef Result<long> ResultLong;
47
+
48
+typedef Result<float> ResultFloat;
49
+
50
+typedef Result<double> ResultDouble;
51
+
52
+typedef Result<char> ResultChar;
53
+
54
+typedef Result<std::string> ResultString;
49 55
 
50 56
 # include "DBO/Result.hxx"
51 57
 
52
-#endif //PDNS_SLAVE_RESULT_H
58
+#endif //RESULT_H

+ 40
- 31
src/DBO/Result.hxx Прегледај датотеку

@@ -2,8 +2,9 @@
2 2
 // Created by robin on 8/9/15.
3 3
 //
4 4
 
5
-#include <iostream>
6 5
 #include "Result.h"
6
+#include <errno.h>
7
+#include <string.h>
7 8
 
8 9
 template<class T>
9 10
 Result<T>::Result()
@@ -11,46 +12,52 @@ Result<T>::Result()
11 12
 }
12 13
 
13 14
 template<class T>
14
-Result<T>::Result(const T &data)
15
-        : _data(data)
15
+const Result<T> Result<T>::ok(const T& data)
16 16
 {
17
+    Result<T> r;
18
+    r._success = true;
19
+    r._data = data;
20
+    return r;
17 21
 }
18 22
 
19 23
 template<class T>
20
-Result<T>::~Result()
24
+const Result<T> Result<T>::strerror()
21 25
 {
26
+    Result<T> r;
27
+    r._success = false;
28
+    r._error = ::strerror(errno);
29
+    return r;
22 30
 }
23 31
 
24 32
 template<class T>
25
-Result<T> &Result<T>::ok(const T &data)
33
+const Result<T> Result<T>::error(const std::string& error)
26 34
 {
27
-    _data = data;
28
-    return *this;
35
+    Result<T> r;
36
+    r._success = false;
37
+    r._error = error;
38
+    return r;
29 39
 }
30 40
 
31 41
 template<class T>
32
-T &Result<T>::getData()
42
+template<class U>
43
+const Result<T> Result<T>::error(const Result<U>& other)
33 44
 {
34
-    return _data;
45
+    Result<T> r;
46
+    r._success = false;
47
+    r.error(other.getError());
48
+    return r;
35 49
 }
36 50
 
37 51
 template<class T>
38
-bool Result<T>::isSuccess() const
52
+T &Result<T>::getData()
39 53
 {
40
-    return _error.empty();
54
+    return _data;
41 55
 }
42 56
 
43 57
 template<class T>
44
-const std::vector<std::string>& Result<T>::getWarnings() const
58
+const bool Result<T>::isSuccess() const
45 59
 {
46
-    return _warnings;
47
-}
48
-
49
-template<class T>
50
-Result<T>& Result<T>::addWarning(const std::string &warning)
51
-{
52
-    _warnings.push_back(warning);
53
-    return *this;
60
+    return _success;
54 61
 }
55 62
 
56 63
 template<class T>
@@ -66,24 +73,26 @@ Result<T>::operator bool() const
66 73
 }
67 74
 
68 75
 template<class T>
69
-Result<T> &Result<T>::error(const std::string &error)
76
+const std::string &Result<T>::getError() const
70 77
 {
71
-    _error = error;
72
-    return *this;
78
+    return _error;
73 79
 }
74 80
 
75
-template<class T>
76
-const std::string &Result<T>::getError() const
81
+template<class U>
82
+std::ostream& operator<<(std::ostream& os, const Result<U>& res)
77 83
 {
78
-    return _error;
84
+    if (res._success) {
85
+        os << "Success";// << res._data;
86
+    }
87
+    else {
88
+        os << "Error: " << (res._error.empty() ? "Unknown error" : res._error);
89
+    }
90
+    return os;
79 91
 }
80 92
 
81 93
 template<class T>
82 94
 const Result<T>& Result<T>::print() const
83 95
 {
84
-    for (auto warning : _warnings)
85
-        std::cerr << "WARNING: " << warning << std::endl;
86
-    if (!isSuccess())
87
-        std::cerr << "ERROR: " << _error << std::endl;
96
+    (_success ? std::cout : std::cerr) << *this << std::endl;
88 97
     return *this;
89
-}
98
+}

+ 10
- 0
src/DataAccess/FreeFareDevice.cpp Прегледај датотеку

@@ -0,0 +1,10 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#include "FreeFareDevice.h"
6
+
7
+FreeFareDevice::FreeFareDevice(NfcDevice *device)
8
+    : _device(device)
9
+{
10
+}

+ 22
- 0
src/DataAccess/FreeFareDevice.h Прегледај датотеку

@@ -0,0 +1,22 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_FREEFAREDEVICE_H
6
+#define MIFARE_TOOLS_FREEFAREDEVICE_H
7
+
8
+
9
+#include "NfcDevice.h"
10
+#include <freefare.h>
11
+
12
+class FreeFareDevice
13
+{
14
+public:
15
+    FreeFareDevice(NfcDevice* device);
16
+
17
+private:
18
+    NfcDevice* _device;
19
+};
20
+
21
+
22
+#endif //MIFARE_TOOLS_FREEFAREDEVICE_H

+ 67
- 0
src/DataAccess/LibNfc.cpp Прегледај датотеку

@@ -0,0 +1,67 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#include "LibNfc.h"
6
+
7
+LibNfc::LibNfc()
8
+    : _context(0)
9
+{
10
+}
11
+
12
+ResultBool LibNfc::init()
13
+{
14
+    if (isInitialized()) {
15
+        return ResultBool::error("LibNfc is already initialized");
16
+    }
17
+    nfc_init(&_context);
18
+    if (!_context) {
19
+        return ResultBool::error("LibNfc could not be initialized");
20
+    }
21
+    return ResultBool::ok(true);
22
+}
23
+
24
+std::string LibNfc::getVersion()
25
+{
26
+    return nfc_version();
27
+}
28
+
29
+LibNfc::~LibNfc()
30
+{
31
+    clean();
32
+}
33
+
34
+bool LibNfc::isInitialized()
35
+{
36
+    return _context != 0;
37
+}
38
+
39
+void LibNfc::clean()
40
+{
41
+    if (isInitialized()) {
42
+        nfc_exit(_context);
43
+        _context = 0;
44
+    }
45
+}
46
+
47
+Result<std::vector<NfcDevice*>> LibNfc::getDevices()
48
+{
49
+    if (!isInitialized()) {
50
+        return Result<std::vector<NfcDevice*>>::error("LibNfc is not initialized");
51
+    }
52
+    nfc_connstring devices[16];
53
+    size_t count = nfc_list_devices(_context, devices, sizeof(devices));
54
+    if (count < 0) {
55
+        return Result<std::vector<NfcDevice*>>::error("Failed to list NFC devices");
56
+    }
57
+    std::vector<NfcDevice*> devicesList;
58
+    for (size_t i = 0; i < count; ++i) {
59
+        devicesList.push_back(new NfcDevice(this, devices[i]));
60
+    }
61
+    return Result<std::vector<NfcDevice*>>::ok(devicesList);
62
+}
63
+
64
+nfc_context *LibNfc::getContext() const
65
+{
66
+    return _context;
67
+}

+ 37
- 0
src/DataAccess/LibNfc.h Прегледај датотеку

@@ -0,0 +1,37 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_LIBNFC_H
6
+#define MIFARE_TOOLS_LIBNFC_H
7
+
8
+#include <nfc/nfc.h>
9
+#include "NfcDevice.h"
10
+#include "DBO/Result.h"
11
+
12
+class NfcDevice;
13
+
14
+class LibNfc
15
+{
16
+public:
17
+    LibNfc();
18
+    ~LibNfc();
19
+
20
+    ResultBool init();
21
+
22
+    void clean();
23
+
24
+    bool isInitialized();
25
+
26
+    Result<std::vector<NfcDevice*>> getDevices();
27
+
28
+    static std::string getVersion();
29
+
30
+    nfc_context* getContext() const;
31
+
32
+private:
33
+    nfc_context* _context;
34
+};
35
+
36
+
37
+#endif //MIFARE_TOOLS_LIBNFC_H

+ 42
- 0
src/DataAccess/NfcDevice.cpp Прегледај датотеку

@@ -0,0 +1,42 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#include "NfcDevice.h"
6
+
7
+NfcDevice::NfcDevice(LibNfc* libNfc, std::string str)
8
+    : _connStr(str)
9
+    , _device(0)
10
+    , _libNfc(libNfc)
11
+{
12
+}
13
+
14
+NfcDevice::~NfcDevice()
15
+{
16
+    close();
17
+}
18
+
19
+ResultBool NfcDevice::open()
20
+{
21
+    if (isOpened()) {
22
+        return ResultBool::error("NFC device is already opened");
23
+    }
24
+    _device = nfc_open(_libNfc->getContext(), _connStr.c_str());
25
+    if (!_device) {
26
+        return ResultBool::error("Failed to open NFC device");
27
+    }
28
+    return ResultBool::ok(true);
29
+}
30
+
31
+bool NfcDevice::isOpened()
32
+{
33
+    return _device != 0;
34
+}
35
+
36
+void NfcDevice::close()
37
+{
38
+    if (isOpened()) {
39
+        nfc_close(_device);
40
+        _device = 0;
41
+    }
42
+}

+ 47
- 0
src/DataAccess/NfcDevice.h Прегледај датотеку

@@ -0,0 +1,47 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_NFCDEVICEDBO_H
6
+#define MIFARE_TOOLS_NFCDEVICEDBO_H
7
+
8
+
9
+#include <string>
10
+#include <nfc/nfc-types.h>
11
+#include <DBO/Result.h>
12
+#include "LibNfc.h"
13
+
14
+class LibNfc;
15
+
16
+class NfcDevice
17
+{
18
+public:
19
+    NfcDevice(LibNfc* libNfc, std::string connStr);
20
+    ~NfcDevice();
21
+
22
+    ResultBool open();
23
+
24
+    void close();
25
+
26
+    bool isOpened();
27
+
28
+    const std::string &getConnStr() const
29
+    {
30
+        return _connStr;
31
+    }
32
+
33
+    void setConnStr(const std::string &connStr)
34
+    {
35
+        _connStr = connStr;
36
+    }
37
+
38
+private:
39
+    std::string _connStr;
40
+
41
+    nfc_device* _device;
42
+
43
+    LibNfc* _libNfc;
44
+};
45
+
46
+
47
+#endif //MIFARE_TOOLS_NFCDEVICEDBO_H

+ 38
- 0
src/Interface/MainClass.cpp Прегледај датотеку

@@ -5,6 +5,7 @@
5 5
 #include <iostream>
6 6
 #include <sysexits.h>
7 7
 #include <DBO/Result.h>
8
+#include <DataAccess/LibNfc.h>
8 9
 #include "CommandLineParser.h"
9 10
 #include "MainClass.h"
10 11
 
@@ -16,6 +17,43 @@ MainClass::MainClass(int argc, char *argv[])
16 17
 
17 18
 int MainClass::main()
18 19
 {
20
+    std::cout << "LibNfc version: " << LibNfc::getVersion() << std::endl;
21
+
22
+    LibNfc libNfc;
23
+    auto init = libNfc.init();
24
+    if (!init) {
25
+        init.print();
26
+        return 1;
27
+    }
28
+
29
+    auto devices = libNfc.getDevices();
30
+    if (!devices) {
31
+        devices.print();
32
+        return 2;
33
+    }
34
+    if (devices.getData().size() == 0) {
35
+        std::cerr << "No NFC device found" << std::endl;
36
+        return 3;
37
+    }
38
+
39
+    std::cout << "Found " << devices.getData().size() << " devices: " << std::endl;
40
+    for (size_t i = 0; i < devices.getData().size(); ++i) {
41
+        std::cout << devices.getData()[i]->getConnStr() << std::endl;
42
+    }
43
+    for (size_t i = 1; i < devices.getData().size(); ++i) {
44
+        delete devices.getData()[i];
45
+    }
46
+
47
+    auto device = devices.getData()[0];
48
+    auto open = device->open();
49
+    if (!open) {
50
+        open.print();
51
+        return 4;
52
+    }
53
+
54
+
55
+
56
+    device->close();
19 57
 
20 58
     return 0;
21 59
 }

Loading…
Откажи
Сачувај