Appendix A : Data Types

In this section we are focusing on the data types needed for implementing the POS Buddy application using the C++ library.
You may refer to the below code sample for a list of data types available in the implementation:

/**
 * @brief Type of comms to use
 *
 */
enum commsType {
    none,
    serial,
    usb,
    websocket
};

/**
 * @brief status of websocket
 *
 */
enum pbConnectStatus {
    STATUS_UNKNOWN,
    STATUS_CONNECTED,
    STATUS_DISCONNECTED,
    STATUS_ERROR
};

/**
 * @brief Return values for POS Buddy functions
 *
 */
enum pbResult {
    RESULT_OK = 0,
    NOT_SUPPORTED = -1000,
    MISSING_PARAMETERS = -1001,
    PARSE_JSON_ERROR = -1002,
    NO_RESPONSE = -1003,
    COMMS_ERROR = -1004,
    INVALID_RESPONSE = -1005,
    AUTH_ERROR = -1006,
    SALE_IN_PROGRESS = -1007,
    SERVER_COMMS_ERROR = -1008,

    COMMS_NOT_INITIALISED = -2000,
    ERROR_OPENING_SERIAL_PORT = -2001,
    ERROR_OPENING_WEBSOCKET = -2002,

    MEMORY_RESOURCE_ERROR = -10000
};

/**
 * @brief Items to use for line display
 *
 */
struct pbItem {
    std::string quantityString;    /*!< Quantity to display on device */
    std::string costString;        /*!< Cost to display on device */
    std::string descriptionString; /*!< Description to display on device */
    long quantity;                 /*!< Value is not used by device. It can be used to make internal calculations easier */
    long cost;                     /*!< Value is not used by device. It can be used to make internal calculations easier */
};


Appendix B: Windows Implementation.

📘

In this section you will find a setup guide for implementing the POS Buddy on a Windows based POS machine.

Below is a sample code for the C++ implementation using libposbuddy.dll in Windows.
A more advanced demo application is also available on request.

#include <windows.h>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <unistd.h>
#include "posbuddyinterface.h"

using namespace std;
PosBuddyInterface *posBuddy;
void showConnectionStatus(pbConnectStatus status);
void authCallback(map<string, string> resultMap);
pbConnectStatus currentStatus;

int main(int argc, char *argv[]) {
    map<string, string> returnedResultMap;
    string authenticationKey;

    // Set customer specific values
    string merchantId = "...";
    string username = "...";
    string applicationKey = "...";

    if (argc <= 2) {
        cout << "Please enter serial port or websocket to connect to, e.g. " << endl;
        cout << "   " << argv[0] << " -SERIAL COM13" << endl;
        cout << "   " << argv[0] << " -WS 123456" << endl;
        exit(1);
    }
    
    // Load the posBuddy dll
    HMODULE hdl = ::LoadLibrary("libposbuddy.dll");
    if (hdl == 0) {
        cout << "error loading libposbuddy.dll " << endl;
        exit(1);
    }

    srand(time(NULL));
    posBuddy = PosBuddyInterface::create();

    if (strncmp(argv[1], "-SERIAL", 7) == 0) {
        if (posBuddy->setComms(serial) != RESULT_OK) {
            cout << "Error opening serial port" << endl;
            exit(1);
        }
    }
    else if (strncmp(argv[1], "-WS", 3) == 0) {
        if (posBuddy->setComms(websocket) != RESULT_OK) {
            cout << "Error opening websocket to " << argv[2] << endl;
            exit(1);
        }
    }
    else {
        cout << "Invalid option: " << argv[1] << endl;
        exit(1);
    }
    
    posBuddy->connect(argv[2], &showConnectionStatus);

    posBuddy->clearItems();
    posBuddy->setMerchantId(merchantId);
    posBuddy->setUsername(username);
    posBuddy->setApplicationKey(applicationKey);
    
    while (currentStatus != STATUS_CONNECTED) {
        cout << "waiting for connection..." << endl;
        usleep(500000);
    }
    
    pbResult result = posBuddy->doAuth(authCallback);
    if (result != RESULT_OK) cout << "Auth error: " << result << endl;

    // Print received result values
    for (auto it : resultMap) {
        cout << it.first << " = " << it.second << endl;
    }
    
}

void showConnectionStatus(pbConnectStatus status) {
    switch (status) {
    case STATUS_UNKNOWN:
        cout << "New status: Unknown" << endl;
        break;
    case STATUS_CONNECTED:
        cout << "New status: Connected" << endl;
        break;
    case STATUS_DISCONNECTED:
        cout << "New status: Disconnected" << endl;
        break;
    case STATUS_ERROR:
        cout << "New status: Error" << endl;
        break;
    }
    
    currentStatus = status;
}

void authCallback(map<string, string> resultMap) {
    if (resultMap.find("authenticationKey") != resultMap.end()) {
        string authenticationKey = resultMap.at("authenticationKey");
        if (authenticationKey.length() > 5) saveAuthenticationKey(authenticationKey); // do not save 'null'
    }
}


Appendix C : Linux implementation

📘

In this section you will find a setup guide for implementing the POS Buddy on a Linux based POS machine.

Below is a sample code for C++ implementation using libposbuddy.a library in Linux.
A more advanced demo application is also available on request.

#include <sys/ioctl.h>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <unistd.h>
#include "posbuddyinterface.h"

using namespace std;
PosBuddyInterface *posBuddy;
void showConnectionStatus(pbConnectStatus status);
void authCallback(map<string, string> resultMap);
pbConnectStatus currentStatus;

int main(int argc, char *argv[]) {
    map<string, string> returnedResultMap;
    string authenticationKey;

    // Set customer specific values
    string merchantId = "...";
    string username = "...";
    string applicationKey = "...";

    if (argc <= 2) {
        cout << "Please enter serial port or websocket to connect to, e.g. " << endl;
        cout << "   " << argv[0] << " -SERIAL COM13" << endl;
        cout << "   " << argv[0] << " -WS 123456" << endl;
        exit(1);
    }
    
    srand(time(NULL));
    posBuddy = PosBuddyInterface::create();

    if (strncmp(argv[1], "-SERIAL", 7) == 0) {
        if (posBuddy->setComms(serial) != RESULT_OK) {
            cout << "Error opening serial port" << endl;
            exit(1);
        }
    }
    else if (strncmp(argv[1], "-WS", 3) == 0) {
        if (posBuddy->setComms(websocket) != RESULT_OK) {
            cout << "Error opening websocket to " << argv[2] << endl;
            exit(1);
        }
    }
    else {
        cout << "Invalid option: " << argv[1] << endl;
        exit(1);
    }

    posBuddy->connect(argv[2], &showConnectionStatus);

    posBuddy->clearItems();
    posBuddy->setMerchantId(merchantId);
    posBuddy->setUsername(username);
    posBuddy->setApplicationKey(applicationKey);
    
    while (currentStatus != STATUS_CONNECTED) {
        cout << "waiting for connection..." << endl;
        usleep(500000);
    }

    pbResult result = posBuddy->doAuth(authCallback);
    if (result != RESULT_OK) cout << "Auth error: " << result << endl;

    // Print received result values
    for (auto it : resultMap) {
        cout << it.first << " = " << it.second << endl;
    }
    
}

void showConnectionStatus(pbConnectStatus status) {
    switch (status) {
    case STATUS_UNKNOWN:
        cout << "New status: Unknown" << endl;
        break;
    case STATUS_CONNECTED:
        cout << "New status: Connected" << endl;
        break;
    case STATUS_DISCONNECTED:
        cout << "New status: Disconnected" << endl;
        break;
    case STATUS_ERROR:
        cout << "New status: Error" << endl;
        break;
    }
    
    currentStatus = status;
}

void authCallback(map<string, string> resultMap) {
    if (resultMap.find("authenticationKey") != resultMap.end()) {
        string authenticationKey = resultMap.at("authenticationKey");
        if (authenticationKey.length() > 5) saveAuthenticationKey(authenticationKey); // do not save 'null'
    }
}