COSA
An Object-Oriented Platform for Arduino Programming
CC3000.cpp
Go to the documentation of this file.
1 
21 #include "CC3000.hh"
22 #if !defined(BOARD_ATTINY)
23 #include "Cosa/RTT.hh"
24 
25 // Enable trace of unsolicited events
26 #define TRACE_ON_EVENT
27 #if defined(TRACE_ON_EVENT)
28 #include "Cosa/Trace.hh"
29 #endif
30 
31 // Some support for setting socket sets for select()
32 #define FD_ZERO() 0UL
33 #define FD_ISSET(fd,set) (((1UL << (fd)) & set) != 0UL)
34 #define FD_SET(fd,set) set = (1UL << (fd)) | set
35 
36 static void
37 memrevcpy(void* dest, const void* src, size_t n)
38 {
39  if (UNLIKELY(n == 0)) return;
40  uint8_t* dp = (uint8_t*) dest;
41  const uint8_t* sp = ((uint8_t*) src) + n ;
42  do *dp++ = *--sp; while (--n);
43 }
44 
45 void
46 CC3000::UnsolicitedEvent::on_event(uint16_t event, void* args, size_t len)
47 {
48  UNUSED(len);
49 #if defined(TRACE_ON_EVENT)
50  trace << RTT::millis() << ':';
51 #endif
52  switch (event) {
54  {
55 #if defined(TRACE_ON_EVENT)
56  trace << PSTR("HCI_EVNT_WLAN_UNSOL_KEEPALIVE:");
57 #endif
58  }
59  break;
61  {
62 #if defined(TRACE_ON_EVENT)
63  trace << PSTR("HCI_EVNT_WLAN_UNSOL_CONNECT:");
64 #endif
65  }
66  break;
68  {
69 #if defined(TRACE_ON_EVENT)
70  trace << PSTR("HCI_EVNT_WLAN_UNSOL_DISCONNECT:");
71 #endif
72  }
73  break;
75  {
78  if (evnt->status != 0) return;
79  m_dev->socket_state(evnt->handle, false);
80 #if defined(TRACE_ON_EVENT)
81  trace << PSTR("HCI_EVNT_WLAN_UNSOL_TCP_CLOSE_WAIT:handle=")
82  << evnt->handle << ',';
83 #endif
84  }
85  break;
87  {
89  evnt = (hci_evnt_data_unsol_free_buff_t*) args;
90  if (evnt->status != 0) return;
92 #if defined(TRACE_ON_EVENT)
93  trace << PSTR("HCI_EVNT_DATA_UNSOL_FREE_BUFF:buffers_freed=")
94  << evnt->flow_control_event.buffers_freed << ',';
95 #endif
96  }
97  break;
99  {
101  evnt = (hci_evnt_wlan_unsol_dhcp_t*) args;
102  if (evnt->status != 0) return;
103  memrevcpy(m_dev->m_ip, evnt->ip, sizeof(m_dev->m_ip));
104  memrevcpy(m_dev->m_subnet, evnt->subnet, sizeof(m_dev->m_subnet));
105  memrevcpy(m_dev->m_gateway, evnt->gateway, sizeof(m_dev->m_gateway));
106  memrevcpy(m_dev->m_dns, evnt->dns, sizeof(m_dev->m_dns));
107 #if defined(TRACE_ON_EVENT)
108  trace << PSTR("HCI_EVNT_WLAN_UNSOL_DHCP:");
109 #endif
110  }
111  break;
112  default:
113 #if defined(TRACE_ON_EVENT)
114  trace << PSTR("HCI_EVNT=") << hex << event
115  << PSTR(",m_buffer_avail=") << m_dev->m_buffer_avail
116  << endl;
117  trace.print(args, len, IOStream::hex);
118 #endif
119  return;
120  }
121 #if defined(TRACE_ON_EVENT)
122  trace << PSTR("m_buffer_avail=") << m_dev->m_buffer_avail << endl;
123 #endif
124 }
125 
126 int
128 {
129  uint32_t readhndls = FD_ZERO();
130  uint32_t writehndls = FD_ZERO();
131  uint32_t errorhndls = FD_ZERO();
132  FD_SET(m_hndl, readhndls);
133  int res = m_dev->select(m_hndl + 1, readhndls, writehndls, errorhndls, 0, 50000);
134  if (res < 0) return (res);
135  return (FD_ISSET(m_hndl,readhndls));
136 }
137 
138 int
140 {
141  // Check room in send buffer
142  return (ENOSYS);
143 }
144 
145 int
146 CC3000::Driver::read(void* buf, size_t size)
147 {
148  int res = available();
149  if (res < 0) return (IOStream::EOF);
150  if (res == 0) return (0);
151  return (m_dev->recv(m_hndl, buf, size));
152 }
153 
154 int
156 {
157  // Force send of buffered message
158  return (ENOSYS);
159 }
160 
161 int
162 CC3000::Driver::open(Protocol proto, uint16_t port, uint8_t flag)
163 {
164  UNUSED(proto);
165  UNUSED(port);
166  UNUSED(flag);
167  return (ENOSYS);
168 }
169 
170 int
172 {
173  return (m_dev->close(m_hndl));
174 }
175 
176 int
178 {
179  return (m_dev->listen(m_hndl));
180 }
181 
182 int
184 {
185  return (m_dev->accept(m_hndl, m_ip, m_port));
186 }
187 
188 int
189 CC3000::Driver::connect(uint8_t addr[4], uint16_t port)
190 {
191  return (m_dev->connect(m_hndl, addr, port));
192 }
193 
194 int
195 CC3000::Driver::connect(const char* hostname, uint16_t port)
196 {
197  UNUSED(hostname);
198  UNUSED(port);
199  return (ENOSYS);
200 }
201 
202 int
204 {
205  return (ENOSYS);
206 }
207 
208 int
210 {
211  return (m_dev->close(m_hndl));
212 }
213 
214 int
215 CC3000::Driver::datagram(uint8_t addr[4], uint16_t port)
216 {
217  UNUSED(addr);
218  UNUSED(port);
219  return (ENOSYS);
220 }
221 
222 int
223 CC3000::Driver::recv(void* buf, size_t len)
224 {
225  return (m_dev->recv(m_hndl, buf, len));
226 }
227 
228 int
229 CC3000::Driver::recv(void* buf, size_t len, uint8_t src[4], uint16_t& port)
230 {
231  UNUSED(buf);
232  UNUSED(len);
233  UNUSED(src);
234  UNUSED(port);
235  return (ENOSYS);
236 }
237 
238 int
239 CC3000::Driver::write(const void* buf, size_t size, bool progmem)
240 {
241  UNUSED(buf);
242  UNUSED(size);
243  UNUSED(progmem);
244  return (ENOSYS);
245 }
246 
247 int
248 CC3000::Driver::send(const void* buf, size_t len, bool progmem)
249 {
250  if (progmem) return (ENOSYS);
251  return (m_dev->send(m_hndl, buf, len));
252 }
253 
254 int
255 CC3000::Driver::send(const void* buf, size_t len,
256  uint8_t dest[4], uint16_t port,
257  bool progmem)
258 {
259  UNUSED(buf);
260  UNUSED(len);
261  UNUSED(dest);
262  UNUSED(port);
263  UNUSED(progmem);
264  return (ENOSYS);
265 }
266 
267 bool
268 CC3000::begin_P(str_P hostname, uint16_t timeout)
269 {
270  UNUSED(hostname);
271  int res;
272 
273  // Setup timeout
274  m_timeout = timeout;
275 
276  // Startup handshake
277  while (m_irq.is_low())
278  ;
279  m_vbat.high();
280  while (m_irq.is_high())
281  ;
282  DELAY(100);
283  m_irq.enable();
284 
285  // Start Simple Link
286  res = simple_link_start(0);
287  if (res < 0) return (false);
288 
289  // Set default connection policy
290  res = wlan_ioctl_set_connection_policy(false, true, false);
291  // res = wlan_ioctl_set_connection_policy(false, false, false);
292  if (res < 0) return (false);
293 
294  // Read number of buffers and buffer size
296  if (res < 0) return (false);
298 
299  // Capture the startup events
301  service();
302  if (res == WLAN_STATUS_CONNECTED) {
303  while (*m_ip == 0) service();
304  }
305 
306  // Read device MAC address
307  res = nvmem_read(NVMEM_MAC_FILEID, m_mac, 0, sizeof(m_mac));
308  if (res < 0) return (false);
310 
311  return (true);
312 }
313 
314 Socket*
315 CC3000::socket(Socket::Protocol proto, uint16_t port, uint8_t flag)
316 {
317  UNUSED(port);
318  UNUSED(flag);
319  int domain = AF_INET;
320  int type, protocol;
321 
322  switch (proto) {
323  case Socket::TCP:
324  protocol = IPPROTO_TCP;
325  type = SOCK_STREAM;
326  break;
327  case Socket::UDP:
328  protocol = IPPROTO_UDP;
329  type = SOCK_DGRAM;
330  break;
331  case Socket::IPRAW:
332  protocol = IPPROTO_RAW;
333  type = SOCK_RAW;
334  break;
335  case Socket::MACRAW:
336  case Socket::PPPoE:
337  default:
338  return (NULL);
339  }
340 
341  int res = socket(domain, type, protocol);
342  if (res < 0) return (NULL);
343 
344  Driver* driver = &m_socket[res];
345  driver->m_hndl = res;
346  driver->m_dev = this;
347 
348  return (driver);
349 }
350 
351 int
352 CC3000::service(uint16_t timeout)
353 {
354  uint32_t start = RTT::millis();
355  while (1) {
356  while (!m_available && (RTT::since(start) < timeout)) yield();
357  if (!m_available) return (0);
359  }
360 }
361 
362 bool
364 {
365  m_irq.disable();
366  m_vbat.low();
367  return (true);
368 }
369 
370 int
372 {
373  // Check arguments
374  if (UNLIKELY(type > WPA2_SECURITY_TYPE)) return (EINVAL);
377 
378  // Build command block and calculate length
379  hci_cmnd_wlan_connect_t cmnd(type, ssid, bssid, key);
380  uint8_t len = sizeof(cmnd) - sizeof(cmnd.data);
381  len += (cmnd.ssid_length + cmnd.key_length);
382 
383  // Issue connect command and await event
384  int res = issue(HCI_CMND_WLAN_CONNECT, &cmnd, len);
385  if (UNLIKELY(res < 0)) return (res);
386  uint32_t saved = m_timeout;
387  m_timeout = 10000;
389  res = await(HCI_EVNT_WLAN_CONNECT, &evnt, sizeof(evnt));
390  m_timeout = saved;
391  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
392  if (UNLIKELY(res < 0)) return (res);
393  return (evnt.result);
394 }
395 
399  4000, // intervall
400  20, // min_dwell_time
401  100, // max_dwell_time
402  5, // num_of_probe_requests
403  0x1fff, // channel_mask
404  -120, // rssi_threshold
405  0, // snr_threshold
406  300, // default_tx_power
407  { // channel_scan_timeout[16]
408  2000,
409  2000,
410  2000,
411  2000,
412  2000,
413  2000,
414  2000,
415  2000,
416  2000,
417  2000,
418  2000,
419  2000,
420  2000,
421  2000,
422  2000,
423  2000
424  }
425 };
426 
427 int
429 {
431  (param != NULL ? param : &DEFAULT_SCANPARAM),
433  if (UNLIKELY(res < 0)) return (res);
434 
435  uint32_t saved = m_timeout;
436  m_timeout = 5000;
438  res = await(HCI_EVNT_WLAN_IOCTL_SET_SCANPARAM, &evnt, sizeof(evnt));
439  m_timeout = saved;
440  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
441  if (UNLIKELY(res < 0)) return (res);
442  return (evnt.result);
443 }
444 
445 int
447 {
449  if (UNLIKELY(res < 0)) return (res);
450 
452  res = await(HCI_EVNT_WLAN_IOCTL_STATUSGET, &evnt, sizeof(evnt));
453  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
454  if (UNLIKELY(res < 0)) return (res);
455  return (evnt.wlan_status);
456 }
457 
458 int
459 CC3000::wlan_ioctl_set_connection_policy(bool should_connect_to_open_ap,
460  bool should_use_fast_connect,
461  bool auto_start_use_profiles)
462 {
464  cmnd(should_connect_to_open_ap, should_use_fast_connect, auto_start_use_profiles);
465  int res = issue(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &cmnd, sizeof(cmnd));
466  if (UNLIKELY(res < 0)) return (res);
467 
468  uint16_t saved = m_timeout;
469  m_timeout = 5000;
471  res = await(HCI_EVNT_WLAN_IOCTL_SET_CONNECTION_POLICY, &evnt, sizeof(evnt));
472  m_timeout = saved;
473  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
474  if (UNLIKELY(res < 0)) return (res);
475  return (evnt.result);
476 }
477 
478 int
480 {
482  int res = issue(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, &cmnd, sizeof(cmnd));
483  if (UNLIKELY(res < 0)) return (res);
484 
485  res = await(HCI_EVNT_WLAN_IOCTL_GET_SCAN_RESULTS, &evnt, sizeof(evnt));
486  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
487  if (UNLIKELY(res < 0)) return (res);
488  return (evnt.network_id);
489 }
490 
491 int
493 {
495  int res = issue(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &cmnd, sizeof(cmnd));
496  if (UNLIKELY(res < 0)) return (res);
497 
498  uint16_t saved = m_timeout;
499  m_timeout = 5000;
501  res = await(HCI_EVNT_WLAN_IOCTL_DEL_PROFILE, &evnt, sizeof(evnt));
502  m_timeout = saved;
503  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
504  if (UNLIKELY(res < 0)) return (res);
505  return (0);
506 }
507 
508 int
510 {
512  int res = issue(HCI_CMND_WLAN_SET_EVENT_MASK, &cmnd, sizeof(cmnd));
513  if (UNLIKELY(res < 0)) return (res);
514 
516  res = await(HCI_EVNT_WLAN_SET_EVENT_MASK, &evnt, sizeof(evnt));
517  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
518  if (UNLIKELY(res < 0)) return (res);
519  return (0);
520 }
521 
522 int
523 CC3000::nvmem_read(uint8_t fileid, void* dst, uint32_t src, size_t length)
524 {
525  hci_cmnd_nvmem_read_t cmnd(fileid, src, length);
526  int res = issue(HCI_CMND_NVMEM_READ, &cmnd, sizeof(cmnd));
527  if (UNLIKELY(res < 0)) return (res);
528 
530  res = await(HCI_EVNT_NVMEM_READ, &evnt, sizeof(evnt));
531  if (UNLIKELY(res < 0)) return (res);
532  delay(10);
534  res = read_data(HCI_DATA_NVMEM_READ, &args, sizeof(args), dst, length);
535  if (UNLIKELY(res < 0)) return (res);
536  if ((args.fileid != fileid)
537  || (args.length != length)
538  || (args.offset != src))
539  return (EFAULT);
540  return (res);
541 }
542 
543 int
545 {
546  // Acquire SPI bus and start message transmission after a short delay
547  spi.acquire(this);
548  spi.begin();
549  DELAY(50);
550 
551  // SPI header with special delay
553  spi.transfer(0);
554  spi.transfer(5);
555  spi.transfer(0);
556  DELAY(50);
557  spi.transfer(0);
558 
559  // HCI header with start command
563  spi.transfer(1);
564  spi.transfer(src);
565 
566  spi.end();
567  spi.release();
568 
569  // Wait for initialization
570  delay(1000);
572  int res = await(HCI_EVNT_SIMPLE_LINK_START, &evnt, sizeof(evnt));
573  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
574  if (UNLIKELY(res < 0)) return (res);
575  return (evnt.status);
576 }
577 
578 int
579 CC3000::read_buffer_size(uint8_t &count, uint16_t &bytes)
580 {
581  int res = issue(HCI_CMND_READ_BUFFER_SIZE);
582  if (UNLIKELY(res < 0)) return (res);
583 
585  res = await(HCI_EVNT_READ_BUFFER_SIZE, &evnt, sizeof(evnt));
586  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
587  if (UNLIKELY(res < 0)) return (res);
588  count = evnt.count;
589  bytes = evnt.bytes;
590  return (evnt.status);
591 }
592 
593 int
594 CC3000::read_sp_version(uint8_t &package_id, uint8_t &package_build_nr)
595 {
596  int res = issue(HCI_CMND_READ_SP_VERSION);
597  if (UNLIKELY(res < 0)) return (res);
598 
600  res = await(HCI_EVNT_READ_SP_VERSION, &evnt, sizeof(evnt));
601  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
602  if (UNLIKELY(res < 0)) return (res);
603  package_id = evnt.package_id;
604  package_build_nr = evnt.package_build_nr;
605  return (evnt.status);
606 }
607 
608 int
609 CC3000::socket(int domain, int type, int protocol)
610 {
611  if (UNLIKELY(domain != AF_INET)) return (EINVAL);
612  hci_cmnd_socket_t cmnd(domain, type, protocol);
613  int res = issue(HCI_CMND_SOCKET, &cmnd, sizeof(cmnd));
614  if (UNLIKELY(res < 0)) return (res);
615 
616  hci_evnt_socket_t evnt;
617  res = await(HCI_EVNT_SOCKET, &evnt, sizeof(evnt));
618  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
619  if (UNLIKELY(res < 0)) return (res);
620  return (evnt.handle);
621 }
622 
623 int
624 CC3000::setsockopt(int hndl, int level, int optname, const void* optval, size_t optlen)
625 {
626  hci_cmnd_setsockopt_t cmnd(hndl, level, optname, optval, optlen);
627  int res = issue(HCI_CMND_SETSOCKOPT, &cmnd, sizeof(cmnd));
628  if (UNLIKELY(res < 0)) return (res);
629 
631  res = await(HCI_EVNT_SETSOCKOPT, &evnt, sizeof(evnt));
632  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
633  if (UNLIKELY(res < 0)) return (res);
634  return (0);
635 }
636 
637 
638 int
639 CC3000::select(int hndls,
640  uint32_t &readhndls, uint32_t &writehndls, uint32_t &errorhndls,
641  uint32_t sec, uint32_t us)
642 {
643  hci_cmnd_select_t cmnd(hndls, readhndls, writehndls, errorhndls, sec, us);
644  int res = issue(HCI_CMND_SELECT, &cmnd, sizeof(cmnd));
645  if (UNLIKELY(res < 0)) return (res);
646 
647  hci_evnt_select_t evnt;
648  res = await(HCI_EVNT_SELECT, &evnt, sizeof(evnt));
649  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
650  if (UNLIKELY(res < 0)) return (res);
651  readhndls = evnt.read_set;
652  writehndls = evnt.write_set;
653  errorhndls = evnt.error_set;
654  return (evnt.result);
655 }
656 
657 int
658 CC3000::connect(int hndl, uint8_t ip[4], int port)
659 {
660  hci_cmnd_connect_t cmnd(hndl, ip, port);
661  int res = issue(HCI_CMND_CONNECT, &cmnd, sizeof(cmnd));
662  if (UNLIKELY(res < 0)) return (res);
663 
664  hci_evnt_connect_t evnt;
665  res = await(HCI_EVNT_CONNECT, &evnt, sizeof(evnt));
666  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
667  if (UNLIKELY(res < 0)) return (res);
668  res = evnt.result;
669  if (!socket_state(res, true)) return (EFAULT);
670  return (res);
671 }
672 
673 int
674 CC3000::recv(int hndl, void* buf, size_t size)
675 {
676  hci_cmnd_recv_t cmnd(hndl, size);
677  int res = issue(HCI_CMND_RECV, &cmnd, sizeof(cmnd));
678 
679  hci_evnt_recv_t evnt;
680  for (uint8_t retry = 0; retry < 3; retry++) {
681  res = await(HCI_EVNT_RECV, &evnt, sizeof(evnt));
682  if (res != ENOMSG) break;
683  }
684  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
685  if (UNLIKELY(res < 0)) return (res);
686  if (UNLIKELY(evnt.handle != hndl)) return (EFAULT);
687  if (UNLIKELY(evnt.count == 0)) return (0);
688 
689  uint32_t start = RTT::millis();
690  uint32_t TIMEOUT = 3000;
691  hci_data_recv_t args;
692  do {
693  while (!m_available && (RTT::since(start) < TIMEOUT)) yield();
694  if (!m_available) return (ETIME);
695  res = read_data(HCI_DATA_RECV, &args, sizeof(args), buf, evnt.count);
696  } while (res == ENOMSG);
697  return (res);
698 }
699 
700 int
701 CC3000::send(int hndl, const void* buf, size_t size)
702 {
703  if (size > BUFFER_MAX) return (EMSGSIZE);
704  while (m_buffer_avail == 0) service();
705  hci_data_send_t cmnd(hndl, size);
706  int res = write_data(HCI_DATA_SEND, &cmnd, sizeof(cmnd), buf, size);
707  if (UNLIKELY(res < 0)) return (res);
708 
709  hci_evnt_send_t evnt;
710  res = await(HCI_EVNT_SEND, &evnt, sizeof(evnt));
711  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
712  if (UNLIKELY(evnt.handle != hndl)) res = EFAULT;
713  if (UNLIKELY(res < 0)) return (res);
714  m_buffer_avail -= 1;
715  return (evnt.result);
716 }
717 
718 int
719 CC3000::bind(int hndl, int port)
720 {
721  hci_cmnd_bind_t cmnd(hndl, port);
722  int res = issue(HCI_CMND_BIND, &cmnd, sizeof(cmnd));
723  if (UNLIKELY(res < 0)) return (res);
724 
725  hci_evnt_bind_t evnt;
726  res = await(HCI_EVNT_BIND, &evnt, sizeof(evnt));
727  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
728  if (UNLIKELY(res < 0)) return (res);
729  return (evnt.result);
730 }
731 
732 int
733 CC3000::listen(int hndl)
734 {
735  hci_cmnd_listen_t cmnd(hndl);
736  int res = issue(HCI_CMND_LISTEN, &cmnd, sizeof(cmnd));
737  if (UNLIKELY(res < 0)) return (res);
738 
739  hci_evnt_listen_t evnt;
740  res = await(HCI_EVNT_LISTEN, &evnt, sizeof(evnt));
741  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
742  if (UNLIKELY(res < 0)) return (res);
743  return (evnt.result);
744 }
745 
746 int
747 CC3000::accept(int hndl, uint8_t ip[4], int &port)
748 {
749  service(1000);
750 
751  hci_cmnd_accept_t cmnd(hndl);
752  int res = issue(HCI_CMND_ACCEPT, &cmnd, sizeof(cmnd));
753  if (UNLIKELY(res < 0)) return (res);
754 
755  hci_evnt_accept_t evnt;
756  res = await(HCI_EVNT_ACCEPT, &evnt, sizeof(evnt));
757  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
758  if (UNLIKELY(evnt.result < 0)) res = evnt.result;
759  if (UNLIKELY(res < 0)) return (res);
760  res = evnt.handle;
761  if (!socket_state(res, true)) return (EFAULT);
762 
763  memrevcpy(ip, evnt.ip, sizeof(evnt.ip));
764  port = evnt.port;
765  m_socket[res].m_hndl = res;
766  return (res);
767 }
768 
769 int
770 CC3000::close(int hndl)
771 {
772  while (m_buffer_avail != BUFFER_COUNT) service(100);
773  service(100);
774 
775  hci_cmnd_close_socket_t cmnd(hndl);
776  int res = issue(HCI_CMND_CLOSE_SOCKET, &cmnd, sizeof(cmnd));
777  if (UNLIKELY(res < 0)) return (res);
778 
780  uint16_t saved = m_timeout;
781  m_timeout = 5000;
782  res = await(HCI_EVNT_CLOSE_SOCKET, &evnt, sizeof(evnt));
783  m_timeout = saved;
784  socket_state(hndl, false);
785  if (UNLIKELY(evnt.status != 0)) res = EFAULT;
786  if (UNLIKELY(res < 0)) return (res);
787  return (evnt.result);
788 }
789 #endif
Definition: Socket.hh:31
int wlan_ioctl_set_connection_policy(bool should_connect_to_open_ap, bool should_use_fast_connect, bool auto_start_use_profiles)
Definition: CC3000.cpp:459
static const hci_cmnd_wlan_ioctl_set_scanparam_t DEFAULT_SCANPARAM
Definition: CC3000.hh:428
static const uint16_t HCI_EVNT_WLAN_IOCTL_SET_CONNECTION_POLICY
Definition: CC3000.hh:1212
static const size_t HCI_CMND_WLAN_CONNECT_KEY_MAX
Definition: CC3000.hh:754
#define EINVAL
Definition: Errno.h:49
uint8_t transfer(uint8_t data)
Definition: SOFT_SPI.cpp:87
virtual int room()
Definition: CC3000.cpp:139
static const uint16_t HCI_EVNT_WLAN_UNSOL_DHCP
Definition: CC3000.hh:1482
static const uint16_t HCI_CMND_ACCEPT
Definition: CC3000.hh:947
static const uint16_t HCI_EVNT_SOCKET
Definition: CC3000.hh:1287
static const uint8_t HCI_DATA_NVMEM_READ
Definition: CC3000.hh:1167
static const uint16_t HCI_EVNT_ACCEPT
Definition: CC3000.hh:1330
static const uint16_t HCI_CMND_BIND
Definition: CC3000.hh:907
virtual int write(const void *buf, size_t size)
Definition: CC3000.hh:74
Security
Definition: CC3000.hh:386
void addr(uint8_t ip[4], uint8_t subnet[4])
Definition: CC3000.hh:329
static const uint16_t HCI_CMND_WLAN_CONNECT
Definition: CC3000.hh:750
static const uint16_t HCI_EVNT_CLOSE_SOCKET
Definition: CC3000.hh:1386
void print(int value, Base base=dec)
Definition: IOStream.cpp:46
int nvmem_read(uint8_t fileid, void *dst, uint32_t src, size_t n)
Definition: CC3000.cpp:523
int service(uint16_t timeout=100)
Definition: CC3000.cpp:352
static const uint16_t HCI_CMND_CLOSE_SOCKET
Definition: CC3000.hh:1072
virtual int datagram(uint8_t addr[4], uint16_t port)
Definition: CC3000.cpp:215
virtual int flush()
Definition: CC3000.cpp:155
int listen(int hndl)
Definition: CC3000.cpp:733
uint8_t m_hndl
Definition: CC3000.hh:261
void acquire(Driver *dev)
Definition: SOFT_SPI.cpp:43
#define NULL
Definition: Types.h:101
#define EMSGSIZE
Definition: Errno.h:117
static const uint16_t HCI_CMND_WLAN_IOCTL_STATUSGET
Definition: CC3000.hh:856
int await(uint16_t op, void *args=NULL, uint8_t len=0)
Definition: HCI.cpp:123
struct CC3000::hci_evnt_data_unsol_free_buff_t::@82 flow_control_event
#define ENOMSG
Definition: Errno.h:69
int wlan_ioctl_set_scanparam(const hci_cmnd_wlan_ioctl_set_scanparam_t *param=NULL)
Definition: CC3000.cpp:428
static const uint16_t HCI_EVNT_SELECT
Definition: CC3000.hh:1364
int bind(int hndl, int port)
Definition: CC3000.cpp:719
Protocol
Definition: Socket.hh:37
virtual int disconnect()
Definition: CC3000.cpp:209
static const uint32_t HCI_CMND_WLAN_IOCTL_SET_SCANPARAM_MAGIC
Definition: CC3000.hh:423
#define PSTR(s)
Definition: Types.h:202
int write_data(uint8_t op, const void *args, uint8_t args_len, const void *data, uint16_t data_len)
Definition: HCI.hh:181
virtual int is_connected()
Definition: CC3000.cpp:203
static const size_t HCI_CMND_WLAN_CONNECT_SSID_MAX
Definition: CC3000.hh:753
static const uint16_t HCI_CMND_READ_SP_VERSION
Definition: CC3000.hh:884
virtual void disable()
int wlan_ioctl_get_scan_results(hci_evnt_wlan_ioctl_get_scan_results_t &ret)
Definition: CC3000.cpp:479
uint8_t data[HCI_CMND_WLAN_CONNECT_DATA_MAX]
Definition: CC3000.hh:764
static const uint16_t HCI_CMND_SETSOCKOPT
Definition: CC3000.hh:1034
virtual int send(const void *buf, size_t len, bool progmem)
Definition: CC3000.cpp:248
static const uint16_t HCI_EVNT_WLAN_UNSOL_TCP_CLOSE_WAIT
Definition: CC3000.hh:1528
static const uint16_t HCI_EVNT_WLAN_IOCTL_DEL_PROFILE
Definition: CC3000.hh:1225
uint8_t m_subnet[4]
Definition: CC3000.hh:679
static const uint16_t HCI_CMND_WLAN_SET_EVENT_MASK
Definition: CC3000.hh:846
uint8_t m_dns[4]
Definition: CC3000.hh:685
#define ENOSYS
Definition: Errno.h:65
#define ETIME
Definition: Errno.h:89
virtual bool available()
Definition: Wireless.hh:165
static const uint16_t HCI_CMND_RECV
Definition: CC3000.hh:930
#define DELAY(us)
Definition: Types.h:280
bool end()
Definition: CC3000.cpp:363
bool is_high() const
Definition: Pin.hh:122
CC3000 * m_dev
Definition: CC3000.hh:258
static const uint16_t HCI_EVNT_RECV
Definition: CC3000.hh:1318
void low() const
Definition: OutputPin.hh:134
static void memrevcpy(void *dest, const void *src, size_t n)
Definition: CC3000.cpp:37
static uint32_t since(uint32_t start)
Definition: RTT.hh:107
IRQPin m_irq
Definition: HCI.hh:341
static const uint16_t HCI_EVNT_WLAN_UNSOL_KEEPALIVE
Definition: CC3000.hh:1519
static const uint16_t HCI_CMND_SIMPLE_LINK_START
Definition: CC3000.hh:1113
static const uint16_t HCI_EVNT_NVMEM_READ
Definition: CC3000.hh:1264
int read_data(uint8_t op, void *args, uint8_t args_len, void *data, uint16_t data_len)
Definition: HCI.cpp:158
static const uint16_t HCI_EVNT_ANY
Definition: CC3000.hh:1176
virtual void on_event(uint16_t event, void *args, size_t len)
Definition: CC3000.cpp:46
void(* delay)(uint32_t ms)
static const uint16_t HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY
Definition: CC3000.hh:798
int wlan_connect(Security type, str_P ssid, str_P bssid, str_P key)
Definition: CC3000.cpp:371
#define FD_ZERO()
Definition: CC3000.cpp:32
Socket * socket(Socket::Protocol proto, uint16_t port=0, uint8_t flag=0)
Definition: CC3000.cpp:315
static const uint16_t HCI_CMND_WLAN_IOCTL_SET_SCANPARAM
Definition: CC3000.hh:792
const class prog_str * str_P
Definition: Types.h:187
OutputPin m_vbat
Definition: CC3000.hh:667
bool begin_P(str_P hostname, uint16_t timeout=5000)
Definition: CC3000.cpp:268
static const uint16_t HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS
Definition: CC3000.hh:833
static const uint16_t HCI_CMND_NVMEM_READ
Definition: CC3000.hh:865
int recv(int hndl, void *buf, size_t size)
Definition: CC3000.cpp:674
static uint32_t millis()
Definition: RTT.cpp:121
uint16_t m_timeout
Definition: HCI.hh:347
static const uint16_t HCI_CMND_WLAN_IOCTL_DEL_PROFILE
Definition: CC3000.hh:820
static const uint16_t HCI_EVNT_BIND
Definition: CC3000.hh:1297
static const uint16_t HCI_EVNT_SIMPLE_LINK_START
Definition: CC3000.hh:1538
static const uint16_t HCI_EVNT_WLAN_UNSOL_CONNECT
Definition: CC3000.hh:1464
static const uint16_t HCI_CMND_CONNECT
Definition: CC3000.hh:976
#define FD_ISSET(fd, set)
Definition: CC3000.cpp:33
void(* yield)()
virtual int read(void *buf, size_t size)
Definition: CC3000.cpp:146
static const uint8_t HCI_DATA_SEND
Definition: CC3000.hh:1128
bool is_low() const
Definition: Pin.hh:152
virtual int recv(void *buf, size_t len)
Definition: CC3000.cpp:223
int connect(int hndl, uint8_t ip[4], int port)
Definition: CC3000.cpp:658
void begin()
Definition: SPI.hh:216
int accept(int hndl, uint8_t ip[4], int &port)
Definition: CC3000.cpp:747
uint8_t m_ip[4]
Definition: CC3000.hh:676
int close(int hndl)
Definition: CC3000.cpp:770
int read_sp_version(uint8_t &package_id, uint8_t &package_build_nr)
Definition: CC3000.cpp:594
void end()
Definition: SPI.hh:226
static const uint16_t HCI_EVNT_WLAN_CONNECT
Definition: CC3000.hh:1182
#define UNUSED(x)
Definition: ATmega328P.hh:31
static const uint16_t HCI_CMND_SOCKET
Definition: CC3000.hh:890
static const int EOF
Definition: IOStream.hh:33
int simple_link_start(uint8_t src)
Definition: CC3000.cpp:544
IOStream & endl(IOStream &outs)
Definition: IOStream.hh:817
uint16_t BUFFER_MAX
Definition: CC3000.hh:691
static const uint16_t HCI_EVNT_LISTEN
Definition: CC3000.hh:1344
HCI Command (SPI_OP_WRITE only).
Definition: HCI.hh:334
static const uint8_t HCI_DATA_RECV
Definition: CC3000.hh:1151
virtual int open(Protocol proto, uint16_t port, uint8_t flag)
Definition: CC3000.cpp:162
static const uint16_t HCI_EVNT_WLAN_UNSOL_DISCONNECT
Definition: CC3000.hh:1473
static const uint16_t HCI_EVNT_READ_BUFFER_SIZE
Definition: CC3000.hh:1547
#define FD_SET(fd, set)
Definition: CC3000.cpp:34
virtual int listen()
Definition: CC3000.cpp:177
static const uint16_t HCI_EVNT_SEND
Definition: CC3000.hh:1307
virtual int available()
Definition: CC3000.cpp:127
Trace trace
Definition: Trace.cpp:23
static const uint16_t HCI_EVNT_WLAN_IOCTL_STATUSGET
Definition: CC3000.hh:1251
int issue(uint16_t op, const void *args=NULL, uint8_t len=0)
Definition: HCI.hh:140
Driver m_socket[SOCKET_MAX]
Definition: CC3000.hh:703
uint8_t BUFFER_COUNT
Definition: CC3000.hh:694
static const uint16_t HCI_EVNT_WLAN_SET_EVENT_MASK
Definition: CC3000.hh:1241
void high() const
Definition: OutputPin.hh:95
volatile bool m_available
Definition: HCI.hh:344
virtual int connect(uint8_t addr[4], uint16_t port)
Definition: CC3000.cpp:189
static const uint16_t HCI_EVNT_CONNECT
Definition: CC3000.hh:1354
static const uint16_t HCI_CMND_LISTEN
Definition: CC3000.hh:960
int wlan_ioctl_statusget()
Definition: CC3000.cpp:446
Definition: INET.hh:31
SPI Write(Payload Length,0).
Definition: HCI.hh:306
static const uint16_t DEFAULT_TIMEOUT
Definition: CC3000.hh:688
SPI spi
Definition: SPI.cpp:29
int wlan_set_event_mask(uint16_t mask)
Definition: CC3000.cpp:509
Definition: INET.hh:40
void release()
Definition: SOFT_SPI.cpp:64
int send(int hndl, const void *buf, size_t size)
Definition: CC3000.cpp:701
static const uint16_t HCI_EVNT_WLAN_IOCTL_GET_SCAN_RESULTS
Definition: CC3000.hh:1235
const CC3000::hci_cmnd_wlan_ioctl_set_scanparam_t CC3000::DEFAULT_SCANPARAM __PROGMEM
Definition: CC3000.cpp:397
uint8_t m_buffer_avail
Definition: CC3000.hh:697
static const uint16_t HCI_EVNT_DATA_UNSOL_FREE_BUFF
Definition: CC3000.hh:1450
int read_buffer_size(uint8_t &count, uint16_t &size)
Definition: CC3000.cpp:579
static const uint16_t HCI_CMND_SELECT
Definition: CC3000.hh:999
uint8_t m_gateway[4]
Definition: CC3000.hh:682
#define UNLIKELY(x)
Definition: Types.h:153
IOStream & hex(IOStream &outs)
Definition: IOStream.hh:793
int setsockopt(int hndl, int level, int optname, const void *optval, size_t optlen)
Definition: CC3000.cpp:624
virtual int close()
Definition: CC3000.cpp:171
size_t strlen_P(str_P s)
Definition: Types.h:254
int wlan_ioctl_del_profile(uint8_t index)
Definition: CC3000.cpp:492
int select(int hndls, uint32_t &readhnds, uint32_t &writehndls, uint32_t &errorhndls, uint32_t sec=0UL, uint32_t us=0UL)
Definition: CC3000.cpp:639
#define EFAULT
Definition: Errno.h:41
int issue_P(uint16_t op, const void *args, uint8_t len)
Definition: HCI.hh:153
static const uint16_t HCI_CMND_READ_BUFFER_SIZE
Definition: CC3000.hh:1122
uint8_t m_mac[6]
Definition: CC3000.hh:673
static const uint16_t HCI_EVNT_SETSOCKOPT
Definition: CC3000.hh:1376
static const uint16_t HCI_EVNT_READ_SP_VERSION
Definition: CC3000.hh:1273
virtual int accept()
Definition: CC3000.cpp:183
static const uint16_t HCI_EVNT_WLAN_IOCTL_SET_SCANPARAM
Definition: CC3000.hh:1202
bool socket_state(int hndl, bool state)
Definition: CC3000.hh:739