cc3000 driver with expanded buffers.
Fork of cc3000_hostdriver_mbedsocket by
Revision 0:615c697c33b0, committed 2013-09-19
- Comitter:
- Kojto
- Date:
- Thu Sep 19 07:55:14 2013 +0000
- Child:
- 1:c7b8f55e0ca1
- Commit message:
- initial commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Helper/def.h Thu Sep 19 07:55:14 2013 +0000 @@ -0,0 +1,28 @@ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef DEF_H +#define DEF_H + +#include "cmsis.h" +//#define htons(x) __REV16(x) +//#define ntohs(x) __REV16(x) +//#define htonl(x) __REV(x) +//#define ntohl(x) __REV(x) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/Endpoint.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,123 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "Socket/Socket.h"
+#include "Socket/Endpoint.h"
+#include <cstring>
+
+ #include "cc3000.h"
+
+using std::memset;
+
+Endpoint::Endpoint() {
+ _cc3000_module = cc3000::get_instance();
+ if (_cc3000_module == NULL) {
+ error("Endpoint constructor error: no cc3000 instance available!\r\n");
+ }
+ reset_address();
+}
+Endpoint::~Endpoint() {}
+
+void Endpoint::reset_address(void) {
+ _ipAddress[0] = '\0';
+ std::memset(&_remote_host,0, sizeof(sockaddr));
+}
+
+int Endpoint::set_address(const char* host, const int port) {
+ reset_address();
+
+ // IP Address
+ char address[5];
+ char *p_address = address;
+
+ // Dot-decimal notation
+ int result = std::sscanf(host, "%3u.%3u.%3u.%3u",
+ (unsigned int*)&address[0], (unsigned int*)&address[1],
+ (unsigned int*)&address[2], (unsigned int*)&address[3]);
+
+ if (result != 4) {
+ //Resolve DNS address or populate hard-coded IP address
+ uint32_t address_integer;
+ _cc3000_module->_socket.get_host_by_name((uint8_t *)host, strlen(host) , &address_integer);
+
+ address[0] = (address_integer >> 24);
+ address[1] = (address_integer >> 16);
+ address[2] = (address_integer >> 8);
+ address[3] = (address_integer >> 0);
+ sprintf(_ipAddress,"%3u.%3u.%3u.%3u", address[0],address[1],address[2],address[3]);
+ _remote_host.sin_addr.s_addr = address_integer;
+ } else {
+ std::memcpy((char*)&_remote_host.sin_addr.s_addr, p_address, 4);
+ }
+
+ /* store address*/
+ _remote_host.sin_family = AF_INET;
+
+ // Set port
+ _remote_host.sin_port = htons(port);
+
+ return 0;
+}
+
+static char *inet_ntoa_r(const in_addr addr, char *buf, int buflen)
+{
+ uint32_t s_addr;
+ char inv[3];
+ char *rp;
+ uint8_t *ap;
+ uint8_t rem;
+ uint8_t n;
+ uint8_t i;
+ int len = 0;
+
+ s_addr = addr.s_addr;
+
+ rp = buf;
+ ap = (uint8_t *)&s_addr;
+ for(n = 0; n < 4; n++) {
+ i = 0;
+ do {
+ rem = *ap % (uint8_t)10;
+ *ap /= (uint8_t)10;
+ inv[i++] = '0' + rem;
+ } while(*ap);
+ while(i--) {
+ if (len++ >= buflen) {
+ return NULL;
+ }
+ *rp++ = inv[i];
+ }
+ if (len++ >= buflen) {
+ return NULL;
+ }
+ *rp++ = '.';
+ ap++;
+ }
+ *--rp = 0;
+ return buf;
+}
+
+char* Endpoint::get_address() {
+ if ((_ipAddress[0] == '\0') && (_remote_host.sin_addr.s_addr != 0))
+ inet_ntoa_r(_remote_host.sin_addr, _ipAddress, sizeof(_ipAddress));
+ return _ipAddress;
+}
+
+
+int Endpoint::get_port() {
+ return ntohs(_remote_host.sin_port);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/Endpoint.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,67 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef ENDPOINT_H
+#define ENDPOINT_H
+
+#include "cc3000.h"
+
+using namespace mbed_cc3000;
+
+class UDPSocket;
+
+/**
+IP Endpoint (address, port)
+*/
+class Endpoint {
+ friend class UDPSocket;
+
+public:
+ /** IP Endpoint (address, port)
+ */
+ Endpoint(void);
+
+ ~Endpoint(void);
+
+ /** Reset the address of this endpoint
+ */
+ void reset_address(void);
+
+ /** Set the address of this endpoint
+ \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
+ \param port The endpoint port
+ \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
+ */
+ int set_address(const char* host, const int port);
+
+ /** Get the IP address of this endpoint
+ \return The IP address of this endpoint.
+ */
+ char* get_address(void);
+
+ /** Get the port of this endpoint
+ \return The port of this endpoint
+ */
+ int get_port(void);
+
+protected:
+ char _ipAddress[17];
+ sockaddr_in _remote_host;
+ cc3000 *_cc3000_module;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/Socket.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,82 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "Socket.h"
+#include <cstring>
+
+Socket::Socket() : _sock_fd(-1), _blocking(true), _timeout(1500) {
+ _cc3000_module = cc3000::get_instance();
+ if (_cc3000_module == NULL) {
+ error("Socket constructor error: no cc3000 instance available!\r\n");
+ }
+}
+
+void Socket::set_blocking(bool blocking, unsigned int timeout) {
+ _blocking = blocking;
+ _timeout = timeout;
+}
+
+int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen) {
+ return _cc3000_module->_socket.set_sockopt(_sock_fd, level, optname, optval, optlen);
+}
+
+int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) {
+ return _cc3000_module->_socket.get_sockopt(_sock_fd, level, optname, optval, optlen);
+}
+
+int Socket::select(struct timeval *timeout, bool read, bool write) {
+ if (_sock_fd < 0 ) {
+ return -1;
+ }
+
+ fd_set fdSet;
+ FD_ZERO(&fdSet);
+ FD_SET(_sock_fd, &fdSet);
+
+ fd_set* readset = (read ) ? (&fdSet) : (NULL);
+ fd_set* writeset = (write) ? (&fdSet) : (NULL);
+
+ int ret = _cc3000_module->_socket.select(_sock_fd+1, readset, writeset, NULL, timeout);
+ return (ret <= 0 || !FD_ISSET(_sock_fd, &fdSet)) ? (-1) : (0);
+}
+
+int Socket::wait_readable(TimeInterval& timeout) {
+ return select(&timeout._time, true, false);
+}
+
+int Socket::wait_writable(TimeInterval& timeout) {
+ return select(&timeout._time, false, true);
+}
+
+int Socket::close() {
+ if (_sock_fd < 0 ) {
+ return -1;
+ }
+
+ _cc3000_module->_socket.closesocket(_sock_fd);
+ return 0;
+}
+
+Socket::~Socket() {
+ close(); //Don't want to leak
+}
+
+TimeInterval::TimeInterval(unsigned int ms) {
+ _time.tv_sec = ms / 1000;
+ _time.tv_usec = (ms - (_time.tv_sec * 1000)) * 1000;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/Socket.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,96 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SOCKET_H_
+#define SOCKET_H_
+
+#include "cc3000.h"
+
+using namespace mbed_cc3000;
+
+class TimeInterval;
+
+/** Socket file descriptor and select wrapper
+ */
+class Socket {
+public:
+ /** Socket
+ */
+ Socket();
+
+ /** Set blocking or non-blocking mode of the socket and a timeout on
+ blocking socket operations
+ \param blocking true for blocking mode, false for non-blocking mode.
+ \param timeout timeout in ms [Default: (1500)ms].
+ */
+ void set_blocking(bool blocking, unsigned int timeout=1500);
+
+ /** Set socket options
+ \param level stack level (see: lwip/sockets.h)
+ \param optname option ID
+ \param optval option value
+ \param socklen_t length of the option value
+ \return 0 on success, -1 on failure
+ */
+ int set_option(int level, int optname, const void *optval, socklen_t optlen);
+
+ /** Get socket options
+ \param level stack level (see: lwip/sockets.h)
+ \param optname option ID
+ \param optval buffer pointer where to write the option value
+ \param socklen_t length of the option value
+ \return 0 on success, -1 on failure
+ */
+ int get_option(int level, int optname, void *optval, socklen_t *optlen);
+
+
+ /** Close the socket file descriptor
+ */
+ int close();
+
+ ~Socket();
+
+protected:
+ int _sock_fd;
+
+ int wait_readable(TimeInterval& timeout);
+ int wait_writable(TimeInterval& timeout);
+
+ bool _blocking;
+ int _timeout;
+
+ cc3000 *_cc3000_module;
+private:
+ int select(struct timeval *timeout, bool read, bool write);
+};
+
+/** Time interval class used to specify timeouts
+ */
+class TimeInterval {
+ friend class Socket;
+
+public:
+ /** Time Interval
+ \param ms time interval expressed in milliseconds
+ */
+ TimeInterval(unsigned int ms);
+
+private:
+ struct timeval _time;
+};
+
+#endif /* SOCKET_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/TCPSocketConnection.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,67 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "TCPSocketConnection.h"
+#include <algorithm>
+
+TCPSocketConnection::TCPSocketConnection() {}
+
+int TCPSocketConnection::connect(const char* host, const int port)
+{
+
+}
+
+bool TCPSocketConnection::is_connected(void)
+{
+
+}
+
+int TCPSocketConnection::send(char* data, int length)
+{
+
+}
+
+// -1 if unsuccessful, else number of bytes written
+int TCPSocketConnection::send_all(char* data, int length)
+{
+ Timer tmr;
+ int idx = 0;
+ tmr.start();
+
+ while ((tmr.read_ms() < _timeout) || _blocking) {
+
+ idx += wifi->send(data, length);
+
+ if (idx == length)
+ return idx;
+ }
+ return (idx == 0) ? -1 : idx;
+}
+
+// -1 if unsuccessful, else number of bytes received
+int TCPSocketConnection::receive(char* data, int length)
+{
+
+}
+
+
+// -1 if unsuccessful, else number of bytes received
+int TCPSocketConnection::receive_all(char* data, int length)
+{
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/TCPSocketConnection.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,76 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef TCPSOCKET_H
+#define TCPSOCKET_H
+
+#include "Socket.h"
+#include "Endpoint.h"
+
+/**
+TCP socket connection
+*/
+class TCPSocketConnection: public Socket, public Endpoint {
+
+public:
+ /** TCP socket connection
+ */
+ TCPSocketConnection();
+
+ /** Connects this TCP socket to the server
+ \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
+ \param port The host's port to connect to.
+ \return 0 on success, -1 on failure.
+ */
+ int connect(const char* host, const int port);
+
+ /** Check if the socket is connected
+ \return true if connected, false otherwise.
+ */
+ bool is_connected(void);
+
+ /** Send data to the remote host.
+ \param data The buffer to send to the host.
+ \param length The length of the buffer to send.
+ \return the number of written bytes on success (>=0) or -1 on failure
+ */
+ int send(char* data, int length);
+
+ /** Send all the data to the remote host.
+ \param data The buffer to send to the host.
+ \param length The length of the buffer to send.
+ \return the number of written bytes on success (>=0) or -1 on failure
+ */
+ int send_all(char* data, int length);
+
+ /** Receive data from the remote host.
+ \param data The buffer in which to store the data received from the host.
+ \param length The maximum length of the buffer.
+ \return the number of received bytes on success (>=0) or -1 on failure
+ */
+ int receive(char* data, int length);
+
+ /** Receive all the data from the remote host.
+ \param data The buffer in which to store the data received from the host.
+ \param length The maximum length of the buffer.
+ \return the number of received bytes on success (>=0) or -1 on failure
+ */
+ int receive_all(char* data, int length);
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/TCPSocketServer.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,36 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "TCPSocketServer.h"
+#include <string>
+
+TCPSocketServer::TCPSocketServer() {}
+
+// Server initialization
+int TCPSocketServer::bind(int port) {
+
+}
+
+int TCPSocketServer::listen(int backlog) {
+
+}
+
+
+int TCPSocketServer::accept(TCPSocketConnection& connection) {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/TCPSocketServer.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,52 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef TCPSOCKETSERVER_H
+#define TCPSOCKETSERVER_H
+
+#include "Socket/Socket.h"
+#include "TCPSocketConnection.h"
+
+/** TCP Server.
+ */
+class TCPSocketServer : public Socket {
+ public:
+ /** Instantiate a TCP Server.
+ */
+ TCPSocketServer();
+
+ /** Bind a socket to a specific port.
+ \param port The port to listen for incoming connections on.
+ \return 0 on success, -1 on failure.
+ */
+ int bind(int port);
+
+ /** Start listening for incoming connections.
+ \param backlog number of pending connections that can be queued up at any
+ one time [Default: 1].
+ \return 0 on success, -1 on failure.
+ */
+ int listen(int backlog=1);
+
+ /** Accept a new connection.
+ \param connection A TCPSocketConnection instance that will handle the incoming connection.
+ \return 0 on success, -1 on failure.
+ */
+ int accept(TCPSocketConnection& connection);
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/UDPSocket.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,98 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "UDPSocket.h"
+
+#include <string>
+#include <algorithm>
+
+UDPSocket::UDPSocket() {
+
+}
+
+int UDPSocket::init(void) {
+ /* open upd socket */
+ _sock_fd = _cc3000_module->_socket.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (_sock_fd == -1) {
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to create new socket (udp).\n");
+#endif
+ return 0;
+ }
+
+ return 1;
+}
+
+// Server initialization
+int UDPSocket::bind(int port) {
+ init();
+
+ sockaddr_in localHost;
+ std::memset(&localHost, 0, sizeof(localHost));
+
+ localHost.sin_family = AF_INET;
+ localHost.sin_port = htons(port);
+ localHost.sin_addr.s_addr = htons(0);
+
+ if (_cc3000_module->_socket.bind(_sock_fd, (sockaddr *)&localHost, sizeof(localHost)) != 0) {
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to bind a socket (udp). Closing socket.\n");
+#endif
+ _cc3000_module->_socket.closesocket(_sock_fd);
+ return -1;
+ }
+ return 0;
+}
+
+// -1 if unsuccessful, else number of bytes written
+int UDPSocket::sendTo(Endpoint &remote, char *packet, int length)
+{
+ if (_sock_fd < 0) {
+ return -1;
+ }
+
+ if (!_blocking) {
+ TimeInterval timeout(_timeout);
+ if (wait_writable(timeout) != 0)
+ return 0;
+ }
+
+ return _cc3000_module->_socket.sendto(_sock_fd, packet, length, 0, (sockaddr *)&remote._remote_host, sizeof(remote._remote_host));
+}
+
+// -1 if unsuccessful, else number of bytes received
+int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length)
+{
+ if (_sock_fd < 0) {
+ return -1;
+ }
+
+ if (!_blocking) {
+ TimeInterval timeout(_timeout);
+ if (wait_readable(timeout) != 0) {
+ return 0;
+ }
+ }
+
+ remote.reset_address();
+ socklen_t remote_host_length = sizeof(remote._remote_host);
+
+ return _cc3000_module->_socket.recvfrom(_sock_fd, buffer, length, 0, (sockaddr *)&remote._remote_host, &remote_host_length);
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/UDPSocket.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,68 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef UDPSOCKET_H
+#define UDPSOCKET_H
+
+#include "Endpoint.h"
+#include "Socket.h"
+
+#include <cstdint>
+
+/**
+UDP Socket
+*/
+class UDPSocket: public Socket {
+
+public:
+ /** Instantiate an UDP Socket.
+ */
+ UDPSocket();
+
+ /** Init the UDP Client Socket without binding it to any specific port
+ \return 0 on success, -1 on failure.
+ */
+ int init(void);
+
+ /** Bind a UDP Server Socket to a specific port
+ \param port The port to listen for incoming connections on
+ \return 0 on success, -1 on failure.
+ */
+ int bind(int port = -1);
+
+ /** Send a packet to a remote endpoint
+ \param remote The remote endpoint
+ \param packet The packet to be sent
+ \param length The length of the packet to be sent
+ \return the number of written bytes on success (>=0) or -1 on failure
+ */
+ int sendTo(Endpoint &remote, char *packet, int length);
+
+ /** Receive a packet from a remote endpoint
+ \param remote The remote endpoint
+ \param buffer The buffer for storing the incoming packet data. If a packet
+ is too long to fit in the supplied buffer, excess bytes are discarded
+ \param length The length of the buffer
+ \return the number of received bytes on success (>=0) or -1 on failure
+ */
+ int receiveFrom(Endpoint &remote, char *buffer, int length);
+};
+
+#include "def.h"
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,477 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+#include "cc3000_event.h"
+
+namespace mbed_cc3000 {
+
+/* TODO this prefix remove? verify */
+static uint8_t cc3000_prefix[] = {'T', 'T', 'T'};
+cc3000 *cc3000::_inst;
+
+cc3000::cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port)
+ : _event(_simple_link, _hci, _spi, *this), _socket(_simple_link, _hci, _event), _spi(cc3000_irq, cc3000_en, cc3000_cs, cc3000_spi, irq_port, _event, _simple_link), _hci(_spi),
+ _nvmem(_hci, _event, _simple_link), _netapp(_simple_link, _nvmem, _hci, _event), _wlan(_simple_link, _event, _spi, _hci), _buffer(256) {
+ /* TODO - pIRQ riorities ?? */
+
+ _simple_link.set_tx_complete_signal(1);
+ _status.dhcp = 0;
+ _status.connected = 0;
+ _status.socket = 0;
+ _status.dhcp_configured = 0;
+ _status.smart_config_complete = 0;
+ _status.stop_smart_config = 0;
+ _status.ok_to_shut_down = 0;
+
+ _inst = this;
+}
+
+cc3000::~cc3000() {
+
+}
+
+void cc3000::usync_callback(int32_t event_type, uint8_t * data, uint8_t length) {
+ if (event_type == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
+ {
+ _status.smart_config_complete = 1;
+ _status.stop_smart_config = 1;
+ }
+
+ if (event_type == HCI_EVNT_WLAN_UNSOL_CONNECT)
+ {
+ _status.connected = 1;
+ }
+
+ if (event_type == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
+ {
+ _status.connected = 0;
+ _status.dhcp = 0;
+ _status.dhcp_configured = 0;
+ }
+
+ if (event_type == HCI_EVNT_WLAN_UNSOL_DHCP)
+ {
+ if ( *(data + NETAPP_IPCONFIG_MAC_OFFSET) == 0) {
+ _status.dhcp = 1;
+ } else {
+ _status.dhcp = 0;
+ }
+ }
+
+ if (event_type == HCI_EVENT_CC3000_CAN_SHUT_DOWN)
+ {
+ _status.ok_to_shut_down = 1;
+ }
+
+ if (event_type == HCI_EVNT_WLAN_ASYNC_PING_REPORT)
+ {
+ memcpy(&_ping_report, data, length);
+ }
+
+ if (event_type == HCI_EVNT_BSD_TCP_CLOSE_WAIT) {
+ uint8_t socketnum;
+ socketnum = data[0];
+ if (socketnum < MAX_SOCKETS) {
+ _closed_sockets[socketnum] = true; /* clients socket is closed */
+ }
+ }
+}
+
+void cc3000::start_smart_config(const uint8_t *smart_config_key) {
+ // Reset all the previous configuration
+ _wlan.ioctl_set_connection_policy(0, 0, 0);
+ _wlan.ioctl_del_profile(255);
+
+ //Wait until CC3000 is disconected
+ while (_status.connected == 1)
+ {
+ wait_us(5);
+ _event.hci_unsolicited_event_handler();
+ }
+
+ // Trigger the Smart Config process
+
+ _wlan.smart_config_set_prefix(cc3000_prefix);
+ // Start the Smart Config process with AES disabled
+ _wlan.smart_config_start(0);
+
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Waiting for smartconfig to be completed.\n");
+#endif
+ // Wait for Smart config finished
+ while (_status.smart_config_complete == 0)
+ {
+ wait_ms(100);
+
+ }
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Smartconfig finished.\n");
+#endif
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+ // create new entry for AES encryption key
+ _nvmem.create_entry(NVMEM_AES128_KEY_FILEID, 16);
+ // write AES key to NVMEM
+ _security.aes_write_key((uint8_t *)(&smart_config_key[0]));
+ // Decrypt configuration information and add profile
+ _wlan.smart_config_process();
+#endif
+
+ // Configure to connect automatically to the AP retrieved in the
+ // Smart config process
+ _wlan.ioctl_set_connection_policy(0, 1, 1);
+
+ // reset the CC3000
+ _wlan.stop();
+ wait(2);
+ _wlan.start(0);
+ wait(2);
+
+ // Mask out all non-required events
+ _wlan.set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT);
+}
+
+bool cc3000::connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) {
+ uint32_t ret;
+
+ _wlan.disconnect();
+ wait_ms(3);
+ ret = _wlan.connect(security_mode, ssid, strlen((const char *)ssid), 0, (uint8_t *)key, strlen((const char *)key));
+ if (ret == 0) { /* TODO static internal cc3000 state 0 to TRUE */
+ ret = true;
+ } else {
+ ret = false;
+ }
+ return ret;
+}
+
+bool cc3000::connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) {
+ Timer t; /* TODO static? */
+ bool ret = true;
+
+ t.start();
+ while (is_connected() == false) {
+ if (key == 0) {
+ if (connect_open(ssid)) {
+ break;
+ }
+ } else {
+#ifndef CC3000_TINY_DRIVER
+ if (connect_secure(ssid,key,security_mode)) {
+ break;
+ }
+#else
+ return false; /* secure connection not supported with TINY_DRIVER */
+#endif
+ }
+
+ /* timeout 10 seconds */
+ if (t.read_ms() > 10000){
+ ret = false;
+#if (CC3000_DEBUG == 1)
+ printf("Connection to AP failed.\n");
+#endif
+ break;
+ }
+ }
+
+ return ret;
+}
+
+void cc3000::start(uint8_t patch) {
+ _wlan.start(patch);
+ _wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE);
+}
+
+void cc3000::stop(void) {
+ _wlan.stop();
+}
+
+void cc3000::restart(uint8_t patch) {
+ _wlan.stop();
+ wait_ms(500);
+ _wlan.start(patch);
+}
+
+bool cc3000::connect_open(const uint8_t *ssid) {
+ uint32_t ret;
+
+ _wlan.disconnect();
+ wait_ms(3);
+#ifndef CC3000_TINY_DRIVER
+ ret = _wlan.connect(0,ssid, strlen((const char *)ssid), 0, 0, 0);
+#else
+ ret = _wlan.connect(ssid, strlen((const char *)ssid));
+#endif
+ if (ret == 0) {
+ ret = true;
+ } else {
+ ret = false;
+ }
+ return ret;
+}
+
+bool cc3000::is_connected() {
+ return _status.connected;
+}
+
+bool cc3000::is_dhcp_configured() {
+ return _status.dhcp;
+}
+
+bool cc3000::is_smart_confing_completed() {
+ return _status.smart_config_complete;
+}
+
+void cc3000::get_mac_address(uint8_t address[6]) {
+ _nvmem.get_mac_address(address);
+}
+
+void cc3000::set_mac_address(uint8_t address[6]) {
+ _nvmem.set_mac_address(address);
+}
+
+void cc3000::get_user_file_info(uint8_t *info_file, size_t size) {
+ _nvmem.read( NVMEM_USER_FILE_1_FILEID, size, 0, info_file);
+}
+
+#ifndef CC3000_TINY_DRIVER
+bool cc3000::get_ip_config(tNetappIpconfigRetArgs *ip_config) {
+ if ((_status.dhcp == false) || (_status.connected == false)) {
+ return false;
+ }
+
+ _netapp.ipconfig(ip_config);
+ return true;
+}
+#endif
+
+cc3000_client cc3000::create_tcp_client(uint32_t ip_address, uint16_t port) {
+ sockaddr socket_address = {0};
+ int32_t tcp_socket;
+
+ tcp_socket = _socket.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (tcp_socket == -1) {
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to create new socket (tcp).\n");
+#endif
+ return cc3000_client(*this);
+ }
+
+ socket_address.family = AF_INET;
+ socket_address.data[0] = (port & 0xFF00) >> 8;
+ socket_address.data[1] = (port & 0x00FF);
+ socket_address.data[2] = ip_address >> 24;
+ socket_address.data[3] = ip_address >> 16;
+ socket_address.data[4] = ip_address >> 8;
+ socket_address.data[5] = ip_address;
+
+ if (_socket.connect(tcp_socket, &socket_address, sizeof(socket_address)) == -1) {
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to connect (tcp).\n");
+#endif
+ _socket.closesocket(tcp_socket);
+ return cc3000_client(*this);
+ }
+
+ return cc3000_client(*this, tcp_socket);
+}
+cc3000_client cc3000::create_udp_client(uint32_t ip_address, uint16_t port) {
+ sockaddr socket_address = {0};
+ int32_t udp_socket;
+
+ udp_socket = _socket.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (udp_socket == -1) {
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to create new socket (udp).\n");
+#endif
+ return cc3000_client(*this);
+ }
+
+ socket_address.family = AF_INET;
+ socket_address.data[0] = (port & 0xFF00) >> 8;
+ socket_address.data[1] = (port & 0x00FF);
+ socket_address.data[2] = ip_address >> 24;
+ socket_address.data[3] = ip_address >> 16;
+ socket_address.data[4] = ip_address >> 8;
+ socket_address.data[5] = ip_address;
+
+ if (_socket.connect(udp_socket, &socket_address, sizeof(socket_address)) == -1) {
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to connect (udp).\n");
+#endif
+ _socket.closesocket(udp_socket);
+ return cc3000_client(*this);
+ }
+
+ return cc3000_client(*this, udp_socket);
+}
+
+cc3000_server cc3000::create_tcp_server(uint32_t ip_address, uint16_t port) {
+ sockaddr socket_address = {0};
+ int32_t tcp_socket;
+
+ tcp_socket = _socket.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (tcp_socket == -1) {
+#if (CC3000_DEBUG == 1)
+ printf("Failed to create new socket.\n");
+#endif
+ return cc3000_server(*this, socket_address);
+ }
+
+ socket_address.family = AF_INET;
+ socket_address.data[0] = (port & 0xFF00) >> 8;
+ socket_address.data[1] = (port & 0x00FF);
+ socket_address.data[2] = ip_address >> 24;
+ socket_address.data[3] = ip_address >> 16;
+ socket_address.data[4] = ip_address >> 8;
+ socket_address.data[5] = ip_address;
+
+ if (_socket.bind(tcp_socket, &socket_address, sizeof(socket_address)) != 0) {
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to bind the new socket.\n");
+#endif
+ return cc3000_server(*this, socket_address);
+ }
+ if (_socket.listen(tcp_socket, 1) != 0) { /* 1 client */
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to listen on the new socket.\n");
+#endif
+ return cc3000_server(*this, socket_address);
+ }
+
+ return cc3000_server(*this, socket_address, tcp_socket);
+}
+
+void cc3000::delete_profiles(void) {
+ tUserFS user_info;
+
+ _wlan.ioctl_set_connection_policy(0, 0, 0);
+ _wlan.ioctl_del_profile(255);
+
+ user_info.FTC = 0;
+ set_user_file_info((uint8_t *)&user_info, sizeof(user_info));
+}
+
+void cc3000::set_user_file_info(uint8_t *info_file, size_t size) {
+ _nvmem.write( NVMEM_USER_FILE_1_FILEID, size, 0, info_file);
+}
+
+bool cc3000::disconnect(void){
+ if (_wlan.disconnect()) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+uint32_t cc3000::ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size) {
+ uint32_t reversed_ip = (ip >> 24) | (ip >> 8) & 0xFF00 | (ip << 8) & 0xFF0000 | (ip << 24);
+
+ _ping_report.packets_received = 0;
+ if (_netapp.ping_send(&reversed_ip, attempts, size, timeout) == -1) {
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Failed to send ping.\n");
+#endif
+ return 0;
+ }
+ wait_ms(timeout*attempts*2);
+
+ /* known issue of cc3000 - sent number is send + received */
+#if (CC3000_DEBUG == 1)
+ printf("DEBUG: Sent: %d \n",_ping_report.packets_sent);
+ printf("DEBUG: Received: %d \n",_ping_report.packets_received);
+ printf("DEBUG: Min time: %d \n",_ping_report.min_round_time);
+ printf("DEBUG: Max time: %d \n",_ping_report.max_round_time);
+ printf("DEBUG: Avg time: %d \n",_ping_report.avg_round_time);
+#endif
+
+ return _ping_report.packets_received;
+}
+
+int32_t cc3000::readable(void) {
+ return _buffer.available();
+}
+
+uint8_t cc3000::getc(void)
+{
+ char c;
+
+ while (!_buffer.available());
+ _buffer.dequeue(&c);
+ return (uint8_t)c;
+}
+
+/* Conversion between uint types and C strings */
+uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32)
+{
+ *(p)++ = (uint8_t)(u32);
+ *(p)++ = (uint8_t)((u32) >> 8);
+ *(p)++ = (uint8_t)((u32) >> 16);
+ *(p)++ = (uint8_t)((u32) >> 24);
+ return p;
+}
+
+
+uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16)
+{
+ *(p)++ = (uint8_t)(u16);
+ *(p)++ = (uint8_t)((u16) >> 8);
+ return p;
+}
+
+
+uint16_t STREAM_TO_UINT16_f(uint8_t *p, uint16_t offset)
+{
+ return (uint16_t)((uint16_t)((uint16_t)
+ (*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset)));
+}
+
+
+uint32_t STREAM_TO_UINT32_f(uint8_t *p, uint16_t offset)
+{
+ return (uint32_t)((uint32_t)((uint32_t)
+ (*(p + offset + 3)) << 24) + (uint32_t)((uint32_t)
+ (*(p + offset + 2)) << 16) + (uint32_t)((uint32_t)
+ (*(p + offset + 1)) << 8) + (uint32_t)(*(p + offset)));
+}
+
+} /* end of mbed_cc3000 namespace */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,703 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef CC3000_H
+#define CC3000_H
+
+#include "mbed.h"
+#include "cc3000_common.h"
+#include "cc3000_spi.h"
+#include "cc3000_simplelink.h"
+#include "cc3000_netapp.h"
+#include "cc3000_nvmem.h"
+#include "cc3000_socket.h"
+
+#define MAX_SOCKETS 4
+
+/** Enable debug messages
+ */
+#define CC3000_DEBUG 1
+
+namespace mbed_cc3000 {
+
+/** User info structure
+ */
+typedef struct {
+ uint8_t FTC; // First time config performed
+ uint8_t PP_version[2]; // Patch Programmer version
+ uint8_t SERV_PACK[2]; // Service Pack Version
+ uint8_t DRV_VER[3]; // Driver Version
+ uint8_t FW_VER[3]; // Firmware Version
+ uint8_t validCIK; // CIK[] is valid (Client Interface Key)
+ uint8_t CIK[40];
+} tUserFS;
+
+/** Function pointers which are not yet implemented
+ */
+enum FunctionNumber {
+ FW_PATCHES = 0,
+ DRIVER_PATCHES = 1,
+ BOOTLOADER_PATCHES = 2,
+};
+
+/** CC3000 Simple Link class which contains status of cc3000.
+ */
+class cc3000_simple_link {
+public:
+ /** ctor - sets magic number in the buffers (overflow mark).
+ */
+ cc3000_simple_link();
+ /** dtor
+ */
+ ~cc3000_simple_link();
+ /** Returns data received flag.
+ * \return
+ * if data have been received.
+ */
+ uint8_t get_data_received_flag();
+ /** Set data received flag.
+ * \param value The value to be set.
+ */
+ void set_data_received_flag(uint8_t value);
+ /** Returns if tx was completed.
+ * \return
+ * true if tx was completed,
+ * false otherwise.
+ */
+ bool get_tx_complete_signal();
+ /**
+ */
+ void set_tx_complete_signal(bool value);
+ /**
+ */
+ uint8_t *get_received_buffer();
+ /**
+ */
+ void set_received_buffer(uint8_t value);
+ /**
+ */
+ uint8_t *get_transmit_buffer();
+ /**
+ */
+ void set_transmit_buffer(uint8_t value);
+ /**
+ */
+ uint16_t get_number_free_buffers();
+ /**
+ */
+ void set_number_free_buffers(uint16_t value);
+ /**
+ */
+ uint16_t get_buffer_length();
+ /**
+ */
+ void set_buffer_length(uint16_t value);
+ /**
+ */
+ uint16_t get_pending_data();
+ /**
+ */
+ void set_pending_data(uint16_t value);
+ /**
+ */
+ uint16_t get_op_code();
+ /**
+ */
+ void set_op_code(uint16_t code);
+ /**
+ */
+ uint16_t get_released_packets();
+ /**
+ */
+ void set_number_of_released_packets(uint16_t value);
+ /**
+ */
+ uint16_t get_sent_packets();
+ /**
+ */
+ void set_sent_packets(uint16_t value);
+
+ int32_t get_transmit_error();
+ void set_transmit_error(int32_t value);
+
+ uint16_t get_buffer_size(void);
+ void set_buffer_size(uint16_t value);
+
+ void *get_func_pointer(FunctionNumber function);
+
+ uint8_t *get_received_data(void);
+ void set_received_data(uint8_t *pointer);
+
+private:
+ uint8_t _data_received_flag;
+ bool _tx_complete_signal;
+ uint16_t _rx_event_opcode;
+ uint16_t _free_buffers;
+ uint16_t _buffer_length;
+ uint16_t _buffer_size;
+ uint16_t _rx_data_pending;
+ uint16_t _sent_packets;
+ uint16_t _released_packets;
+ int32_t _transmit_data_error;
+ uint8_t *_received_data;
+ uint8_t _rx_buffer[CC3000_RX_BUFFER_SIZE];
+ uint8_t _tx_buffer[CC3000_TX_BUFFER_SIZE];
+private:
+ int8_t *(* _fFWPatches)(uint32_t *length);
+ int8_t *(* _fDriverPatches)(uint32_t *length);
+ int8_t *(* _fBootLoaderPatches)(uint32_t *length);
+};
+
+/** Forward declaration classes
+ */
+class cc3000_hci;
+class cc3000_nvmem;
+class cc3000_spi;
+class cc3000;
+
+/**
+ */
+class cc3000_event {
+public:
+ cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000);
+ ~cc3000_event();
+
+ void hci_unsol_handle_patch_request(uint8_t *event_hdr);
+ uint8_t *hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen);
+ int32_t hci_unsol_event_handler(uint8_t *event_hdr);
+ int32_t hci_unsolicited_event_handler(void);
+ int32_t get_socket_active_status(int32_t sd);
+ void set_socket_active_status(int32_t sd, int32_t status);
+ int32_t hci_event_unsol_flowcontrol_handler(uint8_t *event);
+ void update_socket_active_status(uint8_t *resp_params);
+ void simplelink_wait_event(uint16_t op_code, void *ret_param);
+ void simplelink_wait_data(uint8_t *buffer, uint8_t *from, uint8_t *fromlen);
+
+ void received_handler(uint8_t *buffer);
+ private:
+ uint32_t socket_active_status;
+ cc3000_simple_link &_simple_link;
+ cc3000_hci &_hci;
+ cc3000_spi &_spi;
+ cc3000 &_cc3000;
+};
+
+class cc3000_netapp {
+public:
+ cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci, cc3000_event &event);
+ ~cc3000_netapp();
+ int32_t config_mac_adrress(uint8_t *mac);
+ int32_t dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server);
+#ifndef CC3000_TINY_DRIVER
+ void ipconfig(tNetappIpconfigRetArgs *ipconfig);
+ int32_t timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity);
+ int32_t ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout);
+ void ping_report();
+ int32_t ping_stop();
+ int32_t arp_flush();
+#endif
+private:
+ cc3000_simple_link &_simple_link;
+ cc3000_nvmem &_nvmem;
+ cc3000_hci &_hci;
+ cc3000_event &_event;
+};
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+class cc3000_security {
+public:
+ void expandKey(uint8_t *expanded_key, uint8_t *key);
+ uint8_t galois_mul2(uint8_t value);
+ void aes_encr(uint8_t *state, uint8_t *expanded_key);
+ void aes_decr(uint8_t *state, uint8_t *expanded_key);
+ void aes_encrypt(uint8_t *state, uint8_t *key);
+ void aes_decrypt(uint8_t *state, uint8_t *key);
+ int32_t aes_read_key(uint8_t *key);
+ int32_t aes_write_key(uint8_t *key);
+private:
+ uint8_t _expanded_key[176];
+};
+#endif
+
+class cc3000_socket {
+public:
+ cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event);
+ ~cc3000_socket();
+ int32_t HostFlowControlConsumeBuff(int32_t sd);
+ int32_t socket(int32_t domain, int32_t type, int32_t protocol);
+ int32_t closesocket(int32_t sd);
+ int32_t accept(int32_t sd, sockaddr *addr, socklen_t *addrlen);
+ int32_t bind(int32_t sd, const sockaddr *addr, int32_t addrlen);
+ int32_t listen(int32_t sd, int32_t backlog);
+#ifndef CC3000_TINY_DRIVER
+ int32_t get_host_by_name(uint8_t * hostname, uint16_t name_length, uint32_t* out_ip_addr);
+ int32_t set_sockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen);
+#endif
+ int32_t connect(int32_t sd, const sockaddr *addr, int32_t addrlen);
+ int32_t select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout);
+ int32_t get_sockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen);
+ int32_t simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode);
+ int32_t recv(int32_t sd, void *buf, int32_t len, int32_t flags);
+ int32_t recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen);
+ int32_t simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode);
+ int32_t send(int32_t sd, const void *buf, int32_t len, int32_t flags);
+ int32_t sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen);
+ int32_t mdns_advertiser(uint16_t mdns_enabled, uint8_t * device_service_name, uint16_t device_service_name_length);
+private:
+ cc3000_simple_link &_simple_link;
+ cc3000_hci &_hci;
+ cc3000_event &_event;
+};
+
+/** SPI communication class
+ */
+class cc3000_spi {
+public:
+ /** ctor
+ */
+ cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port, cc3000_event &event, cc3000_simple_link &simple_link);
+ /** dtor
+ */
+ ~cc3000_spi();
+ /** Close SPI - disables IRQ and set received buffer to 0
+ * \param none
+ * \return none
+ */
+ void close();
+ /**
+ * \param none
+ * \return none
+ */
+ void open();
+ /**
+ * \param buffer
+ * \param length
+ * \return none
+ */
+ uint32_t first_write(uint8_t *buffer, uint16_t length);
+ /**
+ */
+ uint32_t write(uint8_t *buffer, uint16_t length);
+ /**
+ */
+ void write_synchronous(uint8_t *data, uint16_t size);
+ /**
+ */
+ void read_synchronous(uint8_t *data, uint16_t size);
+ /**
+ */
+ uint32_t read_data_cont();
+ /**
+ */
+ void wlan_irq_enable();
+ /**
+ */
+ void wlan_irq_disable();
+ /**
+ */
+ void wlan_irq_set(uint8_t value);
+ /**
+ */
+ uint32_t wlan_irq_read();
+ /**
+ */
+ void WLAN_IRQHandler();
+ /**
+ */
+ void write_wlan_en(uint8_t value);
+private:
+ tSpiInfo _spi_info;
+ InterruptIn _wlan_irq;
+ DigitalOut _wlan_en;
+ DigitalOut _wlan_cs;
+ SPI _wlan_spi;
+ IRQn_Type _irq_port;
+ pFunctionPointer_t _function_pointer;
+ cc3000_event &_event;
+ cc3000_simple_link &_simple_link;
+};
+
+class cc3000_hci {
+public:
+ cc3000_hci(cc3000_spi &spi);
+ ~cc3000_hci();
+ uint16_t command_send(uint16_t op_code, uint8_t *buffer, uint8_t length);
+ uint32_t data_send(uint8_t op_code, uint8_t *args, uint16_t arg_length,
+ uint16_t data_length, const uint8_t *tail, uint16_t tail_length);
+ void data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length,
+ uint16_t data_length);
+ void patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length);
+private:
+ cc3000_spi &_spi;
+};
+
+class cc3000_nvmem {
+public:
+ cc3000_nvmem(cc3000_hci &hci, cc3000_event &_event,cc3000_simple_link &simple_link);
+ ~cc3000_nvmem();
+ int32_t read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff);
+ int32_t write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff);
+ uint8_t set_mac_address(uint8_t *mac);
+ uint8_t get_mac_address(uint8_t *mac);
+ uint8_t write_patch(uint32_t file_id, uint32_t length, const uint8_t *data);
+ int32_t create_entry(uint32_t file_id, uint32_t new_len);
+#ifndef CC3000_TINY_DRIVER
+ uint8_t read_sp_version(uint8_t* patch_ver);
+#endif
+private:
+ cc3000_hci &_hci;
+ cc3000_event &_event;
+ cc3000_simple_link &_simple_link;
+};
+
+class cc3000_wlan {
+public:
+ cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci);
+ ~cc3000_wlan();
+ /** Send SIMPLE LINK START to cc3000
+ * \param patches_available_host Flag to indicate if patches are available
+ * \return none
+ */
+ void simpleLink_init_start(uint16_t patches_available_host);
+ /** Start wlan device. Blocking call until init is completed
+ * \param patches_available_host Flag to indicate if patches are available
+ * \return none
+ */
+ void start(uint16_t patches_available_host);
+ /** Stop wlan device
+ * \param none
+ * \return none
+ */
+ void stop(void);
+#ifndef CC3000_TINY_DRIVER
+ int32_t connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_length, uint8_t *b_ssid, uint8_t *key, int32_t key_len);
+ int32_t add_profile(uint32_t sec_type, uint8_t* ssid, uint32_t ssid_length, uint8_t *b_ssid, uint32_t priority, uint32_t pairwise_cipher_or_tx_key_len, uint32_t group_cipher_tx_key_index,
+ uint32_t key_mgmt, uint8_t* pf_or_key, uint32_t pass_phrase_length);
+ int32_t ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results);
+ int32_t ioctl_set_scan_params(uint32_t enable, uint32_t min_dwell_time, uint32_t max_dwell_time, uint32_t num_probe_requests,
+ uint32_t channel_mask, int32_t rssi_threshold, uint32_t snr_threshold, uint32_t default_tx_power, uint32_t *interval_list);
+ int32_t ioctl_statusget(void);
+#else
+ int32_t connect(const uint8_t *ssid, int32_t ssid_length);
+ int32_t add_profile(uint32_t sec_type, uint8_t *ssid, uint32_t ssid_length, uint8_t *b_ssid, uint32_t priority,
+ uint32_t pairwise_cipher_or_tx_key_len, uint32_t group_cipher_tx_key_index, uint32_t key_mgmt,
+ uint8_t* pf_or_key, uint32_t pass_phrase_length);
+#endif
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+ int32_t smart_config_process(void);
+#endif
+ int32_t disconnect();
+ int32_t ioctl_set_connection_policy(uint32_t should_connect_to_open_ap, uint32_t use_fast_connect, uint32_t use_profiles);
+ int32_t ioctl_del_profile(uint32_t index);
+ int32_t set_event_mask(uint32_t mask);
+ int32_t smart_config_start(uint32_t encrypted_flag);
+ int32_t smart_config_stop(void);
+ int32_t smart_config_set_prefix(uint8_t *new_prefix);
+private:
+ cc3000_simple_link &_simple_link;
+ cc3000_event &_event;
+ cc3000_spi &_spi;
+ cc3000_hci &_hci;
+};
+
+/** Client TCP/UDP class - TODO - not complete client
+ */
+class cc3000_client {
+public:
+ /**
+ */
+ cc3000_client(cc3000 &cc3000_ref);
+ /**
+ */
+ cc3000_client(cc3000 &cc3000_ref, int16_t socket);
+ /**
+ */
+ bool connected(void);
+ /**
+ */
+ int16_t write(const void *buffer, uint16_t length, uint32_t flags);
+ /**
+ */
+ int16_t read(void *buffer, uint16_t length, uint32_t flags);
+ /**
+ */
+ void close(void);
+
+private:
+ int16_t _current_socket;
+ cc3000 &_cc3000;
+};
+
+/** Server TCP/UDP
+ */
+class cc3000_server {
+public:
+ /** ctor (server was not created successfully)
+ */
+ cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add);
+ /** ctor
+ */
+ cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add, int16_t socket);
+ /** Blocking accept
+ */
+ int32_t accept(void);
+ /**
+ */
+ int32_t receive(void *buffer, uint16_t length, uint32_t flags);
+ /**
+ */
+ int32_t send(void *buffer, uint16_t length, uint32_t flags);
+ /**
+ */
+ void bind(void);
+ /**
+ */
+ void listen(uint32_t backlog);
+ /**
+ */
+ void close(void);
+private:
+ int16_t _current_socket;
+ sockaddr _socket_address;
+ cc3000 &_cc3000;
+};
+
+/** The main class of entire cc3000 implementation
+ */
+class cc3000 {
+public:
+ typedef struct {
+ bool dhcp;
+ bool connected;
+ uint8_t socket;
+ bool smart_config_complete;
+ bool stop_smart_config;
+ bool dhcp_configured;
+ bool ok_to_shut_down;
+ } tStatus;
+ /** ctor for cc3000 class.
+ * \param cc3000_irq IRQ pin
+ * \param cc3000_en Enable pin
+ * \param cc3000_cs Chip select pin
+ * \param cc3000_spi SPI interface
+ * \param irq_port IRQ pin's port
+ */
+ cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port);
+ /** dtor
+ */
+ ~cc3000();
+ /** Initiate cc3000. It starts the wlan communication and deletes profiles.
+ * \param patch Patch
+ */
+ void start(uint8_t patch);
+ /** Stops the wlan communication.
+ */
+ void stop();
+ /** Restarts the wlan communication.
+ */
+ void restart(uint8_t patch);
+ /** Disconnect wlan device
+ *
+ */
+ bool disconnect(void);
+ /** Callback which is called from the event class. This updates status of cc3000.
+ * \param event_type Type of the event
+ * \param data Pointer to data
+ * \param length Length of data
+ * \return none
+ */
+ void usync_callback(int32_t event_type, uint8_t *data, uint8_t length);
+ /** Connect to SSID (open/secured) with timeout (10ms).
+ * \param ssid SSID name
+ * \param key Security key (if key = 0, open connection)
+ * \param security_mode Security mode
+ * \return true if connection was established, false otherwise.
+ */
+ bool connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode);
+ /** Connect to SSID which is secured
+ * \param ssid SSID name
+ * \param key Security key
+ * \param security_mode Security mode
+ * \return true if connection was established, false otherwise.
+ */
+ bool connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode);
+ /** Connect to SSID which is open (no security)
+ * \param ssid SSID name
+ * \return true if connection was established, false otherwise.
+ */
+ bool connect_open(const uint8_t *ssid);
+ /** Status of the cc3000 connection.
+ * \return true if it's connected, false otherwise.
+ */
+ bool is_connected();
+ /** Status of DHCP.
+ * \param none
+ * \return true if DCHP is configured, false otherwise.
+ */
+ bool is_dhcp_configured();
+ /** Status of smart confing completation.
+ * \param none
+ * \return smart config was set, false otherwise.
+ */
+ bool is_smart_confing_completed();
+ /** Return the cc3000's mac address.
+ * \param address Retreived mac address.
+ * \return none
+ */
+ void get_mac_address(uint8_t address[6]);
+ /** Set the cc3000's mac address
+ * \param address Mac address to be set
+ * \return none
+ */
+ void set_mac_address(uint8_t address[6]);
+ /** Get user file info
+ * \param info_file Pointer where info will be stored
+ * \param size Available size
+ * \return none
+ */
+ void get_user_file_info(uint8_t *info_file, size_t size);
+ /** Set user filo info
+ * \param info_file Pointer to user's info
+ * \return none
+ */
+ void set_user_file_info(uint8_t *info_file, size_t size);
+ /** Start smart config
+ * \param smart_config_key Pointer to smart config key
+ * \return none
+ */
+ void start_smart_config(const uint8_t *smart_config_key); /* TODO enable AES ? */
+#ifndef CC3000_TINY_DRIVER
+ /** Return ip configuration
+ * \param ip_config Pointer to ipconfig data
+ * \return true if it's connected and info was retrieved, false otherwise.
+ */
+ bool get_ip_config(tNetappIpconfigRetArgs *ip_config);
+#endif
+ /** Creates tcp client
+ * \param ip_address Client's IP address
+ * \param port Client's PORT
+ * \return client with socket != -1
+ */
+ cc3000_client create_tcp_client(uint32_t ip_address, uint16_t port);
+ /** Creates tcp server
+ * \param ip_address Server's IP address
+ * \param port Server's PORT
+ * \return server with socket != -1
+ */
+ cc3000_server create_tcp_server(uint32_t ip_address, uint16_t port);
+ /** Creates udp client
+ * \param ip_address Server's IP address
+ * \param port Server's PORT
+ * \return client with socket != -1
+ */
+ cc3000_client create_udp_client(uint32_t ip_address, uint16_t port);
+ /** Delete all stored profiles
+ * \param none
+ * \return none
+ */
+ void delete_profiles(void);
+ /**
+ *
+ */
+ uint32_t ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size);
+
+ static cc3000 *get_instance() {
+ return _inst;
+ }
+
+ int32_t readable(void);
+ uint8_t getc(void);
+public:
+ cc3000_simple_link _simple_link;
+ cc3000_event _event;
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+ cc3000_security _security;
+#endif
+ cc3000_socket _socket;
+ cc3000_spi _spi;
+ cc3000_hci _hci;
+ cc3000_nvmem _nvmem;
+ cc3000_netapp _netapp;
+ cc3000_wlan _wlan;
+protected:
+ static cc3000 *_inst;
+ CircBuffer<char> _buffer;
+private:
+ tStatus _status;
+ netapp_pingreport_args_t _ping_report;
+ bool _closed_sockets[MAX_SOCKETS];
+};
+
+/**
+* Copy 32 bit to stream while converting to little endian format.
+* @param p pointer to the new stream
+* @param u32 pointer to the 32 bit
+* @return pointer to the new stream
+*/
+uint8_t *UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32);
+
+/**
+* Copy 16 bit to stream while converting to little endian format.
+* @param p pointer to the new stream
+* @param u32 pointer to the 16 bit
+* @return pointer to the new stream
+*/
+uint8_t *UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16);
+
+/**
+* Copy received stream to 16 bit in little endian format.
+* @param p pointer to the stream
+* @param offset offset in the stream
+* @return pointer to the new 16 bit
+*/
+uint16_t STREAM_TO_UINT16_f(uint8_t* p, uint16_t offset);
+
+/**
+* Copy received stream to 32 bit in little endian format.
+* @param p pointer to the stream
+* @param offset offset in the stream
+* @return pointer to the new 32 bit
+*/
+uint32_t STREAM_TO_UINT32_f(uint8_t* p, uint16_t offset);
+
+} /* end of mbed_cc3000 namespace */
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_client.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,72 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+
+namespace mbed_cc3000 {
+
+
+cc3000_client::cc3000_client(cc3000 &cc3000_ref) : _cc3000(cc3000_ref) {
+ _current_socket = -1;
+}
+
+cc3000_client::cc3000_client(cc3000 &cc3000_ref, int16_t socket) : _cc3000(cc3000_ref) {
+ _current_socket = socket;
+}
+
+bool cc3000_client::connected(void) {
+ if (_current_socket < 0) {
+ return false;
+ }
+
+ return true;
+}
+
+int16_t cc3000_client::write(const void *buffer, uint16_t length, uint32_t flags = 0) {
+ return _cc3000._socket.send(_current_socket, buffer, length, flags);
+}
+
+int16_t cc3000_client::read(void *buffer, uint16_t length, uint32_t flags)
+{
+ return _cc3000._socket.recv(_current_socket, buffer, length, flags);
+
+}
+
+} /* end of mbed_cc3000 namespace */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_event.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,585 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+#include "cc3000_event.h"
+#include "cc3000_netapp.h"
+
+namespace mbed_cc3000 {
+
+cc3000_event::cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000)
+ : socket_active_status(SOCKET_STATUS_INIT_VAL), _simple_link(simplelink), _hci(hci), _spi(spi), _cc3000(cc3000) {
+
+}
+
+cc3000_event::~cc3000_event() {
+
+}
+
+/* TODO removed buffer, set it in init */
+void cc3000_event::received_handler(uint8_t *buffer) {
+ _simple_link.set_data_received_flag(1);
+ _simple_link.set_received_data(buffer);
+
+ hci_unsolicited_event_handler();
+}
+
+void cc3000_event::hci_unsol_handle_patch_request(uint8_t *event_hdr) {
+ uint8_t *params = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+ uint32_t length = 0;
+ uint8_t *patch;
+
+ switch (*params)
+ {
+ case HCI_EVENT_PATCHES_DRV_REQ:
+ {
+ tDriverPatches func_pointer = (tDriverPatches)_simple_link.get_func_pointer(DRIVER_PATCHES);
+ if (func_pointer)
+ {
+ patch = func_pointer(&length);
+ if (patch)
+ {
+ _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), patch, length);
+ return;
+ }
+ }
+
+ // Send 0 length Patches response event
+ _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), 0, 0);
+ break;
+ }
+ case HCI_EVENT_PATCHES_FW_REQ:
+ {
+ tFWPatches func_pointer = (tFWPatches)_simple_link.get_func_pointer(FW_PATCHES);
+ if (func_pointer)
+ {
+ patch = func_pointer(&length);
+ // Build and send a patch
+ if (patch)
+ {
+ _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), patch, length);
+ return;
+ }
+ }
+ // Send 0 length Patches response event
+ _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), 0, 0);
+ break;
+ }
+ case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
+ {
+ tBootLoaderPatches func_pointer = (tBootLoaderPatches)_simple_link.get_func_pointer(BOOTLOADER_PATCHES);
+ if (func_pointer)
+ {
+ patch = func_pointer(&length);
+ if (patch)
+ {
+ _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), patch, length);
+ return;
+ }
+ }
+ // Send 0 length Patches response event
+ _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), 0, 0);
+ break;
+ }
+ }
+}
+
+uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) {
+ uint8_t *received_data, argument_size;
+ uint16_t length;
+ uint8_t *pucReceivedParams;
+ uint16_t received_op_code = 0;
+ uint32_t return_value;
+ uint8_t * RecvParams;
+ uint8_t *RetParams;
+
+ while (1)
+ {
+ if (_simple_link.get_data_received_flag() != 0)
+ {
+ received_data = _simple_link.get_received_data();
+ if (*received_data == HCI_TYPE_EVNT)
+ {
+ // Event Received
+ STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code);
+ pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE;
+ RecvParams = pucReceivedParams;
+ RetParams = (uint8_t *)ret_param;
+
+ // unsolicited event received - finish handling
+ if (hci_unsol_event_handler((uint8_t *)received_data) == 0)
+ {
+ STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length);
+
+ switch(received_op_code)
+ {
+ case HCI_CMND_READ_BUFFER_SIZE:
+ {
+ uint16_t temp = _simple_link.get_number_free_buffers();
+ STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp);
+ _simple_link.set_number_free_buffers(temp);
+
+ temp = _simple_link.get_buffer_length();
+ STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp);
+ _simple_link.set_buffer_length(temp);
+ }
+ break;
+
+ case HCI_CMND_WLAN_CONFIGURE_PATCH:
+ case HCI_NETAPP_DHCP:
+ case HCI_NETAPP_PING_SEND:
+ case HCI_NETAPP_PING_STOP:
+ case HCI_NETAPP_ARP_FLUSH:
+ case HCI_NETAPP_SET_DEBUG_LEVEL:
+ case HCI_NETAPP_SET_TIMERS:
+ case HCI_EVNT_NVMEM_READ:
+ case HCI_EVNT_NVMEM_CREATE_ENTRY:
+ case HCI_CMND_NVMEM_WRITE_PATCH:
+ case HCI_NETAPP_PING_REPORT:
+ case HCI_EVNT_MDNS_ADVERTISE:
+
+ STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
+ break;
+
+ case HCI_CMND_SETSOCKOPT:
+ case HCI_CMND_WLAN_CONNECT:
+ case HCI_CMND_WLAN_IOCTL_STATUSGET:
+ case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
+ case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
+ case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
+ case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
+ case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
+ case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
+ case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
+ case HCI_CMND_EVENT_MASK:
+ case HCI_EVNT_WLAN_DISCONNECT:
+ case HCI_EVNT_SOCKET:
+ case HCI_EVNT_BIND:
+ case HCI_CMND_LISTEN:
+ case HCI_EVNT_CLOSE_SOCKET:
+ case HCI_EVNT_CONNECT:
+ case HCI_EVNT_NVMEM_WRITE:
+
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param);
+ break;
+
+ case HCI_EVNT_READ_SP_VERSION:
+
+ STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 1;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value);
+ UINT32_TO_STREAM((uint8_t *)ret_param, return_value);
+ break;
+
+ case HCI_EVNT_BSD_GETHOSTBYNAME:
+
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param);
+ break;
+
+ case HCI_EVNT_ACCEPT:
+ {
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+
+ //This argument returns in network order
+ memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
+ break;
+ }
+
+ case HCI_EVNT_RECV:
+ case HCI_EVNT_RECVFROM:
+ {
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param);
+
+ if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
+ {
+ set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
+ }
+ break;
+ }
+
+ case HCI_EVNT_SEND:
+ case HCI_EVNT_SENDTO:
+ {
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+
+ break;
+ }
+
+ case HCI_EVNT_SELECT:
+ {
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param);
+ break;
+ }
+
+ case HCI_CMND_GETSOCKOPT:
+
+ STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus);
+ //This argument returns in network order
+ memcpy((uint8_t *)ret_param, pucReceivedParams, 4);
+ break;
+
+ case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
+
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 4;
+ STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 2;
+ STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param);
+ ret_param = ((uint8_t *)ret_param) + 2;
+ memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
+ break;
+
+ case HCI_CMND_SIMPLE_LINK_START:
+ break;
+
+ case HCI_NETAPP_IPCONFIG:
+
+ //Read IP address
+ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+ RecvParams += 4;
+
+ //Read subnet
+ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+ RecvParams += 4;
+
+ //Read default GW
+ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+ RecvParams += 4;
+
+ //Read DHCP server
+ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+ RecvParams += 4;
+
+ //Read DNS server
+ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
+ RecvParams += 4;
+
+ //Read Mac address
+ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
+ RecvParams += 6;
+
+ //Read SSID
+ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
+
+ }
+ }
+ if (received_op_code == _simple_link.get_op_code())
+ {
+ _simple_link.set_op_code(0);
+ }
+ }
+ else
+ {
+ pucReceivedParams = received_data;
+ STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size);
+
+ STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length);
+
+ // Data received: note that the only case where from and from length
+ // are not null is in recv from, so fill the args accordingly
+ if (from)
+ {
+ STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen);
+ memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
+ }
+
+ memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size);
+
+ _simple_link.set_pending_data(0);
+ }
+
+ _simple_link.set_data_received_flag(0);
+
+ //tWlanInterruptEnable func_pointer = (tWlanInterruptEnable)_simple_link.get_func_pointer(WLAN_INTERRUPT_ENABLE);
+ //func_pointer();
+ _spi.wlan_irq_enable();
+
+ // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts
+ if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ))
+ {
+ hci_unsol_handle_patch_request((uint8_t *)received_data);
+ }
+ if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0))
+ {
+ return NULL;
+ }
+ }
+ }
+}
+
+int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) {
+ uint8_t *data = NULL;
+ int32_t event_type;
+ uint32_t number_of_released_packets;
+ uint32_t number_of_sent_packets;
+
+ STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);
+
+ if (event_type & HCI_EVNT_UNSOL_BASE) {
+ switch(event_type) {
+ case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
+ {
+ hci_event_unsol_flowcontrol_handler(event_hdr);
+
+ number_of_released_packets = _simple_link.get_released_packets();
+ number_of_sent_packets = _simple_link.get_sent_packets();
+
+ if (number_of_released_packets == number_of_sent_packets)
+ {
+ if (_simple_link.get_tx_complete_signal())
+ {
+ //tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+ _cc3000.usync_callback(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
+ }
+ }
+ return 1;
+ }
+ }
+ }
+
+ if (event_type & HCI_EVNT_WLAN_UNSOL_BASE) {
+ switch(event_type) {
+ case HCI_EVNT_WLAN_KEEPALIVE:
+ case HCI_EVNT_WLAN_UNSOL_CONNECT:
+ case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
+ case HCI_EVNT_WLAN_UNSOL_INIT:
+ case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
+ // {
+ // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+ // if( func_pointer )
+ // {
+ // func_pointer(event_type, 0, 0);
+ // }
+ _cc3000.usync_callback(event_type, 0, 0);
+ break;
+ // }
+ case HCI_EVNT_WLAN_UNSOL_DHCP:
+ {
+ uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
+ uint8_t *recParams = params;
+ data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+
+ //Read IP address
+ STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
+ data += 4;
+ //Read subnet
+ STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
+ data += 4;
+ //Read default GW
+ STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
+ data += 4;
+ //Read DHCP server
+ STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
+ data += 4;
+ //Read DNS server
+ STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
+ // read the status
+ STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);
+
+ // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+ // if( func_pointer )
+ // {
+ _cc3000.usync_callback(event_type, (uint8_t *)params, sizeof(params));
+ // }
+ break;
+ }
+ case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
+ {
+ netapp_pingreport_args_t params;
+ data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
+ STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
+ STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
+ STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
+ STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
+ STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);
+
+ // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+ // if (func_pointer)
+ // {
+ _cc3000.usync_callback(event_type, (uint8_t *)¶ms, sizeof(params));
+ // }
+ break;
+ }
+ case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
+ {
+ // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB);
+ // if (func_pointer)
+ // {
+ _cc3000.usync_callback(event_type, NULL, 0);
+ // }
+ break;
+ }
+
+ //'default' case which means "event not supported"
+ default:
+ return (0);
+ }
+ return(1);
+ }
+
+ if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || (event_type == HCI_EVNT_WRITE)) {
+ uint8_t *pArg;
+ int32_t status;
+ pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
+ STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
+ if (ERROR_SOCKET_INACTIVE == status) {
+ // The only synchronous event that can come from SL device in form of
+ // command complete is "Command Complete" on data sent, in case SL device
+ // was unable to transmit
+ int32_t transmit_error = _simple_link.get_transmit_error();
+ STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error);
+ _simple_link.set_transmit_error(transmit_error);
+ update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
+ return (1);
+ }
+ else {
+ return (0);
+ }
+ }
+ return(0);
+}
+
+int32_t cc3000_event::hci_unsolicited_event_handler(void) {
+ uint32_t res = 0;
+ uint8_t *received_data;
+
+ if (_simple_link.get_data_received_flag() != 0) {
+ received_data = (_simple_link.get_received_data());
+
+ if (*received_data == HCI_TYPE_EVNT) {
+ // unsolicited event received - finish handling
+ if (hci_unsol_event_handler((uint8_t *)received_data) == 1) {
+ // An unsolicited event was received:
+ // release the buffer and clean the event received
+ _simple_link.set_data_received_flag(0);
+
+ res = 1;
+ _spi.wlan_irq_enable();
+ }
+ }
+ }
+ return res;
+}
+
+void cc3000_event::set_socket_active_status(int32_t sd, int32_t status) {
+ if (M_IS_VALID_SD(sd) && M_IS_VALID_STATUS(status))
+ {
+ socket_active_status &= ~(1 << sd); /* clean socket's mask */
+ socket_active_status |= (status << sd); /* set new socket's mask */
+ }
+}
+
+int32_t cc3000_event::hci_event_unsol_flowcontrol_handler(uint8_t *event) {
+ int32_t temp, value;
+ uint16_t i;
+ uint16_t pusNumberOfHandles=0;
+ uint8_t *pReadPayload;
+
+ STREAM_TO_UINT16((uint8_t *)event,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
+ pReadPayload = ((uint8_t *)event + HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));
+ temp = 0;
+
+ for(i = 0; i < pusNumberOfHandles; i++) {
+ STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value);
+ temp += value;
+ pReadPayload += FLOW_CONTROL_EVENT_SIZE;
+ }
+
+ _simple_link.set_number_free_buffers(_simple_link.get_number_free_buffers() + temp);
+ _simple_link.set_number_of_released_packets(_simple_link.get_released_packets() + temp);
+
+ return(ESUCCESS);
+}
+
+int32_t cc3000_event::get_socket_active_status(int32_t sd) {
+ if(M_IS_VALID_SD(sd)) {
+ return (socket_active_status & (1 << sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
+ } else {
+ return SOCKET_STATUS_INACTIVE;
+ }
+}
+
+void cc3000_event::update_socket_active_status(uint8_t *resp_params) {
+ int32_t status, sd;
+
+ STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd);
+ STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status);
+
+ if(ERROR_SOCKET_INACTIVE == status) {
+ set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+ }
+}
+
+void cc3000_event::simplelink_wait_event(uint16_t op_code, void *ret_param) {
+ // In the blocking implementation the control to caller will be returned only
+ // after the end of current transaction
+ _simple_link.set_op_code(op_code);
+ hci_event_handler(ret_param, 0, 0);
+}
+
+void cc3000_event::simplelink_wait_data(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) {
+ // In the blocking implementation the control to caller will be returned only
+ // after the end of current transaction, i.e. only after data will be received
+ _simple_link.set_pending_data(1);
+ hci_event_handler(pBuf, from, fromlen);
+}
+
+
+} /* end of cc3000 namespace */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_event.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,143 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef CC3000_EVENT_H
+#define CC3000_EVENT_H
+
+typedef struct _bsd_read_return_t
+{
+ int32_t iSocketDescriptor;
+ int32_t iNumberOfBytes;
+ uint32_t uiFlags;
+} tBsdReadReturnParams;
+
+typedef struct _bsd_getsockopt_return_t
+{
+ uint8_t ucOptValue[4];
+ uint8_t iStatus;
+} tBsdGetSockOptReturnParams;
+
+typedef struct _bsd_accept_return_t
+{
+ int32_t iSocketDescriptor;
+ int32_t iStatus;
+ sockaddr tSocketAddress;
+
+} tBsdReturnParams;
+
+typedef struct _bsd_select_return_t
+{
+ int32_t iStatus;
+ uint32_t uiRdfd;
+ uint32_t uiWrfd;
+ uint32_t uiExfd;
+} tBsdSelectRecvParams;
+
+typedef struct _bsd_gethostbyname_return_t
+{
+ int32_t retVal;
+ int32_t outputAddress;
+} tBsdGethostbynameParams;
+
+#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0)
+#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1)
+#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2)
+#define FLOW_CONTROL_EVENT_SIZE (4)
+
+#define BSD_RSP_PARAMS_SOCKET_OFFSET (0)
+#define BSD_RSP_PARAMS_STATUS_OFFSET (4)
+
+#define GET_HOST_BY_NAME_RETVAL_OFFSET (0)
+#define GET_HOST_BY_NAME_ADDR_OFFSET (4)
+
+#define ACCEPT_SD_OFFSET (0)
+#define ACCEPT_RETURN_STATUS_OFFSET (4)
+#define ACCEPT_ADDRESS__OFFSET (8)
+
+#define SL_RECEIVE_SD_OFFSET (0)
+#define SL_RECEIVE_NUM_BYTES_OFFSET (4)
+#define SL_RECEIVE__FLAGS__OFFSET (8)
+
+
+#define SELECT_STATUS_OFFSET (0)
+#define SELECT_READFD_OFFSET (4)
+#define SELECT_WRITEFD_OFFSET (8)
+#define SELECT_EXFD_OFFSET (12)
+
+
+#define NETAPP_IPCONFIG_IP_OFFSET (0)
+#define NETAPP_IPCONFIG_SUBNET_OFFSET (4)
+#define NETAPP_IPCONFIG_GW_OFFSET (8)
+#define NETAPP_IPCONFIG_DHCP_OFFSET (12)
+#define NETAPP_IPCONFIG_DNS_OFFSET (16)
+#define NETAPP_IPCONFIG_MAC_OFFSET (20)
+#define NETAPP_IPCONFIG_SSID_OFFSET (26)
+
+#define NETAPP_IPCONFIG_IP_LENGTH (4)
+#define NETAPP_IPCONFIG_MAC_LENGTH (6)
+#define NETAPP_IPCONFIG_SSID_LENGTH (32)
+
+
+#define NETAPP_PING_PACKETS_SENT_OFFSET (0)
+#define NETAPP_PING_PACKETS_RCVD_OFFSET (4)
+#define NETAPP_PING_MIN_RTT_OFFSET (8)
+#define NETAPP_PING_MAX_RTT_OFFSET (12)
+#define NETAPP_PING_AVG_RTT_OFFSET (16)
+
+#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0)
+#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4)
+#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8)
+#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10)
+#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38)
+
+#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((uint8_t *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE)
+
+#define SOCKET_STATUS_ACTIVE 0
+#define SOCKET_STATUS_INACTIVE 1
+/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE.
+ Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */
+#define SOCKET_STATUS_INIT_VAL 0xFFFF
+#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
+#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
+
+#define BSD_RECV_FROM_FROMLEN_OFFSET (4)
+#define BSD_RECV_FROM_FROM_OFFSET (16)
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_hci.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,149 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+
+namespace mbed_cc3000 {
+
+cc3000_hci::cc3000_hci(cc3000_spi &spi) : _spi(spi) {
+
+}
+
+cc3000_hci::~cc3000_hci() {
+
+}
+
+uint16_t cc3000_hci::command_send(uint16_t op_code, uint8_t *buffer, uint8_t length) {
+ unsigned char *stream;
+
+ stream = (buffer + SPI_HEADER_SIZE);
+
+ UINT8_TO_STREAM(stream, HCI_TYPE_CMND);
+ stream = UINT16_TO_STREAM(stream, op_code);
+ UINT8_TO_STREAM(stream, length);
+ //Update the opcode of the event we will be waiting for
+ _spi.write(buffer, length + SIMPLE_LINK_HCI_CMND_HEADER_SIZE);
+ return(0);
+}
+
+uint32_t cc3000_hci::data_send(uint8_t op_code, uint8_t *args, uint16_t arg_length,
+ uint16_t data_length, const uint8_t *tail, uint16_t tail_length) {
+ unsigned char *stream;
+
+ stream = ((args) + SPI_HEADER_SIZE);
+
+ UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
+ UINT8_TO_STREAM(stream, op_code);
+ UINT8_TO_STREAM(stream, arg_length);
+ stream = UINT16_TO_STREAM(stream, arg_length + data_length + tail_length);
+
+ // Send the packet
+ _spi.write(args, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + arg_length + data_length + tail_length);
+
+ return 0;
+}
+
+void cc3000_hci::data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length, uint16_t data_length) {
+ unsigned char *stream = (buffer + SPI_HEADER_SIZE);
+
+ UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
+ UINT8_TO_STREAM(stream, op_code);
+ UINT8_TO_STREAM(stream, arg_length);
+ stream = UINT16_TO_STREAM(stream, arg_length + data_length);
+
+ // Send the command
+ _spi.write(buffer, arg_length + data_length + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE);
+
+ return;
+}
+
+void cc3000_hci::patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length) {
+ unsigned short usTransLength;
+ unsigned char *stream = (buffer + SPI_HEADER_SIZE);
+ UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
+ UINT8_TO_STREAM(stream, op_code);
+ stream = UINT16_TO_STREAM(stream, data_length + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
+ if (data_length <= SL_PATCH_PORTION_SIZE)
+ {
+ UINT16_TO_STREAM(stream, data_length);
+ stream = UINT16_TO_STREAM(stream, data_length);
+ memcpy((buffer + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, data_length);
+ // Update the opcode of the event we will be waiting for
+ _spi.write(buffer, data_length + HCI_PATCH_HEADER_SIZE);
+ }
+ else
+ {
+
+ usTransLength = (data_length/SL_PATCH_PORTION_SIZE);
+ UINT16_TO_STREAM(stream, data_length + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
+ stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE);
+ memcpy(buffer + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE);
+ data_length -= SL_PATCH_PORTION_SIZE;
+ patch += SL_PATCH_PORTION_SIZE;
+
+ // Update the opcode of the event we will be waiting for
+ _spi.write(buffer, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);
+
+ stream = (buffer + SPI_HEADER_SIZE);
+ while (data_length)
+ {
+ if (data_length <= SL_PATCH_PORTION_SIZE)
+ {
+ usTransLength = data_length;
+ data_length = 0;
+
+ }
+ else
+ {
+ usTransLength = SL_PATCH_PORTION_SIZE;
+ data_length -= usTransLength;
+ }
+
+ *(unsigned short *)stream = usTransLength;
+ memcpy(stream + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength);
+ patch += usTransLength;
+
+ // Update the opcode of the event we will be waiting for
+ _spi.write((unsigned char *)stream, usTransLength + sizeof(usTransLength));
+ }
+ }
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_netapp.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,199 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+#include "cc3000_netapp.h"
+
+namespace mbed_cc3000 {
+
+cc3000_netapp::cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci , cc3000_event &event) :
+ _simple_link(simple_link), _nvmem(nvmem), _hci(hci), _event(event) {
+
+}
+
+cc3000_netapp::~cc3000_netapp() {
+
+}
+
+int32_t cc3000_netapp::config_mac_adrress(uint8_t * mac) {
+ return _nvmem.set_mac_address(mac);
+}
+
+int32_t cc3000_netapp::dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server) {
+ int8_t scRet;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ scRet = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ ARRAY_TO_STREAM(args,ip,4);
+ ARRAY_TO_STREAM(args,subnet_mask,4);
+ ARRAY_TO_STREAM(args,default_gateway,4);
+ args = UINT32_TO_STREAM(args, 0);
+ ARRAY_TO_STREAM(args,dns_server,4);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_NETAPP_DHCP, &scRet);
+
+ return(scRet);
+}
+
+#ifndef CC3000_TINY_DRIVER
+void cc3000_netapp::ipconfig( tNetappIpconfigRetArgs * ipconfig ) {
+ uint8_t *ptr;
+
+ ptr = _simple_link.get_transmit_buffer();
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_NETAPP_IPCONFIG, ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_NETAPP_IPCONFIG, ipconfig );
+}
+
+
+int32_t cc3000_netapp::timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity) {
+ int8_t scRet;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ scRet = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Set minimal values of timers
+ MIN_TIMER_SET(*dhcp)
+ MIN_TIMER_SET(*arp)
+ MIN_TIMER_SET(*keep_alive)
+ MIN_TIMER_SET(*inactivity)
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, *dhcp);
+ args = UINT32_TO_STREAM(args, *arp);
+ args = UINT32_TO_STREAM(args, *keep_alive);
+ args = UINT32_TO_STREAM(args, *inactivity);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_NETAPP_SET_TIMERS, &scRet);
+
+ return(scRet);
+}
+
+int32_t cc3000_netapp::ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout) {
+ int8_t scRet;
+ uint8_t *ptr, *args;
+
+ scRet = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, *ip);
+ args = UINT32_TO_STREAM(args, ping_attempts);
+ args = UINT32_TO_STREAM(args, ping_size);
+ args = UINT32_TO_STREAM(args, ping_timeout);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_NETAPP_PING_SEND, &scRet);
+
+ return(scRet);
+}
+
+void cc3000_netapp::ping_report() {
+ uint8_t *ptr;
+ int8_t scRet;
+ ptr = _simple_link.get_transmit_buffer();
+
+
+ scRet = EFAIL;
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_NETAPP_PING_REPORT, ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_NETAPP_PING_REPORT, &scRet);
+}
+
+int32_t cc3000_netapp::ping_stop() {
+ int8_t scRet;
+ uint8_t *ptr;
+
+ scRet = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_NETAPP_PING_STOP, ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_NETAPP_PING_STOP, &scRet);
+
+ return(scRet);
+}
+
+int32_t cc3000_netapp::arp_flush() {
+ int8_t scRet;
+ uint8_t *ptr;
+
+ scRet = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_NETAPP_ARP_FLUSH, &scRet);
+
+ return(scRet);
+}
+#endif
+
+} /* end of cc3000 namespace */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_netapp.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,88 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef CC3000_NETAPP_H
+#define CC3000_NETAPP_H
+
+#define MIN_TIMER_VAL_SECONDS 20
+#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \
+ { \
+ t = MIN_TIMER_VAL_SECONDS; \
+ }
+
+
+#define NETAPP_DHCP_PARAMS_LEN (20)
+#define NETAPP_SET_TIMER_PARAMS_LEN (20)
+#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4)
+#define NETAPP_PING_SEND_PARAMS_LEN (16)
+
+
+typedef struct _netapp_dhcp_ret_args_t
+{
+ uint8_t aucIP[4];
+ uint8_t aucSubnetMask[4];
+ uint8_t aucDefaultGateway[4];
+ uint8_t aucDHCPServer[4];
+ uint8_t aucDNSServer[4];
+}tNetappDhcpParams;
+
+typedef struct _netapp_ipconfig_ret_args_t
+{
+ uint8_t aucIP[4];
+ uint8_t aucSubnetMask[4];
+ uint8_t aucDefaultGateway[4];
+ uint8_t aucDHCPServer[4];
+ uint8_t aucDNSServer[4];
+ uint8_t uaMacAddr[6];
+ uint8_t uaSSID[32];
+}tNetappIpconfigRetArgs;
+
+
+/*Ping send report parameters*/
+typedef struct _netapp_pingreport_args
+{
+ uint32_t packets_sent;
+ uint32_t packets_received;
+ uint32_t min_round_time;
+ uint32_t max_round_time;
+ uint32_t avg_round_time;
+} netapp_pingreport_args_t;
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_nvmem.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,186 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+#include "cc3000_nvmem.h"
+#include "cc3000_common.h"
+
+namespace mbed_cc3000 {
+
+cc3000_nvmem::cc3000_nvmem(cc3000_hci &hci, cc3000_event &event, cc3000_simple_link &simple_link)
+ : _hci(hci), _event(event), _simple_link(simple_link) {
+
+}
+
+cc3000_nvmem::~cc3000_nvmem() {
+
+}
+
+int32_t cc3000_nvmem::read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff) {
+ uint8_t ucStatus = 0xFF;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, file_id);
+ args = UINT32_TO_STREAM(args, length);
+ args = UINT32_TO_STREAM(args, offset);
+
+ // Initiate HCI command
+ _hci.command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN);
+ _event.simplelink_wait_event(HCI_CMND_NVMEM_READ, &ucStatus);
+
+ // If data is present, read it even when an error is returned.
+ // Note: It is the users responsibility to ignore the data when an error is returned.
+ // Wait for the data in a synchronous way.
+ // We assume the buffer is large enough to also store nvmem parameters.
+ _event.simplelink_wait_data(buff, 0, 0);
+
+ return(ucStatus);
+}
+
+int32_t cc3000_nvmem::write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff) {
+ int32_t iRes;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ iRes = EFAIL;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, file_id);
+ args = UINT32_TO_STREAM(args, 12);
+ args = UINT32_TO_STREAM(args, length);
+ args = UINT32_TO_STREAM(args, entry_offset);
+
+ memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE +
+ NVMEM_WRITE_PARAMS_LEN),buff,length);
+
+ // Initiate a HCI command on the data channel
+ _hci.data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, length);
+
+ _event.simplelink_wait_event(HCI_EVNT_NVMEM_WRITE, &iRes);
+
+ return(iRes);
+}
+
+uint8_t cc3000_nvmem::set_mac_address(uint8_t *mac) {
+ return write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
+}
+
+uint8_t cc3000_nvmem::get_mac_address(uint8_t *mac) {
+ return read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
+}
+
+uint8_t cc3000_nvmem::write_patch(uint32_t file_id, uint32_t length, const uint8_t *data) {
+ uint8_t status = 0;
+ uint16_t offset = 0;
+ uint8_t* spDataPtr = (uint8_t*)data;
+
+ while ((status == 0) && (length >= SP_PORTION_SIZE))
+ {
+ status = write(file_id, SP_PORTION_SIZE, offset, spDataPtr);
+ offset += SP_PORTION_SIZE;
+ length -= SP_PORTION_SIZE;
+ spDataPtr += SP_PORTION_SIZE;
+ }
+
+ if (status !=0)
+ {
+ // NVMEM error occurred
+ return status;
+ }
+
+ if (length != 0)
+ {
+ // If length MOD 512 is nonzero, write the remaining bytes.
+ status = write(file_id, length, offset, spDataPtr);
+ }
+
+ return status;
+}
+
+int32_t cc3000_nvmem::create_entry(uint32_t file_id, uint32_t new_len) {
+ uint8_t *ptr;
+ uint8_t *args;
+ uint16_t retval;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, file_id);
+ args = UINT32_TO_STREAM(args, new_len);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN);
+
+ _event.simplelink_wait_event(HCI_CMND_NVMEM_CREATE_ENTRY, &retval);
+
+ return(retval);
+}
+
+#ifndef CC3000_TINY_DRIVER
+uint8_t cc3000_nvmem::read_sp_version(uint8_t* patch_ver) {
+ uint8_t *ptr;
+ // 1st byte is the status and the rest is the SP version
+ uint8_t retBuf[5];
+
+ ptr = _simple_link.get_transmit_buffer();
+
+ // Initiate a HCI command, no args are required
+ _hci.command_send(HCI_CMND_READ_SP_VERSION, ptr, 0);
+ _event.simplelink_wait_event(HCI_CMND_READ_SP_VERSION, retBuf);
+
+ // package ID
+ *patch_ver = retBuf[3];
+ // package build number
+ *(patch_ver+1) = retBuf[4];
+
+ return(retBuf[0]);
+}
+
+#endif
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cc3000_nvmem.h Thu Sep 19 07:55:14 2013 +0000 @@ -0,0 +1,100 @@ +/***************************************************************************** +* +* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to +* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and +* provided help. +* +* This version of "host driver" uses CC3000 Host Driver Implementation. Thus +* read the following copyright: +* +* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#ifndef CC3000_NVMEM_H +#define CC3000_NVMEM_H + +#define NVMEM_READ_PARAMS_LEN (12) +#define NVMEM_CREATE_PARAMS_LEN (8) +#define NVMEM_WRITE_PARAMS_LEN (16) + + +/**************************************************************************** +** +** Definitions for File IDs +** +****************************************************************************/ +/* --------------------------------------------------------- EEPROM FAT table --------------------------------------------------------- + + File ID Offset File Size Used Size Parameter + # ID address (bytes) (bytes) + -------------------------------------------------------------------------------------------------------------------------------------- + 0 NVMEM_NVS_FILEID 0x50 0x1A0 0x1A RF Calibration results table(generated automatically by TX Bip) + 1 NVMEM_NVS_SHADOW_FILEID 0x1F0 0x1A0 0x1A NVS Shadow + 2 NVMEM_WLAN_CONFIG_FILEID 0x390 0x1000 0x64 WLAN configuration + 3 NVMEM_WLAN_CONFIG_SHADOW_FILEID 0x1390 0x1000 0x64 WLAN configuration shadow + 4 NVMEM_WLAN_DRIVER_SP_FILEID 0x2390 0x2000 variable WLAN Driver ROM Patches + 5 NVMEM_WLAN_FW_SP_FILEID 0x4390 0x2000 variable WLAN FW Patches + 6 NVMEM_MAC_FILEID 0x6390 0x10 0x10 6 bytes of MAC address + 7 NVMEM_FRONTEND_VARS_FILEID 0x63A0 0x10 0x10 Frontend Vars + 8 NVMEM_IP_CONFIG_FILEID 0x63B0 0x40 0x40 IP configuration + 9 NVMEM_IP_CONFIG_SHADOW_FILEID 0x63F0 0x40 0x40 IP configuration shadow +10 NVMEM_BOOTLOADER_SP_FILEID 0x6430 0x400 variable Bootloader Patches +11 NVMEM_RM_FILEID 0x6830 0x200 0x7F Radio parameters +12 NVMEM_AES128_KEY_FILEID 0x6A30 0x10 0x10 AES128 key file +13 NVMEM_SHARED_MEM_FILEID 0x6A40 0x50 0x44 Host-CC3000 shared memory file +14 NVMEM_USER_FILE_1_FILEID 0x6A90 variable variable 1st user file +15 NVMEM_USER_FILE_2_FILEID variable variable variable 2nd user file +*/ +/* NVMEM file ID - system files*/ +#define NVMEM_NVS_FILEID (0) +#define NVMEM_NVS_SHADOW_FILEID (1) +#define NVMEM_WLAN_CONFIG_FILEID (2) +#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3) +#define NVMEM_WLAN_DRIVER_SP_FILEID (4) +#define NVMEM_WLAN_FW_SP_FILEID (5) +#define NVMEM_MAC_FILEID (6) +#define NVMEM_FRONTEND_VARS_FILEID (7) +#define NVMEM_IP_CONFIG_FILEID (8) +#define NVMEM_IP_CONFIG_SHADOW_FILEID (9) +#define NVMEM_BOOTLOADER_SP_FILEID (10) +#define NVMEM_RM_FILEID (11) + +/* NVMEM file ID - user files*/ +#define NVMEM_AES128_KEY_FILEID (12) +#define NVMEM_SHARED_MEM_FILEID (13) +#define NVMEM_USER_FILE_1_FILEID (14) +#define NVMEM_USER_FILE_2_FILEID (15) + +/* max entry in order to invalid nvmem */ +#define NVMEM_MAX_ENTRY (16) + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_security.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,381 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+
+namespace mbed_cc3000 {
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+
+// forward sbox
+static const uint8_t sbox[256] = {
+//0 1 2 3 4 5 6 7 8 9 A B C D E F
+0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
+0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
+0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
+0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
+0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
+0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
+0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
+0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
+0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
+0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
+0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
+0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
+0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
+0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
+0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
+0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
+// inverse sbox
+static const uint8_t rsbox[256] =
+{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
+// round constant
+static const uint8_t Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
+
+void cc3000_security::expandKey(uint8_t *expanded_key, uint8_t *key) {
+ uint16_t ii, buf1;
+ for (ii=0;ii<16;ii++)
+ expanded_key[ii] = key[ii];
+ for (ii=1;ii<11;ii++)
+ {
+ buf1 = expanded_key[ii*16 - 4];
+ expanded_key[ii*16 + 0] = sbox[expanded_key[ii*16 - 3]]^expanded_key[(ii-1)*16 + 0]^Rcon[ii];
+ expanded_key[ii*16 + 1] = sbox[expanded_key[ii*16 - 2]]^expanded_key[(ii-1)*16 + 1];
+ expanded_key[ii*16 + 2] = sbox[expanded_key[ii*16 - 1]]^expanded_key[(ii-1)*16 + 2];
+ expanded_key[ii*16 + 3] = sbox[buf1 ]^expanded_key[(ii-1)*16 + 3];
+ expanded_key[ii*16 + 4] = expanded_key[(ii-1)*16 + 4]^expanded_key[ii*16 + 0];
+ expanded_key[ii*16 + 5] = expanded_key[(ii-1)*16 + 5]^expanded_key[ii*16 + 1];
+ expanded_key[ii*16 + 6] = expanded_key[(ii-1)*16 + 6]^expanded_key[ii*16 + 2];
+ expanded_key[ii*16 + 7] = expanded_key[(ii-1)*16 + 7]^expanded_key[ii*16 + 3];
+ expanded_key[ii*16 + 8] = expanded_key[(ii-1)*16 + 8]^expanded_key[ii*16 + 4];
+ expanded_key[ii*16 + 9] = expanded_key[(ii-1)*16 + 9]^expanded_key[ii*16 + 5];
+ expanded_key[ii*16 +10] = expanded_key[(ii-1)*16 +10]^expanded_key[ii*16 + 6];
+ expanded_key[ii*16 +11] = expanded_key[(ii-1)*16 +11]^expanded_key[ii*16 + 7];
+ expanded_key[ii*16 +12] = expanded_key[(ii-1)*16 +12]^expanded_key[ii*16 + 8];
+ expanded_key[ii*16 +13] = expanded_key[(ii-1)*16 +13]^expanded_key[ii*16 + 9];
+ expanded_key[ii*16 +14] = expanded_key[(ii-1)*16 +14]^expanded_key[ii*16 +10];
+ expanded_key[ii*16 +15] = expanded_key[(ii-1)*16 +15]^expanded_key[ii*16 +11];
+ }
+}
+
+uint8_t cc3000_security::galois_mul2(uint8_t value) {
+ if (value >> 7) {
+ value = value << 1;
+ return (value ^ 0x1b);
+ } else {
+ return (value << 1);
+ }
+}
+
+void cc3000_security::aes_encr(uint8_t *state, uint8_t *expanded_key) {
+ uint8_t buf1, buf2, buf3, round;
+
+ for (round = 0; round < 9; round ++)
+ {
+ // addroundkey, sbox and shiftrows
+ // row 0
+ state[ 0] = sbox[(state[ 0] ^ expanded_key[(round*16) ])];
+ state[ 4] = sbox[(state[ 4] ^ expanded_key[(round*16) + 4])];
+ state[ 8] = sbox[(state[ 8] ^ expanded_key[(round*16) + 8])];
+ state[12] = sbox[(state[12] ^ expanded_key[(round*16) + 12])];
+ // row 1
+ buf1 = state[1] ^ expanded_key[(round*16) + 1];
+ state[ 1] = sbox[(state[ 5] ^ expanded_key[(round*16) + 5])];
+ state[ 5] = sbox[(state[ 9] ^ expanded_key[(round*16) + 9])];
+ state[ 9] = sbox[(state[13] ^ expanded_key[(round*16) + 13])];
+ state[13] = sbox[buf1];
+ // row 2
+ buf1 = state[2] ^ expanded_key[(round*16) + 2];
+ buf2 = state[6] ^ expanded_key[(round*16) + 6];
+ state[ 2] = sbox[(state[10] ^ expanded_key[(round*16) + 10])];
+ state[ 6] = sbox[(state[14] ^ expanded_key[(round*16) + 14])];
+ state[10] = sbox[buf1];
+ state[14] = sbox[buf2];
+ // row 3
+ buf1 = state[15] ^ expanded_key[(round*16) + 15];
+ state[15] = sbox[(state[11] ^ expanded_key[(round*16) + 11])];
+ state[11] = sbox[(state[ 7] ^ expanded_key[(round*16) + 7])];
+ state[ 7] = sbox[(state[ 3] ^ expanded_key[(round*16) + 3])];
+ state[ 3] = sbox[buf1];
+
+ // mixcolums //////////
+ // col1
+ buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
+ buf2 = state[0];
+ buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
+ buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
+ buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
+ buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
+ // col2
+ buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
+ buf2 = state[4];
+ buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
+ buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
+ buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
+ buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
+ // col3
+ buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
+ buf2 = state[8];
+ buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
+ buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
+ buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
+ buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
+ // col4
+ buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
+ buf2 = state[12];
+ buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
+ buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
+ buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
+ buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
+
+ }
+ // 10th round without mixcols
+ state[ 0] = sbox[(state[ 0] ^ expanded_key[(round*16) ])];
+ state[ 4] = sbox[(state[ 4] ^ expanded_key[(round*16) + 4])];
+ state[ 8] = sbox[(state[ 8] ^ expanded_key[(round*16) + 8])];
+ state[12] = sbox[(state[12] ^ expanded_key[(round*16) + 12])];
+ // row 1
+ buf1 = state[1] ^ expanded_key[(round*16) + 1];
+ state[ 1] = sbox[(state[ 5] ^ expanded_key[(round*16) + 5])];
+ state[ 5] = sbox[(state[ 9] ^ expanded_key[(round*16) + 9])];
+ state[ 9] = sbox[(state[13] ^ expanded_key[(round*16) + 13])];
+ state[13] = sbox[buf1];
+ // row 2
+ buf1 = state[2] ^ expanded_key[(round*16) + 2];
+ buf2 = state[6] ^ expanded_key[(round*16) + 6];
+ state[ 2] = sbox[(state[10] ^ expanded_key[(round*16) + 10])];
+ state[ 6] = sbox[(state[14] ^ expanded_key[(round*16) + 14])];
+ state[10] = sbox[buf1];
+ state[14] = sbox[buf2];
+ // row 3
+ buf1 = state[15] ^ expanded_key[(round*16) + 15];
+ state[15] = sbox[(state[11] ^ expanded_key[(round*16) + 11])];
+ state[11] = sbox[(state[ 7] ^ expanded_key[(round*16) + 7])];
+ state[ 7] = sbox[(state[ 3] ^ expanded_key[(round*16) + 3])];
+ state[ 3] = sbox[buf1];
+ // last addroundkey
+ state[ 0]^=expanded_key[160];
+ state[ 1]^=expanded_key[161];
+ state[ 2]^=expanded_key[162];
+ state[ 3]^=expanded_key[163];
+ state[ 4]^=expanded_key[164];
+ state[ 5]^=expanded_key[165];
+ state[ 6]^=expanded_key[166];
+ state[ 7]^=expanded_key[167];
+ state[ 8]^=expanded_key[168];
+ state[ 9]^=expanded_key[169];
+ state[10]^=expanded_key[170];
+ state[11]^=expanded_key[171];
+ state[12]^=expanded_key[172];
+ state[13]^=expanded_key[173];
+ state[14]^=expanded_key[174];
+ state[15]^=expanded_key[175];
+}
+
+void cc3000_security::aes_decr(uint8_t *state, uint8_t *expanded_key) {
+ uint8_t buf1, buf2, buf3;
+ int8_t round;
+ round = 9;
+
+ // initial addroundkey
+ state[ 0]^=expanded_key[160];
+ state[ 1]^=expanded_key[161];
+ state[ 2]^=expanded_key[162];
+ state[ 3]^=expanded_key[163];
+ state[ 4]^=expanded_key[164];
+ state[ 5]^=expanded_key[165];
+ state[ 6]^=expanded_key[166];
+ state[ 7]^=expanded_key[167];
+ state[ 8]^=expanded_key[168];
+ state[ 9]^=expanded_key[169];
+ state[10]^=expanded_key[170];
+ state[11]^=expanded_key[171];
+ state[12]^=expanded_key[172];
+ state[13]^=expanded_key[173];
+ state[14]^=expanded_key[174];
+ state[15]^=expanded_key[175];
+
+ // 10th round without mixcols
+ state[ 0] = rsbox[state[ 0]] ^ expanded_key[(round*16) ];
+ state[ 4] = rsbox[state[ 4]] ^ expanded_key[(round*16) + 4];
+ state[ 8] = rsbox[state[ 8]] ^ expanded_key[(round*16) + 8];
+ state[12] = rsbox[state[12]] ^ expanded_key[(round*16) + 12];
+ // row 1
+ buf1 = rsbox[state[13]] ^ expanded_key[(round*16) + 1];
+ state[13] = rsbox[state[ 9]] ^ expanded_key[(round*16) + 13];
+ state[ 9] = rsbox[state[ 5]] ^ expanded_key[(round*16) + 9];
+ state[ 5] = rsbox[state[ 1]] ^ expanded_key[(round*16) + 5];
+ state[ 1] = buf1;
+ // row 2
+ buf1 = rsbox[state[ 2]] ^ expanded_key[(round*16) + 10];
+ buf2 = rsbox[state[ 6]] ^ expanded_key[(round*16) + 14];
+ state[ 2] = rsbox[state[10]] ^ expanded_key[(round*16) + 2];
+ state[ 6] = rsbox[state[14]] ^ expanded_key[(round*16) + 6];
+ state[10] = buf1;
+ state[14] = buf2;
+ // row 3
+ buf1 = rsbox[state[ 3]] ^ expanded_key[(round*16) + 15];
+ state[ 3] = rsbox[state[ 7]] ^ expanded_key[(round*16) + 3];
+ state[ 7] = rsbox[state[11]] ^ expanded_key[(round*16) + 7];
+ state[11] = rsbox[state[15]] ^ expanded_key[(round*16) + 11];
+ state[15] = buf1;
+
+ for (round = 8; round >= 0; round--)
+ {
+ // barreto
+ //col1
+ buf1 = galois_mul2(galois_mul2(state[0]^state[2]));
+ buf2 = galois_mul2(galois_mul2(state[1]^state[3]));
+ state[0] ^= buf1; state[1] ^= buf2; state[2] ^= buf1; state[3] ^= buf2;
+ //col2
+ buf1 = galois_mul2(galois_mul2(state[4]^state[6]));
+ buf2 = galois_mul2(galois_mul2(state[5]^state[7]));
+ state[4] ^= buf1; state[5] ^= buf2; state[6] ^= buf1; state[7] ^= buf2;
+ //col3
+ buf1 = galois_mul2(galois_mul2(state[8]^state[10]));
+ buf2 = galois_mul2(galois_mul2(state[9]^state[11]));
+ state[8] ^= buf1; state[9] ^= buf2; state[10] ^= buf1; state[11] ^= buf2;
+ //col4
+ buf1 = galois_mul2(galois_mul2(state[12]^state[14]));
+ buf2 = galois_mul2(galois_mul2(state[13]^state[15]));
+ state[12] ^= buf1; state[13] ^= buf2; state[14] ^= buf1; state[15] ^= buf2;
+ // mixcolums //////////
+ // col1
+ buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
+ buf2 = state[0];
+ buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
+ buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
+ buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
+ buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
+ // col2
+ buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
+ buf2 = state[4];
+ buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
+ buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
+ buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
+ buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
+ // col3
+ buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
+ buf2 = state[8];
+ buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
+ buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
+ buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
+ buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
+ // col4
+ buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
+ buf2 = state[12];
+ buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
+ buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
+ buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
+ buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
+
+ // addroundkey, rsbox and shiftrows
+ // row 0
+ state[ 0] = rsbox[state[ 0]] ^ expanded_key[(round*16) ];
+ state[ 4] = rsbox[state[ 4]] ^ expanded_key[(round*16) + 4];
+ state[ 8] = rsbox[state[ 8]] ^ expanded_key[(round*16) + 8];
+ state[12] = rsbox[state[12]] ^ expanded_key[(round*16) + 12];
+ // row 1
+ buf1 = rsbox[state[13]] ^ expanded_key[(round*16) + 1];
+ state[13] = rsbox[state[ 9]] ^ expanded_key[(round*16) + 13];
+ state[ 9] = rsbox[state[ 5]] ^ expanded_key[(round*16) + 9];
+ state[ 5] = rsbox[state[ 1]] ^ expanded_key[(round*16) + 5];
+ state[ 1] = buf1;
+ // row 2
+ buf1 = rsbox[state[ 2]] ^ expanded_key[(round*16) + 10];
+ buf2 = rsbox[state[ 6]] ^ expanded_key[(round*16) + 14];
+ state[ 2] = rsbox[state[10]] ^ expanded_key[(round*16) + 2];
+ state[ 6] = rsbox[state[14]] ^ expanded_key[(round*16) + 6];
+ state[10] = buf1;
+ state[14] = buf2;
+ // row 3
+ buf1 = rsbox[state[ 3]] ^ expanded_key[(round*16) + 15];
+ state[ 3] = rsbox[state[ 7]] ^ expanded_key[(round*16) + 3];
+ state[ 7] = rsbox[state[11]] ^ expanded_key[(round*16) + 7];
+ state[11] = rsbox[state[15]] ^ expanded_key[(round*16) + 11];
+ state[15] = buf1;
+ }
+}
+
+void cc3000_security::aes_encrypt(uint8_t *state, uint8_t *key) {
+ // expand the key into 176 bytes
+ expandKey(_expanded_key, key);
+ aes_encr(state, _expanded_key);
+}
+
+void cc3000_security::aes_decrypt(uint8_t *state, uint8_t *key) {
+ expandKey(_expanded_key, key); // expand the key into 176 bytes
+ aes_decr(state, _expanded_key);
+}
+
+int32_t cc3000_security::aes_read_key(uint8_t *key) {
+ int32_t returnValue;
+
+ returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
+
+ return returnValue;
+}
+
+int32_t cc3000_security::aes_write_key(uint8_t *key) {
+ int32_t returnValue;
+
+ returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
+
+ return returnValue;
+}
+#endif
+
+} /* end of cc3000 namespace */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_server.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,94 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+
+namespace mbed_cc3000 {
+cc3000_server::cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add) : _socket_address(socket_add), _cc3000(cc3000_ref) {
+ _current_socket = -1;
+}
+
+cc3000_server::cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add, int16_t socket) : _socket_address(socket_add), _cc3000(cc3000_ref) {
+ _current_socket = socket;
+}
+
+int32_t cc3000_server::accept(void) {
+ int32_t client_descriptor = -2;
+ sockaddr dest_address;
+
+ socklen_t address_length = sizeof(dest_address);
+ _current_socket = 0;
+
+#if (CC3000_DEBUG == 1)
+ printf("Waiting for receiving a connection.\n");
+#endif
+ while((client_descriptor == -1) || (client_descriptor == -2))
+ {
+ client_descriptor = _cc3000._socket.accept(_current_socket,&dest_address, &address_length);
+ }
+#if (CC3000_DEBUG == 1)
+ printf("Received.\n");
+#endif
+ _current_socket = client_descriptor;
+
+ return _current_socket;
+}
+
+int32_t cc3000_server::receive(void *buffer, uint16_t length, uint32_t flags) {
+ return _cc3000._socket.recv(_current_socket, buffer, length, flags);
+}
+
+int32_t cc3000_server::send(void *buffer, uint16_t length, uint32_t flags) {
+ return _cc3000._socket.send(_current_socket, buffer, length, flags);
+}
+
+void cc3000_server::bind(void) {
+ _cc3000._socket.bind(_current_socket, &_socket_address, sizeof(sockaddr));
+}
+
+void cc3000_server::listen(uint32_t backlog) {
+ _cc3000._socket.listen(_current_socket, backlog);
+}
+
+void cc3000_server::close(void) {
+ _cc3000._socket.closesocket(_current_socket);
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_simplelink.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,185 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+#include "cc3000_common.h"
+
+namespace mbed_cc3000 {
+
+cc3000_simple_link::cc3000_simple_link() {
+ _rx_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
+ _tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
+}
+
+cc3000_simple_link::~cc3000_simple_link() {
+}
+
+uint8_t cc3000_simple_link::get_data_received_flag() {
+ return _data_received_flag;
+}
+
+void *cc3000_simple_link::get_func_pointer(FunctionNumber function){
+ void *result;
+ /* casting to void *, will be casted back once used */
+ switch(function) {
+ case FW_PATCHES:
+ result = (void *)_fFWPatches;
+ break;
+ case DRIVER_PATCHES:
+ result = (void *)_fDriverPatches;
+ break;
+ case BOOTLOADER_PATCHES:
+ result = (void *)_fBootLoaderPatches;
+ break;
+ // case WLAN_CB:
+ // result = (void *)_fWlanCB;
+ // break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+uint8_t *cc3000_simple_link::get_transmit_buffer() {
+ return _tx_buffer;
+}
+
+uint8_t *cc3000_simple_link::get_received_buffer() {
+ return _rx_buffer;
+}
+
+void cc3000_simple_link::set_received_buffer(uint8_t value) {
+ *_rx_buffer = value;
+}
+
+void cc3000_simple_link::set_transmit_buffer(uint8_t value) {
+ *_tx_buffer = value;
+}
+
+void cc3000_simple_link::set_op_code(uint16_t code) {
+ _rx_event_opcode = code;
+}
+
+void cc3000_simple_link::set_pending_data(uint16_t value) {
+ _rx_data_pending = value;
+}
+
+uint16_t cc3000_simple_link::get_pending_data() {
+ return _rx_data_pending;
+}
+
+void cc3000_simple_link::set_number_free_buffers(uint16_t value) {
+ _free_buffers = value;
+}
+
+void cc3000_simple_link::set_number_of_released_packets(uint16_t value) {
+ _released_packets = value;
+}
+
+
+void cc3000_simple_link::set_tx_complete_signal(bool value) {
+ _tx_complete_signal = value;
+}
+
+bool cc3000_simple_link::get_tx_complete_signal() {
+ return _tx_complete_signal;
+}
+
+void cc3000_simple_link::set_data_received_flag(uint8_t value) {
+ _data_received_flag = value;
+}
+
+uint16_t cc3000_simple_link::get_number_free_buffers() {
+ return _free_buffers;
+}
+
+uint16_t cc3000_simple_link::get_buffer_length() {
+ return _buffer_length;
+}
+
+void cc3000_simple_link::set_buffer_length(uint16_t value) {
+ _buffer_length = value;
+}
+
+uint16_t cc3000_simple_link::get_op_code() {
+ return _rx_event_opcode;
+}
+
+uint16_t cc3000_simple_link::get_released_packets() {
+ return _released_packets;
+}
+
+uint16_t cc3000_simple_link::get_sent_packets() {
+ return _sent_packets;
+}
+
+void cc3000_simple_link::set_sent_packets(uint16_t value) {
+ _sent_packets = value;
+}
+
+void cc3000_simple_link::set_transmit_error(int32_t value){
+ _transmit_data_error = value;
+}
+
+int32_t cc3000_simple_link::get_transmit_error(){
+ return _transmit_data_error;
+}
+
+void cc3000_simple_link::set_buffer_size(uint16_t value) {
+ _buffer_size = value;
+}
+
+uint16_t cc3000_simple_link::get_buffer_size(void) {
+ return _buffer_size;
+}
+
+uint8_t *cc3000_simple_link::get_received_data(void) {
+ return _received_data;
+}
+
+void cc3000_simple_link::set_received_data(uint8_t *pointer) {
+ _received_data = pointer;
+}
+
+//void cc3000_simple_link::set_wlan_cb(tWlanCB fpointer) {
+// _fWlanCB = fpointer;
+//}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cc3000_simplelink.h Thu Sep 19 07:55:14 2013 +0000 @@ -0,0 +1,48 @@ +/***************************************************************************** +* +* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to +* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and +* provided help. +* +* This version of "host driver" uses CC3000 Host Driver Implementation. Thus +* read the following copyright: +* +* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#ifndef CC3000_SIMPLELINK_H +#define CC3000_SIMPLELINK_H + +typedef uint8_t *(*tFWPatches)(uint32_t *usLength); +typedef uint8_t *(*tDriverPatches)(uint32_t *usLength); +typedef uint8_t *(*tBootLoaderPatches)(uint32_t *usLength); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_socket.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,602 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+#include "cc3000_socket.h"
+#include "cc3000_event.h" //TODO - remove this
+#include "cc3000_common.h"
+
+namespace mbed_cc3000 {
+
+cc3000_socket::cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event)
+ : _simple_link(simplelink), _hci(hci), _event(event)
+{
+
+}
+
+cc3000_socket::~cc3000_socket()
+{
+
+}
+
+int32_t cc3000_socket::HostFlowControlConsumeBuff(int32_t sd) {
+#ifndef SEND_NON_BLOCKING
+ /* wait in busy loop */
+ do
+ {
+ // When the last transmission failed, return the last failure reason.
+ // Note that the buffer will not be allocated in this case
+ if (_simple_link.get_transmit_error() != 0)
+ {
+ errno = _simple_link.get_transmit_error();
+ _simple_link.set_transmit_error(0);
+ return errno;
+ }
+
+ if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd))
+ return -1;
+ } while(0 == _simple_link.get_number_free_buffers());
+
+ uint16_t free_buffer = _simple_link.get_number_free_buffers();
+ free_buffer--;
+ _simple_link.set_number_free_buffers(free_buffer);
+
+ return 0;
+#else
+
+ // When the last transmission failed, return the last failure reason.
+ // Note that the buffer will not be allocated in this case
+ if (_simple_link.get_transmit_error() != 0)
+ {
+ errno = _simple_link.get_transmit_error();
+ _simple_link.set_transmit_error(0);
+ return errno;
+ }
+ if(SOCKET_STATUS_ACTIVE != get_socket_active_status(sd))
+ return -1;
+
+ // If there are no available buffers, return -2. It is recommended to use
+ // select or receive to see if there is any buffer occupied with received data
+ // If so, call receive() to release the buffer.
+ if(0 == _simple_link.get_number_free_buffers())
+ {
+ return -2;
+ }
+ else
+ {
+ uint16 free_buffer = _simple_link.get_number_free_buffers();
+ free_buffer--;
+ _simple_link.set_number_free_buffers(free_buffer);
+ return 0;
+ }
+#endif
+}
+
+int32_t cc3000_socket::socket(int32_t domain, int32_t type, int32_t protocol) {
+ int32_t ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, domain);
+ args = UINT32_TO_STREAM(args, type);
+ args = UINT32_TO_STREAM(args, protocol);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_CMND_SOCKET, &ret);
+
+ // Process the event
+ errno = ret;
+
+ _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
+
+ return(ret);
+}
+
+int32_t cc3000_socket::closesocket(int32_t sd) {
+ int32_t ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, sd);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_CMND_CLOSE_SOCKET, &ret);
+ errno = ret;
+
+ // since 'close' call may result in either OK (and then it closed) or error, mark this socket as invalid
+ _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+
+ return(ret);
+}
+
+int32_t cc3000_socket::accept(int32_t sd, sockaddr *addr, socklen_t *addrlen) {
+ int32_t ret;
+ uint8_t *ptr, *args;
+ tBsdReturnParams tAcceptReturnArguments;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
+
+
+ // need specify return parameters!!!
+ memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
+ *addrlen = ASIC_ADDR_LEN;
+ errno = tAcceptReturnArguments.iStatus;
+ ret = errno;
+
+ // if succeeded, iStatus = new socket descriptor. otherwise - error number
+ if(M_IS_VALID_SD(ret))
+ {
+ _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
+ }
+ else
+ {
+ _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
+ }
+
+ return(ret);
+}
+
+int32_t cc3000_socket::bind(int32_t sd, const sockaddr *addr, int32_t addrlen) {
+ int32_t ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ addrlen = ASIC_ADDR_LEN;
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, addrlen);
+ ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_CMND_BIND, &ret);
+
+ errno = ret;
+
+ return(ret);
+}
+
+int32_t cc3000_socket::listen(int32_t sd, int32_t backlog) {
+ int32_t ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, backlog);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_CMND_LISTEN, &ret);
+ errno = ret;
+
+ return(ret);
+}
+
+int32_t cc3000_socket::connect(int32_t sd, const sockaddr *addr, int32_t addrlen) {
+ int32_t ret;
+ uint8_t *ptr, *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+ addrlen = 8;
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, addrlen);
+ ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_CMND_CONNECT, &ret);
+
+ errno = ret;
+
+ return((int32_t)ret);
+}
+
+int32_t cc3000_socket::select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) {
+ uint8_t *ptr, *args;
+ tBsdSelectRecvParams tParams;
+ uint32_t is_blocking;
+
+ if( timeout == NULL)
+ {
+ is_blocking = 1; /* blocking , infinity timeout */
+ }
+ else
+ {
+ is_blocking = 0; /* no blocking, timeout */
+ }
+
+ // Fill in HCI packet structure
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, nfds);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, is_blocking);
+ args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0));
+ args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0));
+ args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0));
+
+ if (timeout)
+ {
+ if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS)
+ {
+ timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
+ }
+ args = UINT32_TO_STREAM(args, timeout->tv_sec);
+ args = UINT32_TO_STREAM(args, timeout->tv_usec);
+ }
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_EVNT_SELECT, &tParams);
+
+ // Update actually read FD
+ if (tParams.iStatus >= 0)
+ {
+ if (readsds)
+ {
+ memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
+ }
+
+ if (writesds)
+ {
+ memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));
+ }
+
+ if (exceptsds)
+ {
+ memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));
+ }
+
+ return(tParams.iStatus);
+
+ }
+ else
+ {
+ errno = tParams.iStatus;
+ return(-1);
+ }
+}
+
+int32_t cc3000_socket::get_sockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen) {
+ uint8_t *ptr, *args;
+ tBsdGetSockOptReturnParams tRetParams;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, level);
+ args = UINT32_TO_STREAM(args, optname);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_CMND_GETSOCKOPT, &tRetParams);
+
+ if (((int8_t)tRetParams.iStatus) >= 0)
+ {
+ *optlen = 4;
+ memcpy(optval, tRetParams.ucOptValue, 4);
+ return (0);
+ }
+ else
+ {
+ errno = tRetParams.iStatus;
+ return errno;
+ }
+}
+
+int32_t cc3000_socket::simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode) {
+ uint8_t *ptr, *args;
+ tBsdReadReturnParams tSocketReadEvent;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, len);
+ args = UINT32_TO_STREAM(args, flags);
+
+ // Generate the read command, and wait for the
+ _hci.command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(opcode, &tSocketReadEvent);
+
+ // In case the number of bytes is more then zero - read data
+ if (tSocketReadEvent.iNumberOfBytes > 0)
+ {
+ // Wait for the data in a synchronous way. Here we assume that the bug is
+ // big enough to store also parameters of receive from too....
+ _event.simplelink_wait_data((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen);
+ }
+
+ errno = tSocketReadEvent.iNumberOfBytes;
+
+ return(tSocketReadEvent.iNumberOfBytes);
+}
+
+int32_t cc3000_socket::recv(int32_t sd, void *buf, int32_t len, int32_t flags) {
+ return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV));
+}
+
+int32_t cc3000_socket::recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen) {
+ return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM));
+}
+
+int32_t cc3000_socket::simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode) {
+ uint8_t uArgSize = 0x00, addrlen = 0x00;
+ uint8_t *ptr, *pDataPtr = NULL, *args;
+ uint32_t addr_offset = 0x00;
+ int32_t res;
+ tBsdReadReturnParams tSocketSendEvent;
+
+ // Check the bsd_arguments
+ if (0 != (res = HostFlowControlConsumeBuff(sd)))
+ {
+ return res;
+ }
+
+ //Update the number of sent packets
+ uint16_t sent_packets = _simple_link.get_sent_packets();
+ sent_packets++;
+ _simple_link.set_sent_packets(sent_packets);
+
+ // Allocate a buffer and construct a packet and send it over spi
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_DATA);
+
+ // Update the offset of data and parameters according to the command
+ switch(opcode)
+ {
+ case HCI_CMND_SENDTO:
+ {
+ addr_offset = len + sizeof(len) + sizeof(len);
+ addrlen = 8;
+ uArgSize = SOCKET_SENDTO_PARAMS_LEN;
+ pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
+ break;
+ }
+
+ case HCI_CMND_SEND:
+ {
+ tolen = 0;
+ to = NULL;
+ uArgSize = HCI_CMND_SEND_ARG_LENGTH;
+ pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
+ args = UINT32_TO_STREAM(args, len);
+ args = UINT32_TO_STREAM(args, flags);
+
+ if (opcode == HCI_CMND_SENDTO)
+ {
+ args = UINT32_TO_STREAM(args, addr_offset);
+ args = UINT32_TO_STREAM(args, addrlen);
+ }
+
+ // Copy the data received from user into the TX Buffer
+ ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len);
+
+ // In case we are using SendTo, copy the to parameters
+ if (opcode == HCI_CMND_SENDTO)
+ {
+ ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen);
+ }
+
+ // Initiate a HCI command
+ _hci.data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen);
+ if (opcode == HCI_CMND_SENDTO)
+ _event.simplelink_wait_event(HCI_EVNT_SENDTO, &tSocketSendEvent);
+ else
+ _event.simplelink_wait_event(HCI_EVNT_SEND, &tSocketSendEvent);
+
+ return (len);
+}
+
+int32_t cc3000_socket::send(int32_t sd, const void *buf, int32_t len, int32_t flags) {
+ return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND));
+}
+
+int32_t cc3000_socket::sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen) {
+ return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO));
+}
+
+int32_t cc3000_socket::mdns_advertiser(uint16_t mdns_enabled, uint8_t *device_service_name, uint16_t device_service_name_length) {
+ int32_t ret;
+ uint8_t *pTxBuffer, *pArgs;
+
+ if (device_service_name_length > MDNS_DEVICE_SERVICE_MAX_LENGTH)
+ {
+ return EFAIL;
+ }
+
+ pTxBuffer = _simple_link.get_transmit_buffer();
+ pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+
+ // Fill in HCI packet structure
+ pArgs = UINT32_TO_STREAM(pArgs, mdns_enabled);
+ pArgs = UINT32_TO_STREAM(pArgs, 8);
+ pArgs = UINT32_TO_STREAM(pArgs, device_service_name_length);
+ ARRAY_TO_STREAM(pArgs, device_service_name, device_service_name_length);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + device_service_name_length);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_EVNT_MDNS_ADVERTISE, &ret);
+
+ return ret;
+}
+
+
+#ifndef CC3000_TINY_DRIVER
+int32_t cc3000_socket::get_host_by_name(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) {
+ tBsdGethostbynameParams ret;
+ uint8_t *ptr, *args;
+
+ errno = EFAIL;
+
+ if (name_length > HOSTNAME_MAX_LENGTH)
+ {
+ return errno;
+ }
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, 8);
+ args = UINT32_TO_STREAM(args, name_length);
+ ARRAY_TO_STREAM(args, hostname, name_length);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + name_length - 1);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_EVNT_BSD_GETHOSTBYNAME, &ret);
+
+ errno = ret.retVal;
+
+ (*((int32_t*)out_ip_addr)) = ret.outputAddress;
+
+ return (errno);
+}
+
+int32_t cc3000_socket::set_sockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen) {
+ int32_t ret;
+ uint8_t *ptr, *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, sd);
+ args = UINT32_TO_STREAM(args, level);
+ args = UINT32_TO_STREAM(args, optname);
+ args = UINT32_TO_STREAM(args, 0x00000008);
+ args = UINT32_TO_STREAM(args, optlen);
+ ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen);
+
+ // Since we are in blocking state - wait for event complete
+ _event.simplelink_wait_event(HCI_CMND_SETSOCKOPT, &ret);
+
+ if (ret >= 0)
+ {
+ return (0);
+ }
+ else
+ {
+ errno = ret;
+ return ret;
+ }
+}
+
+#endif
+
+} /* end of cc3000 namespace */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_socket.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,223 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef CC3000_SOCKET_H
+#define CC3000_SOCKET_H
+
+#define SOCKET_STATUS_ACTIVE 0
+#define SOCKET_STATUS_INACTIVE 1
+
+#define SOCKET_STATUS_INIT_VAL 0xFFFF
+#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
+#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
+
+#ifdef _API_USE_BSD_CLOSE
+ #define close(sd) closesocket(sd)
+#endif
+
+//Enable this flag if and only if you must comply with BSD socket read() and
+//write() functions
+#ifdef _API_USE_BSD_READ_WRITE
+ #define read(sd, buf, len, flags) recv(sd, buf, len, flags)
+ #define write(sd, buf, len, flags) send(sd, buf, len, flags)
+#endif
+
+#define SOCKET_OPEN_PARAMS_LEN (12)
+#define SOCKET_CLOSE_PARAMS_LEN (4)
+#define SOCKET_ACCEPT_PARAMS_LEN (4)
+#define SOCKET_BIND_PARAMS_LEN (20)
+#define SOCKET_LISTEN_PARAMS_LEN (8)
+#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9)
+#define SOCKET_CONNECT_PARAMS_LEN (20)
+#define SOCKET_SELECT_PARAMS_LEN (44)
+#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20)
+#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12)
+#define SOCKET_RECV_FROM_PARAMS_LEN (12)
+#define SOCKET_SENDTO_PARAMS_LEN (24)
+#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12)
+
+//#define NULL 0
+
+// The legnth of arguments for the SEND command: sd + buff_offset + len + flags,
+// while size of each parameter is 32 bit - so the total length is 16 bytes;
+
+#define HCI_CMND_SEND_ARG_LENGTH (16)
+#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000
+#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5)
+#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
+#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32)
+
+
+#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value
+
+//--------- Address Families --------
+
+#define AF_INET 2
+#define AF_INET6 23
+
+//------------ Socket Types ------------
+
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 2
+#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers
+#define SOCK_RDM 4
+#define SOCK_SEQPACKET 5
+
+//----------- Socket Protocol ----------
+
+#define IPPROTO_IP 0 // dummy for IP
+#define IPPROTO_ICMP 1 // control message protocol
+#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP
+#define IPPROTO_TCP 6 // tcp
+#define IPPROTO_UDP 17 // user datagram protocol
+#define IPPROTO_IPV6 41 // IPv6 in IPv6
+#define IPPROTO_NONE 59 // No next header
+#define IPPROTO_RAW 255 // raw IP packet
+#define IPPROTO_MAX 256
+
+//----------- Socket retunr codes -----------
+
+#define SOC_ERROR (-1) // error
+#define SOC_IN_PROGRESS (-2) // socket in progress
+
+//----------- Socket Options -----------
+#define SOL_SOCKET 0xffff // socket level
+#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout
+#define SOCKOPT_NONBLOCK 2 // accept non block mode set SOCK_ON or SOCK_OFF (default block mode )
+#define SOCK_ON 0 // socket non-blocking mode is enabled
+#define SOCK_OFF 1 // socket blocking mode is enabled
+
+#define TCP_NODELAY 0x0001
+#define TCP_BSDURGENT 0x7000
+
+#define MAX_PACKET_SIZE 1500
+#define MAX_LISTEN_QUEUE 4
+
+#define IOCTL_SOCKET_EVENTMASK
+
+#define ENOBUFS 55 // No buffer space available
+
+#define __FD_SETSIZE 32
+
+#define ASIC_ADDR_LEN 8
+
+#define NO_QUERY_RECIVED -3
+
+
+typedef struct _in_addr_t
+{
+ uint32_t s_addr; // load with inet_aton()
+} in_addr;
+
+/*typedef struct _sockaddr_t
+{
+ unsigned short int sa_family;
+ unsigned char sa_data[14];
+} sockaddr;*/
+
+typedef struct _sockaddr_in_t
+{
+ int16_t sin_family; // e.g. AF_INET
+ uint16_t sin_port; // e.g. htons(3490)
+ in_addr sin_addr; // see struct in_addr, below
+ uint8_t sin_zero[8]; // zero this if you want to
+} sockaddr_in;
+
+typedef uint32_t socklen_t;
+
+// The fd_set member is required to be an array of longs.
+typedef int32_t __fd_mask;
+
+// It's easier to assume 8-bit bytes than to get CHAR_BIT.
+#define __NFDBITS (8 * sizeof (__fd_mask))
+#define __FDELT(d) ((d) / __NFDBITS)
+#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))
+
+// fd_set for select and pselect.
+typedef struct
+{
+ __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
+#define __FDS_BITS(set) ((set)->fds_bits)
+} fd_set;
+
+// We don't use `memset' because this would require a prototype and
+// the array isn't too big.
+#define __FD_ZERO(set) \
+ do { \
+ uint32_t __i; \
+ fd_set *__arr = (set); \
+ for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
+ __FDS_BITS (__arr)[__i] = 0; \
+ } while (0)
+#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))
+#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d))
+#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))
+
+// Access macros for 'fd_set'.
+#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
+#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp)
+#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp)
+#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
+
+//Use in case of Big Endian only
+
+#define htonl(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \
+ (((uint32_t)(A) & 0x00ff0000) >> 8) | \
+ (((uint32_t)(A) & 0x0000ff00) << 8) | \
+ (((uint32_t)(A) & 0x000000ff) << 24))
+
+#define ntohl htonl
+
+//Use in case of Big Endian only
+#define htons(A) ((((uint32_t)(A) & 0xff00) >> 8) | \
+ (((uint32_t)(A) & 0x00ff) << 8))
+
+
+#define ntohs htons
+
+// mDNS port - 5353 mDNS multicast address - 224.0.0.251
+#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \
+ sockaddr.sa_data[1] = 0xe9; \
+ sockaddr.sa_data[2] = 0xe0; \
+ sockaddr.sa_data[3] = 0x0; \
+ sockaddr.sa_data[4] = 0x0; \
+ sockaddr.sa_data[5] = 0xfb;
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_spi.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,302 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+#include "cc3000_spi.h"
+
+namespace mbed_cc3000 {
+
+cc3000_spi::cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port, cc3000_event &event, cc3000_simple_link &simple_link)
+ : _wlan_irq(cc3000_irq), _wlan_en(cc3000_en), _wlan_cs(cc3000_cs), _wlan_spi(cc3000_spi), _irq_port(irq_port),
+ _event(event), _simple_link(simple_link) {
+ /* TODO = clear pending interrupts for PORTS. This is dependent on the used chip */
+
+ _wlan_spi.format(8,1);
+ _wlan_spi.frequency(12000000);
+ _function_pointer = _wlan_irq.fall(this, &cc3000_spi::WLAN_IRQHandler);
+
+ _wlan_en = 0;
+ _wlan_cs = 1;
+}
+
+cc3000_spi::~cc3000_spi() {
+
+}
+
+void cc3000_spi::wlan_irq_enable()
+{
+ NVIC_EnableIRQ(_irq_port);
+}
+
+void cc3000_spi::wlan_irq_disable() {
+ NVIC_DisableIRQ(_irq_port);
+}
+
+void cc3000_spi::wlan_irq_set(uint8_t value) {
+ if (value)
+ {
+ _wlan_en = 1;
+ }
+ else
+ {
+ _wlan_en = 0;
+ }
+}
+
+uint32_t cc3000_spi::wlan_irq_read() {
+ return _wlan_irq.read();
+}
+
+void cc3000_spi::close() {
+ if (_simple_link.get_received_buffer() != 0)
+ {
+ _simple_link.set_received_buffer(0);
+ }
+ wlan_irq_disable();
+}
+
+// void cc3000_spi::SpiReceiveHandler() {
+// _simple_link.usEventOrDataReceived = 1;
+// //_simple_link.pucReceivedData = (unsigned char *)pvBuffer;
+
+// hci_unsolicited_event_handler();
+// }
+
+
+/* TODO
+ pRxPacket, pTxPacket do we need to hold this pointer ?
+ SPIRxHandler - remove?
+*/
+void cc3000_spi::open() {
+ _spi_info.spi_state = eSPI_STATE_POWERUP;
+ //_spi_info.SPIRxHandler = pfRxHandler;
+ _spi_info.tx_packet_length = 0;
+ _spi_info.rx_packet_length = 0;
+ //_rx_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
+ //_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
+ wlan_irq_enable();
+}
+
+uint32_t cc3000_spi::first_write(uint8_t *buffer, uint16_t length) {
+ _wlan_cs = 0;
+ wait_us(50);
+
+ /* first 4 bytes of the data */
+ write_synchronous(buffer, 4);
+ wait_us(50);
+ write_synchronous(buffer + 4, length - 4);
+ _spi_info.spi_state = eSPI_STATE_IDLE;
+ _wlan_cs = 1;
+
+ return 0;
+}
+
+
+uint32_t cc3000_spi::write(uint8_t *buffer, uint16_t length) {
+ uint8_t pad = 0;
+ // check the total length of the packet in order to figure out if padding is necessary
+ if(!(length & 0x0001))
+ {
+ pad++;
+ }
+ buffer[0] = WRITE;
+ buffer[1] = HI(length + pad);
+ buffer[2] = LO(length + pad);
+ buffer[3] = 0;
+ buffer[4] = 0;
+
+ length += (SPI_HEADER_SIZE + pad);
+
+ // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size)
+ // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever!
+ uint8_t * transmit_buffer = _simple_link.get_transmit_buffer();
+ if (transmit_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
+ {
+ while (1);
+ }
+
+ if (_spi_info.spi_state == eSPI_STATE_POWERUP)
+ {
+ while (_spi_info.spi_state != eSPI_STATE_INITIALIZED);
+ }
+
+ if (_spi_info.spi_state == eSPI_STATE_INITIALIZED)
+ {
+ // TX/RX transaction over SPI after powerup: IRQ is low - send read buffer size command
+ first_write(buffer, length);
+ }
+ else
+ {
+ // Prevent occurence of a race condition when 2 back to back packets are sent to the
+ // device, so the state will move to IDLE and once again to not IDLE due to IRQ
+ wlan_irq_disable();
+
+ while (_spi_info.spi_state != eSPI_STATE_IDLE);
+
+ _spi_info.spi_state = eSPI_STATE_WRITE_IRQ;
+ //_spi_info.pTxPacket = buffer;
+ _spi_info.tx_packet_length = length;
+
+ // Assert the CS line and wait until the IRQ line is active, then initialize the write operation
+ _wlan_cs = 0;
+
+ wlan_irq_enable();
+ }
+
+ // Wait until the transaction ends
+ while (_spi_info.spi_state != eSPI_STATE_IDLE);
+
+ return 0;
+}
+
+void cc3000_spi::write_synchronous(uint8_t *data, uint16_t size) {
+ while(size)
+ {
+ _wlan_spi.write(*data++);
+ size--;
+ }
+}
+
+void cc3000_spi::read_synchronous(uint8_t *data, uint16_t size) {
+ for (uint32_t i = 0; i < size; i++)
+ {
+ data[i] = _wlan_spi.write(0x03);;
+ }
+}
+
+uint32_t cc3000_spi::read_data_cont() {
+ long data_to_recv;
+ unsigned char *evnt_buff, type;
+
+ //determine the packet type
+ evnt_buff = _simple_link.get_received_buffer();
+ data_to_recv = 0;
+ STREAM_TO_UINT8((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);
+
+ switch(type)
+ {
+ case HCI_TYPE_DATA:
+ {
+ // Read the remaining data..
+ STREAM_TO_UINT16((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv);
+ if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1))
+ {
+ data_to_recv++;
+ }
+
+ if (data_to_recv)
+ {
+ read_synchronous(evnt_buff + 10, data_to_recv);
+ }
+ break;
+ }
+ case HCI_TYPE_EVNT:
+ {
+ // Calculate the rest length of the data
+ STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv);
+ data_to_recv -= 1;
+ // Add padding byte if needed
+ if ((HEADERS_SIZE_EVNT + data_to_recv) & 1)
+ {
+ data_to_recv++;
+ }
+
+ if (data_to_recv)
+ {
+ read_synchronous(evnt_buff + 10, data_to_recv);
+ }
+
+ _spi_info.spi_state = eSPI_STATE_READ_EOT;
+ break;
+ }
+ }
+ return (0);
+}
+
+void cc3000_spi::write_wlan_en(uint8_t value) {
+ if (value) {
+ _wlan_en = 1;
+ } else {
+ _wlan_en = 0;
+ }
+}
+
+void cc3000_spi::WLAN_IRQHandler() {
+ if (_spi_info.spi_state == eSPI_STATE_POWERUP)
+ {
+ // Inform HCI Layer that IRQ occured after powerup
+ _spi_info.spi_state = eSPI_STATE_INITIALIZED;
+ }
+ else if (_spi_info.spi_state == eSPI_STATE_IDLE)
+ {
+ _spi_info.spi_state = eSPI_STATE_READ_IRQ;
+ /* IRQ line goes low - acknowledge it */
+ _wlan_cs = 0;
+ read_synchronous(_simple_link.get_received_buffer(), 10);
+ _spi_info.spi_state = eSPI_STATE_READ_EOT;
+
+
+ // The header was read - continue with the payload read
+ if (!read_data_cont())
+ {
+ // All the data was read - finalize handling by switching to the task
+ // Trigger Rx processing
+ wlan_irq_disable();
+ _wlan_cs = 1;
+ // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size)
+ // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever!
+ uint8_t *received_buffer = _simple_link.get_received_buffer();
+ if (received_buffer[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
+ {
+ while (1);
+ }
+ _spi_info.spi_state = eSPI_STATE_IDLE;
+ _event.received_handler(received_buffer + SPI_HEADER_SIZE);
+ }
+ }
+ else if (_spi_info.spi_state == eSPI_STATE_WRITE_IRQ)
+ {
+ write_synchronous(_simple_link.get_transmit_buffer(), _spi_info.tx_packet_length);
+ _spi_info.spi_state = eSPI_STATE_IDLE;
+ _wlan_cs = 1;
+ }
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_spi.h Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,251 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#ifndef CC3000_SPI_H
+#define CC3000_SPI_H
+
+typedef struct
+{
+ uint16_t tx_packet_length;
+ uint16_t rx_packet_length;
+ uint32_t spi_state;
+} tSpiInfo;
+
+
+/* ===========================================================================================
+ SPI
+ =========================================================================================== */
+#define READ 3
+#define WRITE 1
+
+#define HI(value) (((value) & 0xFF00) >> 8)
+#define LO(value) ((value) & 0x00FF)
+
+#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5)
+
+#define SPI_HEADER_SIZE (5)
+
+#define eSPI_STATE_POWERUP (0)
+#define eSPI_STATE_INITIALIZED (1)
+#define eSPI_STATE_IDLE (2)
+#define eSPI_STATE_WRITE_IRQ (3)
+#define eSPI_STATE_WRITE_FIRST_PORTION (4)
+#define eSPI_STATE_WRITE_EOT (5)
+#define eSPI_STATE_READ_IRQ (6)
+#define eSPI_STATE_READ_FIRST_PORTION (7)
+#define eSPI_STATE_READ_EOT (8)
+
+// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
+// for the purpose of detection of the overrun. The location of the memory where the magic number
+// resides shall never be written. In case it is written - overrun occured and either recevie function
+// or send function will be stuck forever.
+#define CC3000_BUFFER_MAGIC_NUMBER (0xDE)
+
+/* ===========================================================================================
+ HCI
+ =========================================================================================== */
+
+#define SL_PATCH_PORTION_SIZE (1000)
+
+#define SPI_HEADER_SIZE (5)
+#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4)
+#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
+#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5)
+#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5)
+#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2)
+
+// Values that can be used as HCI Commands and HCI Packet header defines
+#define HCI_TYPE_CMND 0x1
+#define HCI_TYPE_DATA 0x2
+#define HCI_TYPE_PATCH 0x3
+#define HCI_TYPE_EVNT 0x4
+
+
+#define HCI_EVENT_PATCHES_DRV_REQ (1)
+#define HCI_EVENT_PATCHES_FW_REQ (2)
+#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3)
+
+
+#define HCI_CMND_WLAN_BASE (0x0000)
+#define HCI_CMND_WLAN_CONNECT 0x0001
+#define HCI_CMND_WLAN_DISCONNECT 0x0002
+#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003
+#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004
+#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005
+#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006
+#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007
+#define HCI_CMND_EVENT_MASK 0x0008
+#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009
+#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A
+#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B
+#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C
+#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D
+
+
+#define HCI_CMND_SOCKET_BASE 0x1000
+#define HCI_CMND_SOCKET 0x1001
+#define HCI_CMND_BIND 0x1002
+#define HCI_CMND_RECV 0x1004
+#define HCI_CMND_ACCEPT 0x1005
+#define HCI_CMND_LISTEN 0x1006
+#define HCI_CMND_CONNECT 0x1007
+#define HCI_CMND_BSD_SELECT 0x1008
+#define HCI_CMND_SETSOCKOPT 0x1009
+#define HCI_CMND_GETSOCKOPT 0x100A
+#define HCI_CMND_CLOSE_SOCKET 0x100B
+#define HCI_CMND_RECVFROM 0x100D
+#define HCI_CMND_GETHOSTNAME 0x1010
+#define HCI_CMND_MDNS_ADVERTISE 0x1011
+
+
+#define HCI_DATA_BASE 0x80
+
+#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE)
+#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE)
+#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE)
+#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE)
+
+
+#define HCI_CMND_NVMEM_CBASE (0x0200)
+
+
+#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203)
+#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205)
+#define HCI_CMND_NVMEM_READ (0x0201)
+#define HCI_CMND_NVMEM_WRITE (0x0090)
+#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204)
+#define HCI_CMND_READ_SP_VERSION (0x0207)
+
+#define HCI_CMND_READ_BUFFER_SIZE 0x400B
+#define HCI_CMND_SIMPLE_LINK_START 0x4000
+
+#define HCI_CMND_NETAPP_BASE 0x2000
+
+#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE)
+#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE)
+
+// Values that can be used as HCI Events defines
+#define HCI_EVNT_WLAN_BASE 0x0000
+#define HCI_EVNT_WLAN_CONNECT 0x0001
+#define HCI_EVNT_WLAN_DISCONNECT \
+ 0x0002
+#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \
+ 0x0005
+
+
+#define HCI_EVNT_SOCKET HCI_CMND_SOCKET
+#define HCI_EVNT_BIND HCI_CMND_BIND
+#define HCI_EVNT_RECV HCI_CMND_RECV
+#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT
+#define HCI_EVNT_LISTEN HCI_CMND_LISTEN
+#define HCI_EVNT_CONNECT HCI_CMND_CONNECT
+#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT
+#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET
+#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM
+#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT
+#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT
+#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME
+#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE
+
+#define HCI_EVNT_SEND 0x1003
+#define HCI_EVNT_WRITE 0x100E
+#define HCI_EVNT_SENDTO 0x100F
+
+#define HCI_EVNT_PATCHES_REQ 0x1000
+
+#define HCI_EVNT_UNSOL_BASE 0x4000
+
+#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000)
+
+#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE)
+#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE)
+
+#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \
+ 0x4100
+
+#define HCI_EVNT_NVMEM_CREATE_ENTRY \
+ HCI_CMND_NVMEM_CREATE_ENTRY
+#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY
+
+#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ
+#define HCI_EVNT_NVMEM_WRITE (0x0202)
+
+#define HCI_EVNT_READ_SP_VERSION \
+ HCI_CMND_READ_SP_VERSION
+
+#define HCI_EVNT_INPROGRESS 0xFFFF
+
+
+#define HCI_DATA_RECVFROM 0x84
+#define HCI_DATA_RECV 0x85
+#define HCI_DATA_NVMEM 0x91
+
+#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99
+
+// Prototypes for the structures for HCI APIs.
+#define HCI_DATA_HEADER_SIZE (5)
+#define HCI_EVENT_HEADER_SIZE (5)
+#define HCI_DATA_CMD_HEADER_SIZE (5)
+#define HCI_PATCH_HEADER_SIZE (6)
+
+#define HCI_PACKET_TYPE_OFFSET (0)
+#define HCI_PACKET_ARGSIZE_OFFSET (2)
+#define HCI_PACKET_LENGTH_OFFSET (3)
+
+
+#define HCI_EVENT_OPCODE_OFFSET (1)
+#define HCI_EVENT_LENGTH_OFFSET (3)
+#define HCI_EVENT_STATUS_OFFSET (4)
+#define HCI_DATA_LENGTH_OFFSET (3)
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_wlan.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,699 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+#include "cc3000.h"
+
+namespace mbed_cc3000 {
+
+cc3000_wlan::cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci) :
+ _simple_link(simple_link), _event(event), _spi(spi), _hci(hci) {
+
+}
+
+cc3000_wlan::~cc3000_wlan() {
+
+}
+
+void cc3000_wlan::simpleLink_init_start(uint16_t patches_available_host) {
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
+
+ UINT8_TO_STREAM(args, ((patches_available_host) ? SL_PATCHES_REQUEST_FORCE_HOST : SL_PATCHES_REQUEST_DEFAULT));
+
+ // IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000
+ _hci.command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN);
+ _event.simplelink_wait_event(HCI_CMND_SIMPLE_LINK_START, 0);
+}
+
+void cc3000_wlan::start(uint16_t patches_available_host) {
+ uint32_t spi_irq_state;
+
+ _simple_link.set_sent_packets(0);
+ _simple_link.set_number_of_released_packets(0);
+ _simple_link.set_op_code(0);
+ _simple_link.set_number_free_buffers(0);
+ _simple_link.set_buffer_length(0);
+ _simple_link.set_buffer_size(0);
+ _simple_link.set_pending_data(0);
+ _simple_link.set_transmit_error(0);
+ _simple_link.set_data_received_flag(0);
+ _simple_link.set_buffer_size(0);
+
+ // init spi
+ _spi.open();
+ // Check the IRQ line
+ spi_irq_state = _spi.wlan_irq_read();
+ // ASIC 1273 chip enable: toggle WLAN EN line
+ _spi.write_wlan_en(WLAN_ENABLE);
+
+ if (spi_irq_state)
+ {
+ // wait till the IRQ line goes low
+ while(_spi.wlan_irq_read() != 0)
+ {
+ }
+ }
+ else
+ {
+ // wait till the IRQ line goes high and then low
+ while(_spi.wlan_irq_read() == 0)
+ {
+ }
+ while(_spi.wlan_irq_read() != 0)
+ {
+ }
+ }
+ simpleLink_init_start(patches_available_host);
+
+ // Read Buffer's size and finish
+ _hci.command_send(HCI_CMND_READ_BUFFER_SIZE, _simple_link.get_transmit_buffer(), 0);
+ _event.simplelink_wait_event(HCI_CMND_READ_BUFFER_SIZE, 0);
+}
+
+
+void cc3000_wlan::stop() {
+ // ASIC 1273 chip disable
+ _spi.write_wlan_en( WLAN_DISABLE );
+
+ // Wait till IRQ line goes high...
+ while(_spi.wlan_irq_read() == 0)
+ {
+ }
+
+ // Free the used by WLAN Driver memory
+ if (_simple_link.get_transmit_buffer())
+ {
+ _simple_link.set_transmit_buffer(0);
+ }
+
+ _spi.close();
+}
+
+
+int32_t cc3000_wlan::disconnect() {
+ int32_t ret;
+ uint8_t *ptr;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+
+ _hci.command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_DISCONNECT, &ret);
+ errno = ret;
+
+ return(ret);
+}
+
+
+int32_t cc3000_wlan::ioctl_set_connection_policy(uint32_t should_connect_to_open_ap,
+ uint32_t use_fast_connect,
+ uint32_t use_profiles) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, should_connect_to_open_ap);
+ args = UINT32_TO_STREAM(args, use_fast_connect);
+ args = UINT32_TO_STREAM(args, use_profiles);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret);
+
+ return(ret);
+}
+
+
+int32_t cc3000_wlan::ioctl_del_profile(uint32_t index) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, index);
+ ret = EFAIL;
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, ptr, WLAN_DEL_PROFILE_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);
+
+ return(ret);
+}
+
+int32_t cc3000_wlan::set_event_mask(uint32_t mask) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+
+ if ((mask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE)
+ {
+ _simple_link.set_tx_complete_signal(0);
+
+ // Since an event is a virtual event - i.e. it is not coming from CC3000
+ // there is no need to send anything to the device if it was an only event
+ if (mask == HCI_EVNT_WLAN_TX_COMPLETE)
+ {
+ return 0;
+ }
+
+ mask &= ~HCI_EVNT_WLAN_TX_COMPLETE;
+ mask |= HCI_EVNT_WLAN_UNSOL_BASE;
+ }
+ else
+ {
+ _simple_link.set_tx_complete_signal(1);
+ }
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, mask);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_EVENT_MASK, ptr, WLAN_SET_MASK_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_EVENT_MASK, &ret);
+
+ return(ret);
+}
+
+
+int32_t cc3000_wlan::smart_config_start(uint32_t encrypted_flag) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, encrypted_flag);
+ ret = EFAIL;
+
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, WLAN_SMART_CONFIG_START_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret);
+
+ return(ret);
+}
+
+
+int32_t cc3000_wlan::smart_config_stop(void) {
+ int32_t ret;
+ uint8_t *ptr;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret);
+
+ return(ret);
+}
+
+int32_t cc3000_wlan::smart_config_set_prefix(uint8_t *new_prefix) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ if (new_prefix == NULL)
+ return ret;
+ else // with the new Smart Config, prefix must be TTT
+ {
+ *new_prefix = 'T';
+ *(new_prefix + 1) = 'T';
+ *(new_prefix + 2) = 'T';
+ }
+
+ ARRAY_TO_STREAM(args, new_prefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
+
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret);
+
+ return(ret);
+}
+
+#ifndef CC3000_TINY_DRIVER
+int32_t cc3000_wlan::connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_len, uint8_t *bssid,
+ uint8_t *key, int32_t key_len) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+ uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in command buffer
+ args = UINT32_TO_STREAM(args, 0x0000001c);
+ args = UINT32_TO_STREAM(args, ssid_len);
+ args = UINT32_TO_STREAM(args, sec_type);
+ args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
+ args = UINT32_TO_STREAM(args, key_len);
+ args = UINT16_TO_STREAM(args, 0);
+
+ // padding shall be zeroed
+ if(bssid)
+ {
+ ARRAY_TO_STREAM(args, bssid, ETH_ALEN);
+ }
+ else
+ {
+ ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+ }
+
+ ARRAY_TO_STREAM(args, ssid, ssid_len);
+
+ if(key_len && key)
+ {
+ ARRAY_TO_STREAM(args, key, key_len);
+ }
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len + key_len - 1);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
+ errno = ret;
+
+ return(ret);
+}
+
+int32_t cc3000_wlan::add_profile(uint32_t sec_type,
+ uint8_t* ssid,
+ uint32_t ssid_length,
+ uint8_t *b_ssid,
+ uint32_t priority,
+ uint32_t pairwise_cipher_or_tx_key_len,
+ uint32_t group_cipher_tx_key_index,
+ uint32_t key_mgmt,
+ uint8_t* pf_or_key,
+ uint32_t pass_phrase_len) {
+ uint16_t arg_len = 0x00;
+ int32_t ret;
+ uint8_t *ptr;
+ int32_t i = 0;
+ uint8_t *args;
+ uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ args = UINT32_TO_STREAM(args, sec_type);
+
+ // Setup arguments in accordance with the security type
+ switch (sec_type)
+ {
+ //OPEN
+ case WLAN_SEC_UNSEC:
+ {
+ args = UINT32_TO_STREAM(args, 0x00000014);
+ args = UINT32_TO_STREAM(args, ssid_length);
+ args = UINT16_TO_STREAM(args, 0);
+ if(b_ssid)
+ {
+ ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
+ }
+ else
+ {
+ ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+ }
+ args = UINT32_TO_STREAM(args, priority);
+ ARRAY_TO_STREAM(args, ssid, ssid_length);
+
+ arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ssid_length;
+ }
+ break;
+
+ //WEP
+ case WLAN_SEC_WEP:
+ {
+ args = UINT32_TO_STREAM(args, 0x00000020);
+ args = UINT32_TO_STREAM(args, ssid_length);
+ args = UINT16_TO_STREAM(args, 0);
+ if(b_ssid)
+ {
+ ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
+ }
+ else
+ {
+ ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+ }
+ args = UINT32_TO_STREAM(args, priority);
+ args = UINT32_TO_STREAM(args, 0x0000000C + ssid_length);
+ args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
+ args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
+ ARRAY_TO_STREAM(args, ssid, ssid_length);
+
+ for(i = 0; i < 4; i++)
+ {
+ uint8_t *p = &pf_or_key[i * pairwise_cipher_or_tx_key_len];
+
+ ARRAY_TO_STREAM(args, p, pairwise_cipher_or_tx_key_len);
+ }
+
+ arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ssid_length +
+ pairwise_cipher_or_tx_key_len * 4;
+
+ }
+ break;
+
+ //WPA
+ //WPA2
+ case WLAN_SEC_WPA:
+ case WLAN_SEC_WPA2:
+ {
+ args = UINT32_TO_STREAM(args, 0x00000028);
+ args = UINT32_TO_STREAM(args, ssid_length);
+ args = UINT16_TO_STREAM(args, 0);
+ if(b_ssid)
+ {
+ ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
+ }
+ else
+ {
+ ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+ }
+ args = UINT32_TO_STREAM(args, priority);
+ args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
+ args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
+ args = UINT32_TO_STREAM(args, key_mgmt);
+ args = UINT32_TO_STREAM(args, 0x00000008 + ssid_length);
+ args = UINT32_TO_STREAM(args, pass_phrase_len);
+ ARRAY_TO_STREAM(args, ssid, ssid_length);
+ ARRAY_TO_STREAM(args, pf_or_key, pass_phrase_len);
+
+ arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ssid_length + pass_phrase_len;
+ }
+
+ break;
+ }
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);
+
+ return(ret);
+}
+
+int32_t cc3000_wlan::ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results) {
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, scan_timeout);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, results);
+
+ return(0);
+}
+
+int32_t cc3000_wlan::ioctl_set_scan_params(uint32_t enable,
+ uint32_t min_dwell_time,
+ uint32_t max_dwell_time,
+ uint32_t num_probe_requests,
+ uint32_t channel_mask,
+ int32_t rssi_threshold,
+ uint32_t snr_threshold,
+ uint32_t default_tx_power,
+ uint32_t *interval_list) {
+ uint32_t uiRes;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, 36);
+ args = UINT32_TO_STREAM(args, enable);
+ args = UINT32_TO_STREAM(args, min_dwell_time);
+ args = UINT32_TO_STREAM(args, max_dwell_time);
+ args = UINT32_TO_STREAM(args, num_probe_requests);
+ args = UINT32_TO_STREAM(args, channel_mask);
+ args = UINT32_TO_STREAM(args, rssi_threshold);
+ args = UINT32_TO_STREAM(args, snr_threshold);
+ args = UINT32_TO_STREAM(args, default_tx_power);
+ ARRAY_TO_STREAM(args, interval_list, sizeof(uint32_t) * SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, ptr, WLAN_SET_SCAN_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes);
+
+ return(uiRes);
+}
+
+int32_t cc3000_wlan::ioctl_statusget(void) {
+ int32_t ret;
+ uint8_t *ptr;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_STATUSGET,ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret);
+
+ return(ret);
+}
+
+#else
+int32_t cc3000_wlan::wlan_add_profile(uint32_t sec_type,
+ uint8_t *ssid,
+ uint32_t ssid_length,
+ uint8_t *b_ssid,
+ uint32_t priority,
+ uint32_t pairwise_cipher_or_tx_key_len,
+ uint32_t group_cipher_tx_key_index,
+ uint32_t key_mgmt,
+ uint8_t* pf_or_key,
+ uint32_t pass_phrase_length)
+{
+ return -1;
+}
+
+int32_t cc3000_wlan::connect(const uint8_t *ssid, int32_t ssid_len) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+ uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in command buffer
+ args = UINT32_TO_STREAM(args, 0x0000001c);
+ args = UINT32_TO_STREAM(args, ssid_len);
+ args = UINT32_TO_STREAM(args, 0);
+ args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
+ args = UINT32_TO_STREAM(args, 0);
+ args = UINT16_TO_STREAM(args, 0);
+
+ // padding shall be zeroed
+ ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
+ ARRAY_TO_STREAM(args, ssid, ssid_len);
+
+ // Initiate a HCI command
+ _hci.command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len - 1);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
+ errno = ret;
+
+ return(ret);
+}
+#endif
+
+
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+int32_t cc3000_wlan::smart_config_process(void) {
+ int32_t returnValue;
+ uint32_t ssidLen, keyLen;
+ uint8_t *decKeyPtr;
+ uint8_t *ssidPtr;
+
+ // read the key from EEPROM - fileID 12
+ returnValue = aes_read_key(key);
+
+ if (returnValue != 0)
+ return returnValue;
+
+ // read the received data from fileID #13 and parse it according to the followings:
+ // 1) SSID LEN - not encrypted
+ // 2) SSID - not encrypted
+ // 3) KEY LEN - not encrypted. always 32 bytes long
+ // 4) Security type - not encrypted
+ // 5) KEY - encrypted together with true key length as the first byte in KEY
+ // to elaborate, there are two corner cases:
+ // 1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length
+ // 2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31
+ returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray);
+
+ if (returnValue != 0)
+ return returnValue;
+
+ ssidPtr = &profileArray[1];
+
+ ssidLen = profileArray[0];
+
+ decKeyPtr = &profileArray[profileArray[0] + 3];
+
+ aes_decrypt(decKeyPtr, key);
+ if (profileArray[profileArray[0] + 1] > 16)
+ aes_decrypt((uint8_t *)(decKeyPtr + 16), key);
+
+ if (*(uint8_t *)(decKeyPtr +31) != 0)
+ {
+ if (*decKeyPtr == 31)
+ {
+ keyLen = 31;
+ decKeyPtr++;
+ }
+ else
+ {
+ keyLen = 32;
+ }
+ }
+ else
+ {
+ keyLen = *decKeyPtr;
+ decKeyPtr++;
+ }
+
+ // add a profile
+ switch (profileArray[profileArray[0] + 2])
+ {
+ case WLAN_SEC_UNSEC://None
+ {
+ returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type
+ ssidPtr, // SSID
+ ssidLen, // SSID length
+ NULL, // BSSID
+ 1, // Priority
+ 0, 0, 0, 0, 0);
+
+ break;
+ }
+
+ case WLAN_SEC_WEP://WEP
+ {
+ returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type
+ ssidPtr, // SSID
+ ssidLen, // SSID length
+ NULL, // BSSID
+ 1, // Priority
+ keyLen, // KEY length
+ 0, // KEY index
+ 0,
+ decKeyPtr, // KEY
+ 0);
+
+ break;
+ }
+
+ case WLAN_SEC_WPA: //WPA
+ case WLAN_SEC_WPA2: //WPA2
+ {
+ returnValue = wlan_add_profile(WLAN_SEC_WPA2, // security type
+ ssidPtr,
+ ssidLen,
+ NULL, // BSSID
+ 1, // Priority
+ 0x18, // PairwiseCipher
+ 0x1e, // GroupCipher
+ 2, // KEY management
+ decKeyPtr, // KEY
+ keyLen); // KEY length
+
+ break;
+ }
+ }
+
+ return returnValue;
+}
+#endif
+
+}
