bluez remote improvements
* log BLE battery level to /tmp/batteries/dev_XX_XX_XX_XX_XX_XX
* allow /tmp/gfrm200.{gp,ti}.bin to override /etc/remote/*.bin
* cleanup
Change-Id: Ib84ca289a1b043d0c0f889d8d105938f565af3c4
diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 1bbaa48..58be9fd 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -37,6 +37,7 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include <fcntl.h>
#include <bluetooth/bluetooth.h>
@@ -61,8 +62,9 @@
#define BATT_UUID "0000180f-0000-1000-8000-00805f9b34fb"
#define BATT_LEVEL_UUID "00002a19-0000-1000-8000-00805f9b34fb"
-//#define CHECK_TIME (24*60*60)
-#define CHECK_TIME 10
+#define BATTERY_DIR "/tmp/batteries"
+
+#define CHECK_TIME (8*60*60)
struct service {
guint attio_id;
@@ -79,7 +81,9 @@
struct service level;
- time_t lastCheck;
+ int batt_level;
+
+ time_t next_check;
};
static GSList *devices = NULL;
@@ -89,7 +93,6 @@
{
struct batt_device *battdev;
- DBG("BATT trace");
battdev = g_try_new0(struct batt_device, 1);
if (!battdev)
return NULL;
@@ -102,7 +105,6 @@
static void batt_free_device(struct batt_device *battdev)
{
- DBG("BATT trace");
btd_device_unref(battdev->device);
g_attrib_unref(battdev->attrib);
g_free(battdev->batt_primary);
@@ -119,23 +121,67 @@
return ts.tv_sec;
}
+/* should really be done in the dbus agent, I think */
+static void batt_update_level_file(struct batt_device* battdev)
+{
+ char path[MAXPATHLEN], pathnew[MAXPATHLEN];
+
+ const char* addr = NULL;
+ const char* id = device_get_path(battdev->device);
+
+ /* id == /org/bluez/hci0/dev_D0_5F_B8_29_10_8D */
+
+ if (id != NULL) {
+ addr = rindex(id, '/');
+ if (addr == NULL) {
+ addr = id;
+ } else {
+ addr++;
+ }
+ }
+ if (addr == NULL || *addr == '\0') {
+ addr = "UNKNOWN";
+ }
+
+ snprintf(path, sizeof path, "%s/%s", BATTERY_DIR, addr);
+ snprintf(pathnew, sizeof pathnew, "%s.new", path);
+
+ if (mkdir(BATTERY_DIR, 0777) < 0 && errno != EEXIST) {
+ error("BATT mkdir: %s: %s", BATTERY_DIR, strerror(errno));
+ return;
+ }
+
+ FILE* fp = fopen(pathnew, "w");
+ if (fp == NULL) {
+ error("BATT fopen: %s: %s", pathnew, strerror(errno));
+ return;
+ }
+ fprintf(fp, "%d\n", battdev->batt_level);
+ fclose(fp);
+
+ if (rename(pathnew, path) != 0) {
+ error("BATT rename: %s -> %s: %s", pathnew, path, strerror(errno));
+ return;
+ }
+}
+
static void level_read_char_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
struct batt_device *battdev = user_data;
- DBG("BATT trace");
if (status != 0) {
error("BATT %s failed: %s", __func__, att_ecode2str(status));
return;
}
- int level = pdu[1];
- DBG("BATT level=%d", level);
+ battdev->batt_level = pdu[1];
+ DBG("BATT level=%d", battdev->batt_level);
+ batt_update_level_file(battdev);
}
-static void checkLevel(struct batt_device *battdev)
+static void check_level(struct batt_device *battdev)
{
- battdev->lastCheck = wallclock();
+ battdev->next_check = wallclock() + CHECK_TIME;
if (battdev->level.value_handle == 0)
return;
@@ -143,13 +189,11 @@
level_read_char_cb, battdev);
}
-static int isTimeForLevelCheck(struct batt_device* battdev)
+static int is_time_for_level_check(struct batt_device* battdev)
{
- DBG("BATT trace");
time_t now = wallclock();
- time_t dt = now - battdev->lastCheck;
- if (dt < CHECK_TIME) {
+ if (now < battdev->next_check) {
DBG("BATT not time for level check yet");
return 0;
}
@@ -190,8 +234,8 @@
battdev->level.value_handle = chr->value_handle;
DBG("BATT found BATT_LEVEL_UUID value_handle=0x%04x", chr->value_handle);
//discover_desc(battdev, chr, next);
- if (isTimeForLevelCheck(battdev)) {
- checkLevel(battdev);
+ if (is_time_for_level_check(battdev)) {
+ check_level(battdev);
}
}
}
@@ -203,7 +247,6 @@
struct gatt_primary *prim = battdev->batt_primary;
GSList *l;
- DBG("BATT trace");
DBG("BATT connected");
battdev->attrib = g_attrib_ref(attrib);
@@ -216,8 +259,8 @@
prim->range.end, NULL,
char_discovered_cb, battdev);
} else {
- if (isTimeForLevelCheck(battdev)) {
- checkLevel(battdev);
+ if (is_time_for_level_check(battdev)) {
+ check_level(battdev);
}
}
}
@@ -227,7 +270,6 @@
struct batt_device *battdev = user_data;
GSList *l;
- DBG("BATT trace");
DBG("BATT disconnected");
if (battdev->level.attio_id > 0) {
@@ -246,7 +288,6 @@
GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL;
GIOChannel *io;
- DBG("BATT trace");
battdev = batt_new_device(device, prim->range.start);
if (!battdev)
return NULL;
@@ -263,7 +304,6 @@
static int batt_unregister_device(struct batt_device *battdev)
{
- DBG("BATT trace");
btd_device_remove_attio_callback(battdev->device, battdev->attioid);
batt_free_device(battdev);
@@ -276,7 +316,6 @@
const char *path = device_get_path(device);
GSList *primaries, *l;
- DBG("BATT trace");
DBG("BATT path %s", path);
primaries = btd_device_get_primaries(device);
@@ -307,7 +346,6 @@
struct batt_device *battdev = a;
struct btd_device *device = b;
- DBG("BATT trace");
if (battdev->device != device)
return;
@@ -320,7 +358,6 @@
struct btd_device *device = btd_service_get_device(service);
const char *path = device_get_path(device);
- DBG("BATT trace");
DBG("BATT path %s", path);
g_slist_foreach(devices, remove_device, device);
@@ -337,13 +374,11 @@
{
int err;
- DBG("BATT trace");
return btd_profile_register(&batt_profile);
}
static void batt_exit(void)
{
- DBG("BATT trace");
btd_profile_unregister(&batt_profile);
}
diff --git a/profiles/oad/oad.c b/profiles/oad/oad.c
index 28ab2ce..fd37cd7 100644
--- a/profiles/oad/oad.c
+++ b/profiles/oad/oad.c
@@ -131,6 +131,7 @@
struct oad_fwinfo disk[OADFW_Total];
struct oad_fwinfo remote[OADFW_Total];
+ int force_upgrade;
int retries;
int num_blocks;
int progress;
@@ -182,6 +183,7 @@
error("OAD %s failed: %s", __func__, att_ecode2str(status));
return;
}
+ oaddev->retries = 0; // successful write
}
static void oad_identity_char_write_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data)
@@ -252,8 +254,6 @@
}
gatt_write_char(oaddev->attrib, oaddev->block.value_handle, block,
sizeof(block), oad_block_char_write_cb, oaddev);
-
- oaddev->retries = 0; // got a successful request
}
break;
case OADSTATUS_TransferSuccess: // OK, successful transfer
@@ -400,12 +400,18 @@
{
memset(oaddev->disk, 0, sizeof oaddev->disk);
- // TODO(edjames): change to a directory search list
- // /tmp for debugging
- oad_get_firmware_info(oaddev, "/tmp/" OAD_GP_FIRMWARE);
- oad_get_firmware_info(oaddev, "/tmp/" OAD_TI_FIRMWARE);
- oad_get_firmware_info(oaddev, "/etc/remote/" OAD_GP_FIRMWARE);
- oad_get_firmware_info(oaddev, "/etc/remote/" OAD_TI_FIRMWARE);
+ /* check in tmp first, to make debugging easier */
+ if (access("/tmp/" OAD_GP_FIRMWARE, R_OK) == 0 ||
+ access("/tmp/" OAD_TI_FIRMWARE, R_OK) == 0) {
+ DBG("OAD found firmware in /tmp, ignoring /etc/remote, enabling downgrade.");
+ oaddev->force_upgrade = 1; // allow downgrade
+ oad_get_firmware_info(oaddev, "/tmp/" OAD_GP_FIRMWARE);
+ oad_get_firmware_info(oaddev, "/tmp/" OAD_TI_FIRMWARE);
+ } else {
+ oaddev->force_upgrade = 0;
+ oad_get_firmware_info(oaddev, "/etc/remote/" OAD_GP_FIRMWARE);
+ oad_get_firmware_info(oaddev, "/etc/remote/" OAD_TI_FIRMWARE);
+ }
int i;
for (i = 0; i < OADFW_Total; i++) {
@@ -424,19 +430,12 @@
static void oad_check_for_upgrade(struct oad_device *oaddev)
{
-
if (!oad_is_time_for_upgrade_check(oaddev)) {
return;
}
oad_find_firmware(oaddev);
- int force_upgrade = 0;
-//#define FORCE_UPGRADE
-#ifdef FORCE_UPGRADE
- force_upgrade = 1; // force backward update
-#endif
-
struct oad_fwinfo* fp = NULL;
int i;
for (i = 0; i < OADFW_Total; i++) {
@@ -446,7 +445,8 @@
continue;
}
if (oaddev->disk[i].version == oaddev->remote[i].version ||
- (!force_upgrade && oaddev->disk[i].version < oaddev->remote[i].version)) {
+ (!oaddev->force_upgrade &&
+ oaddev->disk[i].version < oaddev->remote[i].version)) {
DBG("OAD %s firmware is up to date", typeStr);
} else {
fp = &oaddev->disk[i];