I am trying to lock data to a NXP ICODE SLIX SL2S2002 tag type 5 (ISO 15693) to make it readonly by using the WRITE SINGLE BLOCKS command through the NfcV object in an ionic based app:
private readonly cmdISO15693 = {
READ_SINGLE_BLOCK: 0x20,
WRITE_SINGLE_BLOCK: 0x21,
LOCK_BLOCK: 0x22
};
this.nfc.connect('android.nfc.tech.NfcV', 500)
.then(
(data) => {
console.log('connected to', this.nfc.bytesToHexString(tag.id.reverse()).toUpperCase());
console.log('maxTransceiveLength: ', data);
const offset = 0; // offset of first block to read
const blocks = 8; // number of blocks to read
const bytesOfText: number[] = this.nfc.stringToBytes(text);
console.log('bytesOfText: ', bytesOfText);
console.log('hex string: ', this.nfc.bytesToHexString(bytesOfText));
let cmd = new Int8Array([
0x60, // 0: flags: addressed (= UID field present) or 0x90 0x60 0x40 0x20??
this.cmdISO15693.READ_SINGLE_BLOCK, // 1: command
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2-9 placeholder for tag UID
0x00 // 10: block number
// 0x00, 0x00, 0x00, 0x00 // 11- DATA
// ((blocks - 1) & 0x0ff) // number of blocks (-1 as 0x00 means one block)
]);
console.log('cmd: ', [...cmd]);
// tag uid in which direction
cmd = arrayCopy(tag.id.reverse(), 0, cmd, 2, 8);
console.log('cmd new: ', [...cmd]);
console.log('cmd buffer: ', cmd.buffer);
// arrayCopy(bytesOfText, 0, cmd, 11, 4);
this.nfc.transceive(cmd.buffer)
.then((res: ArrayBuffer) => {
console.log('transceive result:', res);
try {
console.log(Utf8ArrayToStr(res));
} catch (e) {
console.log('Utf8ArrayToStr not possible', e);
}
this.nfc.close().then(() => console.log('closed connection'))
.catch((err) => console.log('error closing', err));
})
.catch((err) => {
console.log('error while transceive', err);
this.displayToast('Error to write the RFID-Chips.', 'warning');
});
I don't know which bytes I have to pass for each block. I use the phoneGap-NFC plugin for ionic. Every time I try to set it readonly I get the answer 'Tag was lost' and by the READ_SINGLE_BLOCK command, too.
The Ionic method makeReadOnly() does not work because this is blocked by the tag. I have to set it by means of the bytes.
I dont know do I have to use Int8Array or Unit8Array, do I have to use reverse() on the tagId because the hex is mirrored or do I just pass the UID bytestring instead of the hexstring?
this.nfc.connect('android.nfc.tech.NfcV', 500)
.then(
async () => {
const blocks = 28; // 28 read by app TagInfo memory size: 28 blocks with 4 bytes per block
const cmdLock = this.cmdISO15693.OPTION_FLAG // 0 flag addressed
+ ' ' + this.cmdISO15693.LOCK_BLOCK // 1 command
+ ' ' + this.tagIdHexArr.join(' '); // 2-9 tag uid
let blockError = false;
let resTransceive: ArrayBuffer;
for (let i = 0; i < blocks; i++) {
const block = this.nfc.bytesToHexString([i]).toUpperCase();
const cmd = cmdLock + ' ' + block;
try {
resTransceive = await this.nfc.transceive(cmd);
try {
const view = new Uint8Array(resTransceive);
const resHex = this.nfc.bytesToHexString([...view]);
console.log(resHex);
} catch (e) {
console.log(e);
}
} catch (e) {
blockError = true;
return;
}
if (blockError) {
return;
}
}
if (blockError) {
this.notification.push(new Notification(NotificationType.ERROR, 'Fehler beim Setzen des Schreibschutzes.'));
}
this.nfc.close().then(() => console.log('Closed connection'))
.catch((err) => console.log('Error closing: ', err));
});
Fixed the problem!
Related
I am trying to print to Xprinter 365B 80mm thermal printer through Bluetooth on flutter (unsing an Android device - check multiple devices) and cannot get it to print.
The printer is working fine with native Android / IOS applications by xprintertech.com in both through bluetooth,
I have managed to connect/disconnect with the printer, but nothing happens, the app is notifying the command sent to the printer, sending any type of data, including text/image/esc codes.
No error massage, just not printing.
I have implemented numerous libraries from pub dev for Bluetooth printers like:
esc_pos_printer
print_bluetooth_thermal
printing
One assumption I have is that it is all about the configuration of the printing mode,
In one of the apps I found a way to select "Mode", it has 3 different modes:
Receipts Model
Label mode - TSC instruction
Label mode - CPCL instruction
My printer is printing only when working with TSC mode
I believe if I could set the mode in the code, I will be able to print, but I didn't figure out a way to do it.
Here are relevant parts of the code I am using (with print_bluetooth_thermal / esc_pos libraries from pub.dev)
Query Bluetooth devices:
Future<void> getBluetoothDevices() async {
final List<BluetoothInfo> listResult =
await PrintBluetoothThermal.pairedBluetooths;
if (listResult.isEmpty) {
_msg =
"There are no bluetooth devices linked, go to settings and link the printer";
} else {
_msg = "Touch an item in the list to connect";
}
setState(() {
items = listResult;
});
}
Connect with the printer
Future<void> connect(String mac) async {
setState(() {
_connecting = true;
});
final bool result =
await PrintBluetoothThermal.connect(macPrinterAddress: mac);
print("state connected $result");
if (result) connected = true;
setState(() {
_connecting = false;
});
}
print a full ticket:
Future<List<int>> testTicket() async {
List<int> bytes = [];
final profile = await CapabilityProfile.load();
final generator = Generator(PaperSize.mm58, profile);
bytes += generator.reset();
final ByteData data = await rootBundle.load('assets/myLogo.jpg');
final Uint8List bytesImg = data.buffer.asUint8List();
final image = img.decodeImage(bytesImg);
bytes += generator.image(image!);
bytes += generator.text(
'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ',
styles: const PosStyles());
bytes += generator.text('Special 1: ñÑ àÀ èÈ éÉ üÜ çÇ ôÔ',
styles: const PosStyles(codeTable: 'CP1252'));
bytes += generator.text(
'Special 2: blåbærgrød',
styles: const PosStyles(codeTable: 'CP1252'),
);
bytes += generator.text('Bold text', styles: const PosStyles(bold: true));
bytes +=
generator.text('Reverse text', styles: const PosStyles(reverse: true));
bytes += generator.text('Underlined text',
styles: const PosStyles(underline: true), linesAfter: 1);
bytes += generator.text('Align left',
styles: const PosStyles(align: PosAlign.left));
bytes += generator.text('Align center',
styles: const PosStyles(align: PosAlign.center));
bytes += generator.text('Align right',
styles: const PosStyles(align: PosAlign.right), linesAfter: 1);
bytes += generator.row([
PosColumn(
text: 'col3',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'col6',
width: 6,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'col3',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
]);
//barcode
final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
bytes += generator.barcode(Barcode.upcA(barData));
//QR code
bytes += generator.qrcode('example.com');
bytes += generator.text(
'Text size 50%',
styles: const PosStyles(
fontType: PosFontType.fontB,
),
);
bytes += generator.text(
'Text size 100%',
styles: const PosStyles(
fontType: PosFontType.fontA,
),
);
bytes += generator.text(
'Text size 200%',
styles: const PosStyles(
height: PosTextSize.size2,
width: PosTextSize.size2,
),
);
bytes += generator.feed(2);
//bytes += generator.cut();
return bytes;
}
print label(tsc) (i use xprinter for print ticket)
https://github.com/e3m-software/bluetooth_x_print
I am using xlsx library to convert input excel file into JSON and it works fine but when I test on android it won't trigger reader.onload function. Please suggest to me what's the correct library to use for android or what to need to change
const reader: FileReader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = (e: any) => {
console.log(e)
const binarystr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(binarystr, { type: 'binary' });
const wsname: string = wb.SheetNames[0];
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
const data = XLSX.utils.sheet_to_json(ws);
console.log(data);
this.fileData = data;
};
It doesn't print console.log(e), I've tried try-catch to catch the error but it didn't catch the error as well. Please let me know what's the issue and which library is best for Android as well as IOS
I solved it. Please see the code below, hope it will help someone
incomingfile(event){
this.file= event.target.files[0];
this.readXLSX(this.file);
}
readXLSX(file){
let fileReader = this.getFileReader(file);
fileReader.onload = (e: any) => {
/* create workbook */
const binarystr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(binarystr, { type: 'binary' });
/* selected the first sheet */
const wsname: string = wb.SheetNames[0];
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
/* save data */
const data = XLSX.utils.sheet_to_json(ws); // to get 2d array pass 2nd parameter as object {header: 1}
console.log(data); // Data will be logged in array format containing objects
this.zone.run(() => {
this.fileData = data;
});
};
}
getFileReader(file): FileReader {
const fileReader = new FileReader();
fileReader.readAsBinaryString(file);
const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"];
return zoneOriginalInstance || fileReader;
}
I have a button on the client side that is helping me test a simplified version of a backend function. For some reason, the client side (Logcat in Android Studio) is returning test button isUsernameAvailable: Success. result.data = 2000. When I look at the Firebase console, I see that the code reached _isUsernameAvailable REACHED THEN. However, I don't understand why the client received a 2000 instead of a 5. If it reached the aforementioned section, the line after that reads return 5. Why didn't my client receive a 5?
Client code:
testbutton.setOnClickListener() {
functions = Firebase.functions
var data = hashMapOf<String, Any>()
data["username"] = "ThisUsernameDoesntExist"
functions.getHttpsCallable("isUsernameAvailable")
.call(data)
.addOnSuccessListener {result ->
Log.e(tag, "test button isUsernameAvailable: Success. result.data = " + result.data.toString())
}
.addOnFailureListener {exception ->
Log.e(tag, "test button failure exception: $exception")
}
}
Cloud Function code:
//Check if username is available (callable from client)
exports.isUsernameAvailable = functions.https.onCall(async(data, context) => {
const username = data.username
await admin.firestore().collection('users').where('username', '==', username).limit(1).get()
.then(result => {
console.log('_isUsernameAvailable REACHED THEN ')
return 5
})
.catch(error => {
console.log('_isUsernameAvailable REACHED CATCH ')
return 6
})
return 2000
});
This answer partly explained what's happening on your code. To apply on your case, return 5 is just returning from the Firestore callback function and it does not cause your main function process to end.
A solution is to create a variable to assign the value whenever an event is met instead of returning it:
exports.isUsernameAvailable = functions.https.onCall(async(data, context) => {
const username = data.username
var returnCode = 0
await admin.firestore().collection('users').where('username', '==', username).limit(1).get()
.then(result => {
console.log('_isUsernameAvailable REACHED THEN ')
returnCode = 5
})
.catch(error => {
console.log('_isUsernameAvailable REACHED CATCH ')
returnCode = 6
})
if (returnCode != 2000){
return returnCode
}
return 2000
});
import CryptoJS from "react-native-crypto-js";
//encryption function used in react native code base
export const encryptValue = (text) => {
try {
const key = 'J4f9eO8ayjjEtamRBxSSmsDqXBele1zl'
const iv = CryptoJS.lib.WordArray.random(128 / 8)
let encrypted = CryptoJS.AES.encrypt(
text, key, {
keySize: 16,
iv: iv,
});
let v = { iv: iv.toString(), encryptedData: encrypted.toString() }
return v
} catch (error) {
console.log('error - ', error)
}
}
const crypto = require('crypto-js')
//decryption function used in server - node
export const decrypt = (data) => {
try {
let key = "J4f9eO8ayjjEtamRBxSSmsDqXBele1zl"
let decrypted = crypto.AES.decrypt(
data.encryptedData, key, {
keySize: 16,
iv: data.iv
}).toString(crypto.enc.Utf8)
console.log('decrypted - ', decrypted)
return decrypted.toString()
} catch (err) {
console.log('err', err)
}
}
Above code encryption and decryption works fine for android debug build and server side code. However, Android build generated in release.. generates encrypted text, but does not decrypt at server.
var CryptoJS = require('crypto-js');
export const encryptValue = (text) => {
try {
const key = 'AbcdefghtkmacweBczaOaDMaDCaf1wqs'
const iv = CryptoJS.lib.WordArray.random(128 / 8)
let encrypted = CryptoJS.AES.encrypt(
text, key, {
keySize: 16,
iv: iv,
});
let v = { iv: iv.toString(), encryptedData: encrypted.toString() }
return v
} catch (error) {
console.log('error - ', error)
}
}
export const decrypt = (data) => {
try {
let key = "AbcdefghtkmacweBczaOaDMaDCaf1wqs"
let decrypted = CryptoJS.AES.decrypt(
data.encryptedData, key, {
keySize: 16,
iv: data.iv
}).toString(CryptoJS.enc.Utf8)
return decrypted.toString()
} catch (err) {
console.log('err', err)
}
}
This solution worked for me.
I have create a hotspot/wifi-direct on an android device.And connect this wifi with iOS devices.
Now i want to create a iOS App which will be able to send and receive the data over wifi.
Is it possible if yes then how I can do this ?
yes it is possible, you can run local server on android, I recommend https://github.com/NanoHttpd/nanohttpd
then you must get ip address on iOS device to do http requests, there is c method to get route ip address
#include "IpHelper.h" // my header file
#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <string.h>
#include <arpa/inet.h>
#if TARGET_IPHONE_SIMULATOR
#include <net/route.h>
#else
#include "route.h"
#endif
#define CTL_NET 4 /* network, see socket.h */
#if defined(BSD) || defined(__APPLE__)
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
int getdefaultgateway(in_addr_t * addr)
{
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
NET_RT_FLAGS, RTF_GATEWAY};
size_t l;
char * buf, * p;
struct rt_msghdr * rt;
struct sockaddr * sa;
struct sockaddr * sa_tab[RTAX_MAX];
int i;
int r = -1;
if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
return -1;
}
if(l>0) {
buf = malloc(l);
if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
return -1;
}
for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
rt = (struct rt_msghdr *)p;
sa = (struct sockaddr *)(rt + 1);
for(i=0; i<RTAX_MAX; i++) {
if(rt->rtm_addrs & (1 << i)) {
sa_tab[i] = sa;
sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
} else {
sa_tab[i] = NULL;
}
}
if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
&& sa_tab[RTAX_DST]->sa_family == AF_INET
&& sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
char ifName[128];
if_indextoname(rt->rtm_index,ifName);
if(strcmp("en0",ifName)==0){
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
r = 0;
}
}
}
}
free(buf);
}
return r;
}
#endif
also you need to download and import route.h from apple open-sources from here https://opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/net/route.h
And at the end you are able to get local http url http://+'ip you get before'+ :'port of server you lunched on android'
so, now you are ready to do http request via ALamofire(or other) to local server.
EDIT 1:
I found this code in my old projects you can do data transfer with CocoaAsyncSocket, it is written in swift 3, I know that you want some code written on objC, but can not find such , sorry if i can't fully answer your question.
import CocoaAsyncSocket
import UIKit
enum TAG: Int {
case header = 1
case body = 2
}
class ViewController: UIViewController, NetServiceDelegate, NetServiceBrowserDelegate, GCDAsyncSocketDelegate {
var service : NetService!
var socket : GCDAsyncSocket!
var newSocket: GCDAsyncSocket!
var serviceBrowser = NetServiceBrowser()
var adresses: [Data]?
override func viewDidLoad() {
super.viewDidLoad()
startTalking()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func parseHeader(data: NSData) -> UInt {
var out: UInt = 0
data.getBytes(&out, length: MemoryLayout<UInt>.size)
return out
}
func handleResponseBody(data: NSData) {
if let message = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue) {
print(message)
}
}
func sendText() {
if let data = "aaaaa".data(using: String.Encoding.utf8) {
var header = data.count
let headerData = NSData(bytes: &header, length: MemoryLayout<UInt>.size)
self.socket.write(headerData as Data, withTimeout: -1.0, tag: TAG.header.rawValue)
self.socket.write(data, withTimeout: -1.0, tag: TAG.body.rawValue)
}
}
func startTalking () {
self.socket = GCDAsyncSocket(delegate: self, delegateQueue: DispatchQueue.main)
self.socket.isIPv4PreferredOverIPv6 = false
do {
try self.socket.connect(toHost: "localhost", onPort: UInt16(8080), withTimeout: -1)
} catch let err {
print(err)
}
}
/*
* Delegates of NSNetService
**/
func netServiceBrowser(_ browser: NetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) {
print(111)
}
func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) {
print("aaaaaaa")
}
func netServiceDidPublish(_ sender: NetService) {
print("Bonjour service published. domain: \(sender.domain), type: \(sender.type), name: \(sender.name), port: \(sender.port)")
}
func netService(_ sender: NetService, didNotPublish errorDict: [String : NSNumber]) {
print("Unable to create socket. domain: \(sender.domain), type: \(sender.type), name: \(sender.name), port: \(sender.port), Error \(errorDict)")
}
func netService(_ sender: NetService, didAcceptConnectionWith inputStream: InputStream, outputStream: OutputStream) {
print("4")
}
/*
* END OF Delegates
**/
/*
* Delegates of GCDAsyncSokcket
**/
func socketDidSecure(_ sock: GCDAsyncSocket) {
print("3")
}
func socket(_ sock: GCDAsyncSocket, didConnectToHost host: String, port: UInt16) {
print("connected")
self.socket.readData(toLength: UInt(MemoryLayout<UInt64>.size), withTimeout: -1, tag: 0)
}
func socket(_ sock: GCDAsyncSocket, didAcceptNewSocket newSocket: GCDAsyncSocket) {
print("Did accept new socket")
self.newSocket = newSocket
self.newSocket.readData(toLength: UInt(MemoryLayout<UInt64>.size), withTimeout: -1.0, tag: 0)
print("Connected to " + self.service.name)
}
func socketDidDisconnect(_ sock: GCDAsyncSocket, withError err: Error?) {
print("Socket disconnected: error \(err)")
if self.socket == socket {
// print("Disconnected from " + self.service.name)
}
}
func socket(_ sock: GCDAsyncSocket, didRead data: Data, withTag tag: Int) {
if data.count == MemoryLayout<UInt>.size {
let bodyLength: UInt = self.parseHeader(data: data as NSData)
sock.readData(toLength: bodyLength, withTimeout: -1, tag: TAG.body.rawValue)
} else {
self.handleResponseBody(data: data as NSData)
sock.readData(toLength: UInt(MemoryLayout<UInt>.size), withTimeout: -1, tag: TAG.header.rawValue)
}
}
func socket(_ sock: GCDAsyncSocket, didWriteDataWithTag tag: Int) {
print("Write data with tag of \(tag)")
}
func socket(_ sock: GCDAsyncSocket, didReceive trust: SecTrust, completionHandler: #escaping (Bool) -> Void) {
completionHandler(true)
}
/*
* END OF Delegates
**/
}
EDIT 2:
To parse ip to human readable string here is Objc method for it
+ (NSString *)getGatewayIP {
NSString *ipString = nil;
struct in_addr gatewayaddr;
int r = getdefaultgateway(&(gatewayaddr.s_addr));
if(r >= 0) {
ipString = [NSString stringWithFormat: #"%s",inet_ntoa(gatewayaddr)];
NSLog(#"default gateway : %#", ipString );
} else {
NSLog(#"getdefaultgateway() failed");
}
return ipString;
}