OMAPI  1.8
Open Movement Public API
downloadmem.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 /* Allocate download structure */
56 typedef struct
57 {
58  unsigned char *buffer;
59  int capacity;
60  int length;
62 
63 
64 /* Device updated */
65 static void downloadmem_DeviceCallback(void *reference, int deviceId, OM_DEVICE_STATUS status)
66 {
67  if (status == OM_DEVICE_CONNECTED)
68  {
69  downloadStatus_t *downloadStatus;
70  int result;
71 
72  printf("DOWNLOADMEM #%d: Device CONNECTED\n", deviceId);
73 
74  /* Allocate download structure */
75  downloadStatus = (downloadStatus_t *)malloc(sizeof(downloadStatus_t));
76  if (downloadStatus == NULL)
77  {
78  printf("ERROR: Unable to allocate a download status structure\n");
79  return;
80  }
81 
82  /* Initialize download status structure */
83  memset(downloadStatus, 0, sizeof(downloadStatus));
84 
85  /* Get the data file size */
86  downloadStatus->capacity = OmGetDataFileSize(deviceId);
87  if (OM_FAILED(downloadStatus->capacity))
88  {
89  printf("ERROR: OmGetDataFileSize() %s\n", OmErrorString(downloadStatus->capacity));
90  free(downloadStatus);
91  return;
92  }
93 
94  /* Allocate buffer */
95  downloadStatus->buffer = (unsigned char *)malloc(downloadStatus->capacity);
96  if (downloadStatus->buffer == NULL)
97  {
98  printf("ERROR: Unable to allocate a download buffer (%d bytes)\n", downloadStatus->capacity);
99  free(downloadStatus);
100  return;
101  }
102 
103  /* Begin download */
104  printf("DOWNLOADMEM #%d: Starting download to memory\n", deviceId);
105  downloadStatus->length = 0;
106  result = OmBeginDownloadingReference(deviceId, 0, -1, NULL, downloadStatus);
107  if (OM_FAILED(result))
108  {
109  printf("ERROR: OmBeginDownloadingReference() %s\n", OmErrorString(result));
110  free(downloadStatus->buffer);
111  free(downloadStatus);
112  return;
113  }
114 
115  }
116  else if (status == OM_DEVICE_REMOVED)
117  {
118  printf("DOWNLOADMEM #%d: Device REMOVED\n", deviceId);
119  /* The download will have already been cancelled in the event of a device removal */
120  /*OmCancelDownload(deviceId);*/
121  }
122  else
123  {
124  printf("DOWNLOADMEM #%d: Error, unexpected status %d\n", deviceId, status);
125  }
126  return;
127 }
128 
129 
130 /* Download updated */
131 static void downloadmem_DownloadCallback(void *reference, int deviceId, OM_DOWNLOAD_STATUS status, int value)
132 {
133  downloadStatus_t *downloadStatus = (downloadStatus_t *)reference;
134 
135  if (status == OM_DOWNLOAD_PROGRESS)
136  {
137  printf("DOWNLOADMEM #%d: Progress %d%%.\n", deviceId, value);
138  }
139  else if (status == OM_DOWNLOAD_COMPLETE)
140  {
141  printf("DOWNLOADMEM #%d: Complete.\n", deviceId);
142 
143  if (downloadStatus == NULL)
144  {
145  printf("ERROR: No download status tracker.\n");
146  }
147  else if (downloadStatus->buffer == NULL)
148  {
149  printf("ERROR: No download buffer.\n");
150  }
151  else if (downloadStatus->capacity < 0 || downloadStatus->length < 0 || downloadStatus->length > downloadStatus->capacity)
152  {
153  printf("ERROR: Download buffer offsets invalid.\n");
154  }
155  else if (downloadStatus->length < downloadStatus->capacity)
156  {
157  printf("ERROR: Download buffer was not filled.\n");
158  }
159  else
160  {
161  printf("SUCCESS: Download buffer filled in RAM: %d bytes at 0x%p\n", downloadStatus->length, downloadStatus->buffer);
162  /* TODO: Do something with data at downloadStatus->buffer (downloadStatus->length bytes) */
163  }
164  }
165  else if (status == OM_DOWNLOAD_CANCELLED)
166  {
167  printf("DOWNLOADMEM #%d: Cancelled.\n", deviceId);
168  }
169  else if (status == OM_DOWNLOAD_ERROR)
170  {
171  printf("DOWNLOADMEM #%d: Error. (Diagnostic 0x%04x)\n", deviceId, value);
172  }
173  else
174  {
175  printf("DOWNLOADMEM #%d: Unexpected status %d / 0x%04x\n", deviceId, status, value);
176  }
177 
178  // If download complete, remove download buffer
179  if (status == OM_DOWNLOAD_COMPLETE || status == OM_DOWNLOAD_CANCELLED || status == OM_DOWNLOAD_ERROR)
180  {
181  if (downloadStatus != NULL)
182  {
183  downloadStatus->capacity = 0;
184  if (downloadStatus->buffer != NULL)
185  {
186  printf("NOTE: Freeing download buffer @0x%p\n", downloadStatus->buffer);
187  free(downloadStatus->buffer);
188  downloadStatus->buffer = NULL;
189  }
190  free(downloadStatus);
191  }
192  }
193  return;
194 }
195 
196 
197 /* Download chunk */
198 static void downloadmem_DownloadChunkCallback(void *reference, int deviceId, void *buffer, int offset, int length)
199 {
200  downloadStatus_t *downloadStatus = (downloadStatus_t *)reference;
201  int end;
202 
203  end = offset + length;
204  printf("DOWNLOADMEM #%d: Chunk @%d (of %d bytes) => %d bytes total\n", deviceId, offset, length, end);
205 
206  /* Sanity check buffer and offsets */
207  if (downloadStatus == NULL)
208  {
209  printf("ERROR: No download status tracker.\n");
210  return;
211  }
212  if (downloadStatus->buffer == NULL)
213  {
214  printf("ERROR: No download buffer.\n");
215  return;
216  }
217  if (offset < 0 || offset >= downloadStatus->capacity || end < 0 || end > downloadStatus->capacity)
218  {
219  printf("ERROR: Download chunk offsets out of range.\n");
220  return;
221  }
222 
223  /* Copy data to RAM buffer */
224  memcpy(downloadStatus->buffer + offset, buffer, length);
225  downloadStatus->length = end;
226 
227  return;
228 }
229 
230 
231 /* Download to memory function */
232 int downloadmem(void)
233 {
234  int result;
235 
236  /* Set device callback before API startup to get initially-connected devices through the callback */
237  OmSetDeviceCallback(downloadmem_DeviceCallback, NULL);
238 
239  /* Set download callback */
240  OmSetDownloadCallback(downloadmem_DownloadCallback, NULL);
241 
242  /* Set download chunk callback */
243  OmSetDownloadChunkCallback(downloadmem_DownloadChunkCallback, NULL);
244 
245  printf("Waiting for devices...\n");
246 
247  /* Start the API */
248  result = OmStartup(OM_VERSION);
249  if (OM_FAILED(result)) { printf("ERROR: OmStartup() %s\n", OmErrorString(result)); return -1; }
250 
251  /* Block this thread waiting for a console key-press to terminate the downloader.
252  * The callbacks will allow any existing and future devices connected to have their
253  * data downloaded simultaneously. */
254  getchar();
255  printf("Key pressed, shutting down...\n");
256 
257  /* Shutdown the API (this will cleanly cancel any partial downloads). */
258  result = OmShutdown();
259  if (OM_FAILED(result)) { printf("ERROR: OmShutdown() %s\n", OmErrorString(result)); return -1; }
260  printf("End.\n");
261 
262  return 0;
263 }
264 
265 
266 /* Main function */
267 int downloadmem_main(int argc, char *argv[])
268 {
269  printf("DOWNLOADMEM: download data into RAM from all devices containing data.\n");
270  printf("\n");
271  if (argc == 1)
272  {
273  return downloadmem();
274  }
275  else
276  {
277  printf("Usage: downloadmem\n");
278  printf("\n");
279  printf("Example: downloadmem\n");
280  printf("\n");
281  }
282  return -1;
283 }
284 
downloadmem
int downloadmem(void)
Definition: downloadmem.c:232
OM_DEVICE_REMOVED
Device is being removed, or is already removed.
Definition: omapi.h:289
downloadStatus_t::capacity
int capacity
Definition: downloadmem.c:59
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.
downloadStatus_t
Definition: downloadmem.c:56
OM_DOWNLOAD_COMPLETE
Data download completed successfully.
Definition: omapi.h:852
downloadmem_main
int downloadmem_main(int argc, char *argv[])
Definition: downloadmem.c:267
OM_FAILED
#define OM_FAILED(value)
Macro to check the specified return value for failure.
Definition: omapi.h:1033
OmBeginDownloadingReference
int OmBeginDownloadingReference(int deviceId, int dataOffsetBlocks, int dataLengthBlocks, const char *destinationFile, void *reference)
Begin downloading the data from the current device, passing an additional reference.
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
downloadStatus_t::buffer
unsigned char * buffer
Definition: downloadmem.c:58
OmSetDownloadChunkCallback
int OmSetDownloadChunkCallback(OmDownloadChunkCallback downloadChunkCallback, void *reference)
Sets the chunk callback function that is called when a new download chunk is received.
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
downloadStatus_t::length
int length
Definition: downloadmem.c:60
OmShutdown
int OmShutdown(void)
Shuts down the Open Movement API.
OmGetDataFileSize
int OmGetDataFileSize(int deviceId)
Return the data file size of the specified device.
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.
OM_DEVICE_STATUS
OM_DEVICE_STATUS
Device states used in the OmDeviceCallback handler.
Definition: omapi.h:287