[Pkg-running-devel] [openambit] 29/131: Added support for writing GPS orbit data

Christian Perrier bubulle at moszumanska.debian.org
Thu Jul 17 20:19:08 UTC 2014


This is an automated email from the git hooks/post-receive script.

bubulle pushed a commit to branch master
in repository openambit.

commit 7e2b577f579276b3b89c481580976592f461cfbe
Author: Emil Ljungdahl <emil at kratern.se>
Date:   Thu Jan 9 23:10:02 2014 +0100

    Added support for writing GPS orbit data
---
 src/libambit/libambit.c     |  80 ++++++++++++++----
 src/libambit/libambit.h     |  30 +++++++
 src/libambit/libambit_int.h |  43 ++++++----
 src/libambit/pmem20.c       | 193 ++++++++++++++++++++++++++++++++------------
 src/libambit/protocol.c     |   6 +-
 5 files changed, 265 insertions(+), 87 deletions(-)

diff --git a/src/libambit/libambit.c b/src/libambit/libambit.c
index 24c7bfb..beb3f43 100644
--- a/src/libambit/libambit.c
+++ b/src/libambit/libambit.c
@@ -127,6 +127,9 @@ ambit_object_t *libambit_detect(void)
                 }
                 ret_object->device = device;
                 strncpy(ret_object->device_info.name, device->name, LIBAMBIT_PRODUCT_NAME_LENGTH);
+
+                // Initialize pmem
+                libambit_pmem20_init(ret_object, device->pmem20_chunksize);
             }
             else {
                 free(ret_object);
@@ -146,6 +149,8 @@ void libambit_close(ambit_object_t *object)
 {
     if (object != NULL) {
         if (object->handle != NULL) {
+            // Make sure to clear log lock (if possible)
+            lock_log(object, false);
             hid_close(object->handle);
         }
 
@@ -179,6 +184,16 @@ int libambit_device_info_get(ambit_object_t *object, ambit_device_info_t *info)
     return ret;
 }
 
+void libambit_sync_display_show(ambit_object_t *object)
+{
+    lock_log(object, true);
+}
+
+void libambit_sync_display_clear(ambit_object_t *object)
+{
+    lock_log(object, false);
+}
+
 int libambit_date_time_set(ambit_object_t *object, struct tm *tm)
 {
     uint8_t date_data[8];
@@ -237,6 +252,51 @@ int libambit_personal_settings_get(ambit_object_t *object, ambit_personal_settin
     return ret;
 }
 
+int libambit_gps_orbit_header_read(ambit_object_t *object, uint8_t data[8])
+{
+    uint8_t *reply_data = NULL;
+    size_t replylen = 0;
+    int ret = -1;
+
+    if (libambit_protocol_command(object, ambit_command_gps_orbit_head, NULL, 0, &reply_data, &replylen, 0) == 0 && replylen == 9) {
+        memcpy(data, &reply_data[1], 8);
+        libambit_protocol_free(reply_data);
+
+        ret = 0;
+    }
+
+    return ret;
+}
+
+int libambit_gps_orbit_write(ambit_object_t *object, uint8_t *data, size_t datalen)
+{
+    uint8_t header[8], cmpheader[8];
+    int ret = -1;
+
+    libambit_protocol_command(object, ambit_command_write_start, NULL, 0, NULL, NULL, 0);
+
+    if (libambit_gps_orbit_header_read(object, header) == 0) {
+        cmpheader[0] = data[7]; // Year, swap bytes
+        cmpheader[1] = data[6];
+        cmpheader[2] = data[8];
+        cmpheader[3] = data[9];
+        cmpheader[4] = data[13]; // 4 byte swap
+        cmpheader[5] = data[12];
+        cmpheader[6] = data[11];
+        cmpheader[7] = data[10];
+
+        // Check if new data differs 
+        if (memcmp(header, cmpheader, 8) != 0) {
+            ret = libambit_pmem20_gps_orbit_write(object, data, datalen);
+        }
+        else {
+            ret = 0;
+        }
+    }
+
+    return ret;
+}
+
 int libambit_log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_log_push_cb push_cb, ambit_log_progress_cb progress_cb, void *userref)
 {
     int entries_read = 0;
@@ -253,13 +313,10 @@ int libambit_log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_l
     ambit_log_header_t log_header;
     ambit_log_entry_t *log_entry;
 
-    lock_log(object, true);
-
     /*
      * Read number of log entries
      */
     if (libambit_protocol_command(object, ambit_command_log_count, NULL, 0, &reply_data, &replylen, 0) != 0) {
-        lock_log(object, false);
         return -1;
     }
     log_entries_total = le16toh(*(uint16_t*)(reply_data + 2));
@@ -275,7 +332,6 @@ int libambit_log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_l
     if (skip_cb != NULL) {
         // Rewind
         if (libambit_protocol_command(object, ambit_command_log_head_first, NULL, 0, &reply_data, &replylen, 0) != 0) {
-            lock_log(object, false);
             return -1;
         }
         more = le32toh(*(uint32_t*)reply_data);
@@ -285,7 +341,6 @@ int libambit_log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_l
         while (more == 0x00000400) {
             // Go to next entry
             if (libambit_protocol_command(object, ambit_command_log_head_step, NULL, 0, &reply_data, &replylen, 0) != 0) {
-                lock_log(object, false);
                 return -1;
             }
             libambit_protocol_free(reply_data);
@@ -293,13 +348,12 @@ int libambit_log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_l
             // Assume every header is composited by 2 parts, where only the
             // second is of interrest right now
             if (libambit_protocol_command(object, ambit_command_log_head, NULL, 0, &reply_data, &replylen, 0) != 0) {
-                lock_log(object, false);
                 return -1;
             }
             libambit_protocol_free(reply_data);
 
             if (libambit_protocol_command(object, ambit_command_log_head, NULL, 0, &reply_data, &replylen, 0) == 0) {
-                if (replylen > 8 && libambit_pmem20_parse_header(reply_data + 8, replylen - 8, &log_header) == 0) {
+                if (replylen > 8 && libambit_pmem20_log_parse_header(reply_data + 8, replylen - 8, &log_header) == 0) {
                     if (skip_cb(userref, &log_header) != 0) {
                         // Header was NOT skipped, break out!
                         read_pmem = true;
@@ -308,19 +362,16 @@ int libambit_log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_l
                 }
                 else {
                     printf("Failed to parse log header\n");
-                    lock_log(object, false);
                     return -1;
                 }
                 libambit_protocol_free(reply_data);
             }
             else {
-                lock_log(object, false);
                 return -1;
             }
 
             // Is there more entries to read?
             if (libambit_protocol_command(object, ambit_command_log_head_peek, NULL, 0, &reply_data, &replylen, 0) != 0) {
-                lock_log(object, false);
                 return -1;
             }
             more = le32toh(*(uint32_t*)reply_data);
@@ -332,19 +383,18 @@ int libambit_log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_l
     }
 
     if (read_pmem) {
-        if (libambit_pmem20_init(object, object->device->pmem20_chunksize) != 0) {
-            lock_log(object, false);
+        if (libambit_pmem20_log_init(object) != 0) {
             return -1;
         }
 
         // Loop through all log entries, first check headers
-        while (log_entries_walked < log_entries_total && libambit_pmem20_next_header(object, &log_header) == 1) {
+        while (log_entries_walked < log_entries_total && libambit_pmem20_log_next_header(object, &log_header) == 1) {
             if (progress_cb != NULL) {
                 progress_cb(userref, log_entries_total, log_entries_walked+1, 100*log_entries_walked/log_entries_total);
             }
             // Check if this entry needs to be read
             if (skip_cb == NULL || skip_cb(userref, &log_header) != 0) {
-                log_entry = libambit_pmem20_read_entry(object);
+                log_entry = libambit_pmem20_log_read_entry(object);
                 if (log_entry != NULL) {
                     if (push_cb != NULL) {
                         push_cb(userref, log_entry);
@@ -359,8 +409,6 @@ int libambit_log_read(ambit_object_t *object, ambit_log_skip_cb skip_cb, ambit_l
         }
     }
 
-    lock_log(object, false);
-
     return entries_read;
 }
 
diff --git a/src/libambit/libambit.h b/src/libambit/libambit.h
index 0218cd7..bbac537 100644
--- a/src/libambit/libambit.h
+++ b/src/libambit/libambit.h
@@ -365,6 +365,18 @@ bool libambit_device_supported(ambit_object_t *object);
 int libambit_device_info_get(ambit_object_t *object, ambit_device_info_t *status);
 
 /**
+ * Set sync message to device display
+ * \param object Object to set display on
+ */
+void libambit_sync_display_show(ambit_object_t *object);
+
+/**
+ * Clear sync message from device display
+ * \param object Object to clear display on
+ */
+void libambit_sync_display_clear(ambit_object_t *object);
+
+/**
  * Set current date and time to clock
  * \param object Object to write to
  * \param date_time Date and time to set
@@ -389,6 +401,24 @@ int libambit_device_status_get(ambit_object_t *object, ambit_device_status_t *st
 int libambit_personal_settings_get(ambit_object_t *object, ambit_personal_settings_t *settings);
 
 /**
+ * Read GPS orbit header, useful to check if new write is needed.
+ * NOTE! Reversed byte order compared to the data that is written.
+ * \param object Object to get settings from
+ * \param data Header data (date + !?)
+ * \return 0 on success, else -1
+ */
+int libambit_gps_orbit_header_read(ambit_object_t *object, uint8_t data[8]);
+
+/**
+ * Write GPS orbit data
+ * \param object Object to get settings from
+ * \param data Data to be written
+ * \param datalen Length of data
+ * \return 0 on success, else -1
+ */
+int libambit_gps_orbit_write(ambit_object_t *object, uint8_t *data, size_t datalen);
+
+/**
  * Callback function for checking if a specific log entry should be read out or
  * skipped during log readouts
  * \param object Object reference
diff --git a/src/libambit/libambit_int.h b/src/libambit/libambit_int.h
index 4fe6e82..dfdcf19 100644
--- a/src/libambit/libambit_int.h
+++ b/src/libambit/libambit_int.h
@@ -37,20 +37,22 @@ struct ambit_object_s {
     ambit_device_info_t device_info;
 
     struct {
-        bool initialized;
         uint16_t chunk_size;
-        uint32_t first_entry;
-        uint32_t last_entry;
-        uint32_t entries;
-        uint32_t next_free_address;
         struct {
-            uint32_t current;
-            uint32_t next;
-            uint32_t prev;
-        } current;
-        uint8_t *buffer;
-        uint32_t prev_read;
-        uint32_t last_addr;
+            bool initialized;
+            uint32_t first_entry;
+            uint32_t last_entry;
+            uint32_t entries;
+            uint32_t next_free_address;
+            struct {
+                uint32_t current;
+                uint32_t next;
+                uint32_t prev;
+            } current;
+            uint8_t *buffer;
+            uint32_t prev_read;
+            uint32_t last_addr;
+        } log;
     } pmem20;
 };
 
@@ -60,14 +62,19 @@ enum ambit_commands_e {
     ambit_command_date               = 0x0302,
     ambit_command_status             = 0x0306,
     ambit_command_personal_settings  = 0x0b00,
+    ambit_command_unknown1           = 0x0b04,
     ambit_command_log_count          = 0x0b06,
     ambit_command_log_head_first     = 0x0b07,
     ambit_command_log_head_peek      = 0x0b08,
     ambit_command_log_head_step      = 0x0b0a,
     ambit_command_log_head           = 0x0b0b,
+    ambit_command_gps_orbit_head     = 0x0b15,
+    ambit_command_data_write         = 0x0b16,
     ambit_command_log_read           = 0x0b17,
+    ambit_command_data_tail_len      = 0x0b18,
     ambit_command_lock_check         = 0x0b19,
-    ambit_command_lock_set           = 0x0b1a
+    ambit_command_lock_set           = 0x0b1a,
+    ambit_command_write_start        = 0x0b1b // Really!? Just a guess...
 };
 
 // crc16.c
@@ -79,10 +86,12 @@ int libambit_personal_settings_parse(uint8_t *data, size_t datalen, ambit_person
 
 // pmem20.c
 int libambit_pmem20_init(ambit_object_t *object, uint16_t chunk_size);
-int libambit_pmem20_deinit(ambit_object_t *object);
-int libambit_pmem20_next_header(ambit_object_t *object, ambit_log_header_t *log_header);
-ambit_log_entry_t *libambit_pmem20_read_entry(ambit_object_t *object);
-int libambit_pmem20_parse_header(uint8_t *data, size_t datalen, ambit_log_header_t *log_header);
+int libambit_pmem20_log_init(ambit_object_t *object);
+int libambit_pmem20_log_deinit(ambit_object_t *object);
+int libambit_pmem20_log_next_header(ambit_object_t *object, ambit_log_header_t *log_header);
+ambit_log_entry_t *libambit_pmem20_log_read_entry(ambit_object_t *object);
+int libambit_pmem20_log_parse_header(uint8_t *data, size_t datalen, ambit_log_header_t *log_header);
+int libambit_pmem20_gps_orbit_write(ambit_object_t *object, uint8_t *data, size_t datalen);
 
 // protocol.c
 int libambit_protocol_command(ambit_object_t *object, uint16_t command, uint8_t *data, size_t datalen, uint8_t **reply_data, size_t *replylen, uint8_t legacy_format);
diff --git a/src/libambit/pmem20.c b/src/libambit/pmem20.c
index 1b6e474..dde3010 100644
--- a/src/libambit/pmem20.c
+++ b/src/libambit/pmem20.c
@@ -32,6 +32,7 @@
 #define PMEM20_LOG_START          0x000f4240
 #define PMEM20_LOG_SIZE           0x0029f630 /* 2 750 000 */
 #define PMEM20_LOG_HEADER_MIN_LEN        512 /* Header actually longer, but not interesting*/
+#define PMEM20_GPS_ORBIT_START    0x000704e0
 
 typedef struct __attribute__((__packed__)) periodic_sample_spec_s {
     uint16_t type;
@@ -45,6 +46,7 @@ typedef struct __attribute__((__packed__)) periodic_sample_spec_s {
 static int parse_sample(uint8_t *buf, size_t *offset, uint8_t **spec, ambit_log_entry_t *log_entry, size_t *sample_count);
 static int read_upto(ambit_object_t *object, uint32_t address, uint32_t length);
 static int read_log_chunk(ambit_object_t *object, uint32_t address, uint32_t length, uint8_t *buffer);
+static int write_data_chunk(ambit_object_t *object, uint32_t address, size_t buffer_count, uint8_t **buffers, size_t *buffer_sizes);
 static void add_time(ambit_date_time_t *intime, int32_t offset, ambit_date_time_t *outtime);
 static int is_leap(unsigned int y);
 static void to_timeval(ambit_date_time_t *ambit_time, struct timeval *timeval);
@@ -60,34 +62,40 @@ static void to_timeval(ambit_date_time_t *ambit_time, struct timeval *timeval);
  */
 int libambit_pmem20_init(ambit_object_t *object, uint16_t chunk_size)
 {
+    object->pmem20.chunk_size = chunk_size;
+
+    return 0;
+}
+
+int libambit_pmem20_log_init(ambit_object_t *object)
+{
     int ret = -1;
     size_t offset;
 
     // Allocate buffer for complete memory
-    if (object->pmem20.buffer != NULL) {
-        free(object->pmem20.buffer);
+    if (object->pmem20.log.buffer != NULL) {
+        free(object->pmem20.log.buffer);
     }
-    memset(&object->pmem20, 0, sizeof(object->pmem20));
-    object->pmem20.buffer = malloc(PMEM20_LOG_SIZE);
-    if (object->pmem20.buffer != NULL) {
-        object->pmem20.chunk_size = chunk_size;
+    memset(&object->pmem20.log, 0, sizeof(object->pmem20.log));
+    object->pmem20.log.buffer = malloc(PMEM20_LOG_SIZE);
+    if (object->pmem20.log.buffer != NULL) {
         // Read initial log header
-        ret = read_log_chunk(object, PMEM20_LOG_START, object->pmem20.chunk_size, object->pmem20.buffer);
+        ret = read_log_chunk(object, PMEM20_LOG_START, object->pmem20.chunk_size, object->pmem20.log.buffer);
         if (ret == 0) {
-            object->pmem20.prev_read = PMEM20_LOG_START;
+            object->pmem20.log.prev_read = PMEM20_LOG_START;
 
             // Parse PMEM header
             offset = 0;
-            object->pmem20.last_entry = read32inc(object->pmem20.buffer, &offset);
-            object->pmem20.first_entry = read32inc(object->pmem20.buffer, &offset);
-            object->pmem20.entries = read32inc(object->pmem20.buffer, &offset);
-            object->pmem20.next_free_address = read32inc(object->pmem20.buffer, &offset);
-            object->pmem20.current.current = PMEM20_LOG_START;
-            object->pmem20.current.next = object->pmem20.first_entry;
-            object->pmem20.current.prev = PMEM20_LOG_START;
+            object->pmem20.log.last_entry = read32inc(object->pmem20.log.buffer, &offset);
+            object->pmem20.log.first_entry = read32inc(object->pmem20.log.buffer, &offset);
+            object->pmem20.log.entries = read32inc(object->pmem20.log.buffer, &offset);
+            object->pmem20.log.next_free_address = read32inc(object->pmem20.log.buffer, &offset);
+            object->pmem20.log.current.current = PMEM20_LOG_START;
+            object->pmem20.log.current.next = object->pmem20.log.first_entry;
+            object->pmem20.log.current.prev = PMEM20_LOG_START;
 
             // Set initialized
-            object->pmem20.initialized = true;
+            object->pmem20.log.initialized = true;
         }
     }
 
@@ -96,41 +104,41 @@ int libambit_pmem20_init(ambit_object_t *object, uint16_t chunk_size)
 
 int libambit_pmem20_deinit(ambit_object_t *object)
 {
-    if (object->pmem20.buffer != NULL) {
-        free(object->pmem20.buffer);
+    if (object->pmem20.log.buffer != NULL) {
+        free(object->pmem20.log.buffer);
     }
-    memset(&object->pmem20, 0, sizeof(object->pmem20));
+    memset(&object->pmem20.log, 0, sizeof(object->pmem20.log));
 
     return 0;
 }
 
-int libambit_pmem20_next_header(ambit_object_t *object, ambit_log_header_t *log_header)
+int libambit_pmem20_log_next_header(ambit_object_t *object, ambit_log_header_t *log_header)
 {
     int ret = -1;
     size_t buffer_offset;
     uint16_t tmp_len;
 
-    if (!object->pmem20.initialized) {
+    if (!object->pmem20.log.initialized) {
         return -1;
     }
 
     // Check if we reached end of entries
-    if (object->pmem20.current.current == object->pmem20.current.next) {
+    if (object->pmem20.log.current.current == object->pmem20.log.current.next) {
         return 0;
     }
 
-    if (read_upto(object, object->pmem20.current.next, PMEM20_LOG_HEADER_MIN_LEN) == 0) {
-        buffer_offset = (object->pmem20.current.next - PMEM20_LOG_START);
+    if (read_upto(object, object->pmem20.log.current.next, PMEM20_LOG_HEADER_MIN_LEN) == 0) {
+        buffer_offset = (object->pmem20.log.current.next - PMEM20_LOG_START);
         // First check that header seems to be correctly present
-        if (strncmp((char*)object->pmem20.buffer + buffer_offset, "PMEM", 4) == 0) {
-            object->pmem20.current.current = object->pmem20.current.next;
+        if (strncmp((char*)object->pmem20.log.buffer + buffer_offset, "PMEM", 4) == 0) {
+            object->pmem20.log.current.current = object->pmem20.log.current.next;
             buffer_offset += 4;
-            object->pmem20.current.next = read32inc(object->pmem20.buffer, &buffer_offset);
-            object->pmem20.current.prev = read32inc(object->pmem20.buffer, &buffer_offset);
-            tmp_len = read16inc(object->pmem20.buffer, &buffer_offset);
+            object->pmem20.log.current.next = read32inc(object->pmem20.log.buffer, &buffer_offset);
+            object->pmem20.log.current.prev = read32inc(object->pmem20.log.buffer, &buffer_offset);
+            tmp_len = read16inc(object->pmem20.log.buffer, &buffer_offset);
             buffer_offset += tmp_len;
-            tmp_len = read16inc(object->pmem20.buffer, &buffer_offset);
-            if (libambit_pmem20_parse_header(object->pmem20.buffer + buffer_offset, tmp_len, log_header) == 0) {
+            tmp_len = read16inc(object->pmem20.log.buffer, &buffer_offset);
+            if (libambit_pmem20_parse_header(object->pmem20.log.buffer + buffer_offset, tmp_len, log_header) == 0) {
                 ret = 1;
             }
         }
@@ -138,15 +146,15 @@ int libambit_pmem20_next_header(ambit_object_t *object, ambit_log_header_t *log_
 
     // Unset initialized of something went wrong
     if (ret < 0) {
-        object->pmem20.initialized = false;
+        object->pmem20.log.initialized = false;
     }
 
     return ret;
 }
 
-ambit_log_entry_t *libambit_pmem20_read_entry(ambit_object_t *object)
+ambit_log_entry_t *libambit_pmem20_log_read_entry(ambit_object_t *object)
 {
-    // Note! We assume that the caller has called libambit_pmem20_next_header just before
+    // Note! We assume that the caller has called libambit_pmem20_log_next_header just before
     uint8_t *periodic_sample_spec;
     uint16_t tmp_len;
     size_t buffer_offset, sample_count = 0, i;
@@ -158,46 +166,46 @@ ambit_log_entry_t *libambit_pmem20_read_entry(ambit_object_t *object)
     uint32_t last_small_lat = 0, last_small_long = 0;
     uint32_t last_ehpe = 0;
 
-    if (!object->pmem20.initialized) {
+    if (!object->pmem20.log.initialized) {
         return NULL;
     }
 
     // Allocate log entry
     if ((log_entry = calloc(1, sizeof(ambit_log_entry_t))) == NULL) {
-        object->pmem20.initialized = false;
+        object->pmem20.log.initialized = false;
         return NULL;
     }
 
-    buffer_offset = (object->pmem20.current.current - PMEM20_LOG_START);
+    buffer_offset = (object->pmem20.log.current.current - PMEM20_LOG_START);
     buffer_offset += 12;
     // Read samples content definition
-    tmp_len = read16inc(object->pmem20.buffer, &buffer_offset);
-    periodic_sample_spec = object->pmem20.buffer + buffer_offset;
+    tmp_len = read16inc(object->pmem20.log.buffer, &buffer_offset);
+    periodic_sample_spec = object->pmem20.log.buffer + buffer_offset;
     buffer_offset += tmp_len;
     // Parse header
-    tmp_len = read16inc(object->pmem20.buffer, &buffer_offset);
-    if (libambit_pmem20_parse_header(object->pmem20.buffer + buffer_offset, tmp_len, &log_entry->header) != 0) {
+    tmp_len = read16inc(object->pmem20.log.buffer, &buffer_offset);
+    if (libambit_pmem20_log_parse_header(object->pmem20.log.buffer + buffer_offset, tmp_len, &log_entry->header) != 0) {
         free(log_entry);
-        object->pmem20.initialized = false;
+        object->pmem20.log.initialized = false;
         return NULL;
     }
     buffer_offset += tmp_len;
     // Now that we know number of samples, allocate space for them!
     if ((log_entry->samples = calloc(log_entry->header.samples_count, sizeof(ambit_log_sample_t))) == NULL) {
         free(log_entry);
-        object->pmem20.initialized = false;
+        object->pmem20.log.initialized = false;
         return NULL;
     }
     log_entry->samples_count = log_entry->header.samples_count;
 
     // OK, so we are at start of samples, get them all!
     while (sample_count < log_entry->samples_count) {
-        if (PMEM20_LOG_START + buffer_offset + 2 >= object->pmem20.last_addr ||
-            PMEM20_LOG_START + buffer_offset + 2 + read16(object->pmem20.buffer, buffer_offset) >= object->pmem20.last_addr) {
+        if (PMEM20_LOG_START + buffer_offset + 2 >= object->pmem20.log.last_addr ||
+            PMEM20_LOG_START + buffer_offset + 2 + read16(object->pmem20.log.buffer, buffer_offset) >= object->pmem20.log.last_addr) {
             read_upto(object, PMEM20_LOG_START + buffer_offset, object->pmem20.chunk_size);
         }
 
-        if (parse_sample(object->pmem20.buffer, &buffer_offset, &periodic_sample_spec, log_entry, &sample_count) == 1) {
+        if (parse_sample(object->pmem20.log.buffer, &buffer_offset, &periodic_sample_spec, log_entry, &sample_count) == 1) {
             // Calculate times
             if (log_entry->samples[sample_count-1].type == ambit_log_sample_type_periodic) {
                 last_periodic = &log_entry->samples[sample_count-1];
@@ -267,7 +275,7 @@ ambit_log_entry_t *libambit_pmem20_read_entry(ambit_object_t *object)
     return log_entry;
 }
 
-int libambit_pmem20_parse_header(uint8_t *data, size_t datalen, ambit_log_header_t *log_header)
+int libambit_pmem20_log_parse_header(uint8_t *data, size_t datalen, ambit_log_header_t *log_header)
 {
     size_t offset = 0;
 
@@ -344,6 +352,49 @@ int libambit_pmem20_parse_header(uint8_t *data, size_t datalen, ambit_log_header
     return 0;
 }
 
+int libambit_pmem20_gps_orbit_write(ambit_object_t *object, uint8_t *data, size_t datalen)
+{
+    int ret = -1;
+    uint8_t *bufptrs[2];
+    size_t bufsizes[2];
+    uint8_t startheader[4];
+    uint8_t tailbuf[8];
+    uint32_t *_sizeptr = (uint32_t*)&startheader[0];
+    uint32_t address = PMEM20_GPS_ORBIT_START;
+    size_t offset = 0;
+
+    *_sizeptr = htole32(datalen);
+    bufptrs[0] = startheader;
+    bufsizes[0] = 4;
+    bufptrs[1] = data;
+    bufsizes[1] = object->pmem20.chunk_size - 4; // We assume that data is
+                                                 // always > chunk_size
+
+    // Write first chunk (including length)
+    ret = write_data_chunk(object, address, 2, bufptrs, bufsizes);
+    offset += bufsizes[1];
+    address += object->pmem20.chunk_size;
+
+    // Write rest of the chunks
+    while (ret == 0 && offset < datalen) {
+        bufptrs[0] = data + offset;
+        bufsizes[0] = (datalen - offset > object->pmem20.chunk_size ? object->pmem20.chunk_size : datalen - offset);
+
+        ret = write_data_chunk(object, address, 1, bufptrs, bufsizes);
+        offset += bufsizes[0];
+        address += bufsizes[0];
+    }
+
+    // Write tail length (or what is really!?)
+    if (ret == 0) {
+        *((uint32_t*)(&tailbuf[0])) = htole32(PMEM20_GPS_ORBIT_START);
+        *((uint32_t*)(&tailbuf[4])) = htole32(bufsizes[0]);
+        ret = libambit_protocol_command(object, ambit_command_data_tail_len, tailbuf, sizeof(tailbuf), NULL, NULL, 0);
+    }
+
+    return ret;
+}
+
 /**
  * Parse the given sample
  * \return number of samples added (1 or 0)
@@ -644,12 +695,12 @@ static int read_upto(ambit_object_t *object, uint32_t address, uint32_t length)
     uint32_t start_address = address - ((address - PMEM20_LOG_START) % object->pmem20.chunk_size);
 
     while (start_address < address + length) {
-        if (object->pmem20.prev_read != start_address) {
-            if (read_log_chunk(object, start_address, object->pmem20.chunk_size, object->pmem20.buffer + (start_address - PMEM20_LOG_START)) != 0) {
+        if (object->pmem20.log.prev_read != start_address) {
+            if (read_log_chunk(object, start_address, object->pmem20.chunk_size, object->pmem20.log.buffer + (start_address - PMEM20_LOG_START)) != 0) {
                 return -1;
             }
-            object->pmem20.prev_read = start_address;
-            object->pmem20.last_addr = start_address + object->pmem20.chunk_size - 1;
+            object->pmem20.log.prev_read = start_address;
+            object->pmem20.log.last_addr = start_address + object->pmem20.chunk_size - 1;
         }
         start_address += object->pmem20.chunk_size;
     }
@@ -682,6 +733,46 @@ static int read_log_chunk(ambit_object_t *object, uint32_t address, uint32_t len
     return ret;
 }
 
+static int write_data_chunk(ambit_object_t *object, uint32_t address, size_t buffer_count, uint8_t **buffers, size_t *buffer_sizes)
+{
+    int ret = -1;
+
+    uint8_t *reply = NULL;
+    size_t replylen = 0;
+
+    uint8_t *send_data;
+    size_t send_data_len = 8;
+
+    int i;
+    for (i=0; i<buffer_count; i++) {
+        send_data_len += buffer_sizes[i];
+    }
+    send_data = malloc(send_data_len);
+
+    if (send_data != NULL) {
+        uint32_t *_address = (uint32_t*)&send_data[0];
+        uint32_t *_length = (uint32_t*)&send_data[4];
+        uint8_t *send_data_ptr = &send_data[8];
+
+        *_address = htole32(address);
+        *_length = htole32(send_data_len - 8);
+
+        for (i=0; i<buffer_count; i++) {
+            memcpy(send_data_ptr, buffers[i], buffer_sizes[i]);
+            send_data_ptr += buffer_sizes[i];
+        }
+
+        if (libambit_protocol_command(object, ambit_command_data_write, send_data, send_data_len, &reply, &replylen, 0) == 0) {
+            ret = 0;
+        }
+
+        free(send_data);
+        libambit_protocol_free(reply);
+    }
+
+    return ret;
+}
+
 static void add_time(ambit_date_time_t *intime, int32_t offset, ambit_date_time_t *outtime)
 {
     struct timeval timeval;
diff --git a/src/libambit/protocol.c b/src/libambit/protocol.c
index 95527ba..078a2ca 100644
--- a/src/libambit/protocol.c
+++ b/src/libambit/protocol.c
@@ -32,7 +32,7 @@
 /*
  * Local definitions
  */
-#define READ_TIMEOUT       3000 // ms
+#define READ_TIMEOUT       20000 // ms
 #define READ_POLL_INTERVAL 100  // ms
 #define READ_POLL_RETRY    (READ_TIMEOUT / READ_POLL_INTERVAL)
 
@@ -117,9 +117,9 @@ int libambit_protocol_command(ambit_object_t *object, uint16_t command, uint8_t
     dataoffset += packet_payload_len;
 
     // Send additional packets
-    for(i=2; i<=packet_count; i++) {
+    for(i=1; i<packet_count; i++) {
         msg->MP = 0x5e;
-        msg->parts_seq = htobe16(i);
+        msg->parts_seq = htole16(i);
         packet_payload_len = fmin(54, datalen);
         memcpy(&buf[8], &data[dataoffset], packet_payload_len);
         finalize_packet(buf, packet_payload_len);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-running/openambit.git



More information about the Pkg-running-devel mailing list