1package com.android.bluetooth.tests;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.io.OutputStream;
6
7import android.util.Log;
8
9public class ObexTestDataHandler {
10
11    final String TAG;
12    String TAG_BASE = "ObexTestDataHandler";
13    static final boolean V = true;
14
15    private static final long PROGRESS_INTERVAL_MS = 1000;
16    int mBufferSize = 0;
17    int mThrottle = 0;
18    long mBytesToTransfer = 0;
19    long mBytesTransfered = 0;
20    long mStartTime = 0;
21    long mLastReport = 0;
22    IResultLogger mResults;
23
24    public ObexTestDataHandler(String tag) {
25        TAG = TAG_BASE + tag;
26    }
27
28    /**
29     * Call after a sleep to calculate the number of buffers to
30     * send to match the throttle value.
31     *
32     * @param bufferSize
33     * @param throttle
34     * @return the number of buffers to send, to match the throttle value
35     */
36    private int getNumberOfBuffers() {
37        if(mThrottle == 0) {
38            return 1;
39        }
40        long deltaT = System.currentTimeMillis() - mStartTime;
41        long deltaB = deltaT*mThrottle/1000; // the amount of bytes we should have sent
42        long bytesMissing = deltaB-mBytesTransfered;
43        return (int)((bytesMissing+(mBufferSize>>1))/mBufferSize); // Round result
44    }
45
46    private void publishProgressIfNeeded() {
47        long now = System.currentTimeMillis();
48        if((now-mLastReport) > PROGRESS_INTERVAL_MS) {
49            mLastReport = now;
50            String result = "Avg: " + mResults.getAverageSpeed()/1024
51                    + " Avg(1s): " + mResults.getAverageSpeed(1000)/1024 +
52                    " mBytesTransfered: " + mBytesTransfered + "\n";
53            if(V) Log.v(TAG,result);
54        }
55    }
56
57    public void readData(InputStream inStream, ObexTestParams params) {
58        /* TODO: parse in the step params
59         * Consider introducing a testStep prepare and wait for completion interface?
60         * in stead of using OBEX headers to carry the index... */
61
62        mBufferSize = params.packageSize;
63        mThrottle = params.throttle;
64        mBytesToTransfer = params.bytesToSend;
65        mBytesTransfered = 0;
66        mResults = TestResultLogger.createLogger();
67        mStartTime = System.currentTimeMillis();
68
69        byte[] buffer = new byte[params.packageSize];
70        if(V) Log.v(TAG, "readData() started data to read: " + params.bytesToSend);
71        try {
72            while(mBytesTransfered < mBytesToTransfer) {
73                int nRx = getNumberOfBuffers();
74                for(; nRx > 0 ; nRx--) {
75                    if(V) Log.v(TAG, "Read()");
76                    int count = inStream.read(buffer);
77                    if(V) Log.v(TAG, "Read() done - count=" + count);
78                    if(count == -1) {
79                        throw new IOException("EOF reached too early mBytesTransfered=" + mBytesTransfered);
80                    }
81                    mBytesTransfered += count;
82                    if(mBytesTransfered >= mBytesToTransfer) {
83                        nRx=0; // break
84                    }
85                    mResults.addResult(mBytesTransfered);
86                    publishProgressIfNeeded();
87                }
88                if(mThrottle != 0) {
89                    // Sleep one package of time.
90                    try {
91                        long sleepTime = (1000*mBufferSize)/mThrottle;
92                        if(V) Log.v(TAG, "Throttle Sleep():" + sleepTime);
93                        Thread.sleep(sleepTime);
94                    } catch (InterruptedException e) {
95                        // Just ignore as the getNumberOfBuffersToSend will compensate
96                        // TODO: Handle Abort
97                    }
98                }
99            }
100        }
101        catch(IOException e) {
102            Log.e(TAG, "Error in readData():",e);
103            } finally {
104        }
105    }
106
107    public void writeData(OutputStream outStream, ObexTestParams params) {
108        mBufferSize = params.packageSize;
109        mThrottle = params.throttle;
110        mBytesToTransfer= params.bytesToSend;
111        mBytesTransfered = 0;
112        mResults = TestResultLogger.createLogger();
113        mStartTime = System.currentTimeMillis();
114
115        byte[] buffer = new byte[params.packageSize];
116        if(V) Log.v(TAG, "writeData() started data to write: " + params.bytesToSend);
117        try {
118            while(mBytesTransfered < mBytesToTransfer) {
119                int nTx = getNumberOfBuffers();
120                if(V) Log.v(TAG, "Write nTx " + nTx + " packets");
121                for(; nTx > 0 ; nTx--) {
122                    if(V) Log.v(TAG, "Write()");
123                    if((mBytesTransfered + mBufferSize) < mBytesToTransfer) {
124                        outStream.write(buffer);
125                        mBytesTransfered += mBufferSize;
126                    } else {
127                        outStream.write(buffer, 0, (int) (mBytesToTransfer-mBytesTransfered));
128                        mBytesTransfered += mBytesToTransfer-mBytesTransfered;
129                        nTx = 0;
130                    }
131                    mResults.addResult(mBytesTransfered);
132                    publishProgressIfNeeded();
133                    if(V) Log.v(TAG, "Write mBytesTransfered: " + mBytesTransfered);
134                }
135                if(mThrottle != 0) {
136                    // Sleep one package of time.
137                    try {
138                        long sleepTime = (1000*mBufferSize)/mThrottle;
139                        if(V) Log.v(TAG, "Throttle Sleep():" + sleepTime);
140                        Thread.sleep(sleepTime);
141                    } catch (InterruptedException e) {
142                        // Just ignore as the getNumberOfBuffersToSend will compensate
143                        // TODO: Handle Abort
144                    }
145
146                }
147
148            }
149        }
150        catch(IOException e) {
151            Log.e(TAG, "Error in ListenTask:",e);
152        }
153    }
154}
155