+commit ed267e76eb03c34ec233c33a002ec9e5e53ec83a
+Merge: bd71c839 ef70f80b
+Author: Bdale Garbee <bdale@gag.com>
+Date: Sun Oct 10 21:41:50 2021 -0600
+
+ Merge branch 'master' into branch-1.9
+
+commit ef70f80b324e9c8ba7046b5000e0f28f77a54f8c
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun Oct 10 09:57:45 2021 -0700
+
+ Version 1.9.10
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 67a1d9b5bcd9bd7dd4156010264cef6b9c87caa3
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun Oct 10 09:49:49 2021 -0700
+
+ altos/telemega-v5.0: Add .gitignore
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 47d7affffdf97188a034bb48918ec22f03ea5b38
+Author: Keith Packard <keithp@keithp.com>
+Date: Sun Oct 10 09:47:52 2021 -0700
+
+ doc: Version 1.9.10 notes
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit eb39995ded6b564efcb5a5312119d2672b437bc8
+Author: Keith Packard <keithp@keithp.com>
+Date: Sat Oct 9 21:32:17 2021 -0700
+
+ altosdroid: Catch log file open failures and show an error dialog
+
+ Android changed which directories we can write to once, let's hope it
+ doesn't happen again.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 3488d86de2e114a46e59bd4d2a2d7b95bf633963
+Author: Keith Packard <keithp@keithp.com>
+Date: Sat Oct 9 21:31:24 2021 -0700
+
+ altoslib: Add callback from AltosLog on file open failure
+
+ This lets the UI tell the user that logging isn't working.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 4b3ccb73a26f91917d327558295506ce3c02d684
+Author: Keith Packard <keithp@keithp.com>
+Date: Sat Oct 9 20:58:26 2021 -0700
+
+ altosdroid: Switch storage to media dir
+
+ Even with the WRITE_EXTERNAL_STORAGE permission, we appear to no
+ longer have permission to write to a random external storage
+ dir. Instead, we only have permission to write to an app-specific dir,
+ buried deep in the directory tree. We can get that directory name with
+ getExternalMediaDirs()[0].
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 536e53c2e17b37df8c65d2f6921a5d68791a7789
+Author: Keith Packard <keithp@keithp.com>
+Date: Fri Oct 8 18:31:35 2021 -0700
+
+ Version 1.9.9.1
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 5cb393c1743a5c0f307631199abba067821db370
+Author: Keith Packard <keithp@keithp.com>
+Date: Thu Oct 7 22:45:37 2021 -0700
+
+ libaltos: Use original windows printf/scanf
+
+ mingw now uses "improved" versions of printf/scanf, which may cause
+ trouble with some windows 10 installs. Just use the old versions.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit c15bb9513ab0f8636bf52ec827551134c773e832
+Author: Keith Packard <keithp@keithp.com>
+Date: Wed Oct 6 22:58:09 2021 -0700
+
+ libaltos: Make windows dlls reproducible
+
+ Use SOURCE_DATE_EPOCH=0 to ensure these dlls are
+ reproducible.
+
+ Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit bd71c839b542c417a90ab59db97e0969f7e27731
+Author: Bdale Garbee <bdale@gag.com>
+Date: Thu Oct 7 00:00:42 2021 -0600
+
+ releasing 1.9.9
+
commit 2f1d5b25e72324512238920b45e864bf7c5d16fe
Merge: c0fe810e 6ef22682
Author: Bdale Garbee <bdale@gag.com>
import java.lang.ref.WeakReference;
import java.util.*;
+import java.io.*;
import android.Manifest;
import android.app.Activity;
public static final int MSG_UPDATE_AGE = 2;
public static final int MSG_IDLE_MODE = 3;
public static final int MSG_IGNITER_STATUS = 4;
+ public static final int MSG_FILE_FAILED = 5;
// Intent request codes
public static final int REQUEST_CONNECT_DEVICE = 1;
ad.idle_mode = (Boolean) msg.obj;
ad.update_state(null);
break;
+ case MSG_FILE_FAILED:
+ ad.file_failed((File) msg.obj);
+ break;
}
}
};
}
}
+ boolean fail_shown;
+
+ private void file_failed(File file) {
+ if (!fail_shown) {
+ fail_shown = true;
+ AlertDialog fail = new AlertDialog.Builder(this).create();
+ fail.setTitle("Failed to Create Log File");
+ fail.setMessage(file.getPath());
+ fail.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ });
+ fail.show();
+ }
+ }
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
public String getString(String key, String def) {
String ret;
- ret = prefs.getString(key, def);
-// AltosDebug.debug("AltosDroidPreferencesBackend get string %s:\n", key);
-// if (ret == null)
-// AltosDebug.debug(" (null)\n");
-// else {
-// String[] lines = ret.split("\n");
-// for (String l : lines)
-// AltosDebug.debug(" %s\n", l);
-// }
+ if (key.equals(AltosPreferences.logdirPreference))
+ ret = null;
+ else
+ ret = prefs.getString(key, def);
+ AltosDebug.debug("AltosDroidPreferencesBackend get string %s:\n", key);
+ if (ret == null)
+ AltosDebug.debug(" (null)\n");
+ else {
+ String[] lines = ret.split("\n");
+ for (String l : lines)
+ AltosDebug.debug(" %s\n", l);
+ }
return ret;
}
}
public File homeDirectory() {
- return Environment.getExternalStorageDirectory();
+ return context.getExternalMediaDirs()[0];
}
public void debug(String format, Object ... arguments) {
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.com>
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
package org.altusmetrum.AltosDroid;
+import java.io.*;
+
import org.altusmetrum.altoslib_14.*;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.os.Environment;
-public class TelemetryLogger {
- private Context context = null;
+public class TelemetryLogger implements AltosLogTrace {
+ private TelemetryService service = null;
private AltosLink link = null;
private AltosLog logger = null;
private BroadcastReceiver mExternalStorageReceiver;
- public TelemetryLogger(Context in_context, AltosLink in_link) {
- context = in_context;
+ /* AltosLogTrace interface */
+ public void trace(String format, Object ... arguments) {
+ AltosDebug.debug(format, arguments);
+ }
+
+ public void open_failed(File file) {
+ service.send_file_failed_to_clients(file);
+ }
+
+ public TelemetryLogger(TelemetryService in_service, AltosLink in_link) {
+ service = in_service;
link = in_link;
startWatchingExternalStorage();
if (Environment.MEDIA_MOUNTED.equals(state)) {
if (logger == null) {
AltosDebug.debug("Starting up Telemetry Logging");
- logger = new AltosLog(link);
+ logger = new AltosLog(link,this);
}
} else {
AltosDebug.debug("External Storage not present - stopping");
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
- context.registerReceiver(mExternalStorageReceiver, filter);
+ service.registerReceiver(mExternalStorageReceiver, filter);
handleExternalStorageState();
}
void stopWatchingExternalStorage() {
- context.unregisterReceiver(mExternalStorageReceiver);
+ service.unregisterReceiver(mExternalStorageReceiver);
}
}
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeoutException;
+import java.io.*;
import java.util.*;
import android.app.*;
send_idle_mode_to_client(client);
}
+ private void send_file_failed_to_client(Messenger client, File f) {
+ Message m = Message.obtain(null, AltosDroid.MSG_FILE_FAILED, f);
+ try {
+ client.send(m);
+ } catch (RemoteException e) {
+ AltosDebug.error("Client %s disappeared", client.toString());
+ remove_client(client);
+ }
+ }
+
+ public void send_file_failed_to_clients(File f) {
+ for (Messenger client : clients)
+ send_file_failed_to_client(client, f);
+ }
+
private void telemetry_start() {
if (telemetry_reader == null && idle_monitor == null && !ignite_running) {
telemetry_reader = new TelemetryReader(altos_link, handler);
Thread log_thread;
AltosFile file;
AltosLink link;
+ AltosLogTrace trace;
+
+ private void trace(String format, Object ... arguments) {
+ if (trace != null)
+ trace.trace(format, arguments);
+ }
private void close_log_file() {
if (log_file != null) {
}
boolean open (AltosCalData cal_data) throws IOException, InterruptedException {
+ trace("open serial %d flight %d receiver_serial %d",
+ cal_data.serial,
+ cal_data.flight,
+ cal_data.receiver_serial);
+
AltosFile a = new AltosFile(cal_data);
- log_file = new FileWriter(a, true);
+ trace("open file %s\n", a.getPath());
+
+ try {
+ log_file = new FileWriter(a, true);
+ } catch (IOException ie) {
+ log_file = null;
+ trace("open file failed\n");
+ if (trace != null)
+ trace.open_failed(a);
+ }
if (log_file != null) {
+ trace("open file success\n");
while (!pending_queue.isEmpty()) {
String s = pending_queue.take();
log_file.write(s);
}
public void run () {
+ trace("log run start\n");
try {
AltosConfigData receiver_config = link.config_data();
AltosCalData cal_data = new AltosCalData();
pending_queue.put(line.line);
}
} catch (InterruptedException ie) {
+ trace("interrupted exception\n");
} catch (TimeoutException te) {
+ trace("timeout exception\n");
} catch (IOException ie) {
+ trace("io exception %s message %s\n", ie.toString(), ie.getMessage());
}
+ trace("log run done\n");
close();
}
- public AltosLog (AltosLink link) {
+ public AltosLog (AltosLink link, AltosLogTrace trace) {
pending_queue = new LinkedBlockingQueue<String> ();
input_queue = new LinkedBlockingQueue<AltosLine> ();
link.add_monitor(input_queue);
serial = -1;
flight = -1;
+ this.trace = trace;
this.link = link;
log_file = null;
log_thread = new Thread(this);
log_thread.start();
}
+
+ public AltosLog (AltosLink link) {
+ this(link, null);
+ }
}
--- /dev/null
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.com>
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_14;
+
+import java.io.*;
+import java.net.*;
+
+public interface AltosLogTrace {
+ public abstract void trace(String format, Object ... arguments);
+
+ public abstract void open_failed(File path);
+}
AltosLink.java \
AltosListenerState.java \
AltosLog.java \
+ AltosLogTrace.java \
AltosMag.java \
AltosMma655x.java \
AltosMs5607.java \
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.9.9)
-ANDROID_VERSION=31
+AC_INIT([altos], 1.9.10)
+ANDROID_VERSION=32
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
-RELEASE_DATE=2021-10-06
+RELEASE_DATE=2021-10-10
AC_SUBST(RELEASE_DATE)
DOC_DATE=`LC_ALL=C date -d $RELEASE_DATE +'%d %b %Y'`
endif
RELNOTES_INC=\
+ release-notes-1.9.10.inc \
release-notes-1.9.9.inc \
release-notes-1.9.8.inc \
release-notes-1.9.7.inc \
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.10.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.9.adoc[]
--- /dev/null
+= Release Notes for Version 1.9.10
+include::release-head.adoc[]
+:doctype: article
+
+ Version 1.9.9
+
+ This release contains a couple of bug fixes for ground station software.
+
+ == AltosUI
+
+ * Rework the windows DLL build to make AltosUI run on more
+ instances of Windows 10.
+
+ == AltosDroid
+
+ * Adapt to Android security changes which prevent AltosDroid
+ from storing flights in
+ /storage/emulated/0/AltusMetrum. Now, flights are stored in
+ /storage/emulated/0/media/org.altusmetrum.AltosDroid/AltusMetrum
+ instead. Also, AltosDroid will display an error message if
+ flight data cannot be logged.
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.10.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.9.adoc[]
[appendix]
== Release Notes
+ :leveloffset: 2
+ include::release-notes-1.9.10.adoc[]
+
+ <<<<
:leveloffset: 2
include::release-notes-1.9.9.adoc[]
fat: all altos.dll altos64.dll
altos.dll: $(WINDOWS_SRC) $(WINDOWS_H)
- $(MINGCC32) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
+ SOURCE_DATE_EPOCH=0 $(MINGCC32) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
altos64.dll: $(WINDOWS_SRC) $(WINDOWS_H)
- $(MINGCC64) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
+ SOURCE_DATE_EPOCH=0 $(MINGCC64) -o $@ $(MINGFLAGS) -shared $(WINDOWS_SRC) $(MINGLIBS)
clean-local:
-rm -rf libaltosJNI *.class *.java classlibaltos.stamp $(SWIG_FILE) libaltos_wrap.c altos.dll altos64.dll
char buffer[4096];
GetLocalTime(&time);
- sprintf (buffer, "%4d-%02d-%02d %2d:%02d:%02d. ",
+ __ms_sprintf (buffer, "%4d-%02d-%02d %2d:%02d:%02d. ",
time.wYear, time.wMonth, time.wDay,
time.wHour, time.wMinute, time.wSecond);
va_start(a, fmt);
- vsprintf(buffer + strlen(buffer), fmt, a);
+ __ms_vsprintf(buffer + strlen(buffer), fmt, a);
va_end(a);
fputs(buffer, log);
if (result != 0) {
altos_set_last_windows_error();
} else {
- sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1,
+ __ms_sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1,
"%04X", &vid);
- sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
+ __ms_sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1,
"%04X", &pid);
- sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
+ __ms_sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,
"%d", &serial);
}
if (vid == 0 || pid == 0 || serial == 0) {
instanceid,
sizeof (instanceid),
&instanceid_len)) {
- sscanf((char *) instanceid + sizeof("USB\\VID_") - 1,
+ __ms_sscanf((char *) instanceid + sizeof("USB\\VID_") - 1,
"%04X", &vid);
- sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_") - 1,
+ __ms_sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_") - 1,
"%04X", &pid);
- sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_XXXX\\") - 1,
+ __ms_sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_XXXX\\") - 1,
"%d", &serial);
} else {
altos_set_last_windows_error();
ba2str(BTH_ADDR ba, char *str)
{
- sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
+ __ms_sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
get_byte(ba, 0),
get_byte(ba, 1),
get_byte(ba, 2),
{
unsigned int bytes[6];
- sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
+ __ms_sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
&bytes[0],
&bytes[1],
&bytes[2],
--- /dev/null
+ao_product.h
+telemega-*.elf