OMAPI  1.8
Open Movement Public API
download.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2012, Newcastle University, UK.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
17  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23  * POSSIBILITY OF SUCH DAMAGE.
24  */
25 
43 /* Headers */
44 #ifdef _WIN32
45 #define _CRT_SECURE_NO_WARNINGS
46 #endif
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 
51 /* API header */
52 #include "omapi.h"
53 
54 
55 /* Tee - duplicate output to stderr */
56 char tee = 0;
57 #define printf(...) { fprintf(stdout, __VA_ARGS__); fflush(stdout); if (tee) { fprintf(stderr, __VA_ARGS__); } }
58 
59 
60 /* Globals */
61 static const char *downloadPath = ".";
62 
63 
64 /* Logging callback */
65 void logCallback(void *reference, const char *message)
66 {
67  printf("%s", message);
68 }
69 
70 
71 /* Device updated */
72 static void download_DeviceCallback(void *reference, int deviceId, OM_DEVICE_STATUS status)
73 {
74  if (status == OM_DEVICE_CONNECTED)
75  {
76  int result;
77  unsigned int sessionId;
78  int dataBlockSize = 0, dataOffsetBlocks = 0, dataNumBlocks = 0;
79  OM_DATETIME startTime = 0, endTime = 0;
80 
81  printf("DOWNLOAD #%d: Device CONNECTED\n", deviceId);
82 
83  /* Get the session id */
84  result = OmGetSessionId(deviceId, &sessionId);
85  if (OM_FAILED(result)) { printf("ERROR: OmGetSessionId() %s\n", OmErrorString(result)); return; }
86  printf("DOWNLOAD #%d: SessionId = %d\n", deviceId, sessionId);
87 
88  /* Get the data range */
89  result = OmGetDataRange(deviceId, &dataBlockSize, &dataOffsetBlocks, &dataNumBlocks, &startTime, &endTime);
90  if (OM_FAILED(result)) { printf("ERROR: OmGetDataRange() %s\n", OmErrorString(result)); return; }
91  printf("DOWNLOAD #%d: %d blocks data, at offset %d blocks (1 block = %d bytes)\n", deviceId, dataNumBlocks, dataOffsetBlocks, dataBlockSize);
92  /* Display the data start and end times */
93  {
94  char startString[OM_DATETIME_BUFFER_SIZE], endString[OM_DATETIME_BUFFER_SIZE];
95  OmDateTimeToString(startTime, startString);
96  OmDateTimeToString(endTime, endString);
97  printf("DOWNLOAD #%d: ... %s --> %s\n", deviceId, startString, endString);
98  }
99 
100  /* Check if there's any data blocks stored (not just the headers) */
101  if (dataNumBlocks - dataOffsetBlocks <= 0)
102  {
103  printf("DOWNLOAD #%d: Ignoring - no data stored.\n", deviceId);
104  }
105  else
106  {
107  char *file;
108 
109  /* Allocate filename string */
110  file = (char *)malloc(strlen(downloadPath) + 32); /* downloadPath + "/4294967295-65535.cwa" + 1 (NULL-terminated) */
111 
112  /* Copy path, and platform-specific path separator char */
113  strcpy(file, downloadPath);
114  #ifdef _WIN32
115  if (file[strlen(file) - 1] != '\\') strcat(file, "\\");
116  #else
117  if (file[strlen(file) - 1] != '/') strcat(file, "/");
118  #endif
119 
120  /* Append session-id and device-id as part of the filename */
121  sprintf(file + strlen(file), "%010u-%05u.cwa", sessionId, deviceId);
122 
123  /* Begin download */
124  printf("DOWNLOAD #%d: Starting download to file: %s\n", deviceId, file);
125  result = OmBeginDownloading(deviceId, 0, -1, file);
126  if (OM_FAILED(result)) { printf("ERROR: OmBeginDownloading() %s\n", OmErrorString(result)); }
127 
128  /* Free filename string */
129  free(file);
130  }
131  }
132  else if (status == OM_DEVICE_REMOVED)
133  {
134  printf("DOWNLOAD #%d: Device REMOVED\n", deviceId);
135  /* The download will have already been cancelled in the event of a device removal */
136  /*OmCancelDownload(deviceId);*/
137  }
138  else
139  {
140  printf("DOWNLOAD #%d: Error, unexpected status %d\n", deviceId, status);
141  }
142  return;
143 }
144 
145 
146 /* Download updated */
147 static void download_DownloadCallback(void *reference, int deviceId, OM_DOWNLOAD_STATUS status, int value)
148 {
149  if (status == OM_DOWNLOAD_PROGRESS)
150  {
151  printf("DOWNLOAD #%d: Progress %d%%.\n", deviceId, value);
152  }
153  else if (status == OM_DOWNLOAD_COMPLETE)
154  {
155  printf("DOWNLOAD #%d: Complete.\n", deviceId);
156  }
157  else if (status == OM_DOWNLOAD_CANCELLED)
158  {
159  printf("DOWNLOAD #%d: Cancelled.\n", deviceId);
160  }
161  else if (status == OM_DOWNLOAD_ERROR)
162  {
163  printf("DOWNLOAD #%d: Error. (Diagnostic 0x%04x)\n", deviceId, value);
164  }
165  else
166  {
167  printf("DOWNLOAD #%d: Unexpected status %d / 0x%04x\n", deviceId, status, value);
168  }
169  return;
170 }
171 
172 
173 /* Download function */
174 int download(const char *outpath)
175 {
176  int result;
177 
178  /* Set the global path (used by the device callback) */
179  downloadPath = outpath;
180 
181  /* Sets the callback function that is called whenever an API log message is written. */
182  OmSetLogStream(-1);
184 
185  /* Set device callback before API startup to get initially-connected devices through the callback */
186  OmSetDeviceCallback(download_DeviceCallback, NULL);
187 
188  /* Set download callback */
189  OmSetDownloadCallback(download_DownloadCallback, NULL);
190 
191  printf("Waiting for devices...\n");
192 
193  /* Start the API */
194  result = OmStartup(OM_VERSION);
195  if (OM_FAILED(result)) { printf("ERROR: OmStartup() %s\n", OmErrorString(result)); return -1; }
196 
197  /* Block this thread waiting for a console key-press to terminate the downloader.
198  * The callbacks will allow any existing and future devices connected to have their
199  * data downloaded simultaneously. */
200  getchar();
201  printf("Key pressed, shutting down...\n");
202 
203  /* Shutdown the API (this will cleanly cancel any partial downloads). */
204  result = OmShutdown();
205  if (OM_FAILED(result)) { printf("ERROR: OmShutdown() %s\n", OmErrorString(result)); return -1; }
206  printf("End.\n");
207 
208  return 0;
209 }
210 
211 
212 /* Main function */
213 int download_main(int argc, char *argv[])
214 {
215  const char *outpath = NULL;
216  int i;
217 
218  printf("DOWNLOAD: download data from all devices containing data.\n");
219  printf("\n");
220 
221  for (i = 1; i < argc; i++)
222  {
223  if (argv[i][0] == '-' && argv[i][1] == 't' && argv[i][2] == 'e' && argv[i][3] == 'e' && argv[i][4] == '\0') { tee = 1; }
224  else { outpath = argv[i]; }
225  }
226  if (outpath != NULL)
227  {
228  return download(outpath);
229  }
230  else
231  {
232  printf("Usage: download <output-path>\n");
233  printf("\n");
234  printf("Where: output-path: the directory to download the data files to.\n");
235  printf("\n");
236  printf("Example: download .\n");
237  printf("\n");
238  }
239  return -1;
240 }
241 
OM_DEVICE_REMOVED
Device is being removed, or is already removed.
Definition: omapi.h:289
OM_DEVICE_CONNECTED
Device has been connected.
Definition: omapi.h:290
OmSetDeviceCallback
int OmSetDeviceCallback(OmDeviceCallback deviceCallback, void *reference)
Sets the callback function that is called whenever a device is added or removed.
OmErrorString
const char * OmErrorString(int status)
Returns an error string for the specified API return code.
omapi.h
Open Movement API.
OM_DATETIME
unsigned long OM_DATETIME
Definition: omapi.h:332
OM_DOWNLOAD_COMPLETE
Data download completed successfully.
Definition: omapi.h:852
download_main
int download_main(int argc, char *argv[])
Definition: download.c:213
OM_FAILED
#define OM_FAILED(value)
Macro to check the specified return value for failure.
Definition: omapi.h:1033
OmBeginDownloading
int OmBeginDownloading(int deviceId, int dataOffsetBlocks, int dataLengthBlocks, const char *destinationFile)
Begin downloading the data from the current device.
OM_DOWNLOAD_ERROR
Data download failed with an error (the value parameter to OmDownloadCallback indicates a diagnostic ...
Definition: omapi.h:850
OM_VERSION
#define OM_VERSION
A numeric code for current API version defined in this header file.
Definition: omapi.h:225
OmGetSessionId
int OmGetSessionId(int deviceId, unsigned int *sessionId)
Queries the specified device's session identifier.
logCallback
void logCallback(void *reference, const char *message)
Definition: download.c:65
OmGetDataRange
int OmGetDataRange(int deviceId, int *dataBlockSize, int *dataOffsetBlocks, int *dataNumBlocks, OM_DATETIME *startTime, OM_DATETIME *endTime)
Read the size, time-range, and internal chunking of the data buffer.
OM_DOWNLOAD_PROGRESS
Data download progress (the value parameter to OmDownloadCallback indicates progress percentage)
Definition: omapi.h:851
printf
#define printf(...)
Definition: download.c:57
OmShutdown
int OmShutdown(void)
Shuts down the Open Movement API.
OM_DATETIME_BUFFER_SIZE
#define OM_DATETIME_BUFFER_SIZE
The size of a buffer to hold a string representation of an OM_DATETIME.
Definition: omapi.h:1093
OmSetLogCallback
int OmSetLogCallback(OmLogCallback logCallback, void *reference)
Sets the callback function that is called whenever an API log message is written.
OmSetLogStream
int OmSetLogStream(int fd)
Sets the stream to use for log messages.
OM_DOWNLOAD_CANCELLED
Data download was cancelled cleanly.
Definition: omapi.h:853
OmSetDownloadCallback
int OmSetDownloadCallback(OmDownloadCallback downloadCallback, void *reference)
Sets the callback function that is called for download progress, completion, cancellation,...
OM_DOWNLOAD_STATUS
OM_DOWNLOAD_STATUS
Download states used in the OmDownloadCallback handler.
Definition: omapi.h:847
OmStartup
int OmStartup(int version)
Initializes the Open Movement API.
tee
char tee
Definition: download.c:56
download
int download(const char *outpath)
Definition: download.c:174
OM_DEVICE_STATUS
OM_DEVICE_STATUS
Device states used in the OmDeviceCallback handler.
Definition: omapi.h:287