Skip to content

Commit 3f23a70

Browse files
committed
added MBED wip
1 parent 6023eb9 commit 3f23a70

6 files changed

Lines changed: 484 additions & 0 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
BUILD
2+
mbed-os
3+
.mbed
4+
mbed-os.lib
5+
*.py
6+
*.pyc

.mbedignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
examples/autobahn/*
2+
examples/demo_client/*
3+
examples/transport/*
4+
5+
6+

examples/mbed/readme.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
MBED WIC Wrapper
2+
================
3+
4+
This example makes it a breeze to use WIC on MBED 5 and up.
5+
6+
Work in progress!

examples/mbed/wic_client.cpp

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
#include "mbed.h"
2+
#include "wic_client.hh"
3+
4+
#include <assert.h>
5+
6+
const uint32_t WICClient::socket_open_flag = 1U;
7+
8+
/* constructors *******************************************************/
9+
10+
WICClient::WICClient(NetworkInterface &interface) :
11+
interface(interface),
12+
condition(mutex)
13+
{
14+
init_arg = {0};
15+
16+
init_arg.app = this;
17+
18+
init_arg.tx = tx;
19+
init_arg.tx_max = sizeof(tx);
20+
init_arg.rx = rx;
21+
init_arg.rx_max = sizeof(rx);
22+
23+
init_arg.on_open = handle_open;
24+
init_arg.on_close = handle_close;
25+
init_arg.on_text = handle_text;
26+
init_arg.on_binary = handle_binary;
27+
28+
init_arg.write = handle_write;
29+
init_arg.rand = handle_rand;
30+
31+
init_arg.role = WIC_ROLE_CLIENT;
32+
33+
34+
/* these will block on flags until needed */
35+
writer_thread.start(callback(this, &WICClient::writer_task));
36+
reader_thread.start(callback(this, &WICClient::reader_task));
37+
}
38+
39+
/* static methods *****************************************************/
40+
41+
WICClient *
42+
WICClient::to_obj(struct wic_inst *self)
43+
{
44+
return static_cast<WICClient *>(wic_get_app(self));
45+
}
46+
47+
void
48+
WICClient::handle_write(struct wic_inst *self, const void *data, size_t size)
49+
{
50+
WICClient *obj = to_obj(self);
51+
52+
// this needs to return immediately if there are no buffers
53+
TXBuffer *buf = obj->output.alloc();
54+
55+
(void)memcpy(buf->data, data, size);
56+
buf->size = size;
57+
58+
obj->output.put(buf);
59+
}
60+
61+
uint32_t
62+
WICClient::handle_rand(struct wic_inst *self)
63+
{
64+
// fixme
65+
return 0xaaaaaaaa;
66+
}
67+
68+
void
69+
WICClient::handle_open(struct wic_inst *self)
70+
{
71+
printf("handling open\n");
72+
}
73+
74+
void
75+
WICClient::handle_close(struct wic_inst *self, uint16_t code, const char *reason, uint16_t size)
76+
{
77+
printf("handling close event\n");
78+
79+
WICClient *obj = to_obj(self);
80+
obj->sock.close();
81+
}
82+
83+
void
84+
WICClient::handle_text(struct wic_inst *self, bool fin, const char *data, uint16_t size)
85+
{
86+
printf("handling binary event\n");
87+
}
88+
89+
void
90+
WICClient::handle_binary(struct wic_inst *self, bool fin, const void *data, uint16_t size)
91+
{
92+
printf("handling binary event\n");
93+
}
94+
95+
/* protected instance methods *****************************************/
96+
97+
void
98+
WICClient::do_parse()
99+
{
100+
osEvent evt = input.get();
101+
102+
if(evt.status == osEventMail){
103+
104+
RXBuffer *buf = (RXBuffer *)evt.value.p;
105+
106+
wic_parse(&inst, buf->data, buf->size);
107+
108+
input.free(buf);
109+
}
110+
}
111+
112+
void
113+
WICClient::do_close(bool &done)
114+
{
115+
wic_close(&inst);
116+
done = true;
117+
condition.notify_all();
118+
}
119+
120+
void
121+
WICClient::do_open(bool &done, bool &retval)
122+
{
123+
SocketAddress a;
124+
125+
sock.open(&interface);
126+
127+
interface.gethostbyname(wic_get_url_hostname(&inst), &a);
128+
129+
a.set_port(wic_get_url_port(&inst));
130+
131+
nsapi_error_t err = sock.connect(a);
132+
133+
if(err != NSAPI_ERROR_OK){
134+
135+
switch(err){
136+
case NSAPI_ERROR_DNS_FAILURE:
137+
case NSAPI_ERROR_TIMEOUT:
138+
case NSAPI_ERROR_CONNECTION_TIMEOUT:
139+
//ThisThread::sleep_for(5000);
140+
break;
141+
default:
142+
//ThisThread::sleep_for(5000);
143+
break;
144+
}
145+
146+
//requeue?
147+
//or stay in this event and loop
148+
}
149+
150+
/* this should never fail at this point */
151+
{
152+
bool ok = wic_init(&inst, &init_arg);
153+
assert(ok);
154+
}
155+
156+
/* this might fail if something weird happens like not
157+
* enough memory for all the headers
158+
*
159+
* */
160+
{
161+
bool ok = wic_start(&inst);
162+
assert(ok);
163+
}
164+
165+
flags.set(socket_open_flag);
166+
167+
/* now we actually have to wait for the thign to open */
168+
169+
170+
done = true;
171+
retval = true;
172+
}
173+
174+
void
175+
WICClient::do_tick()
176+
{
177+
}
178+
179+
void
180+
WICClient::do_send_text(bool &done, bool &retval, bool fin, const char *value, uint16_t size)
181+
{
182+
retval = wic_send_text(&inst, fin, value, size);
183+
done = true;
184+
condition.notify_all();
185+
}
186+
187+
void
188+
WICClient::do_send_binary(bool &done, bool &retval, bool fin, const void *value, uint16_t size)
189+
{
190+
retval = wic_send_binary(&inst, fin, value, size);
191+
done = true;
192+
condition.notify_all();
193+
}
194+
195+
void
196+
WICClient::do_signal_socket_error()
197+
{
198+
199+
}
200+
201+
void
202+
WICClient::writer_task(void)
203+
{
204+
osEvent evt;
205+
TXBuffer *buf;
206+
207+
for(;;){
208+
209+
flags.wait_any(socket_open_flag);
210+
211+
for(;;){
212+
213+
evt = output.get();
214+
buf = (TXBuffer *)evt.value.p;
215+
216+
if(sock.send(buf->data, buf->size) != NSAPI_ERROR_OK){
217+
218+
//signal failure to event loop, finalize thread
219+
}
220+
221+
output.free(buf);
222+
}
223+
224+
flags.clear(socket_open_flag);
225+
}
226+
}
227+
228+
void
229+
WICClient::reader_task(void)
230+
{
231+
nsapi_size_or_error_t retval;
232+
RXBuffer *buf;
233+
234+
for(;;){
235+
236+
flags.wait_any(socket_open_flag);
237+
238+
for(;;){
239+
240+
buf = input.alloc();
241+
242+
retval = sock.recv(buf->data, sizeof(buf->data));
243+
244+
if(retval < 0){
245+
246+
// signal failure to event loop
247+
248+
input.free(buf);
249+
break;
250+
}
251+
252+
buf->size = retval;
253+
254+
input.put(buf);
255+
queue.event(this, &WICClient::do_parse);
256+
}
257+
258+
flags.clear(socket_open_flag);
259+
}
260+
}
261+
262+
/* public instance methods ********************************************/
263+
264+
bool
265+
WICClient::open(const char *url)
266+
{
267+
bool retval = false;
268+
bool done = false;
269+
270+
mutex.lock();
271+
272+
do_open(done, retval);
273+
274+
while(!done){
275+
276+
condition.wait();
277+
}
278+
279+
mutex.unlock();
280+
281+
return retval;
282+
}
283+
284+
void
285+
WICClient::close()
286+
{
287+
mutex.lock();
288+
289+
bool done = false;
290+
291+
do_close(done);
292+
293+
while(!done){
294+
295+
condition.wait();
296+
}
297+
298+
mutex.unlock();
299+
}
300+
301+
bool
302+
WICClient::text(const char *value)
303+
{
304+
return text(true, value);
305+
}
306+
307+
bool
308+
WICClient::text(const char *value, uint16_t size)
309+
{
310+
return text(true, value, size);
311+
}
312+
313+
bool
314+
WICClient::text(bool fin, const char *value)
315+
{
316+
bool retval = false;
317+
int size = strlen(value);
318+
319+
if((size >= 0) && (size <= UINT16_MAX)){
320+
321+
retval = text(fin, value, (uint16_t)size);
322+
}
323+
324+
return retval;
325+
}
326+
327+
bool
328+
WICClient::text(bool fin, const char *value, uint16_t size)
329+
{
330+
bool retval = false;
331+
bool done = false;
332+
333+
mutex.lock();
334+
335+
do_send_text(done, retval, fin, value, size);
336+
337+
while(!done){
338+
339+
condition.wait();
340+
}
341+
342+
mutex.unlock();
343+
344+
return retval;
345+
}
346+
347+
bool
348+
WICClient::binary(const void *value, uint16_t size)
349+
{
350+
return binary(true, value, size);
351+
}
352+
353+
bool
354+
WICClient::binary(bool fin, const void *value, uint16_t size)
355+
{
356+
bool retval = false;
357+
bool done = false;
358+
359+
mutex.lock();
360+
361+
do_send_binary(done, retval, fin, value, size);
362+
363+
while(!done){
364+
365+
condition.wait();
366+
}
367+
368+
mutex.unlock();
369+
370+
return retval;
371+
}
372+
373+
bool
374+
WICClient::is_open()
375+
{
376+
return(wic_get_state(&inst) == WIC_STATE_OPEN);
377+
}

0 commit comments

Comments
 (0)