ARMEBS4  revision-26.06.2015
androsensor.c
1 #include "heivs/config.h"
2 #if (USE_STM32_USB_HOST_MODE || USE_STM32_USB_USE_DEVICE_MODE || USE_STM32_USB_OTG_MODE)
3 #include "config/usb_conf.h"
4 #if defined(USE_HOST_MODE)
5 
8 #include <string.h>
9 
10 static const uint32_t USE_KEEPALIVE = 0;
11 #define ANDROSENSOR_KEEPALIVE_TIME_MS (500)
12 
13 static const uint8_t ANDROSENSOR_SOF[] = {0xff,'a','s',0xff,0x00,0x00,0x00,0x01};
14 
15 enum androsensor_msg_type
16 {
17  MSG_TYPE_KEEPALIVE = 0x33,
18  MSG_TYPE_DATA = 0x01,
19 };
20 
21 struct androsensor_msg_t
22 {
23  uint8_t sof[sizeof(ANDROSENSOR_SOF)];
24  uint8_t len[sizeof(uint32_t)];
25  uint8_t type[sizeof(uint32_t)];
26  uint8_t data[];
27 };
28 
29 static void encode_32(uint8_t *data, uint32_t value)
30 {
31  *data++ = value >> 24;
32  *data++ = value >> 16;
33  *data++ = value >> 8;
34  *data++ = value >> 0;
35 }
36 
37 static uint32_t decode_32(uint8_t *data)
38 {
39  uint32_t value = 0;
40  value |= *data++;
41  value <<= 8;
42  value |= *data++;
43  value <<= 8;
44  value |= *data++;
45  value <<= 8;
46  value |= *data++;
47 
48  return value;
49 }
50 
51 static uint32_t buffer[(128+sizeof(struct androsensor_msg_t)+sizeof(uint32_t)-1) / sizeof(uint32_t)];
52 
53 static status_e msg_send(struct androsensor_t *as, enum androsensor_msg_type type, const uint8_t *data, uint32_t len)
54 {
55  struct androsensor_msg_t *msg = (struct androsensor_msg_t *)buffer;
56 
57  if (!androsensor_active(as))
58  {
59  return ERROR_BAD_STATE;
60  }
61 
62  if (len + sizeof(struct androsensor_msg_t) > sizeof(buffer))
63  {
64  return ERROR_BAD_PARAM;
65  }
66 
67  memcpy(msg->sof, ANDROSENSOR_SOF, sizeof(ANDROSENSOR_SOF));
68  encode_32(msg->len, len);
69  encode_32(msg->type, type);
70  memcpy(msg->data, data, len);
71 
72  USBH_ADK_write(&USB_OTG_Core, (uint8_t*)msg, sizeof(*msg) + len);
73 
74  return NO_ERROR;
75 }
76 
77 void androsensor_process(struct androsensor_t *as)
78 {
79  status_e status;
80  const uint8_t keepalive_msg[] = {0x00,0x00};
81  struct androsensor_msg_t *msg = (struct androsensor_msg_t *)&as->inbuff;
82 
83  USBH_Process(&USB_OTG_Core , &USB_Host);
84 
85  if (USE_KEEPALIVE && time_elapsed(as->keepalive_out_timeout))
86  {
87  as->keepalive_out_timeout = time_set_timeout_ms(ANDROSENSOR_KEEPALIVE_TIME_MS);
88  msg_send(as, MSG_TYPE_KEEPALIVE, keepalive_msg, sizeof(keepalive_msg));
89  }
90 
91  if (USE_KEEPALIVE && time_elapsed(as->keepalive_in_timeout))
92  {
93  as->keepalive_in_timeout = time_set_timeout_ms(0);
94  as->keepalive_in_timeout = time_set_timeout_ms(ANDROSENSOR_KEEPALIVE_TIME_MS);
95  if (as->keepalivefatal)
96  {
97  as->state = STATE_UNKNOWN;
98  }
99  }
100 
101  if (!USBH_ADK_Connected())
102  {
103  return;
104  }
105 
106  status = USBH_ADK_read(&USB_OTG_Core, (uint8_t *)as->inbuff, sizeof(as->inbuff), &as->insize);
107  if (status != NO_ERROR)
108  {
109  return ;
110  }
111 
112  if (!as->insize)
113  {
114  return;
115  }
116 
117  if (memcmp(msg->sof, ANDROSENSOR_SOF, sizeof(msg->sof)) )
118  {
119  as->insize = 0;
120  return ;
121  }
122 
123  if (decode_32(msg->type) == MSG_TYPE_KEEPALIVE)
124  {
125  as->keepalive_in_timeout = time_set_timeout_ms(ANDROSENSOR_KEEPALIVE_TIME_MS);
126  as->state = STATE_CONNECTED;
127 
128  return;
129  }
130 
131  as->insize = decode_32(msg->len);
132  if (decode_32(msg->len) > as->insize)
133  {
134  as->insize = 0;
135  return;
136  }
137 
138  memcpy(as->inbuff, msg->data, as->insize);
139 }
140 
141 status_e androsensor_init_master(struct androsensor_t *as, const char* manufacture, const char* model, const char* description, const char* version, const char* uri, const char* serial)
142 {
143  as->keepalive_out_timeout = time_set_timeout_ms(ANDROSENSOR_KEEPALIVE_TIME_MS);
144  as->keepalive_in_timeout = time_set_timeout_ms(ANDROSENSOR_KEEPALIVE_TIME_MS);
145  as->insize = 0;
146  as->keepalivefatal = 0;
147 
148  USBH_ADK_Init
149  (
150  manufacture,
151  model,
152  description,
153  version,
154  uri,
155  serial
156  );
157 
158  return NO_ERROR;
159 }
160 
161 uint32_t androsensor_active(struct androsensor_t *as)
162 {
163  if (!USBH_ADK_Connected())
164  {
165  as->state = STATE_UNKNOWN;
166  }
167  else
168  {
169  as->state = STATE_CONNECTED;
170  }
171 
172  if (as->state != STATE_CONNECTED)
173  {
174  return 0;
175  }
176 
177  return 1;
178 }
179 
180 status_e androsensor_write(struct androsensor_t *as, const uint8_t *data, size_t len)
181 {
182  return msg_send(as, MSG_TYPE_DATA, data, len);
183 }
184 
185 status_e androsensor_read(struct androsensor_t *as, uint8_t *data, size_t len, size_t *rlen)
186 {
187  *rlen = 0;
188  if (as->insize)
189  {
190  memcpy(data, as->inbuff, len);
191  // FIXME : remove the memset when debugged
192  memset(as->inbuff, 0x00, as->insize);
193  *rlen = as->insize;
194  as->insize = 0;
195  }
196 
197  return NO_ERROR;
198 }
199 
200 #endif
201 #endif /* (USE_STM32_USB_HOST_MODE || USE_STM32_USB_USE_DEVICE_MODE || USE_STM32_USB_OTG_MODE) */
void * memcpy(void *dest, const void *src, size_t n)
void * memset(void *dest, int n, size_t n)
Androsensor protocol.
libheivs configuration file
This file contains all the prototypes for the usbh_adk_core.c.
static uint32_t time_elapsed(timeout_t timeout)
Is this time passed?
Definition: time.h:71
Function called at bad time.
Definition: error.h:67
Parameter unsupported.
Definition: error.h:56
timeout_t time_set_timeout_ms(uint32_t ms)
Set an obscure time at least ms milliseconds in the future.
Definition: time.c:15
int memcmp(const void *s1, const void *s2, size_t n)
status_e
Known errors.
Definition: error.h:21
No error.
Definition: error.h:28