I'm trying to start working with ESC/P commands with a label printer Brother TD-4000.
I have tested the properly software of the printer, P-touch Editor 5.1, and I can made several labels, the printer works well but, when I'm tried to make my own labels from Java code, the printer doesn't work at all, it doesn't response.
I've have worked with other label printers with EZPL and I hadn't any problems with this method.
What do I can try now?
My code is very simple, here you are:
public class PrintESC_P {
public static void main(String[] args) {
PrintService printService = null;
String printerName = "Brother TD-4000";
HashAttributeSet attributeSet = new HashAttributeSet();
attributeSet.add(new PrinterName(printerName, null));
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, attributeSet);
if (services.length == 0) {
throw new IllegalArgumentException("Printer not found.");
} else if (services.length > 1) {
System.out.println("Found more than one printer. Only the first printer will be used.");
}
printService = services[0];
System.out.println("Printer found: "+printService.getName());
try {
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
String _ESC_P_Code = "ESC i a 00h\r\n" +
"ESC #\r\n" +
"ESC i L 01h\r\n" +
"ESC ( C 02h 00h FCh 02h\r\n" +
"ESC $ 2Bh 00h\r\n" +
"ESC ( V 02h 00h 6Dh 01h\r\n" +
"ESC k 0bh\r\n" +
"ESC X 00h 64h 00h\r\n" +
"PRINTER TEST\r\n" +
"ESC i C\r\n" +
"FF\r\n";
SimpleDoc doc = new SimpleDoc(_ESC_P_Code.getBytes(), flavor, null);
DocPrintJob job = printService.createPrintJob();
job.print(doc, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thanks in advance!
Finally, I had to change the way to send the code to the printer.
Instead of a String I had to send the code in a byte array in hexadecimal format.
Now the printer works well and recognizes the commands.
I believe your problem is you are including spaces in the string, which is not allowed in ESC/P language.
Instead of (incorrect) string:
String _ESC_P_Code = "ESC i a 00h\r\n"
You must write:
String _ESC_P_Code = "\x1Bia\x00" // that is 4 bytes: 0x1B, 0x69, 0x61, 0x00
You do not have to follow the way I wrote the string, just make sure you are sending raw data.
I solved my problems printing in ESC/P by first debugging the program and viewing the string sent to the printer in binary form, and manually checking if there are no extra bytes - printer will not accept any such errors.
Related
Context
I've got a pcap file containing a bunch of beacon frames (in other words, I put my Wi-Fi adapter in monitor mode, started capturing while filtering on "wlan.fc.type_subtype == 0x08", and saved that).
Now, I want to, somehow, display specific fields of these packets. Among others:
SSID (wlan_mgt.ssid)
MAC (wlan.ta)
Current channel (wlan_mgt.ds.current_channel)
Group Cipher (wlan_mgt.rsn.gcs.type)
PairWise Ciphers (wlan_mgt.rsn.pcs.type)
Authentication Suite (wlan_mgt.rsn.akms.type)
I don't really care about the representation: plain text, xml, json, csv, X. I'm fine with it. I just don't want more data than I really need and the output needs to be meaningful to the human (wireshark newb) eye.
Eventually, I also want to filter the pcap to get a unique set and count the occurrences (some "|sort|uniq -c" will do), but let's not go there for now.
My solution so far
The first step could be, for example:
$ tshark -r capture.pcap -c 1 -T fields -e wlan_mgt.ssid -e wlan.ta -e wlan_mgt.ds.current_channel -e wlan_mgt.rsn.gcs.type -e wlan_mgt.rsn.pcs.type -e wlan_mgt.rsn.akms.type
MySSID XX:XX:XX:XX:XX:XX 2 4 4 2
After (manually) matching the numbers to their textual meaning, you get this:
SSID = MySSID
MAC (wlan.ta) = XX:XX:XX:XX:XX:XX
Current channel = 2
Group Cipher = Group Cipher Suite type: AES (CCM) (4)
PairWise Ciphers = Pairwise Cipher Suite type: AES (CCM) (4)
Authentication Suite = Auth Key Management (AKM) type: PSK (2)
This is what I'm looking for. But, as stated, I have to do it manually, which is not an option.
Question
Above you can see my current approach to the said goal. By doing
tshark -r capture.pcap -c 1 -T pdml
I get, for example (cutout):
<field name="wlan_mgt.rsn.pcs.list" showname="Pairwise Cipher Suite List 00-0f-ac (Ieee8021) AES (CCM)" size="4" pos="112" show="" value="">
<field name="wlan_mgt.rsn.pcs" showname="Pairwise Cipher Suite: 00-0f-ac (Ieee8021) AES (CCM)" size="4" pos="112" show="1027076" value="000fac04">
<field name="wlan_mgt.rsn.pcs.oui" showname="Pairwise Cipher Suite OUI: 00-0f-ac (Ieee8021)" size="3" pos="112" show="4012" value="000fac"/>
<field name="wlan_mgt.rsn.pcs.type" showname="Pairwise Cipher Suite type: AES (CCM) (4)" size="1" pos="115" show="4" value="04"/>
</field>
</field>
..., which tells me that tshark does have the information I need (in the form of the "showname" attribute).
Apparently, when working with "-T fields -e X", tshark outputs the value that's in the "show" attribute". I feel like I want what's behind the "showname" attribute. Unfortunately, after annoying google for a while I still don't know how or if this is even possible.
I'm also open to radically different ideas, but the main takeaway is that I can't part from the pcap file (which rules out iwlist, kismet, etc). I also preferably don't start writing search and replace rules to replace the meaningless numbers with their textual representation. I hope to solve it in cleaner way.
I kept messing with tshark for a while, until I decided that it couldn't be done. A little bit of programming using the amazing C++ library libtins got me where I needed to be.
The source is down below. Enjoy :)
#include <tins/tins.h>
#include <algorithm>
#include <iostream>
#include <map>
#include <string>
using namespace Tins;
using namespace std;
/*
* Container class for the data that is retrieved from the beacon.
*/
class Unit {
public:
/*
* Constructor. Parses the Dot11Beacon object and takes all the necessary
* data from it.
*/
Unit(Dot11Beacon& beacon);
Unit() = default;
unsigned getCount();
void incrementCount();
/*
* Prints this object onto the command line, in CSV format
*/
void print();
private:
string ssid;
string bssid;
unsigned channel;
unsigned count;
string gcs; // Group Cipher Suite
string pcs; // Pairwise Cipher Suite
string akm; // Authentication suite
/*
* Returns a string representation of a RSNInformation::CypherSuites enum value
*/
string type_to_string(const RSNInformation::CypherSuites& type);
/*
* Returns a string representation of a RSNInformation::AKMSuites enum value
*/
string type_to_string(const RSNInformation::AKMSuites& type);
};
Unit::Unit(Dot11Beacon& beacon) :
count {1} /* When this unit is created, it has been seen exactly once */ {
ssid = beacon.ssid();
bssid = beacon.addr3().to_string();
channel = unsigned(beacon.ds_parameter_set());
RSNInformation rsn;
for(const auto &opt : beacon.options()) {
if (opt.option() == Dot11::RSN) {
rsn = beacon.rsn_information();
// Put all authentication suite types in a string
const RSNInformation::akm_type& akmTypeList = rsn.akm_cyphers();
for (const auto& akmIt : akmTypeList) {
if (akm.size() == 0)
akm += type_to_string(akmIt);
else
akm += ";" + type_to_string(akmIt);
}
// Put all group cipher types in a string
const RSNInformation::CypherSuites& gcsType = rsn.group_suite();
gcs = type_to_string(gcsType);
// Put all pairwise ciphers in a string
const RSNInformation::cyphers_type& pcsTypeList = rsn.pairwise_cyphers();
for (const auto& pcsIt : pcsTypeList) {
if (pcs.size() == 0)
pcs += type_to_string(pcsIt);
else
pcs += ";" + type_to_string(pcsIt);
}
}
}
}
unsigned Unit::getCount() {
return count;
}
void Unit::incrementCount() {
count += 1;
}
void Unit::print() {
string ssid_to_print;
if (ssid.length() == 0) {
ssid_to_print = "<ZERO_LENGTH>";
} else if (!isprint(ssid[0])) {
ssid_to_print = to_string(static_cast<int>(ssid[0]));
} else {
ssid_to_print = ssid;
}
if (find(ssid_to_print.begin(), ssid_to_print.end(), ',') != ssid_to_print.end()) {
ssid_to_print = "\"" + ssid_to_print + "\"";
}
cout << ssid_to_print << ","
<< bssid << ","
<< to_string(channel) << ","
<< to_string(count) << ","
<< gcs << ","
<< pcs << ","
<< akm << endl;
}
string Unit::type_to_string(const RSNInformation::CypherSuites& type) {
switch (type) {
case RSNInformation::CypherSuites::CCMP:
return "CCMP";
break;
case RSNInformation::CypherSuites::TKIP:
return "TKIP";
break;
case RSNInformation::CypherSuites::WEP_104:
return "WEP_104";
break;
case RSNInformation::CypherSuites::WEP_40:
return "WEP_40";
break;
}
}
string Unit::type_to_string(const RSNInformation::AKMSuites& type) {
switch (type) {
case RSNInformation::AKMSuites::PMKSA:
return "PMKSA";
break;
case RSNInformation::AKMSuites::PSK:
return "PSK";
break;
}
}
/*
* Class that reads the pcap, keeps track of the units and writes out one
* beacon frame in pcap format for each unique AP it finds. This file is called
* "unique_beacons.pcap"
*/
class PCAPParser {
public:
/*
* Constructor. It takes the exact parameters that it will pas on to its
* FileSniffer object (a FileSniffer is actually just a file reader).
*/
PCAPParser(const string& pcapFilename, const string& filter);
/*
* Start reading the file.
*/
bool run();
/*
* Print CSV header and ask all of our collected Unit objects to print themselves
*/
void print();
private:
FileSniffer sniffer;
PacketWriter writer;
map<string, Unit> apMap; // stands for Access Point Map
bool handler(PDU&);
};
PCAPParser::PCAPParser(const string& pcapFilename, const string& filter) :
sniffer {pcapFilename, filter},
writer {"unique_beacons.pcap", PacketWriter::RADIOTAP} {
for (auto it = apMap.begin(); it != apMap.end(); it++) {
it->second.print();
}
}
bool PCAPParser::run() {
sniffer.sniff_loop( [this] (PDU& pdu) { return (bool) this->handler (pdu); } );
return true;
}
bool PCAPParser::handler(PDU& pdu) {
Dot11Beacon& beacon = pdu.rfind_pdu<Dot11Beacon>();
// An ESSID may span multiple BSSID's. Also, it's nice to keep track of what
// channels an AP has been on. Therefore, the combination of SSID, BSSID and
// channel is considered key.
const string& ssid = beacon.ssid();
const string& mac = beacon.addr3().to_string();
const unsigned channel = unsigned(beacon.ds_parameter_set());
const string key = ssid + mac + to_string(channel);
if (apMap.find(key) == apMap.end()) { // we've got a new one
Unit unit(beacon);
apMap[key] = unit;
writer.write(pdu);
} else {
apMap[key].incrementCount();
}
return true;
}
void PCAPParser::print() {
// Print the headers for the CSV output
cout << "SSID,BSSID,Current_channel,Count,Group_Cipher,Pairwise_Ciphers,Authentication_Suite" << endl;
// Ask each of the units to print themselves for the CSV output
for (auto it = apMap.begin(); it != apMap.end(); it++) {
it->second.print();
}
}
int main(int argc, char *argv[]) {
if(argc != 2) {
std::cout << "Usage: " << *argv << " <PCAP_FILE>\n";
return 1;
}
PCAPParser pcapParser(argv[1], "wlan type mgt subtype beacon");
pcapParser.run();
pcapParser.print();
}
Compile with:
g++ pcapreader.cpp -o pcapreader -O3 -std=c++11 -lpthread -ltins
The output is:
$ ./pcapreader capture.pcap
SSID,BSSID,Current_channel,Count,Group_Cipher, Pairwise_Ciphers,Authentication_Suite
MyWiFi,XX:XX:XX:XX:XX:XX,13,2,TKIP,TKIP;CCMP,PSK
...
...
Final note: if you open unique_beacons.pcap, you may find a lot of [Malformed Packet]. Apparently, a frame can still be successfully parsed if some of the tagged parameters are received wrongly. You could try to modify the code so that it only writes out frames to the pcap file that are completely intact.
tshark will print the "showname" attribute for text output only. You can control the output with a custom formatted by setting the gui.column.format preference. To print just SSID columns:
$ tshark -r capture.pcap -c 1 -T text -o 'gui.column.format:"SSID","%Cus:wlan.ssid"'
I am working on a project where I needed Text to speech conversion. I Downloaded this FreeTTS 1.2 and to get familiar with the working I started making a simple spell bee program where the words will be spoken by the application and you have to spell it correctly. But I'm facing problems with functions like the voice is same irrespective of the changes I make. Like the initially the code I found had following parameters in the Voice() constructor
Voice kevin = new Voice("kevin",
Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);
but then I changed it to
Voice kevin = new Voice("Different1",
Voice.GENDER_FEMALE, Voice.AGE_MIDDLE_ADULT, null);
and still the voice is same. There is a speech.properties file which came with FreeTTS and to run the code I have to paste that file in my home folder. I have searched a lot of links to solve this even checked the Javadocs for JSAPI and FreeTTS. The only thing I got in common was something called MBrola. I don't what this is but when I run the code, the console also gives a message related to it.
System property "mbrola.base" is undefined. Will not use MBROLA voices.
Here's is the whole code:
package game;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Locale;
import javax.speech.Central;
import javax.speech.synthesis.SpeakableAdapter;
import javax.speech.synthesis.SpeakableEvent;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;
public class MixedVoices {
private final static void usage() {
System.out.println("MixedVoices [-showEvents] [-showPropertyChanges]");
}
/**
* Returns a "no synthesizer" message, and asks
* the user to check if the "speech.properties" file is
* at <code>user.home</code> or <code>java.home/lib</code>.
*
* #return a no synthesizer message
*/
static private String noSynthesizerMessage(String synthesizer)
{
String message =
"Cannot find " + synthesizer + ".\n" +
"This may be the result of any number of problems. It's\n" +
"typically due to a missing \"speech.properties\" file that\n" +
"should be at either of these locations: \n\n";
message += "user.home : " + System.getProperty("user.home") + "\n";
message += "java.home/lib: " + System.getProperty("java.home") +
File.separator + "lib\n\n" +
"Another cause of this problem might be corrupt or missing\n" +
"voice jar files in the freetts lib directory. This problem\n" +
"also sometimes arises when the freetts.jar file is corrupt\n" +
"or missing. Sorry about that. Please check for these\n" +
"various conditions and then try again.\n";
return message;
}
public static void main(String[] argv)
{
boolean showEvents = false;
boolean showPropertyChanges = false;
for (int i = 0; i < argv.length; i++)
{
if (argv[i].equals("-showEvents")) {
showEvents = true;
} else if (argv[i].equals("-showPropertyChanges")) {
showPropertyChanges = true;
} else {
usage();
System.exit(0);
}
}
System.out.println(" ** Mixed Voices - JSAPI Demonstration program **");
/* kevin in an 8khz general domain diphone voice
*/
Voice kevin = new Voice("kevin",
Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);
/* kevin16 in a 16khz general domain diphone voice
*/
Voice kevinHQ = new Voice("kevin16",
Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);
try {
/* Find a synthesizer that has the general domain voice
* we are looking for. NOTE: this uses the Central class
* of JSAPI to find a Synthesizer. The Central class
* expects to find a speech.properties file in user.home
* or java.home/lib.
*
* If your situation doesn't allow you to set up a
* speech.properties file, you can circumvent the Central
* class and do a very non-JSAPI thing by talking to
* FreeTTSEngineCentral directly. See the WebStartClock
* demo for an example of how to do this.
*/
SynthesizerModeDesc generalDesc = new SynthesizerModeDesc(
null, // engine name
"general", // mode name
Locale.US, // locale
null, // running
null); // voice
final Synthesizer synthesizer1 =
Central.createSynthesizer(generalDesc);
if (synthesizer1 == null) {
System.err.println(
noSynthesizerMessage("general domain synthesizer"));
System.exit(1);
}
/* Find a synthesizer that has the time domain voice.
*/
SynthesizerModeDesc limitedDesc = new SynthesizerModeDesc(
null, // engine name
"time", // mode name
Locale.US, // locale
null, // running
null); // voice
final Synthesizer synthesizer2 =
Central.createSynthesizer(limitedDesc);
if (synthesizer2 == null) {
System.err.println(
noSynthesizerMessage("time domain synthesizer"));
System.exit(1);
}
System.out.print(" Allocating synthesizers...");
synthesizer1.allocate();
synthesizer2.allocate();
/* get general domain synthesizer ready to speak
*/
System.out.print("Loading voices...");
synthesizer1.getSynthesizerProperties().setVoice(kevinHQ);
synthesizer1.getSynthesizerProperties().setVoice(kevin);
if (showPropertyChanges) {
synthesizer1.getSynthesizerProperties().addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(
PropertyChangeEvent pce) {
if (pce.getNewValue() instanceof Voice) {
String newVoice =
((Voice) pce.getNewValue()).getName();
System.out.println(
" PCE Voice changed to " + newVoice);
}
else {
System.out.println(
" PCE " + pce.getPropertyName()
+ " changed from "
+ pce.getOldValue() + " to " +
pce.getNewValue() + ".");
}
}
});
}
if (showEvents) {
synthesizer1.addSpeakableListener(
new SpeakableAdapter() {
public void markerReached(SpeakableEvent e) {
dumpEvent(e);
}
public void speakableCancelled(SpeakableEvent e) {
dumpEvent(e);
}
public void speakableEnded(SpeakableEvent e) {
dumpEvent(e);
}
public void speakablePaused(SpeakableEvent e) {
dumpEvent(e);
}
public void speakableResumed(SpeakableEvent e) {
dumpEvent(e);
}
public void speakableStarted(SpeakableEvent e) {
dumpEvent(e);
}
public void topOfQueue(SpeakableEvent e) {
dumpEvent(e);
}
public void wordStarted(SpeakableEvent e) {
dumpEvent(e);
}
private void dumpEvent(SpeakableEvent e) {
System.out.println(" EVT: " + e.paramString()
+ " source: " + e.getSource());
}
});
}
System.out.println("And here we go!");
synthesizer1.resume();
synthesizer2.resume();
// speak the "Hello world" string
synthesizer1.speakPlainText("Hello! My name is Kevin.", null);
synthesizer1.speakPlainText("I am a die phone synthesizer", null);
synthesizer1.speakPlainText("I have a friend named Alan.", null);
synthesizer1.speakPlainText("Listen to him count!", null);
// get synth2 ready to speak
synthesizer2.waitEngineState(Synthesizer.ALLOCATED);
synthesizer2.resume();
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.speakPlainText("1 2 3 4 5 6 7 8 9 ten", null);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText("Now listen to me count!", null);
synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
synthesizer1.speakPlainText(
"Now, let's try that a little bit faster.", null);
synthesi zer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setSpeakingRate(240.0f);
synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
synthesizer1.speakPlainText("That's pretty fast.", null);
synthesizer1.speakPlainText("Now lets go very slow.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setSpeakingRate(80.0f);
synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
synthesizer1.speakPlainText("That is pretty slow.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setSpeakingRate(150.0f);
synthesizer1.speakPlainText("Now back to normal", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setPitch(200);
synthesizer1.speakPlainText("I can talk very high.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setPitch(50);
synthesizer1.speakPlainText("and I can talk very low.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setPitch(100);
synthesizer1.getSynthesizerProperties().setVolume(.8f);
synthesizer1.speakPlainText("and I can talk very softly.", null);
synt hesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setVolume(1.0f);
synthesizer1.speakPlainText(
"I can talk with a higher quality voice", null);
synthesizer1.speakPlainText(
"Here is a low quality tongue twister. "
+ "She sells seashells by the seashore.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setVoice(kevinHQ);
synthesizer1.speakPlainText("And this is high quality. "
+ "She sells seashells by the seashore.", null);
synthesizer1.speakPlainText(
"The funny thing is, I do not have a tongue.", null);
synthesizer1.speakPlainText(
"Hey Alan, what time is it where you are right now?", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.speakPlainText(
"the time is now twenty past six.", null);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText("Is that the exact time?", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.speakPlainText("Almost", null);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText(
"Is it twenty past six In the morning or the evening?", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.speakPlainText("in the morning.", null);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText(
"Alan and I can talk at the same time", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 11 12", null);
synthesizer2.speakPlainText("1 2 3 4 5 6 7 8 9", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText( "That is a bit confusing.", null);
synthesizer1.speakPlainText( "Well, thanks. This was fun.", null);
synthesizer1.speakPlainText("Goodbye everyone.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
// clean up
synthesizer1.deallocate();
synthesizer2.deallocate();
}
catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}
The voices that you have access to is controlled by the VoiceManager class. It will search for voice packages installed in your system via a couple of different methods. By default you will have 3 voices installed: "alan", "kevin", and "kevin16". You need to install other voice packages (e.g. CMUArctic or MBROLA) before you can use voices other than the 3 default voices.
However, once you've installed a new voice (look at the corresponding websites for install instructions), you will also need to add that Voice Directory to the correct place, and add its name to a text file that lists all installed voices. Take a look at the Programmer's Guide under Installing Voice Packages. For reference, I ended up adding my new voice package paths to the voices.txt file next to the freetts.jar that I was using (which was a bit ttricky- I forgot I had added it to my Library/Java/Extensions folder on my Mac, so you may have to add the voices.txt file there).
You can check which voice are available with the following code:
VoiceManager voiceManager = VoiceManager.getInstance();
Voice[] voices = voiceManager.getVoices();
for (int i = 0; i < voices.length; i++){
System.out.print( "voice name is: " + voices[i].getName() +"\n");
}
Once you've successfully added the Voice Directories for the voices you've installed, you should see them listed when you run that code.
I'm trying to use vala to start an external application using GLib with spawn_command_line_sync().
According to the documentation (http://valadoc.org/#!api=glib-2.0/GLib.Process.spawn_sync) you can pass a string to store the output of the external application.
While this works fine when starting a script which prints a couple of lines, I need to call a program which will print the content of a binary file.
(for example "cat /usr/bin/apt-get")
Is there any way how I can receive the output of the external program not in a string, but in a DataStream or something like that ?
I'm planning to write the ouput of the external program to a file, so just calling "cat /usr/bin/apt-get > outputfile" would be an alternative (not as nice), but it doesn't seem to work.
Anyway I would prefer it to get some kind of Output Stream.
I would appreciate any help.
Code im using:
using GLib;
static void main(string[] args) {
string execute = "cat /usr/bin/apt-get";
string output = "out";
try {
GLib.Process.spawn_command_line_sync(execute, out output);
} catch (SpawnError e) {
stderr.printf("spawn error!");
stderr.printf(e.message);
}
stdout.printf("Output: %s\n", output);
}
GLib.Process.spawn_async_with_pipes will let you do just that. It spawns the processes and returns a file descriptor for each of stdout, stderr, and stdin. There's a sample of code in the ValaDoc on how to set up IOChannels to monitor the output.
Thanks for that, I must have overread spawn_async_with_pipes() returning ints and not strings.
Is there anything wrong with doing it this way ?
(besides the buffer size of 1)
using GLib;
static void main(string[] args) {
string[] argv = {"cat", "/usr/bin/apt-get"};
string[] envv = Environ.get();
int child_pid;
int child_stdin_fd;
int child_stdout_fd;
int child_stderr_fd;
try {
Process.spawn_async_with_pipes(
".",
argv,
envv,
SpawnFlags.SEARCH_PATH,
null,
out child_pid,
out child_stdin_fd,
out child_stdout_fd,
out child_stderr_fd);
} catch (SpawnError e) {
stderr.printf("spawn error!");
stderr.printf(e.message);
return;
}
FileStream filestream1 = FileStream.fdopen(child_stdout_fd, "r");
FileStream filestream2 = FileStream.open("./stdout", "w");
uint8 buf[1];
size_t t;
while ((t = filestream1.read(buf, 1)) != 0) {
filestream2.write(buf, 1);
}
}
I would like to use BouncyCastle J2ME/RIM Crypto in my Blackberry Application.
The issue i'm having is that I would like to generate the public key for encryption from a C#.NET program that sends the key to the BlackBerry.
Is it possible to encrypt a message using a raw string? Also, do I need to know other common variable such as modulo etc? Apologies but i'm completely new to cryptography algorithms.
Do I need BouncyCastle for this or can the above be done with RIM Crypto?
Thanks,
Conor
I did it using bouncycastle, but with RIM Crypto is similar.
Follow the example. As you can see the keys are strings ... :
public CypherDecypherExample()
{
String plain ="a plain string";
String cipher = null;
String decipher = null;
byte [] byte_cipher = null;
byte [] byte_plain = null;
// key |-- 128 bit -->|-- 256 bit --->|
String key = "aaaaaaaaaaaaaaaacccccccccccccccc";
String iv = "bbbbbbbbbbbbbbbb";
System.out.println("bouncycastle.plain: " + plain);
try {
byte_cipher = encrypt(plain.getBytes(), key.getBytes(), iv.getBytes());
cipher = new String(byte_cipher);
System.out.println("bouncycastle.cipher: " + cipher);
} catch (Exception e) {
e.printStackTrace();
}
try {
byte_plain = decrypt(byte_cipher, key.getBytes(), iv.getBytes());
decipher = new String(byte_plain);
System.out.println("bouncycastle.decipher: " + decipher);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
throws Exception
{
String plain = new String(data);
System.out.println("bouncycastle.cipherData: " + plain);
int minSize = cipher.getOutputSize(data.length);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
System.out.println("bouncycastle.cipherData returning");
return result;
}
private static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv) throws Exception
{
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher((BlockCipher) new CBCBlockCipher(
new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.init(false, ivAndKey);
return cipherData(aes, cipher);
}
private static byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception
{
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.init(true, ivAndKey);
return cipherData(aes, plain);
}
An RSA public key consists of two components, not just one like I thought.
There is the Exponent and Modulus. These are both number but I pass them to the Blackberry from .NET client as Base64 strings and decode them into byte arrays when be used by the RIM Crypto function as they take Byte arrays as parameters.
byte[] exponent = Base64InputStream.decode("exponent base64 string");
byte[] modulus = Base64InputStream.decode("modulus base64 string");
NoCopyByteArrayOutputStream cipherUserData = new NoCopyByteArrayOutputStream();
RSACryptoSystem cryptoSystem = new RSACryptoSystem(1024);
// Create Public key using your variables from before
RSAPublicKey publicKey = new RSAPublicKey( cryptoSystem, exponent, modulus);
// Encryption engine objects
RSAEncryptorEngine eEngine = new RSAEncryptorEngine(publicKey);
PKCS1FormatterEngine fEngine = new PKCS1FormatterEngine(eEngine);
BlockEncryptor cryptoStream = new BlockEncryptor(fEngine, cipherUserData);
// Read the user data and encrypt while doing so. Remember, cryptoStream writes its data to
// cipherUserData so this is where the encrypted version of userData will end up.
cryptoStream.write( userData, 0, userData.length );
cryptoStream.close();
cipherUserData.close();
String encryptedUserData = new String(cipherUserData.toByteArray());
That's pretty much all there is too it folks, it's straightforward but it took me a long time to get this from the API docs :)
Important note
RSA is limited for encryption purposes in that you can only encrypt a message that <= key size.
That is 117 bytes for 1024 Bit RSA and 245 bytes for 2048 RSA. To encrypt larger messages the accepted way is to encrypt the message using AES or similar then encrypt the AES key with the RSA public key. You will the send the AES ciphertext and also the RSA ciphertext containing the key to decrypt the AES ciphertext.
What I have written above took days of tinkering and reading. I hope it helps somebody achieve their goal faster than that. :)
I'm working on a .NET WinForms app that needs to print a FEDEX shipping label. As part of the FedEx api, I can get raw label data for the printer.
I just don't know how to send that data to the printer through .NET (I'm using C#). To be clear, the data is already pre formatted into ZPL (Zebra printer language) I just need to send it to the printer without windows mucking it up.
C# doesn't support raw printing, you'll have to use the win32 spooler, as detailed in this KB article How to send raw data to a printer by using Visual C# .NET.
Hope this helps.
-Adam
I think you just want to send the ZPL (job below) directly to your printer.
private void SendPrintJob(string job)
{
TcpClient client = null;
NetworkStream ns = null;
byte[] bytes;
int bytesRead;
IPEndPoint remoteIP;
Socket sock = null;
try
{
remoteIP = new IPEndPoint( IPAddress.Parse(hostName), portNum );
sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
sock.Connect(remoteIP);
ns = new NetworkStream(sock);
if (ns.DataAvailable)
{
bytes = new byte[client.ReceiveBufferSize];
bytesRead = ns.Read(bytes, 0, bytes.Length);
}
byte[] toSend = Encoding.ASCII.GetBytes(job);
ns.Write(toSend, 0, toSend.Length);
if (ns.DataAvailable)
{
bytes = new byte[client.ReceiveBufferSize];
bytesRead = ns.Read(bytes, 0, bytes.Length);
}
}
finally
{
if( ns != null )
ns.Close();
if( sock != null && sock.Connected )
sock.Close();
if (client != null)
client.Close();
}
}
A little late, but you can use this CodePlex Project for easy ZPL printing
http://sharpzebra.codeplex.com/
Zebra printers don't use a spooler, it isn't raw printing. It's a markup called ZPL. It's text based, not binary.
I've been working with a printer and ZPL for a while now, but with a Ruby app. Sending the ZPL out to the printer via socket works fine.
To check that it works, I often telnet to the printer and type ^XA^PH^XZ to feed a single label. Hope that helps.