Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: FlashAir_Twitter Neon_F303K8_04
Fork of HTTPClient by
Revision 20:51abf34bcc06, committed 2014-12-15
- Comitter:
- ban4jp
- Date:
- Mon Dec 15 12:23:22 2014 +0000
- Parent:
- 19:3b1625dbd7e9
- Commit message:
- Initial commit.
Changed in this revision
--- a/HTTPClient.cpp Sun Dec 14 19:05:31 2014 +0000
+++ b/HTTPClient.cpp Mon Dec 15 12:23:22 2014 +0000
@@ -18,7 +18,7 @@
*/
//Debug is disabled by default
-#if 0
+#if 1
//Enable debug
#include <cstdio>
#define DBG(x, ...) std::printf("[HTTPClient : DBG]"x"\r\n", ##__VA_ARGS__);
@@ -41,15 +41,18 @@
#define MAX(x,y) (((x)>(y))?(x):(y))
#define CHUNK_SIZE 256
+#define HEADER_KEY_MAXLENGTH 64
+#define HEADER_VALUE_MAXLENGTH 128
#include <cstring>
#include "HTTPClient.h"
HTTPClient::HTTPClient() :
- m_sock(), m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0)
+ m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0)
{
-
+ bufferPos = buffer;
+ recvCount = 0;
}
HTTPClient::~HTTPClient()
@@ -100,7 +103,6 @@
#define CHECK_CONN_ERR(ret) \
do{ \
if(ret) { \
- m_sock.close(); \
ERR("Connection error (%d)", ret); \
return HTTP_CONN; \
} \
@@ -108,7 +110,6 @@
#define PRTCL_ERR() \
do{ \
- m_sock.close(); \
ERR("Protocol error"); \
return HTTP_PRTCL; \
} while(0)
@@ -125,6 +126,7 @@
char scheme[8];
uint16_t port;
+ uint16_t cmd;
char host[32];
char path[64];
//First we need to parse the url (http[s]://host[:port][/[path]]) -- HTTPS not supported (yet?)
@@ -137,20 +139,36 @@
if(port == 0) { //TODO do handle HTTPS->443
port = 80;
}
+ if(strcmp(scheme, "http") == 0) {
+ cmd = 0x21; //SendHTTPMessageByRegister
+ } else if(strcmp(scheme, "https") == 0) {
+ cmd = 0x23; //SendHTTPSSLMessageByRegister
+ } else {
+ ERR("Not support scheme %s", scheme);
+ return HTTP_PARSE;
+ }
DBG("Scheme: %s", scheme);
DBG("Host: %s", host);
DBG("Port: %d", port);
+ DBG("Cmd: %x", cmd);
DBG("Path: %s", path);
- //Connect
- DBG("Connecting socket to server");
- int ret = m_sock.connect(host, port);
- if (ret < 0) {
- m_sock.close();
- ERR("Could not connect");
- return HTTP_CONN;
- }
+ int ret;
+
+ //Get card instance
+ card = SD_iSDIO::getInstance();
+ sequenceId = card->getSequenceId();
+
+ //Create card command
+ memset(buffer, 0, 1024);
+ bufferPos = buffer;
+ bufferPos = put_command_header(bufferPos, 1, 0);
+ bufferPos = put_command_info_header(bufferPos, cmd, sequenceId, 2);
+ bufferPos = put_str_arg(bufferPos, host);
+
+ uint8_t* bodyLenPos = bufferPos;
+ bufferPos += 4; //skip value of data size
//Send request
DBG("Sending request");
@@ -159,7 +177,6 @@
snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\nHost: %s\r\n", meth, path, host); //Write request
ret = send(buf);
if(ret) {
- m_sock.close();
ERR("Could not write request");
return HTTP_CONN;
}
@@ -244,6 +261,38 @@
}
}
+ put_u32(bodyLenPos, (bufferPos - bodyLenPos - 4));
+ put_command_header(buffer, 1, (bufferPos - buffer));
+
+#if 0
+ for (int i = 0; i < 0x400; i++) {
+ printf("%2x ", buffer[i]);
+ if ((i & 0xf) == 0xf) printf("\n");
+ if (i == 0x200-1) printf("----\n");
+ }
+ printf((char *)bodyLenPos + 4);
+ printf("\n");
+#endif
+
+ DBG("Send data size %d", (bufferPos - buffer));
+
+ if( card->writeExtDataPort(1, 1, 0x000, buffer) != true ) {
+ ERR("writeExtDataPort error (1)\n");
+ return HTTP_PRTCL;
+ }
+ if( (bufferPos - buffer) > 512 ) {
+ if( card->writeExtDataPort(1, 1, 0x000, &buffer[512]) != true ) {
+ ERR("writeExtDataPort error (2)\n");
+ return HTTP_PRTCL;
+ }
+ }
+
+ DBG("waitResponse");
+ card->waitResponse(sequenceId);
+
+ bufferPos = buffer;
+ recvCount = 0;
+
//Receive response
DBG("Receiving response");
ret = recv(buf, 1, CHUNK_SIZE - 1, &trfLen); //Read n bytes
@@ -285,7 +334,8 @@
PRTCL_ERR();
}
- if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) ) {
+ //if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) ) {
+ if( (m_httpResponseCode < 100) || (m_httpResponseCode >= 600) ) {
//Did not return a 2xx code; TODO fetch headers/(&data?) anyway and implement a mean of writing/reading headers
WARN("Response code %d", m_httpResponseCode);
PRTCL_ERR();
@@ -327,14 +377,14 @@
buf[crlfPos] = '\0';
- char key[32];
- char value[32];
+ char key[HEADER_KEY_MAXLENGTH];
+ char value[HEADER_VALUE_MAXLENGTH];
//key[31] = '\0';
//value[31] = '\0';
- memset(key, 0, 32);
- memset(value, 0, 32);
+ memset(key, 0, HEADER_KEY_MAXLENGTH);
+ memset(value, 0, HEADER_VALUE_MAXLENGTH);
//int n = sscanf(buf, "%31[^:]: %31[^\r\n]", key, value);
@@ -343,12 +393,12 @@
char* keyEnd = strchr(buf, ':');
if(keyEnd != NULL) {
*keyEnd = '\0';
- if(strlen(buf) < 32) {
+ if(strlen(buf) < HEADER_KEY_MAXLENGTH) {
strcpy(key, buf);
n++;
char* valueStart = keyEnd + 2;
if( (valueStart - buf) < crlfPos ) {
- if(strlen(valueStart) < 32) {
+ if(strlen(valueStart) < HEADER_VALUE_MAXLENGTH) {
strcpy(value, valueStart);
n++;
}
@@ -356,7 +406,7 @@
}
}
if ( n == 2 ) {
- DBG("Read header : %s: %s\n", key, value);
+ DBG("Read header : %s: %s", key, value);
if( !strcmp(key, "Content-Length") ) {
sscanf(value, "%d", &recvContentLength);
recvLengthUnknown = false;
@@ -484,7 +534,6 @@
}
- m_sock.close();
DBG("Completed HTTP transaction");
return HTTP_OK;
@@ -495,41 +544,93 @@
DBG("Trying to read between %d and %d bytes", minLen, maxLen);
size_t readLen = 0;
- if(!m_sock.is_connected()) {
- WARN("Connection was closed by server");
- return HTTP_CLOSED; //Connection was closed by server
- }
+ DBG(" recvCount: %d", recvCount);
+
+ if (recvCount == 0) {
- int ret;
- while(readLen < maxLen) {
- if(readLen < minLen) {
- DBG("Trying to read at most %d bytes [Blocking]", minLen - readLen);
- m_sock.set_blocking(false, m_timeout);
- ret = m_sock.receive_all(buf + readLen, minLen - readLen);
- } else {
- DBG("Trying to read at most %d bytes [Not blocking]", maxLen - readLen);
- m_sock.set_blocking(false, 0);
- ret = m_sock.receive(buf + readLen, maxLen - readLen);
+ // Read header and data.
+ if (!card->readExtDataPort(1, 1, 0x200, buffer)) {
+ return HTTP_PRTCL;
+ }
+#if 0
+ for (int i = 0; i < 0x200; i++) {
+ printf("%2x ", buffer[i]);
+ if ((i & 0xf) == 0xf) printf("\n");
+ }
+#endif
+ if (buffer[0] != 0x02) {
+ return HTTP_CONN;
}
- if( ret > 0) {
- readLen += ret;
- } else if( ret == 0 ) {
- break;
+ recvTotalSize = get_u32(buffer + 20);
+ uint32_t recvSize = recvTotalSize > 488 ? 488 : recvTotalSize;
+ uint32_t pos = 24;
+
+ if (recvSize < maxLen) {
+ memcpy(buf, &buffer[pos], recvSize);
+ readLen = recvSize;
} else {
- if(!m_sock.is_connected()) {
- ERR("Connection error (recv returned %d)", ret);
- *pReadLen = readLen;
- return HTTP_CONN;
+ memcpy(buf, &buffer[pos], maxLen);
+ readLen = maxLen;
+ }
+ bufferPos = &buffer[pos] + readLen;
+ recvAvailableSize = recvTotalSize - readLen;
+
+ DBG(" recvTotalSize: %d", recvTotalSize);
+ DBG(" recvAvailableSize: %d", recvAvailableSize);
+
+ recvCount++;
+
+ } else {
+
+ uint32_t recvSize = 512 - (bufferPos - buffer);
+ if (recvAvailableSize < recvSize) recvSize = recvAvailableSize;
+
+ DBG(" recvAvailableSize: %d", recvAvailableSize);
+ DBG(" recvSize: %d", recvSize);
+
+ if (recvSize > 0) {
+
+ if (recvSize < maxLen) {
+ memcpy(buf, bufferPos, recvSize);
+ readLen = recvSize;
} else {
- break;
+ memcpy(buf, bufferPos, maxLen);
+ readLen = maxLen;
+ }
+ bufferPos += readLen;
+ recvAvailableSize -= readLen;
+
+ } else if (recvAvailableSize > 0) {
+
+ // Read next data.
+ if (!card->readExtDataPort(1, 1, 0x200, buffer)) {
+ return HTTP_PRTCL;
}
+#if 0
+ for (int i = 0; i < 0x200; i++) {
+ printf("%2x ", buffer[i]);
+ if ((i & 0xf) == 0xf) printf("\n");
+ }
+#endif
+ recvSize = recvAvailableSize > 512 ? 512 : recvAvailableSize;
+
+ if (recvSize < maxLen) {
+ memcpy(buf, buffer, recvSize);
+ readLen = recvSize;
+ } else {
+ memcpy(buf, buffer, maxLen);
+ readLen = maxLen;
+ }
+ bufferPos = buffer + readLen;
+ recvAvailableSize -= readLen;
+
+ recvCount++;
+
}
- if(!m_sock.is_connected()) {
- break;
- }
}
+
DBG("Read %d bytes", readLen);
*pReadLen = readLen;
return HTTP_OK;
@@ -543,22 +644,13 @@
DBG("Trying to write %d bytes", len);
size_t writtenLen = 0;
- if(!m_sock.is_connected()) {
- WARN("Connection was closed by server");
- return HTTP_CLOSED; //Connection was closed by server
+ if(((buffer + 1024) - bufferPos) >= len) {
+ writtenLen = len;
+ } else {
+ writtenLen = ((buffer + 1024) - bufferPos);
}
-
- m_sock.set_blocking(false, m_timeout);
- int ret = m_sock.send_all(buf, len);
- if(ret > 0) {
- writtenLen += ret;
- } else if( ret == 0 ) {
- WARN("Connection was closed by server");
- return HTTP_CLOSED; //Connection was closed by server
- } else {
- ERR("Connection error (send returned %d)", ret);
- return HTTP_CONN;
- }
+ memcpy(bufferPos, buf, writtenLen);
+ bufferPos += writtenLen;
DBG("Written %d bytes", writtenLen);
return HTTP_OK;
--- a/HTTPClient.h Sun Dec 14 19:05:31 2014 +0000
+++ b/HTTPClient.h Mon Dec 15 12:23:22 2014 +0000
@@ -24,7 +24,7 @@
#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H
-#include "TCPSocketConnection.h"
+#include "iSDIO.h"
#define HTTP_CLIENT_DEFAULT_TIMEOUT 15000
@@ -140,7 +140,14 @@
HTTPResult parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL
//Parameters
- TCPSocketConnection m_sock;
+ SD_iSDIO* card;
+ uint32_t sequenceId;
+
+ uint8_t buffer[512 * 2];
+ uint8_t* bufferPos;
+ uint8_t recvCount;
+ uint32_t recvTotalSize;
+ uint32_t recvAvailableSize;
int m_timeout;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Mon Dec 15 12:23:22 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/mbed/code/SDFileSystem/#7b35d1709458
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iSDIO.cpp Mon Dec 15 12:23:22 2014 +0000
@@ -0,0 +1,207 @@
+#include "mbed.h"
+#include "iSDIO.h"
+
+#define CMD48 0x30
+#define CMD49 0x31
+
+SD_iSDIO::SD_iSDIO(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) :
+ SDFileSystem(mosi, miso, sclk, cs, name)
+{
+ //disk_initialize();
+ instance = this;
+ sequenceId = 0;
+}
+
+SD_iSDIO* SD_iSDIO::instance = 0;
+
+SD_iSDIO* SD_iSDIO::getInstance()
+{
+ return SD_iSDIO::instance;
+}
+
+uint32_t SD_iSDIO::getSequenceId()
+{
+ return sequenceId++;
+}
+
+uint8_t SD_iSDIO::readExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, uint8_t* dst)
+{
+ uint32_t arg =
+ (((uint32_t)mio & 0x1) << 31) |
+ (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
+ (((uint32_t)addr & 0x1FE00) << 9);
+ return readExt(arg, dst, 512);
+}
+
+uint8_t SD_iSDIO::readExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, uint8_t* dst)
+{
+ uint32_t offset = addr & 0x1FF;
+ if (offset + count > 512) count = 512 - offset;
+ if (count == 0) return true;
+ uint32_t arg =
+ (((uint32_t)mio & 0x1) << 31) |
+ (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
+ ((addr & 0x1FFFF) << 9) |
+ ((count - 1) & 0x1FF);
+ return readExt(arg, dst, count);
+}
+
+uint8_t SD_iSDIO::writeExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, const uint8_t* src)
+{
+ uint32_t arg =
+ (((uint32_t)mio & 0x1) << 31) |
+ (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
+ (((uint32_t)addr & 0x1FE00) << 9);
+ return writeExt(arg, src, 512);
+}
+
+uint8_t SD_iSDIO::writeExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, const uint8_t* src)
+{
+ uint32_t arg =
+ (((uint32_t)mio & 0x1) << 31) |
+ (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
+ ((addr & 0x1FFFF) << 9) |
+ ((count - 1) & 0x1FF);
+ return writeExt(arg, src, count);
+}
+
+uint8_t SD_iSDIO::writeExtMask(uint8_t mio, uint8_t func, uint32_t addr, uint8_t mask, const uint8_t* src)
+{
+ uint32_t arg =
+ (((uint32_t)mio & 0x1) << 31) |
+ (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
+ (0x1 << 26) |
+ ((addr & 0x1FFFF) << 9) |
+ mask;
+ return writeExt(arg, src, 1);
+}
+
+uint8_t SD_iSDIO::waitResponse(uint32_t sequenceId)
+{
+ uint8_t buffer[0x14];
+
+ //printf("\nWaiting response ");
+ uint8_t prev = 0xFF;
+ for (int i = 0; i < 20; ++i) {
+ memset(buffer, 0, 0x14);
+ // Read command response status.
+ if (!readExtMemory(1, 1, 0x440, 0x14, buffer)) {
+ return false;
+ }
+ uint8_t resp = get_u8(buffer + 8);
+ if (sequenceId == get_u32(buffer + 4)) {
+ if (prev != resp) {
+ switch (resp) {
+ case 0x00:
+ //printf("\n Initial");
+ break;
+ case 0x01:
+ //printf("\n Command Processing");
+ break;
+ case 0x02:
+ //printf("\n Command Rejected");
+ return false;
+ case 0x03:
+ //printf("\n Process Succeeded");
+ return true;
+ case 0x04:
+ //printf("\n Process Terminated");
+ return false;
+ default:
+ //printf("\n Process Failed ");
+ //printf("%x", resp);
+ return false;
+ }
+ prev = resp;
+ }
+ }
+ //printf(".");
+ wait_ms(1000);
+ }
+ return false;
+}
+
+/** Perform Extention Read. */
+uint8_t SD_iSDIO::readExt(uint32_t arg, uint8_t* dst, uint16_t count)
+{
+ uint16_t i;
+ // send command and argument.
+ if (_cmd(CMD48, arg)) {
+ error("SD_CARD_ERROR_CMD48");
+ _cs = 1;
+ return false;
+ }
+
+ _cs = 0;
+
+ /*
+ // wait for start block token.
+ if (!waitStartBlock()) {
+ _cs = 1;
+ return false;
+ }
+ */
+ while (_spi.write(0xFF) == 0xFF);
+
+ // receive data
+ for (i = 0; i < count; ++i) {
+ dst[i] = _spi.write(0xFF);
+ }
+ // skip dummy bytes and 16-bit crc.
+ for (; i < 514; ++i) {
+ _spi.write(0xFF);
+ }
+ _cs = 1;
+ _spi.write(0xFF); // dummy clock to force FlashAir finish the command.
+ return true;
+}
+
+/** Perform Extention Write. */
+uint8_t SD_iSDIO::writeExt(uint32_t arg, const uint8_t* src, uint16_t count)
+{
+ uint16_t i;
+ uint8_t status;
+ // send command and argument.
+ if (_cmd(CMD49, arg)) {
+ error("SD_CARD_ERROR_CMD49");
+ _cs = 1;
+ return false;
+ }
+
+ _cs = 0;
+
+ // send start block token.
+ //_spi.write(DATA_START_BLOCK);
+ _spi.write(0xFE);
+ // send data
+ for (i = 0; i < count; ++i) {
+ _spi.write(src[i]);
+ }
+ // send dummy bytes until 512 bytes.
+ for (; i < 512; ++i) {
+ _spi.write(0xFF);
+ }
+ // dummy 16-bit crc
+ _spi.write(0xFF);
+ _spi.write(0xFF);
+ // wait a data response token
+ status = _spi.write(0xFF);
+ //if ((status & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
+ if ((status & 0x1F) != 0x05) {
+ error("SD_CARD_ERROR_WRITE");
+ _cs = 1;
+ return false;
+ }
+ // wait for flash programming to complete
+ /*
+ if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
+ error("SD_CARD_ERROR_WRITE_TIMEOUT");
+ _cs = 1;
+ return false;
+ }
+ */
+ while (_spi.write(0xFF) == 0);
+
+ _cs = 1;
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iSDIO.h Mon Dec 15 12:23:22 2014 +0000
@@ -0,0 +1,32 @@
+#ifndef SD_iSDIO_h
+#define SD_iSDIO_h
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+#include "iSDIO_helper.h"
+
+class SD_iSDIO : public SDFileSystem
+{
+public:
+ SD_iSDIO(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name);
+
+ static SD_iSDIO* getInstance();
+ uint32_t getSequenceId();
+
+ uint8_t readExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, uint8_t* dst);
+ uint8_t readExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, uint8_t* dst);
+ uint8_t writeExtDataPort(uint8_t mio, uint8_t func, uint16_t addr, const uint8_t* src);
+ uint8_t writeExtMemory(uint8_t mio, uint8_t func, uint32_t addr, uint16_t count, const uint8_t* src);
+ uint8_t writeExtMask(uint8_t mio, uint8_t func, uint32_t addr, uint8_t mask, const uint8_t* src);
+
+ uint8_t waitResponse(uint32_t sequenceId);
+
+protected:
+ uint8_t readExt(uint32_t arg, uint8_t* src, uint16_t count);
+ uint8_t writeExt(uint32_t arg, const uint8_t* src, uint16_t count);
+
+ static SD_iSDIO* instance;
+ uint32_t sequenceId;
+};
+
+#endif // SD_iSDIO_h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iSDIO_helper.cpp Mon Dec 15 12:23:22 2014 +0000
@@ -0,0 +1,51 @@
+/* Arduino Sdio Library
+ * Copyright (C) 2014 by Munehiro Doi, Fixstars Corporation
+ * All rights reserved.
+ * Released under the BSD 2-Clause license.
+ * http://flashair-developers.com/documents/license.html
+ */
+
+#include "iSDIO_helper.h"
+
+//------------------------------------------------------------------------------
+/** specific version for string. it adds padding bytes after text data. */
+template <>
+uint8_t* put_T(uint8_t* p, const char* value) {
+ while (*value != 0) {
+ *p++ = *((uint8_t*)value++);
+ }
+ return p;
+}
+
+template <>
+uint8_t* put_T_arg(uint8_t* p, const char* value) {
+ uint8_t* orig = p;
+ p += sizeof(uint32_t); // skip length area.
+ p = put_T(p, value); // data
+ uint32_t len = p - orig - sizeof(uint32_t);
+ put_T(orig, len); // write length.
+ for (int i = 0; i < ((4 - (len & 3)) & 3); ++i) { // padding
+ *p++ = 0;
+ }
+ return p;
+}
+
+uint8_t* put_command_header(uint8_t* p, uint8_t num_commands,
+ uint32_t command_bytes) {
+ p = put_u8(p, 0x01); // Write Data ID
+ p = put_u8(p, num_commands); // Number of commands.
+ p = put_u16(p, 0); // reserved.
+ p = put_u32(p, command_bytes); // size of command write data.
+ p = put_u32(p, 0); // reserved.
+ return p;
+}
+
+uint8_t* put_command_info_header(uint8_t* p, uint16_t command_id,
+ uint32_t sequence_id, uint16_t num_args) {
+ p = put_u16(p, 0); // reserved.
+ p = put_u16(p, command_id); // iSDIO command id.
+ p = put_u32(p, sequence_id); // iSDIO command sequence id.
+ p = put_u16(p, num_args); // Number of Arguments.
+ p = put_u16(p, 0); // Reserved.
+ return p;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iSDIO_helper.h Mon Dec 15 12:23:22 2014 +0000
@@ -0,0 +1,220 @@
+/* Arduino Sdio Library
+ * Copyright (C) 2014 by Munehiro Doi, Fixstars Corporation
+ * All rights reserved.
+ * Released under the BSD 2-Clause license.
+ * http://flashair-developers.com/documents/license.html
+ */
+#ifndef iSDIO_helper_h
+#define iSDIO_helper_h
+
+#include <stdint.h>
+
+//------------------------------------------------------------------------------
+// utilities to make a data block.
+template <typename T>
+uint8_t* put_T(uint8_t* p, T value) {
+ *((T*)p) = value;
+ p += sizeof(T);
+ return p;
+}
+/** specific version for string. it set length, data, and paddings. */
+template <>
+uint8_t* put_T(uint8_t* p, const char* value);
+
+// utilities for those who want to see value types by function names.
+static inline
+uint8_t* put_u8(uint8_t* p, uint8_t value) {
+ return put_T(p, value);
+}
+static inline
+uint8_t* put_u16(uint8_t* p, uint16_t value) {
+ return put_T(p, value);
+}
+static inline
+uint8_t* put_u32(uint8_t* p, uint32_t value) {
+ return put_T(p, value);
+}
+static inline
+uint8_t* put_str(uint8_t* p, const char* value) {
+ return put_T(p, value);
+}
+
+static inline
+uint8_t get_u8(uint8_t* p) {
+ return *((uint8_t*)p);
+}
+static inline
+uint16_t get_u16(uint8_t* p) {
+ return *((uint16_t*)p);
+}
+static inline
+uint32_t get_u32(uint8_t* p) {
+ return *((uint32_t*)p);
+}
+
+template <typename T>
+uint8_t* put_T_arg(uint8_t* p, T value) {
+ p = put_T(p, (uint32_t)sizeof(T)); // length
+ p = put_T(p, value); // data
+ for (uint8_t i = 0; i < (4 - sizeof(T)) & 0x3; ++i) { // padding
+ *p++ = 0;
+ }
+ return p;
+}
+template <>
+uint8_t* put_T_arg(uint8_t* p, const char* value);
+
+static inline
+uint8_t* put_u8_arg(uint8_t* p, uint8_t value) {
+ return put_T_arg(p, value);
+}
+static inline
+uint8_t* put_u16_arg(uint8_t* p, uint16_t value) {
+ return put_T_arg(p, value);
+}
+static inline
+uint8_t* put_u32_arg(uint8_t* p, uint32_t value) {
+ return put_T_arg(p, value);
+}
+static inline
+uint8_t* put_str_arg(uint8_t* p, const char* value) {
+ return put_T_arg(p, value);
+}
+uint8_t* put_command_header(uint8_t* p, uint8_t num_commands,
+ uint32_t command_bytes);
+uint8_t* put_command_info_header(uint8_t* p, uint16_t command_id,
+ uint32_t sequence_id, uint16_t num_args);
+
+//------------------------------------------------------------------------------
+/**
+ * Header data for CMD48/49 param
+ */
+typedef struct {
+ uint8_t id;
+ uint8_t number;
+ uint16_t _reserved1;
+ uint32_t size;
+ uint32_t _reserved2;
+} isdio_command_header_t;
+
+/**
+ * Information data for CMD48/49 param
+ */
+typedef struct {
+ uint16_t _reserved0;
+ uint16_t command;
+ uint32_t sequence_id;
+ uint16_t num_args;
+ uint16_t _reserved1;
+} isdio_command_info_header_t;
+
+/**
+ * iSDIO Response Status Register at 0x440
+ */
+typedef struct {
+ uint8_t registration;
+ uint8_t _reserved0;
+ uint16_t command_id;
+ uint32_t sequence_id;
+ uint8_t status;
+ uint8_t _reserved1[3];
+ uint32_t error_status;
+ uint32_t data_size;
+} isdio_response_status_t;
+
+/**
+ * Status Register at 0x400
+ */
+typedef struct {
+ uint8_t CWU :1; // Command Write Update
+ uint8_t CWA :1; // Command Write Abort
+ uint8_t _reserved0:6;
+ uint8_t _reserved1[31];
+ uint16_t CRU :1; // Command Response Update
+ uint16_t ESU :1; // Error Status Update
+ uint16_t MCU :1; // Media Change Update
+ uint16_t ASU :1; // Application Status Update
+ uint16_t _reserved2:12;
+ uint16_t CRU_ENA :1; // CRU Enabled
+ uint16_t ESU_ENA :1; // ESU Enabled
+ uint16_t MCU_ENA :1; // MCU Enabled
+ uint16_t ASU_ENA :1; // ASU Enabled
+ uint16_t _reserved3:12;
+ uint16_t CRE :1; // Command Response Error
+ uint16_t CWE :1; // Command Write Error
+ uint16_t RRE :1; // Response Receive Error
+ uint16_t APE :1; // Application Specific Error
+ uint16_t _reserved4:12;
+ uint16_t MEX :1; // Memory Existence
+ uint16_t FAT :1; // FAT System
+ uint16_t _reserved5:14;
+ uint8_t _reserved6[24];
+ isdio_response_status_t response[8];
+ uint8_t _reserved7[32];
+ uint8_t application_status[256];
+} isdio_status_t;
+
+
+typedef struct {
+ uint8_t ULR :1;
+ uint8_t DLU :1;
+ uint8_t CBR :1;
+ uint8_t CDR :1;
+ uint8_t _reserved0 :4;
+ uint8_t ILU :1;
+ uint8_t FLU :1;
+ uint8_t _reserved1 :6;
+ uint8_t RPO :1;
+ uint8_t RPD :1;
+ uint8_t RPC :1;
+ uint8_t CPI :1;
+ uint8_t DPI :1;
+ uint8_t CIL :1;
+ uint8_t _reserved2 :2;
+ uint8_t _reserved3;
+ uint8_t application;
+ uint8_t _reserved4;
+ uint16_t Scan :1;
+ uint16_t WPS :2;
+ uint16_t Group :1;
+ uint16_t AP_STA :1;
+ uint16_t Infra_Direct :2;
+ uint16_t Connected :1;
+ uint16_t _reserved5 :8;
+ char SSID[32];
+ uint8_t encryption_mode;
+ uint8_t signal_strength;
+ uint8_t channel;
+ uint8_t _reserved6[5];
+ uint8_t MACAddress[6];
+ uint8_t _reserved7[10];
+ uint8_t ID[16];
+ uint8_t IPAddress[4];
+ uint8_t SubnetMask[4];
+ uint8_t DefaultGateway[4];
+ uint8_t PreferredDNSServer[4];
+ uint8_t AlternateDNSServer[4];
+ uint8_t ProxyServer:1;
+ uint8_t _reserved8:7;
+} isdio_wlan_status_t;
+
+/**
+ * iSDIO Vendor Status Register at 0x5C0
+ */
+typedef struct {
+ uint32_t vendorId;
+ uint32_t vendorFunction;
+ uint32_t HttpBodyTransferSize;
+ uint32_t HttpBodyTotalSize;
+ uint32_t HttpBuffSize;
+ uint32_t LHFStatus:8;
+ uint32_t PhotoshareStatus:8;
+ uint32_t FileDownloadStatus:8;
+ uint32_t rsv0:8;
+ uint32_t FtpTransferSize;
+ uint32_t rsv1;
+ uint32_t rsv2[4];
+ uint8_t VendorFwVersion[16];
+} isdio_vender_status_t;
+
+#endif // iSDIO_helper_h
