blob: 3d1f216f881e6818d33f3152b58a6461cd17d567 [file] [log] [blame]
Damien065f8a52013-12-05 20:38:23 +00001#include <stdlib.h>
2#include <stdint.h>
3#include <stm32f4xx.h>
4#include <stm32f4xx_rcc.h>
5#include <stm32f4xx_gpio.h>
6#include <stm32f4xx_tim.h>
7#include <stm32f4xx_pwr.h>
8#include <stm32f4xx_rtc.h>
9#include <stm32f4xx_usart.h>
10#include <stm_misc.h>
11#include "std.h"
12
13#include "misc.h"
14#include "mpyconfig.h"
15#include "systick.h"
16
17#include "nlr.h"
18#include "misc.h"
19#include "lexer.h"
20#include "parse.h"
21#include "compile.h"
22#include "runtime.h"
23
24#include "cc3k/ccspi.h"
25#include "cc3k/hci.h"
26#include "cc3k/socket.h"
27#include "cc3k/netapp.h"
28#include "cc3k/wlan.h"
29#include "cc3k/nvmem.h"
30
31py_obj_t pyb_wlan_connect(int n_args, const py_obj_t *args) {
32 const char *ap;
33 const char *key;
34 if (n_args == 2) {
35 ap = qstr_str(py_obj_get_qstr(args[0]));
36 key = qstr_str(py_obj_get_qstr(args[1]));
37 } else {
38 ap = "Rama3";
39 key = "underthechristmastree";
40 }
41 // might want to set wlan_ioctl_set_connection_policy
42 int ret = wlan_connect(WLAN_SEC_WPA2, ap, strlen(ap), NULL, (byte*)key, strlen(key));
43 return py_obj_new_int(ret);
44}
45
46py_obj_t pyb_wlan_disconnect(void) {
47 int ret = wlan_disconnect();
48 return py_obj_new_int(ret);
49}
50
51py_obj_t decode_addr(unsigned char *ip, int nBytes) {
52 char data[64] = "";
53 if (nBytes == 4) {
54 snprintf(data, 64, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]);
55 } else if (nBytes == 6) {
56 snprintf(data, 64, "%02x:%02x:%02x:%02x:%02x:%02x", ip[5], ip[4], ip[3], ip[2], ip[1], ip[0]);
57 } else if (nBytes == 32) {
58 snprintf(data, 64, "%s", ip);
59 }
60 return py_obj_new_str(qstr_from_strn_copy(data, strlen(data)));
61}
62
63void _wlan_getIP_get_address(py_obj_t object, qstr q_attr, unsigned char *ip, int nBytes) {
64 rt_store_attr(object, q_attr, decode_addr(ip, nBytes));
65}
66
67py_obj_t pyb_wlan_get_ip(void) {
68 tNetappIpconfigRetArgs ipconfig;
69 netapp_ipconfig(&ipconfig);
70
71 /* If byte 1 is 0 we don't have a valid address */
72 if (ipconfig.aucIP[3] == 0) return py_const_none;
73
74 py_obj_t data = py_module_new(); // TODO should really be a class
75 _wlan_getIP_get_address(data, qstr_from_str_static("ip"), &ipconfig.aucIP[0], 4);
76 _wlan_getIP_get_address(data, qstr_from_str_static("subnet"), &ipconfig.aucSubnetMask[0], 4);
77 _wlan_getIP_get_address(data, qstr_from_str_static("gateway"), &ipconfig.aucDefaultGateway[0], 4);
78 _wlan_getIP_get_address(data, qstr_from_str_static("dhcp"), &ipconfig.aucDHCPServer[0], 4);
79 _wlan_getIP_get_address(data, qstr_from_str_static("dns"), &ipconfig.aucDNSServer[0], 4);
80 _wlan_getIP_get_address(data, qstr_from_str_static("mac"), &ipconfig.uaMacAddr[0], 6);
81 _wlan_getIP_get_address(data, qstr_from_str_static("ssid"), &ipconfig.uaSSID[0], 32);
82
83 return data;
84}
85
86uint32_t last_ip = 0; // XXX such a hack!
87py_obj_t pyb_wlan_get_host(py_obj_t host_name) {
88 const char *host = qstr_str(py_obj_get_qstr(host_name));
89 uint32_t ip;
90 if (gethostbyname(host, strlen(host), &ip) < 0) {
91 printf("gethostbyname failed\n");
92 return py_const_none;
93 }
94 if (ip == 0) {
95 // unknown host
96 return py_const_none;
97 }
98 last_ip = ip;
99 byte ip_data[4];
100 ip_data[0] = ((ip >> 0) & 0xff);
101 ip_data[1] = ((ip >> 8) & 0xff);
102 ip_data[2] = ((ip >> 16) & 0xff);
103 ip_data[3] = ((ip >> 24) & 0xff);
104 return decode_addr(ip_data, 4);
105}
106
107py_obj_t py_obj_new_exception_2(qstr, const char *, void*, void*);
108
109py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) {
110 if (host_name == py_const_none) {
111 last_ip = (192 << 24) | (168 << 16) | (0 << 8) | (3);
112 } else {
113 if (pyb_wlan_get_host(host_name) == py_const_none) {
114 nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "unknown host", NULL, NULL));
115 }
116 }
117 int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
118 if (sd < 0) {
119 nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd, NULL));
120 }
121 //printf("socket seemed to work\n");
122 //sys_tick_delay_ms(200);
123 sockaddr_in remote;
124 memset(&remote, 0, sizeof(sockaddr_in));
125 remote.sin_family = AF_INET;
126 remote.sin_port = htons(80);
127 remote.sin_addr.s_addr = htonl(last_ip);
128 int ret = connect(sd, (sockaddr*)&remote, sizeof(sockaddr));
129 if (ret != 0) {
130 nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "connect failed: %d", (void*)ret, NULL));
131 }
132 //printf("connect seemed to work\n");
133 //sys_tick_delay_ms(200);
134
135 vstr_t *vstr = vstr_new();
136 vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", qstr_str(py_obj_get_qstr(host_path)), qstr_str(py_obj_get_qstr(host_name)));
137 const char *query = vstr_str(vstr);
138
139 // send query
140 {
141 int sent = 0;
142 while (sent < strlen(query)) {
143 /*
144 extern void SpiIntGPIOHandler(void);
145 SpiIntGPIOHandler();
146 */
147 //printf("sending %d bytes\n", strlen(query + sent));
148 ret = send(sd, query + sent, strlen(query + sent), 0);
149 //printf("sent %d bytes\n", ret);
150 if (ret < 0) {
151 nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "send failed", NULL, NULL));
152 }
153 sent += ret;
154 //sys_tick_delay_ms(200);
155 }
156 }
157
158 //printf("send seemed to work!\n");
159 //sys_tick_delay_ms(5000);
160
161 // receive reply
162 py_obj_t py_ret = py_const_none;
163 {
164 //printf("doing receive\n");
165 char buf[64];
166 vstr_reset(vstr);
167
168 for (;;) {
169 // do a select() call on this socket
170 timeval timeout;
171 fd_set fd_read;
172
173 memset(&fd_read, 0, sizeof(fd_read));
174 FD_SET(sd, &fd_read);
175
176 timeout.tv_sec = 0;
177 timeout.tv_usec = 500000; // 500 millisec
178
179 int s = select(sd+1, &fd_read, NULL, NULL, &timeout);
180 if (s == 0) {
181 // no data available
182 break;
183 }
184
185 // read data
186 ret = recv(sd, buf, 64, 0);
187 if (ret < 0) {
188 nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "recv failed %d", (void*)ret, NULL));
189 }
190 vstr_add_strn(vstr, buf, ret);
191 }
192
193 py_ret = py_obj_new_str(qstr_from_str_take(vstr_str(vstr)));
194 }
195
196 closesocket(sd);
197
198 return py_ret;
199}
200
201py_obj_t pyb_wlan_serve(void) {
202 printf("serve socket\n");
203 int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
204 printf("serve socket got %d\n", sd);
205 sys_tick_delay_ms(500);
206 if (sd < 0) {
207 printf("socket fail\n");
208 nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd, NULL));
209 }
210
211 /*
212 if (setsockopt(sd, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, SOCK_ON, sizeof(SOCK_ON)) < 0) {
213 printf("couldn't set socket as non-blocking\n");
214 return py_const_none;
215 }
216 */
217
218 sockaddr_in remote;
219 memset(&remote, 0, sizeof(sockaddr_in));
220 remote.sin_family = AF_INET;
221 remote.sin_port = htons(8080);
222 remote.sin_addr.s_addr = htonl(0);
223 printf("serve bind\n");
224 int ret = bind(sd, (sockaddr*)&remote, sizeof(sockaddr));
225 printf("serve bind got %d\n", ret);
226 sys_tick_delay_ms(100);
227 if (ret != 0) {
228 printf("bind fail\n");
229 nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "bind failed: %d", (void*)ret, NULL));
230 }
231 printf("bind seemed to work\n");
232
233 // listen
234 ret = listen(sd, 0);
235 printf("listen = %d\n", ret);
236 sys_tick_delay_ms(100);
237
238 // accept connections
239 int fd = -1;
240 for (;;) {
241 sockaddr accept_addr;
242 socklen_t accept_len;
243 fd = accept(sd, &accept_addr, &accept_len);
244 printf("accept = %d\n", fd);
245 sys_tick_delay_ms(500);
246 if (fd >= 0) {
247 break;
248 }
249 }
250
251 // receive some data
252 {
253 printf("receiving on sd=%d fd=%d\n", sd, fd);
254 char buf[64];
255 ret = recv(fd, buf, 64, 0);
256 printf("recv = %d\n", ret);
257 if (ret > 0) {
258 printf("****%.*s****\n", ret, buf);
259 }
260 sys_tick_delay_ms(100);
261 }
262
263 // send some data
264 ret = send(fd, "test data!", 10, 0);
265 printf("send = %d\n", ret);
266 sys_tick_delay_ms(100);
267
268 closesocket(fd);
269 closesocket(sd);
270
271 return py_const_none;
272}
273
274//*****************************************************************************
275//
276//! CC3000_UsynchCallback
277//!
278//! @param lEventType Event type
279//! @param data
280//! @param length
281//!
282//! @return none
283//!
284//! @brief The function handles asynchronous events that come from CC3000
285//! device and operates a led for indicate
286//
287//*****************************************************************************
288void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
289{
290 if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
291 {
292 //ulSmartConfigFinished = 1;
293 //ucStopSmartConfig = 1;
294 printf("WLAN: simple config done\n");
295 }
296
297 if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
298 {
299 //ulCC3000Connected = 1;
300 printf("WLAN unsol connect\n");
301 }
302
303 if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
304 {
305 //ulCC3000Connected = 0;
306 //ulCC3000DHCP = 0;
307 //ulCC3000DHCP_configured = 0;
308 printf("WLAN unsol disconnect\n");
309 }
310
311 if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
312 {
313 //ulCC3000DHCP = 1;
314 printf("WLAN unsol DHCP\n");
315 }
316
317 if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN)
318 {
319 //OkToDoShutDown = 1;
320 printf("WLAN can shut down\n");
321 }
322
323 if (lEventType == HCI_EVNT_WLAN_ASYNC_PING_REPORT)
324 {
325 printf("WLAN async ping report\n");
326 //PRINT_F("CC3000: Ping report\n\r");
327 //pingReportnum++;
328 //memcpy(&pingReport, data, length);
329 }
330
331 if (lEventType == HCI_EVNT_BSD_TCP_CLOSE_WAIT) {
332 printf("WLAN bsd tcp close wait\n");
333 /*
334 uint8_t socketnum;
335 socketnum = data[0];
336 //PRINT_F("TCP Close wait #"); printDec(socketnum);
337 if (socketnum < MAX_SOCKETS)
338 closed_sockets[socketnum] = true;
339 */
340 }
341}
342
343void pyb_wlan_init(void) {
344 SpiInit();
345 wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin);
346
347 py_obj_t m = py_module_new();
348 rt_store_attr(m, qstr_from_str_static("connect"), rt_make_function_var(0, pyb_wlan_connect));
349 rt_store_attr(m, qstr_from_str_static("disconnect"), rt_make_function_0(pyb_wlan_disconnect));
350 rt_store_attr(m, qstr_from_str_static("ip"), rt_make_function_0(pyb_wlan_get_ip));
351 rt_store_attr(m, qstr_from_str_static("get_host"), rt_make_function_1(pyb_wlan_get_host));
352 rt_store_attr(m, qstr_from_str_static("http_get"), rt_make_function_2(pyb_wlan_http_get));
353 rt_store_attr(m, qstr_from_str_static("serve"), rt_make_function_0(pyb_wlan_serve));
354 rt_store_name(qstr_from_str_static("wlan"), m);
355}
356
357void pyb_wlan_start(void) {
358 wlan_start(0);
359
360 // TODO: check return value !=0
361
362 wlan_ioctl_set_connection_policy(0, 0, 0); // don't auto-connect
363 wlan_ioctl_del_profile(255); // delete stored eeprom data
364
365 // Mask out all non-required events from CC3000
366 wlan_set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT |
367 //HCI_EVNT_WLAN_ASYNC_PING_REPORT |// we want ping reports
368 //HCI_EVNT_BSD_TCP_CLOSE_WAIT |
369 //HCI_EVNT_WLAN_TX_COMPLETE |
370 HCI_EVNT_WLAN_KEEPALIVE);
371
372 /*
373 byte ver[2];
374 int ret = nvmem_read_sp_version(ver);
375 printf("nvmem_read_sp_version=%d; %02x %02x\n", ret, ver[0], ver[1]);
376 */
377}