Reading data from a device connected to usb port - java

I have to read data(signals) from a device which sends signals continously to USB port and display it on monitor.
As POC I tried reading data from USB flash drive connected to my system. I am using JUSB library for windows. But, as I change ,my device driver settings as described in below doc for JUSB, my device configurations disappear( I get null for device.getConfiguration();).
http://www.steelbrothers.ch/jusb/ -- documents-->appendix D
Can anyone please help me to figure out where I am going wrong or suggest me some other good API to read data from USB device using JAVA.
Code is below,
try{
Device device = null;
DeviceImpl dev;
for(int k=0; k < busses.length ; k++){
System.out.println("\n\nBus[ " + ((USB)busses[k]).getBusNum() + " ] ");
for(int i = 0; i < 5; i++){
dev = (DeviceImpl)busses[k].getDevice(i);
device = busses[k].getDevice(i);
System.out.print(" [ " + i + " ] : ");
if(dev != null){
if(dev.getAddress() == 0) System.out.println(" [ROOT] numOfPort:" + dev.getNumPorts()+" Address:" + dev.getAddress());
else {
if(dev.getNumPorts() > 0) System.out.println(" [EXTERNAL HUB] numOfPort:" + dev.getNumPorts()+" Address:" + dev.getAddress());
else System.out.println(" [USB DEVICE] on Port "+dev.getHubPortNum() + " Address : " + dev.getAddress());
System.out.println(" uniqueID : " + dev.getUniqueDeviceID());
System.out.println(" driverKeyName : " + dev.getDriverKeyName());
System.out.println(" friendlyDeviceName: " + dev.getFriendlyDeviceName());
if (dev instanceof Device) System.out.print(" Object Type : Device");
if (dev instanceof DeviceImpl) System.out.print(", DeviceImpl");
if (dev instanceof JUSB) System.out.println(", JUSB");
if (dev instanceof NonJUSB) System.out.println(", NonJUSB");
System.out.println("***************confoig: "+dev.configuration);//getConfiguration(0));
boolean brk = false;
StringTokenizer uniqueNameValPairs = new StringTokenizer(dev.getUniqueDeviceID(),"&");
while(uniqueNameValPairs.hasMoreTokens()){
StringTokenizer strToken = new StringTokenizer(uniqueNameValPairs.nextToken(),"_");
while(strToken.hasMoreTokens()){
if(strToken.nextToken().equals("03f0")){
System.out.println("breaking");
readData(dev);
brk = true;
break;
}
}
}
static void readData(DeviceImpl device){
try{
if (device != null)
{
// Obtain the current Configuration of the device and the number of
// Interfaces available under the current Configuration.
Configuration config = device.getConfiguration();
if(null == config)
config = device.configuration;
System.out.println("config: "+config);
int total_interface = config.getNumInterfaces();
// Traverse through the Interfaces
for (int k=0; k<total_interface; k++)
{
// Access the currently Interface and obtain the number of
// endpoints available on the Interface.
Interface itf = config.getInterface(k, 0);
int total_ep = itf.getNumEndpoints();
// Traverse through all the endpoints.
for (int l=0; l<total_ep; l++)
{
// Access the endpoint, and obtain its I/O type.
Endpoint ep = itf.getEndpoint(l);
String io_type = ep.getType();
boolean input = ep.isInput();
System.out.println("ep.getInputStream(): "+ep.getInputStream());
// If the endpoint is an input endpoint, obtain its
// InputStream and read in data.
if (input)
{
InputStream in;
System.out.println("ep.getInputStream()111: "+ep.getInputStream());
BufferedReader brIn = new BufferedReader(new InputStreamReader(ep.getInputStream()));
System.out.println("**************Input stream: "+brIn);
String inStr = null;
while( (inStr = brIn.readLine()) != null){
System.out.println(inStr);
}
// Read in data here
// in.close();
}
// If the Endpoint is and output Endpoint, obtain its
// OutputStream and write out data.
else
{
OutputStream out;
out = ep.getOutputStream();
System.out.println("**************Output stream: "+out);
// Write out data here.
out.close();
}
}
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
//System.exit(0);
}
}

Related

How to send ADB commands to USB Host-connected device (Oculus)

First of all, I'd just like to point out that I'm a junior dev breaking new ground here for myself. I'm trying to send an ADB command to my Oculus to change the texture quality so that I don't have to hook up my Oculus to my PC every time with SideQuest. I've had no luck and there's no documentation that I can find to do this. Here's the code I have...
Retrieving the correct endpoint
private static UsbEndpoint getCorrectEndpoint(UsbDevice device, boolean outEndpoint) {
UsbEndpoint result = null;
//get interfaces
ArrayList<UsbInterface> usbInterfaceArrayList = new ArrayList<>();
for (int i = 0; i < device.getInterfaceCount(); i++) {
usbInterfaceArrayList.add(device.getInterface(i));
}
//get endpoints from those interfaces
UsbEndpoint endpointOut = null;
UsbEndpoint endpointIn = null;
for (int i = 0; i < usbInterfaceArrayList.get(0).getEndpointCount(); i++) {
if (usbInterfaceArrayList.get(0).getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (usbInterfaceArrayList.get(0).getEndpoint(i).getDirection() == UsbConstants.USB_DIR_OUT) {
endpointOut = usbInterfaceArrayList.get(0).getEndpoint(i); //If this Endpoint is XFER_BULK and DIR_OUT
} else {
endpointIn = usbInterfaceArrayList.get(0).getEndpoint(i); //If this EndPoint is XFER_BULK and DIR_IN
}
}
}
if (outEndpoint) { //Check the parameter to see which endpoint the user wants
result = endpointOut;
} else {
result = endpointIn;
}
return result;
}
Sending the data
public static void setOculusTexture(double textureWidth, Context context, Intent intent, TextView textView) {
double textureHeight = textureWidth * 1.0997;
boolean forceClaim = true;
int timeout = 0;
String textureString = "adb shell " + OculusADBConstants.OCULUS_TEXTURE_ADB_BASE + "Width " + textureWidth +
" && " + OculusADBConstants.OCULUS_TEXTURE_ADB_BASE + "Height " + textureHeight;
byte[] textureStringBytes = textureString.getBytes();
if (getOculusDeviceFromUSB(context) != null) { //If there is an Oculus connected
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
UsbDevice usbDevice = (UsbDevice) getOculusDeviceFromUSB(context);
UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(usbDevice);
usbDeviceConnection.claimInterface(usbDevice.getInterface(0), forceClaim);
int cmdBulkTransfer = usbDeviceConnection.bulkTransfer(getCorrectEndpoint(usbDevice, true), textureStringBytes, textureStringBytes.length, timeout);
int controlTransferResult = usbDeviceConnection.controlTransfer(UsbConstants.USB_DIR_OUT, 1,
0, 0, textureStringBytes, textureStringBytes.length, timeout);
textView.append(textureString + " data sent to device..." + "\n");
textView.append("cmdBulkTransfer Result = " + (cmdBulkTransfer) + "\n");
textView.append("ControlTransfer Result = " + controlTransferResult);
} else { //If there isn't an Oculus connected
Toast.makeText(context, "No Oculus detected. Is it plugged into your phone?", Toast.LENGTH_LONG).show();
}
}
The bulk transfer returns an actual number while the controlled transfer returns -1. I'm fairly sure that I need to somehow initiate an ADB request from my phone, but I have no idea how to do that. I assume this because when I connect my phone to the Oculus, and use the BugJaeger app, the BugJaeger app somehow makes the Oculus prompt with allowing USB Debugging dialog. My app does not cause that to happen. What am I doing wrong?

Read and Write to USB Device on Raspberry Pi 3 using Java

I'm using Raspbian on a Raspberry Pi 3. I'm learning how to code in Java (SE runtime version 1.8.0_65), and I need to communicate raw data with a USB connected Bill Acceptor. According to the manufacturer's documentation, the USB unit mimics a serial-type interface. When I plug the device in, it appears in /dev/serial/by-id. I wrote C code 20+ years ago using modems on SCO Unix setups. If memory serves, I basically treated the modems /dev/ttyxx as a file for reading and writing. I wrote a C++ program 10+ years ago on Windows XP using a similar Bill Acceptor unit (same manufacturer and model) connected to a serial port instead of USB. The documentation shows both USB and serial units use the same data strings for input and output, so I know the SendString data should be correct for triggering a valid response. However, I'm not getting a reply from the unit, so I'm guessing I'm not connecting properly to it.
Here is the code...
public static void main(String[] args) {
try
{
System.out.println("*****************************");
System.out.println("***** Starting Program *****");
System.out.println("*****************************");
String strUsbDeviceDir = "/dev/serial/by-id";
File myUsbDeviceDir = new File(strUsbDeviceDir);
if(myUsbDeviceDir.exists())
{
String[] myUsbDevices = myUsbDeviceDir.list();
for(int i=0; i<myUsbDevices.length; i++)
{
if(myUsbDevices[i].contains("EBDS_over_USB"))
{
System.out.println("Connecting to " + myUsbDevices[i]);
funcBillAcceptor(strUsbDeviceDir + "/" + myUsbDevices[i]);
}
else
{
System.out.println("Not using " + myUsbDevices[i]);
}
}
}
}
catch (Exception ex)
{
System.err.println(ex.toString());
}
}
public static void funcBillAcceptor(String strBillAcceptor)
{
boolean bOddCount = false;
byte[] SendString = new byte[8];
byte[] RecvString = new byte[10];
byte CheckDigit;
int iSendStringCount, iRecvStringCount, iRecvEmptyCount;
try
{
File fBillAcceptor = new File(strBillAcceptor);
if(!fBillAcceptor.canRead())
{
System.out.println("No Read Permission for " + strBillAcceptor);
return;
}
if(!fBillAcceptor.canWrite())
{
System.out.println("No Write Permission for " + strBillAcceptor);
return;
}
RandomAccessFile rafBillAcceptor = new RandomAccessFile(strBillAcceptor, "rwd");
if(rafBillAcceptor != null)
{
System.out.println("Successfully opened " + strBillAcceptor);
}
while(fBillAcceptor.exists())
{
SendString[0] = (byte) 0x02; //STX
SendString[1] = (byte) 0x08;
if(bOddCount)
{
SendString[2] = (byte) 0x10;
bOddCount = false;
}
else
{
SendString[2] = (byte) 0x11;
bOddCount = true;
}
SendString[3] = (byte) 0x1F;
SendString[4] = (byte) 0x0C;
SendString[5] = (byte) 0x00;
SendString[6] = (byte) 0x03; //ETX
//CheckDigit skips STX (byte 0) with byte 1 as seed/initial value
//To calculate the check digit, start with next byte (2)
CheckDigit = SendString[1];
iSendStringCount = 2;
while(SendString[iSendStringCount] != 0x03)
{
CheckDigit = (byte) (SendString[iSendStringCount]^CheckDigit); //XOR current CheckDigit value with next byte
iSendStringCount++;
}
iSendStringCount++; //advance one more so we don't overwrite ETX
SendString[iSendStringCount] = (byte) CheckDigit;
try
{
rafBillAcceptor.write(SendString);
System.out.println("Sent: " + DatatypeConverter.printHexBinary(SendString));
}
catch (Exception ex)
{
System.err.println("Write exception: " + ex.toString());
}
System.out.println("Reading...");
iRecvStringCount = iRecvEmptyCount = 0;
try
{
do
{
iRecvStringCount = rafBillAcceptor.read(RecvString);
System.out.println("Read " + iRecvStringCount + " bytes.");
if(iRecvStringCount < 0)
{
iRecvEmptyCount++;
Thread.sleep(5);
}
} while (iRecvStringCount < 0 && iRecvEmptyCount < 100);
if(iRecvStringCount > 0)
{
System.out.println("Received: " + DatatypeConverter.printHexBinary(RecvString));
}
}
catch (Exception ex)
{
System.err.println("Read exception: " + ex.toString());
}
}
}
catch (Exception ex)
{
System.err.println(ex.toString());
}
}
Here is the output I'm getting...
*****************************
***** Starting Program *****
*****************************
Connecting to usb-Silicon_Labs_Series_2000_Bill_Acceptor__EBDS_over_USB__46580120748-if00-port0
Successfully opened /dev/serial/by-id/usb-Silicon_Labs_Series_2000_Bill_Acceptor__EBDS_over_USB__46580120748-if00-port0
Sent: 0208111F0C00030A
Reading...
Am I missing something obvious, or just going about this all wrong? Thanks for any suggestions!
I was able to successfully communicate with the Bill Acceptor from a Raspberry Pi 3 (running Raspbian) using the RXTXComm library. When communicating with the device from an old Windows XP computer using a 9-pin serial/RS232 harness, I had to use 9600/7/E/1. If I don't use those values for setSerialPortParams (in my sample code), I'm not able to correctly send/receive data. So, you need to know what the device is expecting in order to use this approach with other "serial" hardware connected via USB. Below is code with the basic functionality. I started with one of the sample programs that come with the RXTXComm library and built out from there. Since this is a sample program, I haven't yet added logic to verify the checksum digit for data coming from the device.
You may notice at the bottom of the code that I'm able to determine the /dev/ttyUSBx using the canonical name of the device that I pull from the /dev/serial/by-id directory/folder. It finds the correct device name regardless of which USB port the unit is plugged in to or what order the USB devices get initialized by the system. I have a card dispenser that is also a USB serial device, so I was able to test and confirm this functionality.
public TwoWaySerialComm()
{
super();
}
static boolean bReadyToSend = false;
void connect ( String portName ) throws Exception
{
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if ( portIdentifier.isCurrentlyOwned() )
{
System.out.println("Error: " + portName + " is currently in use.");
}
else
{
CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000);
if ( commPort instanceof SerialPort )
{
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_7, SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
// Thread handling logic
// https://www.javaspecialists.eu/archive/Issue056.html
Thread readThread = new Thread(new SerialReader(in));
readThread.start();
Thread writeThread = new Thread(new SerialWriter(out));
writeThread.start();
// Running threads for 10 seconds then stopping to ensure threads are shutting down
long threadCurrTime = System.currentTimeMillis();
long threadStartTime = System.currentTimeMillis();
while( (threadCurrTime - threadStartTime) < 10000)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException ex)
{
Logger.getLogger(TwoWaySerialComm.class.getName()).log(Level.SEVERE, null, ex);
}
threadCurrTime = System.currentTimeMillis();
}
if(writeThread.isAlive())
{
//System.out.println("Sending interrupt to SerialWriter thread...");
writeThread.interrupt();
writeThread.join();
//System.out.println("SerialWriter thread is shut down.");
}
//else
//{
// System.out.println("SerialWriter thread is already shut down.");
//}
if(readThread.isAlive())
{
//System.out.println("Sending interrupt to SerialReader thread...");
readThread.interrupt();
readThread.join();
//System.out.println("SerialReader thread is shut down.");
}
//else
//{
// System.out.println("SerialReader thread is already shut down.");
//}
commPort.close();
}
else
{
System.out.println("Error: " + portName + " is not recognized as a valid serial device.");
}
}
}
/* SerialReader thread logic */
public static class SerialReader implements Runnable
{
InputStream in;
boolean bShuttingDown = false;
public SerialReader ( InputStream in )
{
this.in = in;
}
public void run ()
{
byte[] RecvString = new byte[12];
String strResponse;
int len = -1;
try
{
while (!bShuttingDown)
{
len = this.in.read(RecvString);
if( len > -1 )
{
strResponse = "";
if(RecvString[0] == 0x02 && RecvString[9] == 0x03)
{
if(RecvString[3] == 0x00 && RecvString[4] == 0x00 && RecvString[5] == 0x00 && RecvString[6] == 0x00)
{
strResponse = "Device not ready.";
}
else
{
//-- RecvString[3]------------------
if(RecvString[3] == 0x01)
strResponse = " - Idling";
else
if(RecvString[3] == 0x02)
strResponse = " - Accepting";
else
if(RecvString[3] == 0x04)
{
strResponse = " - Escrowed";
if(RecvString[5] == 0x08)
strResponse += " $1";
else
if(RecvString[5] == 0x10)
strResponse += " $2";
else
if(RecvString[5] == 0x18)
strResponse += " $5";
else
if(RecvString[5] == 0x20)
strResponse += " $10";
else
if(RecvString[5] == 0x28)
strResponse += " $20";
else
strResponse += " unrecognized bill inserted";
}
else
if(RecvString[3] == 0x08)
strResponse = " - Stacking";
else
if(RecvString[3] == 0x10)
strResponse = " - Stacked";
else
if(RecvString[3] == 0x11)
strResponse = " - Returning";
else
if(RecvString[3] == 0x12)
strResponse = " - Returned";
//-- RecvString[4]------------------
if(RecvString[4] == 0x01)
strResponse += " - Cheated";
else
if(RecvString[4] == 0x02)
strResponse += " - Rejected";
else
if(RecvString[4] == 0x04)
strResponse += " - Jammed";
else
if(RecvString[4] == 0x08)
strResponse += " - Bill Stacker Full";
else
if(RecvString[4] == 0x10)
strResponse += " - Removable Cassette Installed";
else
if(RecvString[4] == 0x11)
strResponse += " - Reserved";
else
if(RecvString[4] == 0x12)
strResponse += " - Calibration mode";
//-- RecvString[5]------------------
if(RecvString[5] == 0x01)
strResponse += " - Power Up Reset";
else
if(RecvString[5] == 0x02)
strResponse += " - Invalid Command";
else
if(RecvString[5] == 0x04)
strResponse += " - Non-recoverable fault";
}
if(!strResponse.contains("Idling"))
System.out.println("Recv: " + DatatypeConverter.printHexBinary(RecvString) + strResponse);
}
else
{
System.out.println("Recv (invalid): " + DatatypeConverter.printHexBinary(RecvString));
}
try
{
Thread.sleep(100); // need this delay before we send next polling message, otherwise the data doesn't come in correctly
bReadyToSend = true;
}
catch (InterruptedException ex)
{
Thread.currentThread().interrupt();
//System.out.println("Shut down SerialReader thread.");
bShuttingDown = true;
break;
}
}
}
}
catch ( IOException ex )
{
System.out.println("Recv exception: " + ex.toString());
}
}
}
/* SerialWriter thread logic */
public static class SerialWriter implements Runnable
{
OutputStream out;
long lastSendTime = System.currentTimeMillis() - 1001;
long currSendTime;
byte[] SendString = new byte[8];
byte CheckDigit;
int iSendStringCount;
boolean bOddCount = true;
boolean bShuttingDown = false;
public SerialWriter ( OutputStream out )
{
this.out = out;
}
public void run ()
{
while(!bShuttingDown)
{
currSendTime = System.currentTimeMillis();
if(currSendTime - lastSendTime > 1000) // if it's been more than a second, send query string
bReadyToSend = true;
if(bReadyToSend)
{
SendString[0] = (byte) 0x02; //STX
SendString[1] = (byte) 0x08;
if(bOddCount)
{
SendString[2] = (byte) 0x10;
bOddCount = false;
}
else
{
SendString[2] = (byte) 0x11;
bOddCount = true;
}
SendString[3] = (byte) 0x7F;
SendString[4] = (byte) 0x1C;
SendString[5] = (byte) 0x00;
SendString[6] = (byte) 0x03; //ETX
//CheckDigit skips STX (byte 0) with byte 1 as seed/initial value
//To calculate the check digit, start with next byte (2)
CheckDigit = SendString[1];
iSendStringCount = 2;
while(SendString[iSendStringCount] != 0x03)
{
CheckDigit = (byte) (SendString[iSendStringCount]^CheckDigit); //XOR current CheckDigit value with next byte
iSendStringCount++;
}
iSendStringCount++; //advance one more so we don't overwrite ETX
SendString[iSendStringCount] = (byte) CheckDigit;
try
{
lastSendTime = System.currentTimeMillis();
this.out.write(SendString);
//System.out.println("Sent: " + DatatypeConverter.printHexBinary(SendString));
}
catch ( IOException ex )
{
System.out.println("Send exception: " + ex.toString());
}
try
{
Thread.sleep(1); // this is hear simply to catch an external interrupt
}
catch (InterruptedException ex)
{
Thread.currentThread().interrupt();
//System.out.println("Shut down SerialWriter thread.");
bShuttingDown = true;
break;
}
bReadyToSend = false;
}
}
}
}
public static void main ( String[] args )
{
try
{
System.out.println("*****************************");
System.out.println("***** Starting Program *****");
System.out.println("*****************************");
String strUsbDeviceDir = "/dev/serial/by-id";
File myUsbDeviceDir = new File(strUsbDeviceDir);
if(myUsbDeviceDir.exists())
{
String[] myUsbDevices = myUsbDeviceDir.list();
for(int i=0; i<myUsbDevices.length; i++)
{
if(myUsbDevices[i].contains("EBDS_over_USB"))
{
File tempFile = new File(strUsbDeviceDir + "/" + myUsbDevices[i]);
String usbCanonicalName = tempFile.getCanonicalFile().toString(); //gives me /dev/ttyUSBx where 'x' is the USB device number
System.out.println("Connecting to " + usbCanonicalName + " (" + myUsbDevices[i] + ")");
(new TwoWaySerialComm()).connect(usbCanonicalName);
}
else
{
System.out.println("Not using " + myUsbDevices[i]);
}
}
}
}
catch ( Exception ex )
{
System.out.println("Connect exception: " + ex.toString());
}
System.out.println("*****************************");
System.out.println("***** Program Finished ******");
System.out.println("*****************************");
}
Output when I put a $1 bill in (I'm developing/compiling from NetBeans IDE 8.2 on Windows 10 Pro and running using remote debugging on the RPi3. I'm guessing that's the source of the RXTX Version mismatch warning):
*****************************
***** Starting Program *****
*****************************
Connecting to /dev/ttyUSB0 (usb-Silicon_Labs_Series_2000_Bill_Acceptor__EBDS_over_USB__46580120748-if00-port0)
Stable Library
=========================================
Native lib Version = RXTX-2.2pre2
Java lib Version = RXTX-2.1-7
WARNING: RXTX Version mismatch
Jar version = RXTX-2.1-7
native lib Version = RXTX-2.2pre2
Recv (invalid): 020000000000000000000000
Recv (invalid): 0B2001100800503603540000
Recv: 020B20041008005036035100 - Escrowed $1 - Removable Cassette Installed
*****************************
***** Program Finished ******
*****************************
I hope this description and sample code can help someone else.

Displaying data from an ISP/Telephone (Telstra.com.au in Australia)

I am currently having issues in attempting to display data (i.e. itemSummaries with a certain ContainerType) for sites that are ISP, as an example, www.telstra.com.au from Australia
Logging into the site works fine, and the credentials for the site work fine (in other words, it does a refresh which succeeds), however there doesn't appear to be a way to display the itemSummary data
The soap command getItemSummaries, doesn't display data for the item (it displays item data from financial institutions fine). Upon examining the sample code provided by Yodlee for the java soap api, you are meant to use the getItemSummaries1 along with setting ContainerTypes using a SummaryRequest
The problem is that this returns a CoreExceptionFaultMessage. The getItemSummaries1 command is causing the CoreExceptionFaultError. Using different ContainerTypes with different combinations (i.e. ISP, Telephone, Bills) didn't alleviate the issue
The same error message is returned in Yodlees own sample code, i.e. java_soap_example (run the com.yodlee.sampleapps.accountsummary.DisplayBillsData main method and provide the Yodlee login info as command line arguments)
As a reference, the code that is provided by Yodlee sample app is below
Running the getItemSummaries1 command
public void displayBillsData (UserContext userContext)
{
/*SummaryRequest sr = new SummaryRequest(
new String[] {ContainerTypes.BILL, ContainerTypes.TELEPHONE},
new DataExtent[] { DataExtent.getDataExtentForAllLevels(),DataExtent.getDataExtentForAllLevels() }
);*/
SummaryRequest sr = new SummaryRequest();
List list = new List();
list.setElements(new String[] {ContainerTypesHelper.BILL, ContainerTypesHelper.TELEPHONE});
sr.setContainerCriteria(list);
Object[] itemSummaries = null;
List itemSummariesList = null;
try {
itemSummariesList = dataService.getItemSummaries1(userContext, sr);
if (itemSummariesList != null){
itemSummaries = itemSummariesList.getElements();
}
} catch (StaleConversationCredentialsExceptionFault e) {
e.printStackTrace();
} catch (InvalidConversationCredentialsExceptionFault e) {
e.printStackTrace();
} catch (CoreExceptionFault e) {
e.printStackTrace();
} catch (IllegalArgumentTypeExceptionFault e) {
e.printStackTrace();
} catch (IllegalArgumentValueExceptionFault e) {
e.printStackTrace();
} catch (InvalidUserContextExceptionFault e) {
e.printStackTrace();
} catch (IllegalDataExtentExceptionFault e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
if (itemSummaries == null || itemSummaries.length == 0) {
System.out.println ("No bills data available");
return;
}
for (int i = 0; i < itemSummaries.length; i++) {
ItemSummary is = (ItemSummary) itemSummaries[i];
displayBillsDataForItem(is);
// Dump the BillsData Object
// dumpBillsDataForItem(is);
}
}
Printing the item data
public void displayBillsDataForItem (ItemSummary is)
{
String containerType = is.getContentServiceInfo ().
getContainerInfo ().getContainerName ();
System.out.println("containerType = " + containerType );
if (!(containerType.equals(ContainerTypesHelper.BILL ) || containerType.equals(ContainerTypesHelper.TELEPHONE)
|| containerType.equals(ContainerTypesHelper.MINUTES))) {
throw new RuntimeException ("displayBillsDataForItem called with " +
"invalid container type: " + containerType);
}
DisplayItemInfo displayItemInfo = new DisplayItemInfo ();
System.out.println("DisplayItemInfo:");
displayItemInfo.displayItemSummaryInfo (is);
System.out.println("");
ItemData id = is.getItemData();
if(id == null){
System.out.println("ItemData == null");
}else{
List accountsList = id.getAccounts();
Object[] accounts = null;
if (accountsList != null){
accounts = accountsList.getElements();
}
if (accounts == null || accounts.length == 0) {
System.out.println ("\tNo accounts");
}else {
for (int accts = 0; accts < accounts.length; accts++) {
BillsData billsData = (BillsData) accounts[accts];
System.out.println("\tAccount Holder: " + billsData.getAccountHolder() );
System.out.println("\tAccount Id: " + billsData.getAccountId());
System.out.println("\tItemAccountId: " + billsData.getItemAccountId() );
System.out.println("\tAccountName: " + billsData.getAccountName() );
System.out.println("\tAccountNumber: " + billsData.getAccountNumber() );
System.out.println("");
// Get List of Bill Objects
List billsList = billsData.getBills();
Object[] bills = null;
if (billsList != null){
bills = billsList.getElements();
}
if (bills == null || bills.length == 0) {
System.out.println ("\t\tNo Bill objects");
}else {
for (int b = 0; b < bills.length; b++) {
Bill bill = (Bill) bills[b];
System.out.println("\t\tBill Account Number: " + bill.getAccountNumber() );
System.out.println("\t\tBill Acct Type: " + bill.getAcctType() );
System.out.println("\t\tBill Due Date: " + Formatter.formatDate(bill.getDueDate().getDate(), Formatter.DATE_SHORT_FORMAT) );
System.out.println("\t\tBill Date: " + Formatter.formatDate(bill.getBillDate().getDate(), Formatter.DATE_SHORT_FORMAT) );
System.out.println("\t\tBill Past Due: "
+ (bill.getPastDue() != null ? bill
.getPastDue().getAmount() : 0.0));
System.out
.println("\t\tBill Last payment: "
+ (bill.getLastPayment() != null ? bill
.getLastPayment()
.getAmount()
: 0.0));
System.out.println("\t\tBill Amount Due: "
+ (bill.getAmountDue() != null ? bill
.getAmountDue().getAmount() : 0.0));
System.out
.println("\t\tBill Min Payment: "
+ (bill.getMinPayment() != null ? bill
.getMinPayment()
.getAmount()
: 0.0));
System.out.println("");
// Get List of AccountUsageData
List acctUsageDataList = bill.getAccountUsages();
Object[] acctUsageData = null;
if (acctUsageDataList != null){
acctUsageData = acctUsageDataList.getElements();
}
if (acctUsageData == null || acctUsageData.length == 0) {
System.out.println ("\t\t\tNo AccountUsageData objects");
}else {
for (int usage = 0; usage < acctUsageData.length; usage++) {
AccountUsageData aud = (AccountUsageData) acctUsageData[usage];
System.out.println("\t\t\tAccount Usage Bill ID: " + aud.getBillId() );
System.out.println("\t\t\tAccount Usage Units Used: " + aud.getUnitsUsed() );
}
}
}
}
System.out.println("");
// Get List of AccountUsageData
List acctUsageDataList = billsData.getAccountUsages();
Object[] acctUsageData = null;
if (acctUsageDataList != null){
acctUsageData = acctUsageDataList.getElements();
}
if (acctUsageData == null || acctUsageData.length == 0) {
System.out.println ("\t\tNo AccountUsageData objects");
}else {
for (int usageData = 0; usageData < acctUsageData.length; usageData++) {
AccountUsageData aud = (AccountUsageData) acctUsageData[usageData];
System.out.println("\t\tAccount Usage Bill ID: " + aud.getBillId() );
System.out.println("\t\tAccount Usage Units Used: " + aud.getUnitsUsed() );
}
}
}
}
}
}
EDIT2:
I have updated the getItemSummaries1 command to look like this
ContainerCriteria bills = new ContainerCriteria();
ContainerCriteria telephone = new ContainerCriteria();
ContainerCriteria isp = new ContainerCriteria();
ContainerCriteria utilities = new ContainerCriteria();
bills.setContainerType(ContainerTypesHelper.BILL);
telephone.setContainerType(ContainerTypesHelper.TELEPHONE);
isp.setContainerType(ContainerTypesHelper.ISP);
utilities.setContainerType(ContainerTypesHelper.UTILITIES);
Object[] containerList = {
bills,telephone,isp,utilities
};
SummaryRequest sr = new SummaryRequest();
List list = new List();
list.setElements(containerList);
sr.setContainerCriteria(list);
The command now executes and works correctly, however its returning a list of 0 elements (using DataExtents with different values didn't change anything). My suspicion is that Telstra.com.au site is broken on Yodlee's end (when a full refresh is done on the Telstra site, Yodlee returns a null for refreshing that specific site).
So far I can see some deviation, so do modify your container criteria as mentioned below
object[] list = {
new ContainerCriteria { containerType = "bills" },
new ContainerCriteria { containerType = "telephone" }
};
sr.containerCriteria = list;
You may additionally provide data extent as follows
DataExtent de = new DataExtent();
dataExtent.startLevel = 0; //as per your needs
dataExtent.endLevel = 0; //as per your needs
object[] list = {
new ContainerCriteria { containerType = "bills", dataExtent = de },
new ContainerCriteria { containerType = "telephone", dataExtent = de }
};
sr.containerCriteria = list;
This should solve your issue. If not then try to get the detail which is is node in the response for the CoreExceptionFaultMessage, this detail may help to diagnose the accurate issue.
To get data for any of the container first you need to add an account for the site belonging to that container. Once you have added the account successfully then only you will be able to pull in the data for such container. Also you can check the tag returned in the getItemSummaries API which has and once this statusCode = 0 then only you have data present for that account.
You can do testing by using the Dummy account which yodlee provides. Please refer to Yodlee Dummy account generator page for more info on Dummy accounts.

Issue creating number of sockets one by one in loop

I have made a school app in which teacher sends a string message to the students. Teacher holds a hash-map of logged in students. When Teacher presses next page command in his tablet, students should see the next page. And that is what happens normally, but sometimes when teacher is not able to make connection with a single student in the hash-map for some reason whole process gets very slow and rarely the systems ceases to respond any further.
public static void SendToEveryStudent(String message) throws IOException, ELearningException
{
String command;
String host;
int port;
String failedStudents = "";
int leftOverStudents = 0;
ApplicationLog.log("Command Queue: sendToEveryStudent : " + message, InitializeTeacherJar.getInstance().isLoggingEnabled());
int socketTimeout;
Socket studentSocket = null;
StudentUtility.studentCounter = 0;
port = InitializeTeacherJar.getGlobalPort();
socketTimeout = InitializeTeacherJar.getInstance().getTeacherStudentSocketTimeout();
// Check if no of students are more then zero
if (InitializeTeacherJar.getInstance().getStudentIPList().keySet().size() > 0)
{
StudentUtility.studentCounter = InitializeTeacherJar.getInstance().getStudentIPList().keySet().size();
for (String key : InitializeTeacherJar.getInstance().getStudentIPList().keySet())
{
try
{
host = InitializeTeacherJar.getInstance().getStudentIPList().get(key).get(0);
if (!host.equalsIgnoreCase(""))
{
if (studentSocket != null)
{
studentSocket.close();
studentSocket = null;
}
try
{
studentSocket = new Socket(InetAddress.getByName(host), port);
studentSocket.setSoTimeout(socketTimeout);
}
catch (Exception e)
{
leftOverStudents++;
failedStudents = key + InitializeTeacherJar.getInstance().getDelimiter();
ApplicationLog.log("Exception :: " + host +" is not reachable as the server is down at his end.", InitializeTeacherJar.getInstance().isLoggingEnabled());
continue;
}
if (studentSocket != null)
{
if (InitializeTeacherJar.getInstance().getStudentIPList().get(key).get(1).equalsIgnoreCase("present"))
{
studentSocket.getOutputStream().write((message + "\n").getBytes());
ApplicationLog.log("Command Queue: Message to student :: " + message + " :: " + key, InitializeTeacherJar.getInstance().isLoggingEnabled());
BufferedReader in = new BufferedReader(new InputStreamReader(studentSocket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null)
{
if (line.equalsIgnoreCase("ack"))
{
//ApplicationLog.log("InitializeTeacherJar :: Student Counter is :: " + StudentUtility.studentCounter, InitializeTeacherJar.getInstance().isLoggingEnabled());
ApplicationLog.log("Command Queue: Ack recvd for :: "+ key + " :: " + host, InitializeTeacherJar.getInstance().isLoggingEnabled());
}
else
{
ApplicationLog.log("Command Queue: Did Not received ACK for :: "+ key + " :: " + host, InitializeTeacherJar.getInstance().isLoggingEnabled());
}
}
}
else
{
studentSocket.getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + ErrorCodes.TABLET_NOT_ASSIGNED).getBytes());
ApplicationLog.log("StudentUtility :: Tablet not assigned to :: " + key, InitializeTeacherJar.getInstance().isLoggingEnabled());
}
studentSocket.close();
}
}
}
catch (Exception e)
{
ApplicationLog.log("CommandQueue :: sendToEveryStudent Exception :: " + e, InitializeTeacherJar.getInstance().isLoggingEnabled());
studentSocket.close();
}
studentSocket = null;
}
}
if (leftOverStudents > 0)
{
failedStudents = StudentUtility.m_stripLastChar(failedStudents);
ApplicationLog.log("SendToEveryStudent :: Some Students Were Not Connected :: " + ErrorCodes.TEACHER_STUDENT_SOCKET_NOT_CONNECTED + InitializeTeacherJar.getInstance().getDelimiter() + failedStudents, InitializeTeacherJar.getInstance().isLoggingEnabled());
InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + ErrorCodes.TEACHER_STUDENT_SOCKET_NOT_CONNECTED + InitializeTeacherJar.getInstance().getDelimiter() + failedStudents + InitializeTeacherJar.getInstance().getCommandDelimeter()).getBytes());
InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().flush();
}
else if (leftOverStudents == 0)
{
InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().write((CONSTANTS.ALERT + InitializeTeacherJar.getInstance().getDelimiter() + CONSTANTS.SENT_SUCCESSFULLY_TO_ALL + InitializeTeacherJar.getInstance().getDelimiter() + "Sent To All" + InitializeTeacherJar.getInstance().getCommandDelimeter()).getBytes());
InitializeTeacherJar.getInstance().getMyFlexSocket().getOutputStream().flush();
}
StudentUtility.studentCounter = StudentUtility.studentCounter - leftOverStudents;
}
}
The area where my apprehensions lies are
1) Loop - loop, which makes the sockets and call the blocking call i.e. accept, should go in a AsynTask.
2) SocketTimeout - it should be bare minimal, right now its 1.2 secs. What is the optimal value for this?
This might be little too much code, but I hope the explanation helps.
Thanking in advance.
This is sort of a backwards setup. Imagine a web server that would go and connect to all potential clients to push a web page - skipping all the NAT/firewall issues that just doesn't scale and is prone to head-of-the-list delays in a sequential single-threaded implementation and to waste of resources in any multi-threaded setup.
I would suggest switching to conventional client-server model where teacher is the server, and students are the clients connecting on demand.
For the time being I have got a shim to be over with it. However I am going to try the "collection of live sockets" thing after I get over with the due release of the software.
Anyways what i have done is following changes to the above code:
try
{
inAddress = InetAddress.getByName(host);
if (!inAddress.isReachable())
{
leftOverStudents++;
failedStudents = key + InitializeTeacherJar.getInstance().getDelimiter();
ApplicationLog.log("Exception :: " + host +" is not reachable as the server is down at his end.", InitializeTeacherJar.getInstance().isLoggingEnabled());
continue;
}
studentSocket = new Socket(inAddress, port);
studentSocket.setSoTimeout(socketTimeout);
}
All I do is just move to next student if it is not reachable.
Thanks for the help anyways.

read sent mails from mail server

i know how can we retrive the mails from INBOX folder...but now i want to retrieve mails from SENT ITEMS folder...i am using imap to retrieve the data...
Let me know what parameter i should pass in this function to get mails from SENT ITEMS folder
Folder folder=store.getFolder("inbox");i should change the inbox as some stirng i want to know that string...
There is not a standard name here. The IMAP spec requires that the inbox be called "INBOX", but no other folders are specifically defined. It's just a name of a folder after all - some providers will use "Sent", some will use "Sent Items" and you might even see some other variants about.
I'd recommend listing the folders that the server knows about, and selecting the appropriate one from there (either interactively, or perhaps grepping for "sent" in the name if running headless). A better option overall might be to make this a configurable parameter (if your application already has a properties file).
Of course, if this is a throwaway project you could just hard-code the value for the specific server in question. But if you want to do it properly, you'll need to be flexible.
I found the solution for my problem....
i used this code to list out the folders from mail server
and pass those values in getFolder() function...it's working fine..
Folder[] folderList = store.getDefaultFolder().list();
for (int i = 0; i < folderList.length; i++) {
System.out.println(folderList[i].getFullName());
}
Gmail stores sent mails under a folder called Sent Mail inside [Gmail] folder. So I was able to get the sent mail folder through this;
Folder sentMail = store.getFolder( "[Gmail]" ).getFolder( "Sent Mail" );
This code will retrieve all mails and will print the contents and store in local if have any attachment
public class MailReader {
Folder inbox;
public MailReader() {
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "username",
"password");
/* Mention the folder name which you want to read. */
inbox = store.getFolder("Inbox");
System.out.println("No of Unread Messages : "
+ inbox.getMessageCount() + " "
+ inbox.getUnreadMessageCount());
/* Open the inbox using store. */
inbox.open(Folder.READ_ONLY);
/*
* Get the messages which is unread in the Inbox Message messages[]
* = inbox.search(new FlagTerm( new Flags(Flag.SEEN), false));
*/
Message messages[] = inbox.getMessages();
/* Use a suitable FetchProfile */
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.CONTENT_INFO);
inbox.fetch(messages, fp);
try {
printAllMessages(messages);
inbox.close(true);
store.close();
} catch (Exception ex) {
System.out.println("Exception arise at the time of read mail");
ex.printStackTrace();
}
} catch (NoSuchProviderException e) {
e.printStackTrace();
System.exit(1);
} catch (MessagingException e) {
e.printStackTrace();
System.exit(2);
}
}
public void printAllMessages(Message[] msgs) throws Exception {
for (int i = 0; i < msgs.length; i++) {
System.out.println("MESSAGE #" + (i + 1) + ":");
printEnvelope(msgs[i]);
}
}
/* Print the envelope(FromAddress,ReceivedDate,Subject) */
public void printEnvelope(Message message) throws Exception {
Address[] a;
// FROM
if ((a = message.getFrom()) != null) {
for (int j = 0; j < a.length; j++) {
System.out.println("FROM: " + a[j].toString());
}
}
// TO
if ((a = message.getRecipients(Message.RecipientType.TO)) != null) {
for (int j = 0; j < a.length; j++) {
System.out.println("TO: " + a[j].toString());
}
}
String subject = message.getSubject();
Date receivedDate = message.getReceivedDate();
String content = message.getContent().toString();
System.out.println("Subject : " + subject);
System.out.println("Received Date : " + receivedDate.toString());
System.out.println("Content : " + content);
getContent(message);
}
public void getContent(Message msg) {
try {
String contentType = msg.getContentType();
System.out.println("Content Type : " + contentType);
Multipart mp = (Multipart) msg.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++) {
dumpPart(mp.getBodyPart(i));
}
} catch (Exception ex) {
System.out.println("Exception arise at get Content");
ex.printStackTrace();
}
}
public void dumpPart(Part p) throws Exception {
// Dump input stream ..
if (p.getFileName() == null) {
return;
}
System.out.println("filename:" + p.getFileName());
System.out.println(p.ATTACHMENT);
InputStream is = p.getInputStream();
File file = new File(p.getFileName());
FileOutputStream fout = null;
fout = new FileOutputStream(p.getFileName());
// If "is" is not already buffered, wrap a BufferedInputStream
// around it.
if (!(is instanceof BufferedInputStream)) {
is = new BufferedInputStream(is);
}
int c;
System.out.println("Message : ");
while ((c = is.read()) != -1) {
fout.write(c);
}
if (fout != null) {
fout.close();
}
}
public static void main(String args[]) {
new MailReader();
}
}

Categories