Author: kmorin Date: 2014-02-14 15:49:07 +0100 (Fri, 14 Feb 2014) New Revision: 48 Url: http://forge.codelutin.com/projects/wlo/repository/revisions/48 Log: fixes #4264 Recevoir les mesures de l'ichtyom?\195?\168tre Added: trunk/src/fr/ifremer/wlo/utils/BigFinFeedReaderRecord.java Modified: trunk/AndroidManifest.xml trunk/res/layout/measurement.xml trunk/src/fr/ifremer/wlo/BigFinCommunicationService.java trunk/src/fr/ifremer/wlo/DeviceListActivity.java trunk/src/fr/ifremer/wlo/MainActivity.java trunk/src/fr/ifremer/wlo/measurement/MeasurementActivity.java Modified: trunk/AndroidManifest.xml =================================================================== --- trunk/AndroidManifest.xml 2014-02-13 21:28:40 UTC (rev 47) +++ trunk/AndroidManifest.xml 2014-02-14 14:49:07 UTC (rev 48) @@ -23,6 +23,7 @@ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" /> + <uses-permission android:name="android.permission.VIBRATE"/> <application android:label="@string/app_name" android:icon="@drawable/wlo_ico" Modified: trunk/res/layout/measurement.xml =================================================================== --- trunk/res/layout/measurement.xml 2014-02-13 21:28:40 UTC (rev 47) +++ trunk/res/layout/measurement.xml 2014-02-14 14:49:07 UTC (rev 48) @@ -4,7 +4,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:keepScreenOn="true"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" Modified: trunk/src/fr/ifremer/wlo/BigFinCommunicationService.java =================================================================== --- trunk/src/fr/ifremer/wlo/BigFinCommunicationService.java 2014-02-13 21:28:40 UTC (rev 47) +++ trunk/src/fr/ifremer/wlo/BigFinCommunicationService.java 2014-02-14 14:49:07 UTC (rev 48) @@ -58,6 +58,7 @@ import android.support.v4.app.TaskStackBuilder; import android.util.Log; import com.google.common.collect.Lists; +import fr.ifremer.wlo.utils.BigFinFeedReaderRecord; import java.io.IOException; import java.io.InputStream; @@ -552,17 +553,48 @@ while (true) { try { // Read from the InputStream - bytes = mmInStream.read(buffer); +// bytes = mmInStream.read(buffer); - Log.d(TAG, "received " + new String(buffer, 0, bytes)); +// Log.d(TAG, "received " + new String(buffer, 0, bytes)); + String result = ""; + + // wait until got a @ + + boolean complete = false; + while (!complete) { + while (mmInStream.available() > 0) { +// if (stop) { +// break; +// } + int c = mmInStream.read(); + if (c == '@') { + complete = true; + } else { + result += (char) c; + } + } + } + +// int atSignIndex = result.indexOf('@'); +// result = result.substring(0, atSignIndex); + + int lastComma = result.lastIndexOf(','); + result = result.substring(0, lastComma); + + lastComma = result.lastIndexOf(',') + 1; + String record = result.substring(0, lastComma); + + String crc = result.substring(lastComma); + + Log.d(TAG, String.format("Record: %s / %s", record, crc)); + BigFinFeedReaderRecord readerRecord = new BigFinFeedReaderRecord(record, crc); + // Send the obtained bytes to the UI Activity + sendMessage(MESSAGE_READ, -1, -1, readerRecord); - sendMessage(MESSAGE_READ, bytes, -1, buffer); - } catch (IOException e) { Log.e(TAG, "disconnected", e); connectionLost(); - break; } } } Modified: trunk/src/fr/ifremer/wlo/DeviceListActivity.java =================================================================== --- trunk/src/fr/ifremer/wlo/DeviceListActivity.java 2014-02-13 21:28:40 UTC (rev 47) +++ trunk/src/fr/ifremer/wlo/DeviceListActivity.java 2014-02-14 14:49:07 UTC (rev 48) @@ -19,8 +19,8 @@ /* * #%L * WLO - * $Id:$ - * $HeadURL:$ + * $Id$ + * $HeadURL$ * %% * Copyright (C) 2013 - 2014 Ifremer * %% @@ -62,6 +62,7 @@ import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; +import fr.ifremer.wlo.utils.BigFinFeedReaderRecord; import java.util.Set; @@ -323,10 +324,9 @@ break; case BigFinCommunicationService.MESSAGE_READ: - byte[] readBuf = (byte[]) msg.obj; + BigFinFeedReaderRecord record = (BigFinFeedReaderRecord) msg.obj; // construct a string from the valid bytes in the buffer - String readMessage = new String(readBuf, 0, msg.arg1); - Log.d(TAG, "read " + readMessage); + Log.d(TAG, "read " + record.getLength()); break; case BigFinCommunicationService.MESSAGE_DEVICE_NAME: Modified: trunk/src/fr/ifremer/wlo/MainActivity.java =================================================================== --- trunk/src/fr/ifremer/wlo/MainActivity.java 2014-02-13 21:28:40 UTC (rev 47) +++ trunk/src/fr/ifremer/wlo/MainActivity.java 2014-02-14 14:49:07 UTC (rev 48) @@ -41,6 +41,7 @@ import fr.ifremer.wlo.preferences.SettingsActivity; import fr.ifremer.wlo.storage.DataCache; import fr.ifremer.wlo.storage.WloSqlOpenHelper; +import fr.ifremer.wlo.utils.BigFinFeedReaderRecord; import java.io.IOException; Modified: trunk/src/fr/ifremer/wlo/measurement/MeasurementActivity.java =================================================================== --- trunk/src/fr/ifremer/wlo/measurement/MeasurementActivity.java 2014-02-13 21:28:40 UTC (rev 47) +++ trunk/src/fr/ifremer/wlo/measurement/MeasurementActivity.java 2014-02-14 14:49:07 UTC (rev 48) @@ -28,7 +28,13 @@ import android.content.Intent; import android.content.res.Configuration; import android.database.Cursor; +import android.media.AudioManager; +import android.media.ToneGenerator; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.os.Vibrator; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.text.Editable; @@ -47,6 +53,7 @@ import android.widget.TextView; import com.google.common.base.Function; import com.google.common.collect.Lists; +import fr.ifremer.wlo.BigFinCommunicationService; import fr.ifremer.wlo.CommercialSpeciesFormActivity; import fr.ifremer.wlo.MainActivity; import fr.ifremer.wlo.MetierFormActivity; @@ -72,6 +79,7 @@ import fr.ifremer.wlo.storage.WloSqlOpenHelper; import fr.ifremer.wlo.utils.BaseModelArrayAdapter; import fr.ifremer.wlo.utils.BaseTextWatcher; +import fr.ifremer.wlo.utils.BigFinFeedReaderRecord; import fr.ifremer.wlo.utils.UIUtils; import org.apache.commons.lang3.ObjectUtils; @@ -272,6 +280,31 @@ commercialSpecies.getPrecision()); actionBar.setSubtitle(vessel.toString(this) + " / " + metier.toString(this)); + + mMessenger = new Messenger(new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case BigFinCommunicationService.MESSAGE_READ: + BigFinFeedReaderRecord record = (BigFinFeedReaderRecord) msg.obj; + + if (record != null && record.getLength() != null) { + final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, ToneGenerator.MAX_VOLUME); + tg.startTone(ToneGenerator.TONE_PROP_BEEP); + + // Get instance of Vibrator from current Context + Vibrator v = (Vibrator) getSystemService(VIBRATOR_SERVICE); + // Vibrate for 300 milliseconds + v.vibrate(300); + + int size = Math.round(record.getLength()); + measurement.setSize(size); + addMeasurement(null); + } + break; + } + } + }); } @Override Added: trunk/src/fr/ifremer/wlo/utils/BigFinFeedReaderRecord.java =================================================================== --- trunk/src/fr/ifremer/wlo/utils/BigFinFeedReaderRecord.java (rev 0) +++ trunk/src/fr/ifremer/wlo/utils/BigFinFeedReaderRecord.java 2014-02-14 14:49:07 UTC (rev 48) @@ -0,0 +1,166 @@ +package fr.ifremer.wlo.utils; + +/* + * #%L + * Tutti :: Ichtyometer API + * $Id: FeedReaderRecord.java 1574 2014-02-06 17:34:03Z tchemit $ + * $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-ichtyometer/src/main/ja... $ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import android.util.Log; +import org.apache.commons.lang3.builder.ToStringBuilder; + +/** + * Record_id,length(mm),weight(g),species,cruise,station,pan,Dt,sz class,gender,text, + * <p/> + * Created on 1/24/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.1 + */ +public class BigFinFeedReaderRecord { + + /** Logger. */ + private static final String TAG = "BigFinFeedReaderRecord"; + + /** + * Incoming raw record. + */ + protected final String record; + + /** + * Incoming crc. + */ + protected final String crc; + + /** + * Our computed crc. + */ + protected final String computedCrc; + + /** + * Extracted length (the first data of the record). + */ + protected final Float length; + + /** + * Computed valid flag (if crc == computedCrc and length != null). + */ + protected final boolean valid; + + public BigFinFeedReaderRecord(String record, String crc) { + this.record = record; + this.crc = crc; + this.computedCrc = computeCRC(record); + this.length = computeLength(record); + + //FIXME Uncomment when computedCrc will be ok + this.valid = length != null; /*&& crc.equals(computedCrc);*/ + } + + public boolean isValid() { + return valid; + } + + public String getRecord() { + return record; + } + + public String getCrc() { + return crc; + } + + public String getComputedCrc() { + return computedCrc; + } + + public Float getLength() { + return length; + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("record", record) + .append("crc", crc) + .append("computedCrc", computedCrc) + .append("valid", valid) + .append("length", length) + .toString(); + } + + public static String computeCRC(String record) { + + // use long because int are signed and add doesn't work correctly + long checksum = 0; + + // to keep using 4 octets (32bites) + long mask = 0b0000000000000000000000000000000011111111111111111111111111111111L; + + for (int i = 0, recordLength = record.length(); i < recordLength; i++) { + + // keep only the first 32 bites + checksum = checksum & mask; + + // get msb bite value + long msb = checksum >> 31; + + Log.d(TAG, String.format("i=%4d char=%s(int:%3d) incoming checksum=%10d msb=%d bits=%33s", i, record.charAt(i), (int) record.charAt(i), checksum, msb, Long.toBinaryString(checksum))); + + // logical shift left + checksum <<= 1; + Log.d(TAG, String.format("After lef shift : %33s", Long.toBinaryString(checksum))); + + // rotates msb to lsb + checksum += msb; + Log.d(TAG, String.format("After add smb : %33s", Long.toBinaryString(checksum))); + + // add new caracter + checksum += record.charAt(i); + Log.d(TAG, String.format("After add car : %33s", Long.toBinaryString(checksum))); + } + + // get a hexadecimal on 32bites -> 8 hexadecimal caracters + String hex = Long.toHexString(checksum).toUpperCase(); + Log.d(TAG, "checksum= " + checksum); + return hex; + } + + protected Float computeLength(String record) { + Float length; + try { + String[] cells = record.split("\\s*,\\s*"); + // first cell is the record number, second one is the length + String lengthCell = cells[1]; + // remove any spaces + lengthCell = lengthCell.replaceAll("\\s*", ""); + + // remove any starting 0 + lengthCell = lengthCell.replaceAll("^0*", ""); + + length = Float.valueOf(lengthCell) * 10; + + } catch (Exception e) { + Log.e(TAG, "Could not get length from " + record, e); + length = null; + } + return length; + } +}