Socket ScanAPI Reference Manual

Date
4/29/2011
6/16/2011
9/16/2011
10/19/2011
11/04/2011
12/02/2011
01/06/2012
06/19/2012
09/19/2012
12/06/2012
01/15/2013
01/18/2013
02/25/2013
05/29/2013
ScanAPI Reference
History
Socket ScanAPI Reference
06/03/2013
06/3/2013
© 2013 Socket Mobile, Inc. 2/152
Socket ScanAPI Reference
6/2012 Document# 6410-00319 A
COPYRIGHT NOTICE
Copyright © 2012 Socket Mobile, Inc. All rights reserved.
Socket, the Socket logo, Battery Friendly, Socket Bluetooth Cordless Hand Scanner, and SocketScan are trademarks or registered trademarks of Socket Mobile, Inc. Bluetooth and the Bluetooth logos are registered trademarks owned by Bluetooth SIG, Inc., U.S.A. and licensed to Socket Mobile, Inc. All other brand and product names are trademarks of their respective holders.
The Socket Bluetooth Cordless Hand Scanner includes technology licensed under United States Patent Numbers 5,902,991, 7,429,000 B1 and D526,320 S.
Reproduction of the contents of this manual without the permission of Socket Mobile is expressly prohibited. Please be aware that the products described in this manual may change without notice. Feel free to contact Socket Mobile at:
Other than the above, Socket Mobile can assume no responsibility for anything resulting from the application of information contained in this manual.
Please refrain from any applications of the Socket Bluetooth Cordless Hand Scanner that are not described in this manual. Please refrain from disassembling the Bluetooth Cordless Hand Scanner. Disassembly of this device will void the product warranty.
You can track new product releases, software updates and technical bulletins by visiting the Socket Mobile website at:
http://www.socketmobile.com.
Socket Mobile, Inc.
39700 Eureka Drive, Newark, CA 94560-4808, USA +1-510-933-3000 USA/Canada Toll-free: 1-800-552-3300
http://www.socketmobile.com/contact
© 2013 Socket Mobile, Inc. 3/152
Socket ScanAPI Reference
Table of contents
COPYRIGHT NOTICE ................................................................................................................ 3
1 Scanner connection overview .................................................................................. 7
1.1 Scanner connection information ........................................................................... 7
2 ScanAPI Introduction .............................................................................................. 10
3 SoftScan Feature ....................................................................................................... 11
3.1 Licensing requirements ...................................................................................... 11
3.2 iOS requirements ................................................................................................ 11
3.3 Android requirements ......................................................................................... 12
4 Concept ..................................................................................................................... 12
4.1 ScanAPI object ................................................................................................... 12
4.2 Device object ...................................................................................................... 13
4.3 ScanObject ......................................................................................................... 13
4.4 Using ScanAPI ................................................................................................... 14
4.5 ScanAPI configuration ....................................................................................... 14
4.6 Get or Set a property ........................................................................................ 15
4.7 Example of sending a command ...................................................................... 16
4.8 Handling asynchronous events or completion events .................................. 25
4.9 Termination ...................................................................................................... 25
5 ScanAPI Helper (available for Java, C# and Objective C) ..................................... 26
5.1 Handling the ScanAPI Helper notifications .................................................... 26
5.2 Set ScanAPI Helper notification ....................................................................... 32
5.3 Open ScanAPI Helper ....................................................................................... 32
5.4 Close ScanAPI Helper ....................................................................................... 32
5.5 Scanner arrival .................................................................................................. 32
5.6 Decoded data notification ................................................................................ 33
5.7 Scanner removal ............................................................................................... 33
5.8 Is there a connected Scanner ........................................................................... 34
5.9 Get the list of scanners ..................................................................................... 34
5.10 No Device Connected item ........................................................................... 34
6 IDE Integration ........................................................................................................ 34
6.1 C/C++ Version ................................................................................................... 34
6.2 Java Version ....................................................................................................... 34
6.3 C# Version ......................................................................................................... 36
6.4 Objective C Xcode integration .......................................................................... 36
7 Recommendations ..................................................................................................... 37
7.1 General ............................................................................................................... 37
7.2 Android ............................................................................................................... 37
7.3 iOS ...................................................................................................................... 38
8 Device Connection and Disconnection process .................................................... 38
8.1 Initial Connection ............................................................................................. 38
8.2 Subsequent Connection .................................................................................... 39
8.3 Reconnection ..................................................................................................... 39
8.4 Disconnection.................................................................................................... 39
© 2013 Socket Mobile, Inc. 4/152
Socket ScanAPI Reference
8.5 Roaming ............................................................................................................. 40
8.6 Socket EZ Pair feature ...................................................................................... 40
9 API Functions ........................................................................................................... 41
9.1 Open Function ................................................................................................... 41
9.2 Close Function ................................................................................................... 46
9.3 Set Function....................................................................................................... 48
9.4 Get Function ...................................................................................................... 53
9.5 Wait Function .................................................................................................... 57
9.6 Release Function ............................................................................................... 60
10 ScanObject ............................................................................................................. 62
11 Asynchronous messages and events .................................................................. 63
11.1 Device Arrival ................................................................................................ 63
11.2 Device Removal ............................................................................................. 63
11.3 Terminate ...................................................................................................... 63
11.4 Set Complete .................................................................................................. 63
11.5 Get Complete ................................................................................................. 64
11.6 Events ............................................................................................................. 64
12 Introduction to Properties ................................................................................... 69
13 ScanAPI object properties ................................................................................... 70
13.1 Property kSktScanPropIdAbort ................................................................... 70
13.2 Property kSktScanPropIdVersion ................................................................ 71
13.3 Property kSktScanPropIdInterfaceVersion ................................................ 73
13.4 Property kSktScanPropIdConfiguration ..................................................... 74
13.5 Property kSktScanPropIdDataConfirmationMode ..................................... 76
13.6 Property kSktScanPropIdDataConfirmationAction ................................... 78
13.7 Property kSktScanPropIdMonitorMode ..................................................... 79
13.8 Property kSktScanPropIdSoftScanStatus ....................................................... 81
14 Device object properties ...................................................................................... 82
14.1 Property kSktScanPropIdVersionDevice .................................................... 82
14.2 Property kSktScanPropIdDeviceType ......................................................... 82
14.3 Property kSktScanPropIdDeviceSpecific .................................................... 84
14.4 Property kSktScanPropIdSymbologyDevice ............................................... 85
14.5 Property kSktScanPropIdTriggerDevice ..................................................... 87
14.6 Property kSktScanPropIdApplyConfigDevice ............................................ 88
14.7 Property kSktScanPropIdPreambleDevice ................................................. 89
14.8 Property kSktScanPropIdPostambleDevice ............................................... 89
14.9 Property kSktScanPropIdCapabilitiesDevice ............................................. 90
14.10 Property kSktScanPropIdChangeIdDevice ................................................. 92
14.11 Property kSktScanPropIdFriendlyNameDevice ......................................... 93
14.12 Property kSktScanPropIdSecurityModeDevice .......................................... 95
14.13 Property kSktScanPropIdPinCodeDevice ................................................... 96
14.14 Property kSktScanPropIdDeletePairingBondingDevice ............................ 97
14.15 Property kSktScanPropIdRestoreFactoryDefaultsDevice ......................... 98
14.16 Property kSktScanPropIdSetPowerOffDevice ............................................ 98
14.17 Property kSktScanPropIdButtonStatusDevice ........................................... 98
14.18 Property kSktScanPropIdSoundConfigDevice ............................................ 99
© 2013 Socket Mobile, Inc. 5/152
Socket ScanAPI Reference
14.19 Property kSktScanPropIdTimersDevice ................................................... 102
14.20 Property kSktScanPropIdLocalAcknowledgmentDevice ........................ 104
14.21 Property kSktScanPropIdDataConfirmationDevice ................................. 105
14.22 Property kSktScanPropIdBatteryLevelDevice.......................................... 106
14.23 Property kSktScanPropIdLocalDecodeActionDevice ............................... 107
14.24 Property kSktScanPropIdBluetoothAddress ............................................ 108
14.25 Property kSktScanPropIdStatisticCountersDevice .................................. 108
14.26 Property kSktScanPropIdRumbleConfigDevice ....................................... 111
14.27 Property kSktScanPropIdProfileConfigDevice ......................................... 113
14.28 Property kSktScanPropIdDisconnectDevice............................................. 114
14.29 Property kSktScanPropIdDataStoreDevice .............................................. 115
14.30 Property kSktScanPropIdNotificationsDevice.......................................... 116
14.31 Property kSktScanPropIdConnectReasonDevice ..................................... 117
14.32 Property kSktScanPropIdPowerStateDevice ............................................ 118
14.33 Property kSktScanPropIdStartUpRoleSPPDevice .................................... 119
14.34 Property kSktScanPropIdConnectionBeepConfigDevice ......................... 120
14.35 Property kSktScanPropIdFlashDevice ......................................................... 121
14.36 Property kSktScanPropIdOverlayViewDevice ............................................. 122
15 ScanAPI Error handling and definitions ........................................................... 124
15.1 Error codes .................................................................................................. 127
16 Symbologies Enumeration ................................................................................. 129
17 Data confirmation feature ................................................................................. 130
18 Sample handling asynchronous events of ScanAPI ......................................... 131
19 SktScanAPIOwnership (available for Java platforms) ..................................... 138
19.1 Constructor .................................................................................................. 139
19.2 register ......................................................................................................... 140
19.3 unregister .................................................................................................... 142
19.4 askForOwnership ........................................................................................ 143
19.5 claimOwnership .......................................................................................... 144
19.6 releaseOwnership ....................................................................................... 146
19.7 Notification onScanApiOwnershipChange ................................................ 147
20 SoftScan feature ...................................................................................................... 150
20.1 Usage ............................................................................................................ 150
20.2 iOS integration. ............................................................................................. 151
20.3 Android integration ....................................................................................... 152
© 2013 Socket Mobile, Inc. 6/152
Socket ScanAPI Reference
1 Scanner connection overview
This SDK is designed for use with the Socket CHS 7 series scanners on several OS platforms including Apple iOS, Android, RIM, Windows Desktop and Windows Mobile 6.x. The intended usage is to develop a native application that includes built in support for the Socket 7 series scanners. This SDK gives the full programmatic access to a connected 7 series scanner to customize the scanner Symbology and data support, manages scanner feedback messages and functions or modifies default scanner behavior.
Before beginning the process of implementing the ScanAPI into an application it is first recommended reading through this intro regarding the connection process of the scanner as this might answer many questions in regards to how an application communicates with the scanner.
1.1 Scanner connection information
The connection information below applies mainly to the Android, RIM and Windows operating systems.
For the iOS platform the connection is simplified based on the host iOS handling the connection. It is recommended to refer to the readme.rtf file from the ScanAPI SDK DMG install that is part of the ScanAPI iOS SDK..
1.1.1 Scanner HID mode
The CHS 7 series scanners are shipped by default in HID profile mode and will display the following friendly name:
For the 7Xi series:
Socket 7Xi [xxxxxx] (where x’s are the last 6 digits of the BD address of the
scanner) Or for the 7Ci/M/P series: Socket CHS [xxxxxx] In this mode the scanner functions as a standard HID keyboard device and can
be tested in this mode as if it is a keyboard. It will NOT work with an application using ScanAPI.
NOTE: if the scanner in HID mode is discovered and tested it may cause conflicts
© 2013 Socket Mobile, Inc. 7/152
Socket ScanAPI Reference
with discovering and using the scanner in SPP mode due to the fact that some devices will cache the name and service information of the device.
Socket recommends that the pairing information is removed by deleting or unpairing the device using the host device Bluetooth manager before connecting the scanner in a different mode.
1.1.2 SPP Mode for the SDK
The SPP Mode is the required mode for the Scanner to be able to communicate with an application using ScanAPI.
The SPP Mode has 2 configurations. One configuration called Acceptor, and another called Initiator.
In Acceptor configuration, the scanner is discoverable and connectable and basically waits for a host to connect. The scanner indicates that it is in this mode by a slow blue LED flashing.
In Initiator configuration, the scanner knows the Bluetooth address of the host to connect to. Each time the scanner is powered on in this configuration, it will try to connect to the host corresponding to the Bluetooth address it has in memory.
The scanner indicates that it is in this mode by a fast blue LED flashing. The scanner stays in this mode until it successfully connects to the host or after a 2minutes timeout occurs, which it will signal by doing a long beep. At this point the scanner can be powered off and on to retry to connect to the host.
1.1.3 Initial connection to iOS host or to any host for a 7Ci,M and P
series
The process of connecting a scanner to an iOS host device or a 7Ci, M and P scanner to any host device is the same and can be summarized to these simple steps. Step 1: The scanner must be in Acceptor mode. For an iOS device, the scanner can be in configured in Acceptor mode by
scanning a barcode that has the value of “#FNC IOS ACCEPTOR 000000000000#” for a 7Xi or “#FNB00F40002#” for a 7Ci.
For any other host Device (not iOS) the scanner can be configured in Acceptor mode by scanning a barcode that has the value of “#FNB00F40000#” for a 7 P,M or Ci series, or “#FNC SPP ACCEPTOR 0000000000#” for a 7Xi series scanner.
© 2013 Socket Mobile, Inc. 8/152
Socket ScanAPI Reference
The barcode can be a 2D barcode for a 7Xi scanner only. Step 2: Discover and pair the scanner from the host.
By using the Bluetooth settings of your host device, discover and pair the
scanner. If a PIN code is request use “0000” (4 zeros) and the pairing should
complete. For iOS host device this is the final step. The scanner can now be used by the application using ScanAPI.
Step 3: (For all hosts but iOS devices) Instruct the scanner to connect back to the host by using Socket EZ Pair application.
Once the scanner is configured correctly, it will always try to reconnect back to the host each time it is powered on or back in range.
1.1.4 Simplified connection process to any host but iOS devices
There is a simplified process that can be used when the host Bluetooth device address is known either by printing out barcode or by using 7xi with Socket EzPair.
This process isn’t possible for iOS device as there is no API to retrieve the iOS
Bluetooth address and the iOS devices won’t authorize a scanner to connect
and pair unless the Bluetooth Settings page is displayed on the screen. The following steps for 7Xi series is as simple as scanning a 2D barcode that has
the value: “#FNC SPP INITIATOR xxxxxxxxxxxx#” with xxxxxxxxxxxx replaced by
the host Bluetooth address, or by scanning out of the Socket EZ Pair screen the 2D barcode.
The same principle for 7 P, M and Ci series scanner, by scanning a Code 128
barcode that has the value: “#FNIxxxxxxxxxxxx#” with xxxxxxxxxxxx replaced by
the host Bluetooth address. NOTE the 7 P, M and Ci series scanner shoud be
first and only once set to SPP mode by scanning the “#FNB00F40000#” Code
128 barcode.
1.1.5 Connection Process integration
For the 7P, M and Ci series scanners there are two methods that canbe used to configure the scanner to be an initiator to the host device:
Method 1:
© 2013 Socket Mobile, Inc. 9/152
Socket ScanAPI Reference
Implement the 1D EZ Pair process in your app to select a pre discovered scanner and configure it to be an initiator to the host device. This process is explained in paragraph 8.6 Socket EZ Pair feature.
Method 2:
-Manually create an EZ Pair barcode with each host system Bluetooth address so that the 1D scanner simply needs to scan the barcode to configure it as an initiator to the host device
For the 7Xi series scanners you can just present the EZ pair barcode as part of your application setup process.
Either way once that part is done your app just needs to have ScanAPI initialized and waiting to receive the incoming connection of the scanner.
2 ScanAPI Introduction
ScanAPI delivers an application programming interface (API) to control and configure Socket Bluetooth Cordless Handled Scanners (CHS) connected to a host computer.
A ScanApi Helper component is provided for Objective C, C# and Java platforms to integrate more easily ScanAPI into an application. ScanAPI Helper handles the asynchronous events through callbacks, and gives an easy way to manipulate the asynchronous commands an application can send to a CHS by providing a callback mechanism that is invoked when the command response is received.
A CHS has severall properties that can be retrieved, modified or actioned. CHS properties can be by example a symbology state, its friendly name, or triggering a scan.
This API is asynchronous. The property operation is therefore a 2-step process. The application sends a property get or set command and if this is successful, a property get or set complete event is received with the CHS result of that property command.
At any time a CHS can send events to the host that are retrieved using the same mechanism as the completion of the property operation.
ScanAPI has only one entry point to receive these asynchronous events making it very easy to manage.
The other benefit of this asynchronous API is to be able to drive a scanner from a graphical user interface (GUI) application without danger of blocking the user interface while waiting for a lengthy operation to complete.
© 2013 Socket Mobile, Inc. 10/152
Socket ScanAPI Reference
3 SoftScan Feature
The SoftScan is a feature that makes the host device built-in camera acting as a barcode scanner. This feature is implemented using third-party technology and therefore the developer should comply to the third-party license agreement.
Currently the SoftScan feature is available on for iOS and Android based devices.
This feature is not activated by default. In order to activate it, the application should set the ScanAPI kSktScanPropIdSoftScanStatus to kSktScanEnableSoftScan. As soon as ScanAPI is initialized and SoftScan is enabled, a SoftScanner device arrival event is generated. A device removal event is generated when the SoftScan feature is disabled by using the same ScanAPI property with its value sets to kSktScanDisableSoftScan.
The SoftScanner doesn’t support all the properties described in this document and
returns a ESKT_NOTSUPPORTED error for them.
3.1 Licensing requirements
The third-party used for implementing the SoftScan feature is RedLaser from eBay corporation. The RedLaser requires a license to be purchased in order to offer unlimited scan. Without the license the SoftScanner is limited to 25 scans on a particular host. The License should be purchase on RedLaser portal, and the license file should be part of the application package.
3.2 iOS requirements
The ScanAPI library for iOS is split in to 2 versions; one that supports the SoftScan feature and one that doesn’t. In the version that doesn’t support the SoftScan feature the required frameworks are:
- externalAccessory.framework
- audioToolbox.framework
In the version that does support the SoftScan feature the extra frameworks required are:
- QuartzCore.framework,
- CoreVideo.framework,
- CoreMedia.framework,
- CoreGraphics.framework,
- AVFoundation.framework,
- OpenGLES.framework,
© 2013 Socket Mobile, Inc. 11/152
Socket ScanAPI Reference
- Security.framework,
- libiconv.dylib,
- libstdc++.dylib or libstd++6.0.9.dylib if you’re using OS6.x SDK.
3.3 Android requirements
The overlay view is a requirement for the SoftScanner in order to display the video output in the application. This is implemented through an Activity that must be added to the application manifest. This activity is defined as com.SocketMobile.ScanAPI.SoftScanActivity.
The manifest should also have the following permissions:
- android.permission.CAMERA,
- android.permission.ACCESS_NETWORK_STATE
- android.permission.INTERNET
A specific layout should be created that will be displayed as the overlay view of the SoftScan. This layout can have a white rectangle that is called a “View Finder” that is used as a scanning guide but also is use by the softscan scanner to improve the
barcode recognition in this region. The “View Finder” ID can be passed in the hash
table of the kSktScanPropIdOverlayViewDevice property. A flash button can be added as well and its ID should be also specified in the same hash table of the same property. If the flash feature is not available the SoftScan scanner will disable it automatically.
The RedLaser libraries must be added to the Android application. The simplest way for doing this is to copy the redlasersdk.jar and the armeabi/libredlaser.so in the
“libs” directory of the Android application. That “libs” subdirectory is automatically
taking in consideration by Android Development tools (ADT 18 or higher).
4 Concept
This API defines 3 main objects: ScanAPI object, Device object and ScanObject.
4.1 ScanAPI object
This object controls the API.
In order to use ScanAPI, this object must be opened first and this first open initializes ScanAPI. The handle returned from this open must be used for any subsequent ScanAPI operations.
All asynchronous events are received through this ScanAPI object.
© 2013 Socket Mobile, Inc. 12/152
Socket ScanAPI Reference
The ScanAPI object has few properties that can be retrieved or modified.
When an application is ready to use ScanAPI, it can open it by using the ScanAPI Open API with no device name in the parameter.
4.2 Device object
The Device object represents a CHS. In order to use and receive events from a CHS, its corresponding Device object must be opened.
The handle returned from opening a Device object is used by the application to retrieve or modify a particular property of the CHS.
ScanAPI notifies the application each time a Device Object is available by sending a Device Arrival event with a UUID identifying the Device Object. The application can open this particular Device Object by specifying this UUID in the ScanAPI open API.
If a CHS disconnects from the host, a Device Removal is sent by ScanAPI to the application to indicate that the matching Device Object is no longer valid and the application should close it if it has it opened.
4.3 ScanObject
The ScanObject is a data placeholder used for exchanging information between the application and the CHS or ScanAPI object.
A ScanObject holds 2 kinds of information: a property and a message.
When a ScanObject is sent from the application to ScanAPI, only the property information in ScanObject is relevant.
When a ScanObject is received from ScanAPI by the application, the message information is always relevant and depending on the message received the property information might be relevant.
ScanAPI creates a ScanObject each time it receives an asynchronous event, and in this case the application must release this ScanObject by calling a ScanAPI release API.
The application can create a ScanObject to send specific information to either a Device or ScanAPI. In this case the application is responsible for releasing the ScanObject correctly.
© 2013 Socket Mobile, Inc. 13/152
Socket ScanAPI Reference
4.4 Using ScanAPI
An application has two things to do in order to setup ScanAPI correctly. It needs first to open ScanAPI by specifying no name in the open parameter API, and then starts either a timer or a thread to consume the asynchronous events coming from ScanAPI.
When a CHS connects to the host, ScanAPI sends a Device Arrival event to the application through the application ScanAPI consumer logic.
The Device Arrival event contains an UUID identifying a Device Object that represents a CHS. The application can open the Device Object by specifying this UUID in the ScanAPI open function.
Once the Device Object is opened, the application can retrieve or modify the CHS properties by using the get property or set property API.
The get property and set property APIs are asynchronous. These APIs return success if the property has been sent correctly to the CHS. The property completion event is received in the application consumer.
If the CHS doesn't respond to a get or set property within the timeout period (about 5 seconds), for whatever reason, a matching property get or set complete event is generated with a timeout error.
Only one property can be sent at the time to the CHS. An error occurs if a property is sent prior the completion of the previous property operation.
ScanAPI sends a Device Removal event when a CHS disconnects from the host. The application should close the matching Device Object if it has it opened.
4.5 ScanAPI configuration
ScanAPI has one thread listening on a serial communication port. This configuration can be retrieved or modified by creating a ScanObject and setting its property to ScanAPI configuration property. The ScanObject can be sent to ScanAPI using the get property or set property API to respectively retrieve or modify this property.
Modifying the ScanAPI configuration will prompt the listener thread to restart. An error event is generated if the configuration is incorrect.
Each time the listener starts, a Listener Start event is generated.
© 2013 Socket Mobile, Inc. 14/152
Socket ScanAPI Reference
ScanAPI drops the connection to a CHS if it was connected during the process of changing the ScanAPI configuration.
Please refer to the ScanAPI object properties paragraph for more information.
4.6 Get or Set a property
The ScanAPI object and the Device object have both properties that can be retrieved or altered by using the get property or set property API.
The process of getting or setting a property is simple. A ScanObject holds a Property field. The application must create a ScanObject instance and fill its Property member according to the property of the object it would like to modify.
A property has an ID, a data type,data value and a context. They must be specified accordingly to the characteristics of the property that needs to be retrieved or modified. The context is a field an application can use for maintaining a context. This context is returned when a property set or get operation completes.
Once the property member of the ScanObject has been filled correctly, the application can call the get or set API with the reference of the object to which it wishes to retrieve or modify the property.
If the API returns success, the application can wait for the completion to be received through the wait API.
An application cannot send multiple properties to the same object before the previous set or get property operation has been fully completed. An error is generated during the Set or Get API call if the previous property of the same object hasn’t been completed yet.
The application receives the complete event through its ScanAPI consumer logic that uses the wait API with the ScanAPI object reference.
A ScanObject that is received from ScanAPI has always its message field filled out.
The property complete event is received in a ScanObject with a Message ID set to a Get Complete ID or Set Complete ID.
The Message has a result field that indicates if the completion of the get or set property has been successful or not. The Property member of the ScanObject contains the Property ID matching to the one that has been set, and in case of success, the data type and value are filled as expected.
© 2013 Socket Mobile, Inc. 15/152
Socket ScanAPI Reference
An important point is the fact that a property set or get can fail for many reasons, and some of them will require the application to retry the operation and some should just be taken into consideration. For example, if a property returns a REQUEST TIMEOUT error because the scanner is out of the range for a brief instant or busy receiving decoded data, having retry logic can fix this issue.
4.7 Example of sending a command
This section describes the steps for sending a command to a device.
Let’s imagine an application using ScanAPI has a button on its UI to trigger a scan.
For clarity purposes we assume the application correctly handles the connection of the scanner and has kept a handle to ScanAPI and to this scanner accessible.
The application has ScanAPI consumer logic that will receive the messages from ScanAPI. This consumer logic uses the wait API with the ScanAPI object reference that has been previously opened with the open API with NULL as device name.
The button handler creates a ScanObject, and fills the Property part with a property ID set to kSktScanPropIdTriggerDevice, a property type set to byte, and the property byte value set to kSktScanTriggerStart as explained in the paragraph 14.5 Property kSktScanPropIdTriggerDevice.
This button handler uses the set API to send this property to the device identified by its reference. If the return code of this API is successful, the button handler can then disable the trigger button indicating the trigger is in progress.
The application’s ScanAPI consumer logic that was waiting for ScanAPI messages by using the wait API should receive the Set Complete message with the property ID set to kSktScanPropIdTriggerDevice.
The result indicates if the trigger worked. At that point the device should have the aim light turned on and should be ready to scan and decode data. The application trigger button can then be enabled.
C++ Source code sample:
void CMyAppDlg::OnTriggerButton()
{ SKTRESULT Result=ESKT_NOERROR;
TSktScanObject ScanObj; memset(&ScanObj,0,sizeof(ScanObj));
© 2013 Socket Mobile, Inc. 16/152
Socket ScanAPI Reference
// initialize a ScanObject to // trigger the device ScanObj.Property.ID=kSktScanPropIdTriggerDevice; ScanObj.Property.Type=kSktScanPropTypeByte; ScanObj.Property.Byte=kSktScanTriggerStart;
// set the property with the // device handle Result=SktScanSet(m_hDevice,&ScanObj);
// check the Set result if(SKTSUCCESS(Result)) m_TriggerBtn.Enable(FALSE); else { // display an error message DisplayError(_T("Unable to trigger: %d"),Result); } }
SKTRESULT CMyAppDlg::Consume( IN SKTHANDLE hScanAPI, IN unsigned long ulTimeoutInMilliseconds, OUT BOOL* pbContinue) { SKTRESULT Result; TSktScanObject* pSktObject=NULL; Result=SktScanWait(hScanAPI,&pSktObject,ulTimeoutInMilliseconds); if(SKTSUCCESS(Result)) { if(Result!=ESKT_WAITTIMEOUT) { if(pSktObject) { switch(pSktObject->Msg.MsgID) { case kSktScanMsgIdDeviceArrival: Result=HandleDeviceArrival(pSktObject); break; case kSktScanMsgIdDeviceRemoval: Result=HandleDeviceRemoval(pSktObject); break; case kSktScanMsgIdTerminate: // we are done with ScanAPI, somebody // called SktSet with Abort MsgId if(pbContinue) *pbContinue=FALSE;// quit the for TraceInfo(_T("Receive a Terminate Msg, \
then shutdown the App receiving \ thread"));
break; case kSktScanMsgSetComplete: case kSktScanMsgGetComplete: Result=
HandleGetOrSetComplete(pSktObject);
break;
© 2013 Socket Mobile, Inc. 17/152
Socket ScanAPI Reference
case kSktScanMsgEvent: Result=
HandleAsynchronousEvent(pSktObject); break; default: { TraceInfo(_T("unknown Message ID \
received:0x%x"),
pSktObject->Msg.MsgID); } break; } // release the ScanObj we received in the wait SktScanRelease(hScanAPI,pSktObject); } } } return Result; }
// called from the ScanAPI consumer logic // that is using SktScanWait API
void CMyAppDlg::HandleGetOrSetComplete(
IN TSktScanObject* pScanObj ) { switch(pScanObj->Property.ID) { case kSktScanPropIdTrigger: // ungray out the trigger btn m_TriggerBtn.Enable(TRUE); if(!SKTSUCCESS(pScanObj->Msg.Result)) { DisplayError(_T("Failed to trigger: %d"), pScanObj->Msg.Result); } break; } }
C# source code:
public partial class Form1 : Form { private ISktScanApi _scanApi; private ISktScanDevice _device; public Form1() { InitializeComponent(); InitializeScanAPI(); }
© 2013 Socket Mobile, Inc. 18/152
Socket ScanAPI Reference
private void buttonTrigger_Click(object sender, EventArgs e) { // create a ScanObject instance ISktScanObject scanObj = SktClassFactory.createScanObject();
// Initialize a ScanObject to // Trigger the device scanObj.Property.ID = ISktScanProperty.propId.kSktScanPropIdTriggerDevice;
scanObj.Property.Type = ISktScanProperty.types.kSktScanPropTypeByte;
scanObj.Property.Byte = ISktScanProperty.values.trigger.kSktScanTriggerStart;
// set the property with the device // reference long result = _device.SetProperty(scanObj); if (SktScanErrors.SKTSUCCESS(result)) { buttonTrigger.Enabled = false; } else { // display an error message DisplayError("Unable to trigger: " + result); } }
// timer to checking and consuming ScanObject from ScanAPI private void timerScanAPIConsumer_Tick(object sender,
{ ISktScanObject scanObj=null;
// wait for ScanAPI ScanObject long result = _scanApi.WaitForScanObject(out scanObj, 10);
if (SktScanErrors.SKTSUCCESS(result)) { if (result != SktScanErrors.ESKT_WAITTIMEOUT) { int propId = scanObj.Msg.ID; switch (propId) { case ISktScanMsg.kSktScanMsgIdDeviceArrival: result = HandleDeviceArrival(scanObj); break; case ISktScanMsg.kSktScanMsgIdDeviceRemoval: result = HandleDeviceRemoval(scanObj); break; case ISktScanMsg.kSktScanMsgIdTerminate: // we are done with ScanAPI, somebody
EventArgs e
© 2013 Socket Mobile, Inc. 19/152
Socket ScanAPI Reference
// called Set with kSktScanPropIdAbort
// as Property ID
result = HandleTerminate(scanObj); break; case ISktScanMsg.kSktScanMsgGetComplete: case ISktScanMsg.kSktScanMsgSetComplete: result = HandleGetOrSetComplete(scanObj); break; case ISktScanMsg.kSktScanMsgEvent: result = HandleEvent(scanObj); break; } // release the ScanObject we received in the wait _scanApi.ReleaseScanObject(scanObj); } } }
private long HandleGetOrSetComplete(ISktScanObject scanObj) { long result = SktScanErrors.ESKT_NOERROR; ISktScanProperty property = scanObj.Property; switch (property.ID) {
case ISktScanProperty.propId.kSktScanPropIdTriggerDevice:
// ungrey out the trigger button buttonTrigger.Enabled = true; result = scanObj.Msg.Result; if (!SktScanErrors.SKTSUCCESS(result)) { DisplayError("Failed to trigger: " + result); } break; } return result; }
Java source code:
// handler for the Trigger button
class TriggerButtonHandler implements Runnable {
private ISktScanDevice _device=null; private ButtonField _button;
// constructor public TriggerButtonHandler( ISktScanDevice device, ButtonField button) { _device=device; _button=button; }
© 2013 Socket Mobile, Inc. 20/152
Socket ScanAPI Reference
public void run() {
// create a ScanObject instance ISktScanObject scanObj= SktClassFactory.createScanObject();
// Initialize a ScanObject to // Trigger the device ISktScanProperty property= scanObj.getProperty();
property.setID( ISktScanProperty.propId. kSktScanPropIdTriggerDevice);
property.setType( ISktScanProperty.types. kSktScanPropTypeByte);
property.setByte( ISktScanProperty.values.trigger. kSktScanTriggerStart);
// set the property with the device // reference long result=_device.SetProperty(scanObj);
// check the set result if(SktScanErrors.SKTSUCCESS(result)){ _button.setVisualState(VISUAL_STATE_DISABLED); } else { // display an error message DisplayError("Unable to trigger: "+result); } }
}
class ScanAPIConsumer extends TimerTask {
private ISktScanApi _scanApi; private AppRef _appRef; public ScanAPIConsumer(ISktScanApi scanApi,AppRef appRef) { _scanApi=scanApi; _appRef=appRef; }
public void run() { ISktScanObject[]scanObj=new ISktScanObject[1];
// wait for scanAPI ScanObject long result=_scanApi.WaitForScanObject(scanObj,10);
if(SktScanErrors.SKTSUCCESS(result)) { if(result!=SktScanErrors.ESKT_WAITTIMEOUT) {
© 2013 Socket Mobile, Inc. 21/152
Socket ScanAPI Reference
int propId= scanObj[0].getMessage().getID();
switch(propId){ case ISktScanMsg.kSktScanMsgIdDeviceArrival:
result= HandleDeviceArrival(scanObj[0]); break;
case ISktScanMsg.kSktScanMsgIdDeviceRemoval: result= HandleDeviceRemoval(scanObj[0]); break;
case ISktScanMsg.kSktScanMsgIdTerminate: // we are done with ScanAPI, somebody // called Set with Abort as MsgID result= HandleTerminate(scanObj[0]); break;
case ISktScanMsg.kSktScanMsgSetComplete: case ISktScanMsg.kSktScanMsgGetComplete: result= HandleGetOrSetComplete(scanObj[0]); break;
case ISktScanMsg.kSktScanMsgEvent: break; } // release the ScanObj we received in the wait _scanApi.ReleaseScanObject(scanObj[0]); } } }
// called from the ScanAPI consumer logic // that is using the wait API private long HandleGetOrSetComplete(ISktScanObject scanObj) { long result=SktScanErrors.ESKT_NOERROR; ISktScanProperty property=scanObj.getProperty(); switch(property.getID()){ case ISktScanProperty.propId. kSktScanPropIdTriggerDevice:
// ungray out the trigger btn _appRef.getTriggerBtn(). setVisualState(VISUAL_STATE_NORMAL);
result=scanObj.getMessage().getResult();
if(!SktScanErrors.SKTSUCCESS(result)){ DisplayError("Failed to trigger: "+result); } break; } return result; }
};
© 2013 Socket Mobile, Inc. 22/152
Socket ScanAPI Reference
Objective C source code:
-(IBAction)btnClicked:(id)sender{ id<ISktScanObject> scanObj=[SktClassFactory createScanObject]; [[scanObj Property] setID:kSktScanPropIdTriggerDevice]; [[scanObj Property]setType:kSktScanPropTypeByte]; [[scanObj Property]setByte:kSktScanTriggerStart]; [_rootViewController AddPropertyToSet:scanObj]; [_rootViewController SendFirstPropertyToSet]; }
// timer handler for consuming ScanObject from ScanAPI // if ScanAPI is not initialized this handler does nothing
-(void)onTimer{ if(_scanApiInitialized==true){ SKTRESULT result=[_scanapi WaitForScanObject:_scanObjectReceived TimeOut:0]; if (SKTSUCCESS(result)) { if (result!=ESKT_WAITTIMEOUT) { [self HandleScanObject:_scanObjectReceived]; [_scanapi ReleaseScanObject:_scanObjectReceived]; } } }
}
-(void) HandleScanObject:(id<ISktScanObject>)scanobject{
switch ([[scanobject Msg] MsgID]) {
case kSktScanMsgIdDeviceArrival:
[self HandleDeviceArrival:scanobject];
break;
case kSktScanMsgIdDeviceRemoval:
[self HandleDeviceRemoval:scanobject];
break;
case kSktScanMsgGetComplete:
[self DoGetComplete:scanobject];
break;
case kSktScanMsgSetComplete:
[self DoSetComplete:scanobject];
break;
case kSktScanMsgIdTerminate:
[_scanapi Close];
break;
case kSktScanMsgEvent:
[self HandleEvent:scanobject];
break;
default:
break;
}
}
-(void) DoGetComplete:(id<ISktScanObject>)scanObject{
SKTRESULT result=ESKT_NOERROR;
if (scanObject!=nil) {
© 2013 Socket Mobile, Inc. 23/152
Socket ScanAPI Reference
result=[[scanObject Msg]Result];
id<ISktScanProperty> property=[scanObject Property];
int ID=[property getID];
switch (ID) {
case kSktScanPropIdFriendlyNameDevice:
result=[self OnFriendlyName:scanObject];
break; case kSktScanPropIdBluetoothAddressDevice:
result=[self OnBtAddress:scanObject];
break; case kSktScanPropIdDeviceType:
result=[self OnScannerType:scanObject];
break; case kSktScanPropIdVersionDevice:
result=[self OnScannerFirmware:scanObject];
break; case kSktScanPropIdBatteryLevelDevice:
result=[self OnBatteryLevel:scanObject];
break; case kSktScanPropIdLocalDecodeActionDevice:
result=[self OnDecodeAction:scanObject];
break; case kSktScanPropIdCapabilitiesDevice:
result=[self OnCapabilitiesDevice:scanObject];
break; case kSktScanPropIdPostambleDevice:
result=[self OnPostambleDevice:scanObject];
break; case kSktScanPropIdSymbologyDevice:
result=[self OnSymbologyInfo:scanObject];
break; default: break;
}
// send a notification to update the progress bar
[[NSNotificationCenter defaultCenter] postNotificationName:@"msg_name" object:nil
userInfo:nil];
// and send the next property if there is one [self SendFirstPropertyFromList];
}
}
-(void) DoSetComplete:(id<ISktScanObject>)scanObject{
SKTRESULT result=ESKT_NOERROR;
if (scanObject!=nil) {
result=[[scanObject Msg]Result]; // send a notification to update the progress bar
[[NSNotificationCenter defaultCenter] postNotificationName:@"msg_name" object:nil
userInfo:nil];
_propertySetPending=NO;
// and send the next property if there is one [self SendFirstPropertyToSet];
}
}
© 2013 Socket Mobile, Inc. 24/152
Socket ScanAPI Reference
4.8 Handling asynchronous events or completion events
The ScanAPI object maintains a queue to receive asynchronous events and property operation complete events waitting for the application to consume them.
An application can retrieve these events by using the wait API. This API returns a ScanObject that will need to get released once the application is done with it by calling the release API.
The wait API returns immediately if there is an event in the queue, or it will wait the specified input parameter time if the queue is empty.
Completion events or asynchronous events can arrive at any time and in any order.
The recommended way for handling these events is to create a switch statement on the message ID received in the ScanObject.
There are only 6 possible message types: kSktScanMsgIdDeviceArrival, kSktScanMsgIdDeviceRemoval, kSktScanMsgIdTerminate, kSktScanMsgSetComplete, kSktScanMsgGetComplete and kSktScanMsgEvent.
For each of these message types a handler function can be called. Inside the handler function, the Result member of the Message received should be checked to be sure the process can continue.
The handler functions for the Set Property Complete or Get Property Complete event can also have a switch statement on the property ID. If the application used the context member of a property, the same context is then returned in the complete property.
The decoded data or the CHS buttons press status is received in the handler functions for the messages that have kSktScanMsgEvent as message ID.
4.9 Termination
When ScanAPI is no longer needed it can be terminated by setting an Abort property to the ScanAPI object.
At that point, if there are any devices open, ScanAPI sends a Removal event for each of the Device objects open, upon which the Device object should be closed by the application using the close API.
Once all the Device objects have been closed, ScanAPI sends a Terminate event and at that point it is safe to close ScanAPI.
© 2013 Socket Mobile, Inc. 25/152
Socket ScanAPI Reference
5 ScanAPI Helper (available for Java, C# and Objective C)
ScanAPI Helper has been created to facilitate the integration of ScanAPI into an application.
It is released as source code and therefore can be highly customizable for the need of your application. Some basic and common features are provided as sample on how to use ScanAPI.
NOTE: ScanAPI Helper is available for Java, C# and Objective C base code.
ScanAPI Helper maintains a list of commands to send to ScanAPI. Since properties cannot be sent before the completion of the previous one, it offers an easy way to queue the commands and provides a callback for each command completion. A command in this context is either a “Set Property” or a “Get Property”.
By example, if an application wants to retrieve the friendly name and the version of
the connected device, it uses ScanAPIHelper to do a “PostGetFriendlyName” and a “PostGetDeviceVersion” in a row, and for each of these functions, a callback is
passed, so when the Get Friendly Name completes, the callback is called and the application can refresh the UI with the new friendly name, and it follows the same logic when Get Device Version completes.
It retries sending the command up to 3 times if the command completion failed in time out error.
The Java version of ScanAPI Helper creates a timer task to consume asynchronous ScanObject coming from ScanAPI.
The C# and Objective C version of ScanAPI Helper does not create a timer, but instead provides a method, DoScanAPIReceive, that has to be called from a timer function or a thread.
The following paragraph describes the steps required for using ScanAPI Helper.
5.1 Handling the ScanAPI Helper notifications
Since most of the ScanAPI operations are asynchronous, it is very important to setup a way for handling notifications. ScanAPI Helper provides a ScanAPIHelperNotification interface or a ScanApiHelperDelegate protocol for Objective C environment that must be implemented in order to handle the various notifications correctly. Here is how Scanner Settings for Android is using this interface:
private ScanApiHelperNotification _scanApiHelperNotification=new ScanApiHelperNotification() {
/**
* receive a notification indicating ScanAPI has terminated, * then send an intent to finish the activity if it is still
© 2013 Socket Mobile, Inc. 26/152
Socket ScanAPI Reference
* running */
public void onScanApiTerminated() { _consumerTerminatedEvent.set(); if(_forceCloseUI){ Intent intent=new Intent(NOTIFY_CLOSE_ACTIVITY); sendBroadcast(intent); } } /**
* ScanAPI is now initialized, if there is an error * then ask the activity to display it */
public void onScanApiInitializeComplete(long result) { // if ScanAPI couldn't be initialized // then display an error if(!SktScanErrors.SKTSUCCESS(result)){ _scanApiOwnership.releaseOwnership(); String text=getString(R.string.failed_to_initialize_scanapi_error_)+result; Intent intent=new Intent(NOTIFY_ERROR_MESSAGE); intent.putExtra(EXTRA_ERROR_MESSAGE,text); } } /**
* ask the activity to display any asynchronous error * received from ScanAPI */
public void onError(long result) { String text=getString(R.string.scanapi_is_reporting_an_error_)+result; Intent intent=new Intent(NOTIFY_ERROR_MESSAGE); intent.putExtra(EXTRA_ERROR_MESSAGE,text); }
/**
* a device has disconnected. Update the UI accordingly */
public void onDeviceRemoval(DeviceInfo deviceRemoved) { _currentSelectedDevice=null; Intent intent=new Intent(NOTIFY_SCANNER_REMOVAL); intent.putExtra(EXTRA_DEVICENAME,deviceRemoved.getName()); sendBroadcast(intent); }
/**
* a device is connecting, update the UI accordingly */
public void onDeviceArrival(long result, DeviceInfo newDevice) { Intent intent=null; if(SktScanErrors.SKTSUCCESS(result)){ _currentSelectedDevice=newDevice; intent=new Intent(NOTIFY_SCANNER_ARRIVAL); intent.putExtra(EXTRA_DEVICENAME,newDevice.getName()); } else { String text=getString(R.string.error_)+result+ getString(R.string._during_device_arrival_notification); intent=new Intent(NOTIFY_ERROR_MESSAGE); intent.putExtra(EXTRA_ERROR_MESSAGE,text); } sendBroadcast(intent); } /**
* ScanAPI is delivering some decoded data * ask the activity to display them */
public void onDecodedData(DeviceInfo deviceInfo, ISktScanDecodedData decodedData) { Intent intent=new Intent(NOTIFY_DATA_ARRIVAL);
© 2013 Socket Mobile, Inc. 27/152
Socket ScanAPI Reference
intent.putExtra(EXTRA_SYMBOLOGY_NAME,decodedData.getSymbologyName()); intent.putExtra(EXTRA_DECODEDDATA,decodedData.getData()); sendBroadcast(intent); } /**
* an error occurs during the retrieval of ScanObject * from ScanAPI, this is critical error and only a restart * can fix this. */
public void onErrorRetrievingScanObject(long result) { Intent intent=new Intent(NOTIFY_ERROR_MESSAGE); String text="Error unable to retrieve ScanAPI message: "; text+="("+result+")"; text+="Please close this application and restart it"; intent.putExtra(EXTRA_ERROR_MESSAGE,text); sendBroadcast(intent); } };
The same notification handler but this time for the BlackBerry version of Scanner Settings:
private ScanApiHelperNotification _scanApiHelperNotification=new ScanApiHelperNotification() {
public void onScanApiTerminated() { System.exit(0); }
public void onScanApiInitializeComplete(long result) { // Display an error message indicating that ScanAPI failed // to initialize correctly _scanAPIInitError=result; if(SktScanErrors.SKTSUCCESS(result)){ synchronized(UiApplication.getEventLock()){ delete(_pleaseWaitWhileInitializingScanAPI); add(_displayDeviceslist); } } else{ UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() { synchronized(UiApplication.getEventLock()){ Status.show("Unable to initialize ScanAPI
("+_scanAPIInitError+")");
_ScanApi=null; delete(_pleaseWaitWhileInitializingScanAPI); add(new LabelField("Please restart this
application",Field.FIELD_HCENTER));
} } }); } }
public void onErrorRetrievingScanObject(long result) { // TODO Auto-generated method stub
}
public void onError(long result) { // TODO Auto-generated method stub
}
public void onDeviceRemoval(DeviceInfo deviceRemoved) { synchronized(UiApplication.getEventLock()){
© 2013 Socket Mobile, Inc. 28/152
Socket ScanAPI Reference
deviceRemoved.CloseScreenButThis(_this); int size=_scanApiHelper.getDevicesList().size(); _displayDeviceslist.setSize(size); } _deviceconnected=false; }
public void onDeviceArrival(long result, DeviceInfo newDevice) { synchronized(UiApplication.getEventLock()){ int size=_scanApiHelper.getDevicesList().size(); _displayDeviceslist.setSize(size); } _deviceconnected=true; }
public void onDecodedData(DeviceInfo deviceInfo, ISktScanDecodedData decodedData) { if(_scanwindow!=null)
_scanwindow.DoScannedData(decodedData.getData(),decodedData.getSymbologyName()); }
};
Same notification handler but this time from Objective C version of Scanner Settings:
© 2013 Socket Mobile, Inc. 29/152
Socket ScanAPI Reference
© 2013 Socket Mobile, Inc. 30/152
Loading...
+ 122 hidden pages