Sample Source Code

Overview

This chapter describes how to use the Zebra Scanner SDK, and includes code snippets from the sample application.

NOTE For a list of a scanner's supported attribute (parameter) numbers and definitions, refer to the scanner Product Reference Guide, available on the Zebra Support website: http://www.zebra.com/support. Attributes include configuration parameters, monitored data, and asset tracking information.


SDK Sample Utilities

The Zebra Scanner SDK includes the following sample utilities that demonstrate SDK functionalities. This section describes how to use the utilities to gain an understanding of the SDK.

Developing a Console Application Using zebra-scanner-devel and Libraries

zebra-scanner-sdk main packages include a development package that contains header files to access CoreScanner API calls, as well as source code for a sample application. The sample application can be modified and compiled using the make file to create a new application. Include a path for header files and LD_FLAGS.

NOTE The sample application demonstrates how to develop an application for Zebra scanner drivers.

Table Installation Locations for Sample Application, Development Resources, and Shared Libraries

Application Type Installation Location File
Sample application /usr/share/zebra-scanner/samples/co nsole-app Makefile
ConsoleApplication
/usr/share/zebra-scanner/samples/co nsole-app/include ConsoleSampleEventListener.h
ConsoleMain.h
/usr/share/zebra-scanner/samples/co nsole-app/src ConsoleSampleEventListener.cpp
ConsoleMain.cpp
Development files for uPOS applications, files are installed by zebra-scanner-devel package /usr/include/zebra-scanner CsBarcodeTypes.h
CsUserDefs.h
CsIEventListenerXml.h
Cslibcorescanner_xml.h
CoreScanner shared libraries /usr/lib/zebra-scanner/corescanner libcs-iudev.so.4.0.0
libcs-comm.so.4.0.0
libcs-common.so.4.0.0
libcscl-snapi.so.4.0.0
libcs-client.so.4.0.0
libcs-clientscanner.so.4.0.0
libcs-clientscale.so.4.0.0
libcscl-ibmtt.so.4.0.0
libcscl-ibmhh.so.4.0.0
libcscl-hidkb.so.4.0.0
libcs-client.so
libcs-clientscale.so
libcs-clientscanner.so
libcs-comm.so
libcs-common.so
libcs-iudev.so
libcscl-hidkb.so
libcscl-snapi.so
libcscl-ibmtt.so
libcscl-ibmhh.so

An application should extend the IEventListenerXml class from the zebra-scanner-devel package. IEventListenerXml is an abstract class with pure virtual functions for all event handling. The included sample application implements all event handling methods. Additional methods support required features, and each method calls the ExecCommand() method after preparing input XML.

For example, ConsoleSampleEventListener.h is implemented in the IEventListenerXml class of the Console Application.

A developer implements all pure abstract methods inside the sample application's class SampleEventListener, which is derived from the IEventListenerXML interface. The SampleEventListener class can then be instantiated inside the main method. The following API calls are used for further development:

  • Open
  • GetScanners
  • ExecCommand
  • ExecCommandAsync
  • Close

Source Code for the Console Application

Class SampleEventListener (ConsoleSampleEventListener.h)


/*
* ©2015 Symbol Technologies LLC. All rights reserved.
*/

#ifndef SAMPLEEVENTLISTENER_H_ 
#define SAMPLEEVENTLISTENER_H_

#include "CsIEventListenerXml.h" 
#include "CsUserDefs.h"
#include "CsBarcodeTypes.h" 
#include "Cslibcorescanner_xml.h"

#include <iostream> 
    
using namespace std;

class SampleEventListener : public IEventListenerXml
{
public:
    explicit SampleEventListener(); virtual ~SampleEventListener();
    virtual void OnImageEvent( short eventType, 
        int size, 
        short imageFormat,
        char* sfimageData, 
        int dataLength,
        std::string& pScannerData
        );

    virtual void OnVideoEvent( short eventType, 
        int size, 
        char* sfvideoData,
        int dataLength, 
        std::string& pScannerData
        );

    virtual void OnBarcodeEvent( short eventType, std::string& pscanData ); 
    virtual void OnPNPEvent( short eventType, std::string ppnpData );
    virtual void OnCommandResponseEvent( short status, std::string& prspData );
    virtual void OnScannerNotification( short notificationType, std::string& pScannerData); 
    virtual void OnIOEvent( short type, unsigned char data );
    virtual void OnScanRMDEvent( short eventType, std::string& prmdData ); 
    virtual void OnDisconnect();

    void Open();
    void GetScanners();
    void GetAttribute();
    void DiscoverTunnelingDevice();
    void GetAllAttributes();
    void SetAttribute();
    void SetAttributeStore();
    void SetZeroWeight();
    void Close();

    void RebootScanner();
    void ExecuteActionCommand(CmdOpcode opCode);
    void GetDeviceTopology();
    void FirmwareUpdate();
    void StartNewFirmware();
    void AbortFirmwareUpdate();
};

#endif /* SAMPLEEVENTLISTENER_H_ */                                                            

Class SampleEventListener Definitions/Implementation (ConsoleSampleEventListener.cpp)


/*
* ©2015 Symbol Technologies LLC. All rights reserved.
*/

#include "ConsoleSampleEventListener.h"
#include <stdlib.h>

/**
* Default constructor
*/ SampleEventListener::SampleEventListener()
{

}

/**
* distructor
*/ SampleEventListener::~SampleEventListener()

{
Close();
}

/**
* Implementation of open()
*/
void SampleEventListener::Open()
{
    StatusID status;

    ::Open(this, SCANNER_TYPE_ALL, &status); std::string inXml = "<inArgs><cmdArgs><arg-int>7</arg-int><arg-int>1,2,4,8,16,32,128</arg-int></cmdArgs></inArgs>";
    std::string outXml;
    ::ExecCommand(CMD_REGISTER_FOR_EVENTS, inXml, outXml, &status);
}

/**
* implementation for GetScanners() method
*/
void SampleEventListener::GetScanners()
{
    unsigned short count;
    vector list;
    string outXml;
    StatusID eStatus;

    ::GetScanners(&count, &list, outXml, &eStatus);

    cout << "GetScanners ******* Scanner Count: " << count << endl; cout << outXml << endl;
}

/**
* Implementation of GetDeviceTopology()
*/
void SampleEventListener::GetDeviceTopology()
{
    string inXml;
    string outXml;
    StatusID sId;
    StatusID eStatus;

    cout << "GetDeviceTopology" << endl;
    ::ExecCommand(CMD_GET_DEVICE_TOPOLOGY, inXml, outXml, &sId);

    cout << "GetDeviceTopology" << endl; cout << outXml << endl;
}

/**
* Implementation of GetAttribute()method
*/
void SampleEventListener::GetAttribute()
{
    cout << "================================" << endl;
    cout << "GetAttribute " << endl; 
    std::string scannerID = "";
    
    cout << "Enter Scanner ID" << endl;
    cin >> scannerID;
    
    cout << "Enter attribute number or comma separated attribute numbers : " ;
    std::string attribute_number = "";
    cin >> attribute_number;

    std::string inXml = "<inArgs><scannerID>" + 
                        scannerID +
                        "</scannerID><cmdArgs><arg-xml><attrib_list>" +
                        attribute_number + 
                        "</attrib_list></arg-xml></cmdArgs></inArgs>";

    cout << "In XML : " << inXml << endl << endl; StatusID sId;
    std::string outXml;
    ::ExecCommand(CMD_RSM_ATTR_GET, inXml, outXml, &sId);

    cout << "Out XML : " << outXml << endl;
    cout << "================================" << endl;
}

/**
* Implementation of GetAllAttributes()method
*/
void SampleEventListener::GetAllAttributes()
{
    std::string scannerID = "";
    std::string subscannerID = "";
    cout << "================================" << endl;
    cout << "Enter scanner ID: ";
    cin >> scannerID;

    std::string inXml = ""+scannerID+""; 
    
    cout << "InXML : " << inXml << endl;
    StatusID sId;
    std::string outXml;

    ::ExecCommand(CMD_RSM_ATTR_GETALL, inXml, outXml, &sId);

    cout << "Out XML" << outXml << endl;
    cout << "================================" << endl;
}

void SampleEventListener::DiscoverTunnelingDevice()
{
    ::RefreshDevicelTopology();
}

/**
* Implementation of SetAttribute()method
*/
void SampleEventListener::SetAttribute()
{
    cout << "================================" << endl;
    cout << "GetAttribute " << endl; 
    std::string scannerID = "";

    cout << "Enter scanner ID : " << endl;
    cin >> scannerID;

    std::string attributeNumber = "";
    cout << "Enter attribute number : " << endl;
    cin >> attributeNumber;

    std::string dataType = "";
    cout << "Enter data type : " << endl;
    cin >> dataType;

    std::string attributeValue = "";
    cout << "Enter attribute value : " << endl; 
    cin >> attributeValue;

    std::string inXml = "<inArgs><scannerID>"+ 
                        scannerID +
                        "</scannerID><cmdArgs><arg-xml><attrib_list><attribute><id>" +
                        attributeNumber +
                        "</id><datatype>" + dataType + "</datatype><value>" + attributeValue +
                        "</value></attribute></attrib_list></arg-xml></cmdArgs></inArgs>";

    cout << "In XML : " << inXml << endl << endl;
    StatusID sId;
    std::string outXml;
    ::ExecCommand(CMD_RSM_ATTR_SET, inXml, outXml, &sId);
    cout << "Out XML : " << outXml << endl;
    cout << "================================" << endl;
}

/**
* Implementation of SetAttributeStore() method
*/
void SampleEventListener::SetAttributeStore()
{
    cout << "================================" << endl;
    cout << "GetAttribute " << endl;
    
    std::string scannerID = "";
    cout << "Enter scanner ID : " << endl;
    cin >> scannerID;

    std::string attributeNumber = "";
    cout << "Enter attribute number : " << endl;
    cin >> attributeNumber;

    std::string dataType = "";
    cout << "Enter data type : " << endl;
    cin >> dataType;

    std::string attributeValue = "";
    cout << "Enter attribute value : " << endl;
    cin >> attributeValue;

    std::string inXml = "<inArgs><scannerID>" + 
                        scannerID +
                        "</scannerID><cmdArgs><arg-xml><attrib_list><attribute><id>" +
                        attributeNumber +
                        "</id><datatype>" + dataType +
                        "</datatype><value>" + attributeValue + "</value></attribute></attrib_list></arg-xml></cmdArgs></inArgs>";

    cout << "In XML : " << inXml << endl << endl;
    StatusID sId;
    std::string outXml;
    ::ExecCommand(CMD_RSM_ATTR_STORE, inXml, outXml, &sId); 
    cout << "Out XML : " << outXml << endl;
    cout << "================================" << endl;
}

void SampleEventListener::SetZeroWeight()
{
    std::string inXml = "<inArgs><scannerID>1</scannerID><cmdArgs><arg-xml><attrib_list><attribute><id>6019</id><datatype>X</datatype><value>0</value></attribute></attrib_list></arg-xml></cmdArgs></inArgs>";

    cout << "In XML : " << inXml << endl << endl;
    StatusID sId;
    std::string outXml;
    ::ExecCommand(CMD_RSM_ATTR_SET, inXml, outXml, &sId);
    cout << "Out XML : " << outXml << endl;
}

void SampleEventListener::Close()
{
    StatusID status;
    ::Close(0, &status);
}

void SampleEventListener::OnImageEvent( short eventType, int size, short imageFormat, char* sfimageData, int dataLength, std::string& pScannerData )
{
    cout << "OnImageEvent" << endl;
}

void SampleEventListener::OnVideoEvent( short eventType, int size, char* sfvideoData, int dataLength, std::string& pScannerData )
{
    cout << "OnVideoEvent" << endl;
}

void SampleEventListener::OnPNPEvent( short eventType, std::string ppnpData )
{
    string str;
    if (eventType == SCANNER_ATTACHED) 
    {
        str = ppnpData;
    } 
    else if (eventType == SCANNER_DETACHED) 
    { 
        str =	ppnpData;
    } 
    else 
    {
        str = " UNKNOWN PNP Event ";
    }
    cout << str << endl;
}

void SampleEventListener::OnCommandResponseEvent( short status, std::string& prspData )
{
    cout << endl << "Scanner data: " << prspData << endl;
    cout << "OnCommandResponseEvent" << endl;
    cout << prspData << endl;
}

void SampleEventListener::OnScannerNotification( short notificationType, std::string& pScannerData )
{
    cout << endl << "Scanner event data: " << pScannerData << endl;
    cout << "OnScannerNotification" << endl;
}

void SampleEventListener::OnIOEvent( short type, unsigned char data )
{
    cout << "OnIOEvent" << endl;
}

void SampleEventListener::OnScanRMDEvent( short eventType, std::string& prmdData )
{
    cout << "OnScanRMDEvent" << endl; cout << "Out XML " << endl;
    cout << prmdData << endl;
}

void SampleEventListener::OnDisconnect()
{
    cout << "OnDisconnect" << endl;
}

void SampleEventListener::OnBarcodeEvent(short int eventType, std::string & pscanData)
{
    cout << "Barcode Detected" << endl;
    cout << "Out XML" << endl;
    cout << pscanData << endl;
}

void SampleEventListener::RebootScanner()
{

}

void SampleEventListener::FirmwareUpdate()
{
    std::string inXml;
    std::string outXml;
    std::string datFilePath;
    StatusID sId;
    StatusID eStatus;
    std::string scannerID;
    std::string bulkOption;

    cout << "================================" << endl;
    std::cout << "FirmwareUpdate" << std::endl;
    std::cout << "Enter Scanner ID: " << std::endl;
    std::cin >> scannerID;
    std::cout << "Enter Firmware DAT file path: " << std::endl; std::cin >> datFilePath;
    std::cout << "Enter USB communication mode 1=hid, 2=bulk : ";
    std::cin >> bulkOption;

    inXml = "<inArgs><scannerID>" + scannerID + "</scannerID><cmdArgs><arg-string>" + datFilePath + "</arg-string><arg-int>" + bulkOption + "</arg-int></cmdArgs></inArgs>";
    cout << "InXML : " << inXml << endl;

    ::ExecCommand(CMD_DEVICE_UPDATE_FIRMWARE, inXml, outXml, &sId);

    cout << "================================" << endl;
    cout << outXml << endl;
}

void SampleEventListener::FirmwareUpdateFromPlugin()
{
    std::string inXml;
    std::string outXml;
    std::string pluginFilePath="";
    StatusID sId;
    StatusID eStatus;
    std::string scannerID;
    std::string bulkOption;

    cout << "================================" << endl;
    std::cout << "FirmwareUpdate From Plugin." << std::endl;
    std::cout << "Enter Scanner ID: " << std::endl;
    std::cin >> scannerID;
    std::cout << "Enter Firmware Pugin file path: " << std::endl;

    while ( pluginFilePath.size() < 4 )
    {
        std::getline(std::cin, pluginFilePath);
    }

    if ( !(pluginFilePath.substr(pluginFilePath.find_last_of(".")+ 1) == "SCNPLG") )
    {
        std::cout << "Please Enter a file with extension .SCNPLG." << std::endl;
        return;
    }

    std::cout << "Enter USB communication mode 1=hid, 2=bulk : ";
    std::cin >> bulkOption;

    inXml = "<inArgs><scannerID>" + scannerID + "</scannerID><cmdArgs><arg-string>" + pluginFilePath + "</arg-string><arg-int>" + bulkOption + "</arg-int></cmdArgs></inArgs>";
    cout << "InXML : " << inXml << endl;

    ::ExecCommand(CMD_DEVICE_UPDATE_FIRMWARE_FROM_PLUGIN, inXml, outXml, &sId);
    cout << "================================" << endl;
    cout << outXml << endl;
}

void SampleEventListener::StartNewFirmware()
{
    std::string inXml;
    std::string outXml;
    StatusID sId;
    StatusID eStatus;
    std::string scannerID;

    cout << "================================" << endl;
    std::cout << "Starting new firmware" << std::endl;
    std::cout << "Enter Scanner ID: " << std::endl;
    std::cin >> scannerID;
    std::cout << "Enter Firmware DAT file path: " << std::endl;

    inXml = "<inArgs><scannerID>" + scannerID + "</scannerID></inArgs>"; 
    cout << "InXML : " << inXml << endl;
    ::ExecCommand(CMD_START_NEW_FIRMWARE, inXml, outXml, &sId);

    cout << "================================" << endl;
    cout << outXml << endl;
}

void SampleEventListener::AbortFirmwareUpdate()
{
    std::string inXml;
    std::string outXml;
    StatusID sId;
    StatusID eStatus;
    std::string scannerID;

    cout << "================================" << endl;
    std::cout << "Abort Firmware Update" << std::endl;
    std::cout << "Enter Scanner ID: " << std::endl;
    std::cin >> scannerID;

    inXml = "<inArgs><scannerID>" + scannerID + "</scannerID></inArgs>"; cout << "InXML : " << inXml << endl;
    ::ExecCommand(CMD_DEVICE_ABORT_UPDATE_FIRMWARE, inXml, outXml, &sId);

    cout << "================================" << endl;
    cout << outXml << endl;
}

/**
*	Method to execute action attribute related commands.
*	added to v1.3.0 release.
*	@param opCode
*/
void SampleEventListener::ExecuteActionCommand(CmdOpcode opCode)
{
    std::string scannerID = "";
    std::string ledNumber = "";
    std::string beeperCode = ""; 
    std::string inXml;

    cout << "================================" << endl;

    switch (opCode)
    {
        case CMD_DEVICE_LED_ON: case CMD_DEVICE_LED_OFF:
        {
            cout << "Enter scanner ID: ";
            cin >> scannerID;
            cout << "Enter LED number: ";
            cin >> ledNumber;

            inXml = "<inArgs><scannerID>" + 
                    scannerID +
                    "</scannerID><cmdArgs><arg-int>" + ledNumber + "</arg-int></cmdArgs></inArgs>";
            break;
        }
        case CMD_DEVICE_BEEP_CONTROL:
        {
            cout << "Enter scanner ID: ";
            cin >> scannerID;
            cout << "Enter Beeper code: ";
            cin >> beeperCode;

            inXml = "<inArgs><scannerID>" + 
                    scannerID +
                    "</scannerID><cmdArgs><arg-int>" + beeperCode + "</arg-int></cmdArgs></inArgs>";
            break;
        }
        default:
        {
            cout << "Enter scanner ID: ";
            cin >> scannerID;

            inXml = "<inArgs><scannerID>" + scannerID + "</scannerID></inArgs>";
            break;
        }
    }

    cout << "InXML : " << inXml << endl;
    StatusID sId;
    std::string outXml;

    ::ExecCommand(opCode, inXml, outXml, &sId);

    cout << "Out XML" << outXml << endl;
    cout << "================================" << endl;
}

After implementation for the class IEventListenerXml, the main class can create an instance of the class SampleEventListener for the demonstration application. It is mandatory to implement IEventListenerXml class because it is an abstract class provided by zebra-scanner. Following is main.cpp for the sample application.

Main Method Implementation


/*
*	©2015 Symbol Technologies LLC. All rights reserved.
*/

#include "ConsoleMain.h"
#include "ConsoleSampleEventListener.h"

#include <stdlib.h>
//class LoggingContext;

bool hasAlreadyOpen = false; 

int ReturnChoice()
{
    cout << "======Select CoreScanner command====" << endl;
    cout << "=== 1. GetAttribute " << endl;
    cout << "=== 2. GetAllAttributes " << endl;
    cout << "=== 3. Get Scanners " << endl;
    cout << "=== 4. SetAttribute " << endl;
    cout << "=== 5. SetAttribute-Store " << endl;
    cout << "=== 6. Device LED ON or OFF " << endl;
    cout << "=== 7. Scanner Enable " << endl;
    cout << "=== 8. Scanner Disable " << endl;
    cout << "=== 9. Scanner Reboot " << endl;
    cout << "== 10. Refresh Device Topology" << endl;
    cout << "== 11. Action - Beeper command" << endl;
    cout << "== 12. AIM ON" << endl;
    cout << "== 13. AIM OFF" << endl;
    cout << "====================================" << endl;
    cout << "=== 0. Exit" << endl;
    cout << "= 100. Main Menu" << endl;
    cout << "====================================" << endl;
    cout << "Enter choice : " ;

    int choice = 0;
    cin >> choice;
    return choice;
}

int main(void)
{
    cout << "Zebra Scanner Sample Application" << endl; 
    cout << "====================================" << endl;

    SampleEventListener sel;

    sel.Open();
    sel.GetScanners();

    int choice = ReturnChoice(); 
    do {
        switch (choice) {
            case 1:
                sel.GetAttribute();
                break;
            case 2:
                sel.GetAllAttributes();
                break;
            case 3:
                sel.GetScanners();
                break;
            case 4:
                sel.SetAttribute();
                break;
            case 5:
                sel.SetAttributeStore();
                break;
            case 6:
                sel.ExecuteActionCommand(CMD_DEVICE_LED_ON);
                break;
            case 7:
                sel.ExecuteActionCommand(CMD_DEVICE_SCAN_ENABLE);
                break;
            case 8:
                sel.ExecuteActionCommand(CMD_DEVICE_SCAN_DISABLE);
                break;
            case 9:
                sel.ExecuteActionCommand(CMD_REBOOT_SCANNER);
                break;
            case 10:
                sel.DiscoverTunnelingDevice();
                break;
            case 11:
                sel.ExecuteActionCommand(CMD_DEVICE_BEEP_CONTROL);
                break;
            case 12:
                sel.ExecuteActionCommand(CMD_DEVICE_AIM_ON);
                break;
            case 13:
                sel.ExecuteActionCommand(CMD_DEVICE_AIM_OFF);
                break;
            case 100:
                cout << "====================================" << endl;
                break; 
            case 0: 
            default:
                break;
        }

        if(choice != 0)
        choice = ReturnChoice();

    } 
    while (choice);
    sel.Close();
    return 0;
}

Calling Open Command


void SampleEventListener::Open()
{
    StatusID status;
    ::Open(this, SCANNER_TYPE_ALL, &status);

    // register for all events.
    std::string inXml = "<inArgs><cmdArgs><arg-int>7</arg-int><arg-int>1,2,4,8,16,32,128</arg-int></cmdArgs></inArgs>";

    std::string outXml;
    ::ExecCommand(CMD_REGISTER_FOR_EVENTS, inXml, outXml, &status);
}

Calling Close Command


void SampleEventListener::Close()
{
    StatusID status;
    ::Close(0, &status);
}

Calling GetScanners Command


void SampleEventListener::GetScanners()
{
    unsigned short count;
    vector<unsigned int> list;
    string outXml;
    StatusID eStatus;

    ::GetScanners(&count, &list, outXml, &eStatus);

    cout << "GetScanners" << endl;
    cout << outXml << endl;
}

Calling ExecCommand Command and ExecCommandAsync Command


void SampleEventListener::GetAttribute()
{
    cout << "================================" << endl;
    cout << "GetAttribute " << endl;
    std::string scannerID = "";
    
    cout << "Enter Scanner ID" << endl;
    cin >> scannerID;
    
    cout << "Enter attribute number or comma separated attribute numbers : ";
    std::string attribute_number = "";
    cin >> attribute_number;

    std::string inXml = "<inArgs><scannerID>" + 
                        scannerID +
                        "</scannerID><cmdArgs><arg-xml><attrib_list>" +
                        attribute_number + 
                        "</attrib_list></arg-xml></cmdArgs></inArgs>";

    cout << "In XML : " << inXml << endl << endl;
    StatusID sId;
    std::string outXml;
    ::ExecCommand(CMD_RSM_ATTR_GET, inXml, outXml, &sId);

    cout << "Out XML : " << outXml << endl;
    cout << "================================" << endl;
}