commit 482570518b5a08e3b22383f90f43f2d73c69e004 Author: Deployment Bot (from Travis CI) Date: Wed Nov 11 01:29:23 2020 +0000 Deploy OPEnSLab-OSU/SSLClient to github.com/OPEnSLab-OSU/SSLClient.git:gh-pages diff --git a/_c_o_d_e___o_f___c_o_n_d_u_c_t_8md.html b/_c_o_d_e___o_f___c_o_n_d_u_c_t_8md.html new file mode 100644 index 0000000..9a784f5 --- /dev/null +++ b/_c_o_d_e___o_f___c_o_n_d_u_c_t_8md.html @@ -0,0 +1,124 @@ + + + + + + +SSLClient: CODE_OF_CONDUCT.md File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
CODE_OF_CONDUCT.md File Reference
+
+
+
+
+ + + + diff --git a/_c_o_n_t_r_i_b_u_t_i_n_g_8md.html b/_c_o_n_t_r_i_b_u_t_i_n_g_8md.html new file mode 100644 index 0000000..5f888cf --- /dev/null +++ b/_c_o_n_t_r_i_b_u_t_i_n_g_8md.html @@ -0,0 +1,124 @@ + + + + + + +SSLClient: CONTRIBUTING.md File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
CONTRIBUTING.md File Reference
+
+
+
+
+ + + + diff --git a/_r_e_a_d_m_e_8md.html b/_r_e_a_d_m_e_8md.html new file mode 100644 index 0000000..e4b3006 --- /dev/null +++ b/_r_e_a_d_m_e_8md.html @@ -0,0 +1,124 @@ + + + + + + +SSLClient: README.md File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
README.md File Reference
+
+
+
+
+ + + + diff --git a/_s_s_l_client_8cpp.html b/_s_s_l_client_8cpp.html new file mode 100644 index 0000000..76a095f --- /dev/null +++ b/_s_s_l_client_8cpp.html @@ -0,0 +1,125 @@ + + + + + + +SSLClient: src/SSLClient.cpp File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
SSLClient.cpp File Reference
+
+
+
#include "SSLClient.h"
+
+
+ + + + diff --git a/_s_s_l_client_8h.html b/_s_s_l_client_8h.html new file mode 100644 index 0000000..4ac5791 --- /dev/null +++ b/_s_s_l_client_8h.html @@ -0,0 +1,139 @@ + + + + + + +SSLClient: src/SSLClient.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
SSLClient.h File Reference
+
+
+
#include "Client.h"
+#include "SSLSession.h"
+#include "SSLClientParameters.h"
+#include <vector>
+
+

Go to the source code of this file.

+ + + + + +

+Classes

class  SSLClient
 The main SSLClient class. Check out README.md for more info. More...
 
+
+
+ + + + diff --git a/_s_s_l_client_8h_source.html b/_s_s_l_client_8h_source.html new file mode 100644 index 0000000..6314599 --- /dev/null +++ b/_s_s_l_client_8h_source.html @@ -0,0 +1,161 @@ + + + + + + +SSLClient: src/SSLClient.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
SSLClient.h
+
+
+Go to the documentation of this file.
1 /* Copyright 2019 OSU OPEnS Lab
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy of this
4  * software and associated documentation files (the "Software"), to deal in the Software
5  * without restriction, including without limitation the rights to use, copy, modify,
6  * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7  * permit persons to whom the Software is furnished to do so, subject to the following
8  * conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in all
11  * copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include "Client.h"
22 #include "SSLSession.h"
23 #include "SSLClientParameters.h"
24 #include <vector>
25 
26 #ifndef SSLClient_H_
27 #define SSLClient_H_
28 
34 class SSLClient : public Client {
35 public:
44  enum Error {
45  SSL_OK = 0,
58  };
59 
66  enum DebugLevel {
68  SSL_NONE = 0,
70  SSL_ERROR = 1,
72  SSL_WARN = 2,
74  SSL_INFO = 3,
76  SSL_DUMP = 4,
77  };
78 
96  explicit SSLClient( Client& client,
97  const br_x509_trust_anchor *trust_anchors,
98  const size_t trust_anchors_num,
99  const int analog_pin,
100  const size_t max_sessions = 1,
101  const DebugLevel debug = SSL_WARN);
102 
103  //========================================
104  //= Functions implemented in SSLClient.cpp
105  //========================================
106 
146  int connect(IPAddress ip, uint16_t port) override;
147 
184  int connect(const char *host, uint16_t port) override;
185 
209  size_t write(const uint8_t *buf, size_t size) override;
211  size_t write(uint8_t b) override { return write(&b, 1); }
212 
231  int available() override;
232 
254  int read(uint8_t *buf, size_t size) override;
259  int read() override { uint8_t read_val; return read(&read_val, 1) > 0 ? read_val : -1; };
260 
269  int peek() override;
270 
278  void flush() override;
279 
288  void stop() override;
289 
303  uint8_t connected() override;
304 
305  //========================================
306  //= Functions Not in the Client Interface
307  //========================================
308 
317  void setMutualAuthParams(const SSLClientParameters& params);
318 
333  SSLSession* getSession(const char* host);
334 
343  void removeSession(const char* host);
344 
350  size_t getSessionCount() const { return m_sessions.size(); }
351 
357  operator bool() { return connected() > 0; }
358 
360  Client& getClient() { return m_client; }
361 
366  void setTimeout(unsigned int t) { m_timeout = t; }
367 
372  unsigned int getTimeout() const { return m_timeout; }
373 
385  void setVerificationTime(uint32_t days, uint32_t seconds);
386 
387 private:
389  Client& get_arduino_client() { return m_client; }
390  const Client& get_arduino_client() const { return m_client; }
391 
393  bool m_soft_connected(const char* func_name);
395  int m_start_ssl(const char* host = nullptr, SSLSession* ssl_ses = nullptr);
397  int m_run_until(const unsigned target);
399  unsigned m_update_engine();
401  int m_get_session_index(const char* host) const;
402 
404  void m_print_prefix(const char* func_name, const DebugLevel level) const;
405 
407  void m_print_ssl_error(const int ssl_error, const DebugLevel level) const;
408 
410  void m_print_br_error(const unsigned br_error_code, const DebugLevel level) const;
411 
413  void m_print_br_state(const unsigned br_state, const DebugLevel level) const;
414 
416  template<typename T>
417  void m_print(const T str, const char* func_name, const DebugLevel level) const {
418  // check the current debug level and serial status
419  if (level > m_debug || !Serial) return;
420  // print prefix
421  m_print_prefix(func_name, level);
422  // print the message
423  Serial.println(str);
424  }
425 
427  template<typename T>
428  void m_info(const T str, const char* func_name) const { m_print(str, func_name, SSL_INFO); }
429 
430  template<typename T>
431  void m_warn(const T str, const char* func_name) const { m_print(str, func_name, SSL_WARN); }
432 
433  template<typename T>
434  void m_error(const T str, const char* func_name) const { m_print(str, func_name, SSL_ERROR); }
435 
436  //============================================
437  //= Data Members
438  //============================================
439  // create a reference the client
440  Client& m_client;
441  // also store an array of SSLSessions, so we can resume communication with multiple websites
442  std::vector<SSLSession> m_sessions;
443  // as well as the maximmum number of sessions we can store
444  const size_t m_max_sessions;
445  // store the pin to fetch an RNG see from
446  const int m_analog_pin;
447  // store whether to enable debug logging
448  const DebugLevel m_debug;
449  // store if we are connected in bearssl or not
450  bool m_is_connected;
451  // store the timeout for SSL internals
452  unsigned int m_timeout;
453  // store the context values required for SSL
454  br_ssl_client_context m_sslctx;
455  br_x509_minimal_context m_x509ctx;
456  // use a mono-directional buffer by default to cut memory in half
457  // can expand to a bi-directional buffer with maximum of BR_SSL_BUFSIZE_BIDI
458  // or shrink to below BR_SSL_BUFSIZE_MONO, and bearSSL will adapt automatically
459  // simply edit this value to change the buffer size to the desired value
460  // additionally, we need to correct buffer size based off of how many sessions we decide to cache
461  // since SSL takes so much memory if we don't it will cause the stack and heap to collide
469  unsigned char m_iobuf[2048];
470  // store the index of where we are writing in the buffer
471  // so we can send our records all at once to prevent
472  // weird timing issues
473  size_t m_write_idx;
474  // store the last BearSSL state so we can print changes to the console
475  unsigned m_br_last_state;
476 };
477 
478 #endif
uint8_t connected() override
Check if the device is connected.
Definition: SSLClient.cpp:223
+
Definition: SSLClient.h:76
+
Definition: SSLClient.h:57
+
This class stores values which allow SSLClient to save and resume SSL sessions.
Definition: SSLSession.h:51
+
void setTimeout(unsigned int t)
Set the timeout when waiting for an SSL response.
Definition: SSLClient.h:366
+
Definition: SSLClient.h:47
+
Definition: SSLClient.h:74
+
Definition: SSLClient.h:53
+
SSLClient(Client &client, const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const size_t max_sessions=1, const DebugLevel debug=SSL_WARN)
Initialize SSLClient with all of the prerequisites needed.
Definition: SSLClient.cpp:24
+
void flush() override
Force writing the buffered bytes from SSLClient::write to the network.
Definition: SSLClient.cpp:182
+
SSLSession * getSession(const char *host)
Gets a session reference corresponding to a host and IP, or a reference to a empty session if none ex...
Definition: SSLClient.cpp:254
+
int available() override
Returns the number of bytes available to read from the data that has been received and decrypted...
Definition: SSLClient.cpp:134
+
The main SSLClient class. Check out README.md for more info.
Definition: SSLClient.h:34
+
Definition: SSLClient.h:72
+
void stop() override
Close the connection.
Definition: SSLClient.cpp:196
+
Definition: SSLClient.h:70
+
int connect(IPAddress ip, uint16_t port) override
Connect over SSL to a host specified by an IP address.
Definition: SSLClient.cpp:52
+
size_t write(const uint8_t *buf, size_t size) override
Write some bytes to the SSL connection.
Definition: SSLClient.cpp:93
+
int read() override
Read a single byte, or -1 if none is available.
Definition: SSLClient.h:259
+
void setMutualAuthParams(const SSLClientParameters &params)
Add a client certificate and enable support for mutual auth.
Definition: SSLClient.cpp:278
+
Error
Static constants defining the possible errors encountered.
Definition: SSLClient.h:44
+
Definition: SSLClient.h:51
+
unsigned int getTimeout() const
Get the timeout when waiting for an SSL response.
Definition: SSLClient.h:372
+
DebugLevel
Level of verbosity used in logging for SSLClient.
Definition: SSLClient.h:66
+
int peek() override
View the first byte of the buffer, without removing it from the SSLClient Buffer. ...
Definition: SSLClient.cpp:170
+
void setVerificationTime(uint32_t days, uint32_t seconds)
Change the time used during x509 verification to a different value.
Definition: SSLClient.cpp:300
+ +
Definition: SSLClient.h:49
+ +
size_t write(uint8_t b) override
Definition: SSLClient.h:211
+
Client & getClient()
Returns a reference to the client object stored in this class. Take care not to break it...
Definition: SSLClient.h:360
+
void removeSession(const char *host)
Clear the session corresponding to a host and IP.
Definition: SSLClient.cpp:267
+
This class stores data required for SSLClient to use mutual authentication.
Definition: SSLClientParameters.h:52
+
Definition: SSLClient.h:68
+
size_t getSessionCount() const
Get the maximum number of SSL sessions that can be stored at once.
Definition: SSLClient.h:350
+
Definition: SSLClient.h:45
+
Definition: SSLClient.h:55
+
+
+ + + + diff --git a/_s_s_l_client_parameters_8cpp.html b/_s_s_l_client_parameters_8cpp.html new file mode 100644 index 0000000..b50ca4e --- /dev/null +++ b/_s_s_l_client_parameters_8cpp.html @@ -0,0 +1,145 @@ + + + + + + +SSLClient: src/SSLClientParameters.cpp File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
SSLClientParameters.cpp File Reference
+
+
+ + + + +

+Classes

struct  ssl_pem_decode_state
 
+ + + +

+Namespaces

 std
 
+ + + +

+Functions

void std::__attribute__ ((weak)) __throw_length_error(char const *)
 
+
+
+ + + + diff --git a/_s_s_l_client_parameters_8cpp.js b/_s_s_l_client_parameters_8cpp.js new file mode 100644 index 0000000..ff66c8f --- /dev/null +++ b/_s_s_l_client_parameters_8cpp.js @@ -0,0 +1,5 @@ +var _s_s_l_client_parameters_8cpp = +[ + [ "ssl_pem_decode_state", "structssl__pem__decode__state.html", "structssl__pem__decode__state" ], + [ "__attribute__", "_s_s_l_client_parameters_8cpp.html#a39074ff6e8f24ae9df1cabe6767f8a4d", null ] +]; \ No newline at end of file diff --git a/_s_s_l_client_parameters_8h.html b/_s_s_l_client_parameters_8h.html new file mode 100644 index 0000000..e55bf77 --- /dev/null +++ b/_s_s_l_client_parameters_8h.html @@ -0,0 +1,137 @@ + + + + + + +SSLClient: src/SSLClientParameters.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
SSLClientParameters.h File Reference
+
+
+
#include "bearssl.h"
+#include <vector>
+
+

Go to the source code of this file.

+ + + + + +

+Classes

class  SSLClientParameters
 This class stores data required for SSLClient to use mutual authentication. More...
 
+
+
+ + + + diff --git a/_s_s_l_client_parameters_8h_source.html b/_s_s_l_client_parameters_8h_source.html new file mode 100644 index 0000000..9ff8822 --- /dev/null +++ b/_s_s_l_client_parameters_8h_source.html @@ -0,0 +1,132 @@ + + + + + + +SSLClient: src/SSLClientParameters.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
SSLClientParameters.h
+
+
+Go to the documentation of this file.
1 /* Copyright 2019 OSU OPEnS Lab
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy of this
4  * software and associated documentation files (the "Software"), to deal in the Software
5  * without restriction, including without limitation the rights to use, copy, modify,
6  * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7  * permit persons to whom the Software is furnished to do so, subject to the following
8  * conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in all
11  * copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
28 #include "bearssl.h"
29 #undef min
30 #undef max
31 #include <vector>
32 
33 #ifndef SSLClientParameters_H_
34 #define SSLClientParameters_H_
35 
53 public:
84  static SSLClientParameters fromPEM(const char* cert_pem, const size_t cert_len, const char* key_pem, const size_t key_len);
85 
112  static SSLClientParameters fromDER(const char* cert_der, const size_t cert_len, const char* key_der, const size_t key_len);
113 
115  const br_x509_certificate* getCertChain() const { return &m_cert_struct; }
116 
118  int getCertType() const { return br_skey_decoder_key_type(&m_key_struct); }
119 
121  const br_ec_private_key* getECKey() const { return br_skey_decoder_get_ec(&m_key_struct); }
122 
124  const br_rsa_private_key* getRSAKey() const { return br_skey_decoder_get_rsa(&m_key_struct); }
125 
126 protected:
127  SSLClientParameters(const char* cert, const size_t cert_len, const char* key, const size_t key_len, bool is_der);
128 
129 private:
130  const std::vector<char> m_cert;
131  const br_x509_certificate m_cert_struct;
132  const br_skey_decoder_context m_key_struct;
133 };
134 
135 #endif
const br_ec_private_key * getECKey() const
Definition: SSLClientParameters.h:121
+
static SSLClientParameters fromDER(const char *cert_der, const size_t cert_len, const char *key_der, const size_t key_len)
Create mutual authentication parameters from a DER certificate and private key.
Definition: SSLClientParameters.cpp:91
+
static SSLClientParameters fromPEM(const char *cert_pem, const size_t cert_len, const char *key_pem, const size_t key_len)
Create mutual authentication parameters from a PEM certificate and private key.
Definition: SSLClientParameters.cpp:86
+
const br_x509_certificate * getCertChain() const
Definition: SSLClientParameters.h:115
+
const br_rsa_private_key * getRSAKey() const
Definition: SSLClientParameters.h:124
+
SSLClientParameters(const char *cert, const size_t cert_len, const char *key, const size_t key_len, bool is_der)
Definition: SSLClientParameters.cpp:80
+
This class stores data required for SSLClient to use mutual authentication.
Definition: SSLClientParameters.h:52
+
int getCertType() const
Definition: SSLClientParameters.h:118
+
+
+ + + + diff --git a/_s_s_l_session_8h.html b/_s_s_l_session_8h.html new file mode 100644 index 0000000..4a6a6d9 --- /dev/null +++ b/_s_s_l_session_8h.html @@ -0,0 +1,137 @@ + + + + + + +SSLClient: src/SSLSession.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
SSLSession.h File Reference
+
+
+
#include "bearssl.h"
+#include "Arduino.h"
+
+

Go to the source code of this file.

+ + + + + +

+Classes

class  SSLSession
 This class stores values which allow SSLClient to save and resume SSL sessions. More...
 
+
+
+ + + + diff --git a/_s_s_l_session_8h_source.html b/_s_s_l_session_8h_source.html new file mode 100644 index 0000000..eb99de3 --- /dev/null +++ b/_s_s_l_session_8h_source.html @@ -0,0 +1,128 @@ + + + + + + +SSLClient: src/SSLSession.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
SSLSession.h
+
+
+Go to the documentation of this file.
1 /* Copyright 2019 OSU OPEnS Lab
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy of this
4  * software and associated documentation files (the "Software"), to deal in the Software
5  * without restriction, including without limitation the rights to use, copy, modify,
6  * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7  * permit persons to whom the Software is furnished to do so, subject to the following
8  * conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in all
11  * copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
28 #include "bearssl.h"
29 #include "Arduino.h"
30 
31 #ifndef SSLSession_H_
32 #define SSLSession_H_
33 
51 class SSLSession : public br_ssl_session_parameters {
52 
53 public:
59  SSLSession(const char* hostname)
60  : m_hostname(hostname) {}
61 
70  const String& get_hostname() const { return m_hostname; }
71 
73  br_ssl_session_parameters* to_br_session() { return (br_ssl_session_parameters *)this; }
74 
75 private:
76  // aparently a hostname has a max length of 256 chars. Go figure.
77  String m_hostname;
78 };
79 
80 
81 
82 #endif /* SSLSession_H_ */
This class stores values which allow SSLClient to save and resume SSL sessions.
Definition: SSLSession.h:51
+
br_ssl_session_parameters * to_br_session()
Returns a pointer to the ::br_ssl_session_parameters component of this class.
Definition: SSLSession.h:73
+
SSLSession(const char *hostname)
SSLSession constructor.
Definition: SSLSession.h:59
+
const String & get_hostname() const
Get the hostname string associated with this session.
Definition: SSLSession.h:70
+
+
+ + + + diff --git a/_trust_anchors_8md.html b/_trust_anchors_8md.html new file mode 100644 index 0000000..885f61c --- /dev/null +++ b/_trust_anchors_8md.html @@ -0,0 +1,124 @@ + + + + + + +SSLClient: TrustAnchors.md File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
TrustAnchors.md File Reference
+
+
+
+
+ + + + diff --git a/annotated.html b/annotated.html new file mode 100644 index 0000000..6b25ad1 --- /dev/null +++ b/annotated.html @@ -0,0 +1,133 @@ + + + + + + +SSLClient: Class List + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+ + + + + +
 Cssl_pem_decode_state
 CSSLClientThe main SSLClient class. Check out README.md for more info
 CSSLClientParametersThis class stores data required for SSLClient to use mutual authentication
 CSSLSessionThis class stores values which allow SSLClient to save and resume SSL sessions
+
+
+
+ + + + diff --git a/annotated_dup.js b/annotated_dup.js new file mode 100644 index 0000000..a72472c --- /dev/null +++ b/annotated_dup.js @@ -0,0 +1,7 @@ +var annotated_dup = +[ + [ "ssl_pem_decode_state", "structssl__pem__decode__state.html", "structssl__pem__decode__state" ], + [ "SSLClient", "class_s_s_l_client.html", "class_s_s_l_client" ], + [ "SSLClientParameters", "class_s_s_l_client_parameters.html", "class_s_s_l_client_parameters" ], + [ "SSLSession", "class_s_s_l_session.html", "class_s_s_l_session" ] +]; \ No newline at end of file diff --git a/arrowdown.png b/arrowdown.png new file mode 100644 index 0000000..0b63f6d Binary files /dev/null and b/arrowdown.png differ diff --git a/arrowright.png b/arrowright.png new file mode 100644 index 0000000..c6ee22f Binary files /dev/null and b/arrowright.png differ diff --git a/bc_s.png b/bc_s.png new file mode 100644 index 0000000..224b29a Binary files /dev/null and b/bc_s.png differ diff --git a/bdwn.png b/bdwn.png new file mode 100644 index 0000000..940a0b9 Binary files /dev/null and b/bdwn.png differ diff --git a/class_s_s_l_client-members.html b/class_s_s_l_client-members.html new file mode 100644 index 0000000..51b8112 --- /dev/null +++ b/class_s_s_l_client-members.html @@ -0,0 +1,163 @@ + + + + + + +SSLClient: Member List + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
SSLClient Member List
+
+
+ +

This is the complete list of members for SSLClient, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
available() overrideSSLClient
connect(IPAddress ip, uint16_t port) overrideSSLClient
connect(const char *host, uint16_t port) overrideSSLClient
connected() overrideSSLClient
DebugLevel enum nameSSLClient
Error enum nameSSLClient
flush() overrideSSLClient
getClient()SSLClientinline
getSession(const char *host)SSLClient
getSessionCount() const SSLClientinline
getTimeout() const SSLClientinline
operator bool()SSLClientinline
peek() overrideSSLClient
read(uint8_t *buf, size_t size) overrideSSLClient
read() overrideSSLClientinline
removeSession(const char *host)SSLClient
setMutualAuthParams(const SSLClientParameters &params)SSLClient
setTimeout(unsigned int t)SSLClientinline
setVerificationTime(uint32_t days, uint32_t seconds)SSLClient
SSL_BR_CONNECT_FAIL enum valueSSLClient
SSL_BR_WRITE_ERROR enum valueSSLClient
SSL_CLIENT_CONNECT_FAIL enum valueSSLClient
SSL_CLIENT_WRTIE_ERROR enum valueSSLClient
SSL_DUMP enum valueSSLClient
SSL_ERROR enum valueSSLClient
SSL_INFO enum valueSSLClient
SSL_INTERNAL_ERROR enum valueSSLClient
SSL_NONE enum valueSSLClient
SSL_OK enum valueSSLClient
SSL_OUT_OF_MEMORY enum valueSSLClient
SSL_WARN enum valueSSLClient
SSLClient(Client &client, const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const size_t max_sessions=1, const DebugLevel debug=SSL_WARN)SSLClientexplicit
stop() overrideSSLClient
write(const uint8_t *buf, size_t size) overrideSSLClient
write(uint8_t b) overrideSSLClientinline
+
+ + + + diff --git a/class_s_s_l_client.html b/class_s_s_l_client.html new file mode 100644 index 0000000..4766f28 --- /dev/null +++ b/class_s_s_l_client.html @@ -0,0 +1,1027 @@ + + + + + + +SSLClient: SSLClient Class Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
SSLClient Class Reference
+
+
+ +

The main SSLClient class. Check out README.md for more info. + More...

+ +

#include <SSLClient.h>

+
+Inheritance diagram for SSLClient:
+
+
+ + + +
+ + + + + + + + +

+Public Types

enum  Error {
+  SSL_OK = 0, +SSL_CLIENT_CONNECT_FAIL = 2, +SSL_BR_CONNECT_FAIL = 3, +SSL_CLIENT_WRTIE_ERROR = 4, +
+  SSL_BR_WRITE_ERROR = 5, +SSL_INTERNAL_ERROR = 6, +SSL_OUT_OF_MEMORY = 7 +
+ }
 Static constants defining the possible errors encountered. More...
 
enum  DebugLevel {
+  SSL_NONE = 0, +SSL_ERROR = 1, +SSL_WARN = 2, +SSL_INFO = 3, +
+  SSL_DUMP = 4 +
+ }
 Level of verbosity used in logging for SSLClient. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 SSLClient (Client &client, const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const size_t max_sessions=1, const DebugLevel debug=SSL_WARN)
 Initialize SSLClient with all of the prerequisites needed. More...
 
int connect (IPAddress ip, uint16_t port) override
 Connect over SSL to a host specified by an IP address. More...
 
int connect (const char *host, uint16_t port) override
 Connect over SSL to a host specified by a hostname. More...
 
size_t write (const uint8_t *buf, size_t size) override
 Write some bytes to the SSL connection. More...
 
size_t write (uint8_t b) override
 
int available () override
 Returns the number of bytes available to read from the data that has been received and decrypted. More...
 
int read (uint8_t *buf, size_t size) override
 Read size bytes from the SSL client buffer, copying them into *buf, and return the number of bytes read. More...
 
int read () override
 Read a single byte, or -1 if none is available. More...
 
int peek () override
 View the first byte of the buffer, without removing it from the SSLClient Buffer. More...
 
void flush () override
 Force writing the buffered bytes from SSLClient::write to the network. More...
 
void stop () override
 Close the connection. More...
 
uint8_t connected () override
 Check if the device is connected. More...
 
void setMutualAuthParams (const SSLClientParameters &params)
 Add a client certificate and enable support for mutual auth. More...
 
SSLSessiongetSession (const char *host)
 Gets a session reference corresponding to a host and IP, or a reference to a empty session if none exist. More...
 
void removeSession (const char *host)
 Clear the session corresponding to a host and IP. More...
 
size_t getSessionCount () const
 Get the maximum number of SSL sessions that can be stored at once. More...
 
 operator bool ()
 Equivalent to SSLClient::connected() > 0. More...
 
Client & getClient ()
 Returns a reference to the client object stored in this class. Take care not to break it. More...
 
void setTimeout (unsigned int t)
 Set the timeout when waiting for an SSL response. More...
 
unsigned int getTimeout () const
 Get the timeout when waiting for an SSL response. More...
 
void setVerificationTime (uint32_t days, uint32_t seconds)
 Change the time used during x509 verification to a different value. More...
 
+

Detailed Description

+

The main SSLClient class. Check out README.md for more info.

+

Member Enumeration Documentation

+ +
+
+ + + + +
enum SSLClient::DebugLevel
+
+ +

Level of verbosity used in logging for SSLClient.

+

Use these values when initializing SSLClient to set how many logs you would like to see in the Serial monitor.

+ + + + + + +
Enumerator
SSL_NONE  +

No logging output

+
SSL_ERROR  +

Only output errors that result in connection failure

+
SSL_WARN  +

Output errors and warnings (useful when just starting to develop)

+
SSL_INFO  +

Output errors, warnings, and internal information (very verbose)

+
SSL_DUMP  +

In addition to the above logs, dumps every byte in SSLClient::write to the Serial monitor

+
+ +
+
+ +
+
+ + + + +
enum SSLClient::Error
+
+ +

Static constants defining the possible errors encountered.

+

If SSLClient encounters an error, it will generally output logs into the serial monitor. If you need a way of programmatically checking the errors, you can do so with SSLClient::getWriteError(), which will return one of these values.

+ + + + + + + + +
Enumerator
SSL_OK  +
SSL_CLIENT_CONNECT_FAIL  +

The underlying client failed to connect, probably not an issue with SSL

+
SSL_BR_CONNECT_FAIL  +

BearSSL failed to complete the SSL handshake, check logs for bear ssl error output

+
SSL_CLIENT_WRTIE_ERROR  +

The underlying client failed to write a payload, probably not an issue with SSL

+
SSL_BR_WRITE_ERROR  +

An internal error occurred with BearSSL, check logs for diagnosis.

+
SSL_INTERNAL_ERROR  +

An internal error occurred with SSLClient, and you probably need to submit an issue on Github.

+
SSL_OUT_OF_MEMORY  +

SSLClient detected that there was not enough memory (>8000 bytes) to continue.

+
+ +
+
+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SSLClient::SSLClient (Client & client,
const br_x509_trust_anchor * trust_anchors,
const size_t trust_anchors_num,
const int analog_pin,
const size_t max_sessions = 1,
const DebugLevel debug = SSL_WARN 
)
+
+explicit
+
+ +

Initialize SSLClient with all of the prerequisites needed.

+
Precondition
You will need to generate an array of trust_anchors (root certificates) based off of the domains you want to make SSL connections to. Check out the TrustAnchors.md file for more info.
+
+The analog_pin should be set to input.
+
Parameters
+ + + + + + + +
clientThe base network device to create an SSL socket on. This object will be copied and the copy will be stored in SSLClient.
trust_anchorsTrust anchors used in the verification of the SSL server certificate. Check out TrustAnchors.md for more info.
trust_anchors_numThe number of objects in the trust_anchors array.
analog_pinAn analog pin to pull random bytes from, used in seeding the RNG.
max_sessionsThe maximum number of SSL sessions to store connection information from.
debugThe level of debug logging (use the ::DebugLevel enum).
+
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
int SSLClient::available ()
+
+override
+
+ +

Returns the number of bytes available to read from the data that has been received and decrypted.

+

This function updates the state of the SSL engine (including writing any data, see SSLClient::write) and as a result should be called periodically when expecting data. Additionally, since if there are no bytes and if SSLClient::connected is false this function returns zero (this same behavior is found in EthernetClient), it is prudent to ensure in your own code that the preconditions are met before checking this function to prevent an ambiguous result.

+

The implementation for this function can be found in SSLClientImpl::available

+
Precondition
SSLClient::connected must be true. (Call SSLClient::connected before this function)
+
Returns
The number of bytes available (can be zero), or zero if any of the pre conditions aren't satisfied.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int SSLClient::connect (IPAddress ip,
uint16_t port 
)
+
+override
+
+ +

Connect over SSL to a host specified by an IP address.

+

SSLClient::connect(host, port) should be preferred over this function, as verifying the domain name is a step in ensuring the certificate is legitimate, which is important to the security of the device. Additionally, SSL sessions cannot be resumed when using this function, which can drastically increase initial connect time.

+

This function initializes the socket by calling m_client::connect(IPAddress, uint16_t) with the parameters supplied, then once the socket is open, uses BearSSL to to complete a SSL handshake. Due to the design of the SSL standard, this function will probably take an extended period (1-4sec) to negotiate the handshake and finish the connection. This function runs until the SSL handshake succeeds or fails.

+

SSL requires the client to generate some random bits (to be later combined with some random bits from the server), so SSLClient uses the least significant bits from the analog pin supplied in the constructor. The random bits are generated from 16 consecutive analogReads, and given to BearSSL before the handshake starts.

+

The implementation for this function can be found in SSLClientImpl::connect_impl(IPAddress, uint16_t).

+
Precondition
The underlying client object (passed in through the constructor) is in a non- error state, and must be able to access the IP.
+
+SSLClient can only have one connection at a time, so the client object must not already be connected.
+
+There must be sufficient memory available on the device to verify the certificate (if the free memory drops below 8000 bytes during certain points in the connection, SSLClient will fail).
+
+There must be a trust anchor given to the constructor that corresponds to the certificate provided by the IP address being connected to. For more information check out TrustAnchors.md .
+
Parameters
+ + + +
ipThe IP address to connect to
portthe port to connect to
+
+
+
Returns
1 if success, 0 if failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int SSLClient::connect (const char * host,
uint16_t port 
)
+
+override
+
+ +

Connect over SSL to a host specified by a hostname.

+

This function initializes the socket by calling m_client::connect(const char*, uint16_t) with the parameters supplied, then once the socket is open, uses BearSSL to complete a SSL handshake. This function runs until the SSL handshake succeeds or fails.

+

SSL requires the client to generate some random bits (to be later combined with some random bits from the server), so SSLClient uses the least significant bits from the analog pin supplied in the constructor. The random bits are generated from 16 consecutive analogReads, and given to BearSSL before the handshake starts.

+

This function will usually take around 4-10 seconds. If possible, this function also attempts to resume the SSL session if one is present matching the hostname string, which will reduce connection time to 100-500ms. To read more about this functionality, check out Session Caching in the README.

+

The implementation for this function can be found in SSLClientImpl::connect_impl(const char*, uint16_t)

+
Precondition
The underlying client object (passed in through the constructor) is in a non- error state, and must be able to access the IP.
+
+SSLClient can only have one connection at a time, so the client object must not already be connected.
+
+There must be sufficient memory available on the device to verify the certificate (if the free memory drops below 8000 bytes during certain points in the connection, SSLClient will fail).
+
+There must be a trust anchor given to the constructor that corresponds to the certificate provided by the IP address being connected to. For more information check out TrustAnchors.md .
+
Parameters
+ + + +
hostThe hostname as a null-terminated c-string ("www.google.com")
portThe port to connect to on the host (443 for HTTPS)
+
+
+
Returns
1 of success, 0 if failure
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
uint8_t SSLClient::connected ()
+
+override
+
+ +

Check if the device is connected.

+

Use this function to determine if SSLClient is still connected and a SSL connection is active. It should be noted that this function should be called before SSLClient::available– both functions send and receive data with the SSLClient::m_client device, however SSLClient::available has some delays built in to protect SSLClient::m_client from being polled too frequently, and SSLClient::connected contains logic to ensure that if the socket is dropped SSLClient will react accordingly.

+

The implementation for this function can be found in SSLClientImpl::connected_impl.

+
Returns
1 if connected, 0 if not
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SSLClient::flush ()
+
+override
+
+ +

Force writing the buffered bytes from SSLClient::write to the network.

+

This function is blocking until all bytes from the buffer are written. For an explanation of how writing with SSLClient works, please see SSLClient::write. The implementation for this function can be found in SSLClientImpl::flush.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
Client& SSLClient::getClient ()
+
+inline
+
+ +

Returns a reference to the client object stored in this class. Take care not to break it.

+ +
+
+ +
+
+ + + + + + + + +
SSLSession * SSLClient::getSession (const char * host)
+
+ +

Gets a session reference corresponding to a host and IP, or a reference to a empty session if none exist.

+

If no session corresponding to the host and IP exist, then this function will cycle through sessions in a rotating order. This allows the session cache to continually store sessions, however it will also result in old sessions being cleared and returned. In general, it is a good idea to use a SessionCache size equal to the number of domains you plan on connecting to.

+

The implementation for this function can be found at SSLClientImpl::get_session_impl.

+
Parameters
+ + + +
hostA hostname c string, or NULL if one is not available
addrAn IP address
+
+
+
Returns
A pointer to the SSLSession, or NULL of none matched the criteria available
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
size_t SSLClient::getSessionCount () const
+
+inline
+
+ +

Get the maximum number of SSL sessions that can be stored at once.

+
Returns
The SessionCache template parameter.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
unsigned int SSLClient::getTimeout () const
+
+inline
+
+ +

Get the timeout when waiting for an SSL response.

+
Returns
The timeout value in milliseconds.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
SSLClient::operator bool ()
+
+inline
+
+ +

Equivalent to SSLClient::connected() > 0.

+
Returns
true if connected, false if not
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SSLClient::peek ()
+
+override
+
+ +

View the first byte of the buffer, without removing it from the SSLClient Buffer.

+

The implementation for this function can be found in SSLClientImpl::peek

Precondition
SSLClient::available must be >0
+
Returns
The first byte received, or -1 if the preconditions are not satisfied (warning: do not use if your data may be -1, as the return value is ambiguous)
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int SSLClient::read (uint8_t * buf,
size_t size 
)
+
+override
+
+ +

Read size bytes from the SSL client buffer, copying them into *buf, and return the number of bytes read.

+

This function checks if bytes are ready to be read by calling SSLClient::available, and if so copies size number of bytes from the IO buffer into the buf pointer. Data read using this function will not include any SSL or socket commands, as the Client and BearSSL will capture those and process them separately.

+

If you find that you are having a lot of timeout errors, SSLClient may be experiencing a buffer overflow. Checkout README.md for more information.

+

The implementation for this function can be found in SSLClientImpl::read_impl(uint8_t*, size_t)

+
Precondition
SSLClient::available must be >0
+
Parameters
+ + + +
bufThe pointer to the buffer to put SSL application data into
sizeThe size (in bytes) to copy to the buffer
+
+
+
Returns
The number of bytes copied (<= size), or -1 if the preconditions are not satisfied.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SSLClient::read ()
+
+inlineoverride
+
+ +

Read a single byte, or -1 if none is available.

+
See also
SSLClient::read(uint8_t*, size_t)
+ +
+
+ +
+
+ + + + + + + + +
void SSLClient::removeSession (const char * host)
+
+ +

Clear the session corresponding to a host and IP.

+

The implementation for this function can be found at SSLClientImpl::remove_session_impl.

+
Parameters
+ + + +
hostA hostname c string, or nullptr if one is not available
addrAn IP address
+
+
+ +
+
+ +
+
+ + + + + + + + +
void SSLClient::setMutualAuthParams (const SSLClientParametersparams)
+
+ +

Add a client certificate and enable support for mutual auth.

+

Please ensure that the values in params are valid for the lifetime of SSLClient. You may want to make them global constants.

+
Precondition
SSLClient has not already started an SSL connection.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
void SSLClient::setTimeout (unsigned int t)
+
+inline
+
+ +

Set the timeout when waiting for an SSL response.

+
Parameters
+ + +
tThe timeout value, in milliseconds (defaults to 30 seconds if not set). Do not set to zero.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void SSLClient::setVerificationTime (uint32_t days,
uint32_t seconds 
)
+
+ +

Change the time used during x509 verification to a different value.

+

This function directly calls br_x509_minimal_set_time to change the validation time used by the minimal verification engine. You can use this function if the default value of the compile time is causing issues. See https://bearssl.org/apidoc/bearssl__x509_8h.html#a7f3558b1999ce904084d578700b1002c for more information what this function does and how to use it.

+
Parameters
+ + + +
daysDays are counted in a proleptic Gregorian calendar since January 1st, 0 AD.
secondsSeconds are counted since midnight, from 0 to 86400 (a count of 86400 is possible only if a leap second happened).
+
+
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
void SSLClient::stop ()
+
+override
+
+ +

Close the connection.

+

If the SSL session is still active, all incoming data is discarded and BearSSL will attempt to close the session gracefully (will write to the network), and then call m_client::stop. If the session is not active or an error was encountered previously, this function will simply call m_client::stop. The implementation for this function can be found in SSLClientImpl::peek.

+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
size_t SSLClient::write (const uint8_t * buf,
size_t size 
)
+
+override
+
+ +

Write some bytes to the SSL connection.

+

Assuming all preconditions are met, this function writes data to the BearSSL IO buffer, BUT does not initially send the data. Instead, you must call SSLClient::available or SSLClient::flush, which will detect that the buffer is ready for writing, and will write the data to the network. Alternatively, if this function is requested to write a larger amount of data than SSLClientImpl::m_iobuf can handle, data will be written to the network in pages the size of SSLClientImpl::m_iobuf until all the data in buf is sent–attempting to keep all writes to the network grouped together. For information on why this is the case check out README.md .

+

The implementation for this function can be found in SSLClientImpl::write_impl(const uint8_t*, size_t)

+
Precondition
The socket and SSL layer must be connected, meaning SSLClient::connected must be true.
+
+BearSSL must not be waiting for the recipt of user data (if it is, there is probably an error with how the protocol in implemented in your code).
+
Parameters
+ + + +
bufthe pointer to a buffer of bytes to copy
sizethe number of bytes to copy from the buffer
+
+
+
Returns
The number of bytes copied to the buffer (size), or zero if the BearSSL engine fails to become ready for writing data.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + +
size_t SSLClient::write (uint8_t b)
+
+inlineoverride
+
+
See also
SSLClient::write(uint8_t*, size_t)
+ +
+
+
The documentation for this class was generated from the following files: +
+
+ + + + diff --git a/class_s_s_l_client.js b/class_s_s_l_client.js new file mode 100644 index 0000000..8c0dcff --- /dev/null +++ b/class_s_s_l_client.js @@ -0,0 +1,40 @@ +var class_s_s_l_client = +[ + [ "DebugLevel", "class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1", [ + [ "SSL_NONE", "class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a24122d1e1bb724237f305a0b4a21ff75", null ], + [ "SSL_ERROR", "class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a199742ec5c99c72d9cede1fda0f125c5", null ], + [ "SSL_WARN", "class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a26f3e5f1481f3ea22ea4ab5370b0fa97", null ], + [ "SSL_INFO", "class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a8d5f7561f9cc0a2f3e5f362b02f4a5b2", null ], + [ "SSL_DUMP", "class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1ad1cf0d4d876daa655edb8331bfe2ce39", null ] + ] ], + [ "Error", "class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6cea", [ + [ "SSL_OK", "class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa18dbddc0a3d4a94ee0f298fe55a06a94", null ], + [ "SSL_CLIENT_CONNECT_FAIL", "class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa7510402478ffbecd6e1aa3811b175cfd", null ], + [ "SSL_BR_CONNECT_FAIL", "class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa6a9cc2412a53b5981e937a41523eece5", null ], + [ "SSL_CLIENT_WRTIE_ERROR", "class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaab8581e1172fbf15067d435706d3a03a8", null ], + [ "SSL_BR_WRITE_ERROR", "class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa37bef298be71b84a57e59fadbfbd9016", null ], + [ "SSL_INTERNAL_ERROR", "class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaaf66f8d5f6601f9e7607b78bf7a07fc84", null ], + [ "SSL_OUT_OF_MEMORY", "class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa0a4f8af0226cf29ede8f6fe4a9047b08", null ] + ] ], + [ "SSLClient", "class_s_s_l_client.html#a68f026a625ca1ccd1aba87bb6e670376", null ], + [ "available", "class_s_s_l_client.html#a0e775669b4a040fbd3f281dcbcd2de78", null ], + [ "connect", "class_s_s_l_client.html#ab97c0745f65a6c6009ac938b3b9912c3", null ], + [ "connect", "class_s_s_l_client.html#a248a5152cc3c3e7666bf5443bfd57c90", null ], + [ "connected", "class_s_s_l_client.html#a5488f01ccfddfd9e41f54dfbda48bcae", null ], + [ "flush", "class_s_s_l_client.html#aaf2192a6621fdf2f89cc26a9a1584f8c", null ], + [ "getClient", "class_s_s_l_client.html#a9a4e9c9877ab73cf7e82d6942cc7db21", null ], + [ "getSession", "class_s_s_l_client.html#a2bd012ef6f01df9694ba9fd0a3c227c3", null ], + [ "getSessionCount", "class_s_s_l_client.html#a51dd3097cf5a3a8bf7644517026954b5", null ], + [ "getTimeout", "class_s_s_l_client.html#a08f05da0fca82c3470be4c1da8cf80a3", null ], + [ "operator bool", "class_s_s_l_client.html#a4192ee3562c4806d4a6829356ca2636b", null ], + [ "peek", "class_s_s_l_client.html#a0c0b6f2ad25701d1e45adb613d072d86", null ], + [ "read", "class_s_s_l_client.html#a4c5420541a06213133ae308a3bca1c95", null ], + [ "read", "class_s_s_l_client.html#aef1b52f4ad9633126cb68739175920eb", null ], + [ "removeSession", "class_s_s_l_client.html#ad5d9d8a4187a3f8918bf66af83e733c4", null ], + [ "setMutualAuthParams", "class_s_s_l_client.html#aeee217b5558dfb0724f2319888a77256", null ], + [ "setTimeout", "class_s_s_l_client.html#a8da354f30537c1064d554921937a73ae", null ], + [ "setVerificationTime", "class_s_s_l_client.html#ab285c2f5a03124558ef7f74b9f3d12ad", null ], + [ "stop", "class_s_s_l_client.html#ad8ed697371748e31e01c3f697bc36cbe", null ], + [ "write", "class_s_s_l_client.html#a03c7926938acd57cfc3b982edf725a86", null ], + [ "write", "class_s_s_l_client.html#a7343a58457b4659f83b61cac1f442c3d", null ] +]; \ No newline at end of file diff --git a/class_s_s_l_client.png b/class_s_s_l_client.png new file mode 100644 index 0000000..181cd65 Binary files /dev/null and b/class_s_s_l_client.png differ diff --git a/class_s_s_l_client_parameters-members.html b/class_s_s_l_client_parameters-members.html new file mode 100644 index 0000000..3ab2a73 --- /dev/null +++ b/class_s_s_l_client_parameters-members.html @@ -0,0 +1,135 @@ + + + + + + +SSLClient: Member List + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
SSLClientParameters Member List
+
+
+ +

This is the complete list of members for SSLClientParameters, including all inherited members.

+ + + + + + + + +
fromDER(const char *cert_der, const size_t cert_len, const char *key_der, const size_t key_len)SSLClientParametersstatic
fromPEM(const char *cert_pem, const size_t cert_len, const char *key_pem, const size_t key_len)SSLClientParametersstatic
getCertChain() const SSLClientParametersinline
getCertType() const SSLClientParametersinline
getECKey() const SSLClientParametersinline
getRSAKey() const SSLClientParametersinline
SSLClientParameters(const char *cert, const size_t cert_len, const char *key, const size_t key_len, bool is_der)SSLClientParametersprotected
+
+ + + + diff --git a/class_s_s_l_client_parameters.html b/class_s_s_l_client_parameters.html new file mode 100644 index 0000000..e54f976 --- /dev/null +++ b/class_s_s_l_client_parameters.html @@ -0,0 +1,443 @@ + + + + + + +SSLClient: SSLClientParameters Class Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ + +
+ +

This class stores data required for SSLClient to use mutual authentication. + More...

+ +

#include <SSLClientParameters.h>

+ + + + + + + + + + +

+Public Member Functions

const br_x509_certificate * getCertChain () const
 
int getCertType () const
 
const br_ec_private_key * getECKey () const
 
const br_rsa_private_key * getRSAKey () const
 
+ + + + + + + +

+Static Public Member Functions

static SSLClientParameters fromPEM (const char *cert_pem, const size_t cert_len, const char *key_pem, const size_t key_len)
 Create mutual authentication parameters from a PEM certificate and private key. More...
 
static SSLClientParameters fromDER (const char *cert_der, const size_t cert_len, const char *key_der, const size_t key_len)
 Create mutual authentication parameters from a DER certificate and private key. More...
 
+ + + +

+Protected Member Functions

 SSLClientParameters (const char *cert, const size_t cert_len, const char *key, const size_t key_len, bool is_der)
 
+

Detailed Description

+

This class stores data required for SSLClient to use mutual authentication.

+

SSLClientParameters.h

+

This file contains a simple utility class to store parameters about an SSL Session for reuse later. TLS mutual authentication is a process in which both the server and client perform cryptographic operations to verify the authenticity of eachother, for more information check out this article: https://medium.com/sitewards/the-magic-of-tls-x509-and-mutual-authentication-explained-b2162dec4401 . If this struct is provided to SSLClient::SSLClient via SSLClient::setMutualAuthParams, SSLClient will automatically send a client certificate if one is requested by the server. This will happen for all SSLClient connections, and may cause issues for websites that do not need mutual authentication—as a result, please only turn on mutual authentication if you are sure it is neccesary.

+

SSLClientParameters supports both ECC and RSA client certificates. I recommend using ECC certificates if possible, as SSLClientParameters will make a copy of both the certificate and the private key in memory, and ECC keys tend to be smaller than RSA ones.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SSLClientParameters::SSLClientParameters (const char * cert,
const size_t cert_len,
const char * key,
const size_t key_len,
bool is_der 
)
+
+protected
+
+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SSLClientParameters SSLClientParameters::fromDER (const char * cert_der,
const size_t cert_len,
const char * key_der,
const size_t key_len 
)
+
+static
+
+ +

Create mutual authentication parameters from a DER certificate and private key.

+

Use this function to create a mutual tls context from a DER client certificate and DER private key. This function will copy the certificate and private key, extract the needed information from the private key, and store both that information and the copied cert into a SSLClientParameters object. Given the key parsed correctly, you can then use SSLClient::setMutualAuthParams at the begining of your sketch to enable mTLS with SSLClient. This function supports both ECC and RSA certificate/private keys (use EC keys wherever possible, as they are signifigantly smaller and faster), however SSLClient only supports the p256, p384, and p512 curves for ECC.

+

Because SSLClientParameters creates a copy of both the certificate and key, you do not need to ensure that the data pointed to by cert_der or key_der is accessible after this function (i.e. you can free them afterwards).

+

Please note that if the private key is incorrect, this function will not report an error, and instead SSLClient will fall back to regular TLS when making a connection.

+
Parameters
+ + + + + +
cert_derA DER encoded certificate, can be ECC or RSA.
cert_lenThe number of bytes in cert_der.
key_derA DER encoded private key, can be ECC or RSA.
key_lenThe number of bytes in key_ders
+
+
+
Returns
An SSLClientParameters context, to be used with SSLClient::setMutualAuthParams.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SSLClientParameters SSLClientParameters::fromPEM (const char * cert_pem,
const size_t cert_len,
const char * key_pem,
const size_t key_len 
)
+
+static
+
+ +

Create mutual authentication parameters from a PEM certificate and private key.

+

Use this function to create a mutual tls context from a PEM client certificate and PEM private key. This function will convert the PEM certificates into DER format (creating a copy in the process), extract the needed information from the private key, and store that information into a SSLClientParameters object. Given the certifiate and key parsed correctly, you can then use SSLClient::setMutualAuthParams at the begining of your sketch to enable mTLS with SSLClient. This function supports both ECC and RSA certificate/private keys (use EC keys wherever possible, as they are signifigantly smaller and faster), however SSLClient only supports the p256, p384, and p512 curves for ECC.

+

Because SSLClientParameters creates a copy of both the certificate and key, you do not need to ensure that the data pointed to by cert_pem or key_pem is accessible after this function (i.e. you can free them afterwards).

+

Please note that if the certificate or private key are incorrect, this function will not report an error, and instead SSLClient will fall back to regular TLS when making a connection.

+
Parameters
+ + + + + +
cert_pemA PEM formatted certificate, including the "BEGIN" and "END" header/footers. Can be ECC or RSA. cert_pem supports both LF and CRLF for endlines, but all other constraints on a valid PEM file apply.
cert_lenThe number of bytes in cert_pem.
key_pemA PEM formatted private key, including the "BEGIN" and "END" header/footers. Can be ECC or RSA. key_pem supports both LF and CRLF for endlines, but all other constraints \ on a valid PEM file apply.
key_lenThe number of bytes in key_pem
+
+
+
Returns
An SSLClientParameters context, to be used with SSLClient::setMutualAuthParams.
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const br_x509_certificate* SSLClientParameters::getCertChain () const
+
+inline
+
+

mTLS information used by SSLClient during authentication

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
int SSLClientParameters::getCertType () const
+
+inline
+
+

mTLS information used by SSLClient during authentication

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const br_ec_private_key* SSLClientParameters::getECKey () const
+
+inline
+
+

mTLS information used by SSLClient during authentication

+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
const br_rsa_private_key* SSLClientParameters::getRSAKey () const
+
+inline
+
+

mTLS information used by SSLClient during authentication

+ +
+
+
The documentation for this class was generated from the following files: +
+
+ + + + diff --git a/class_s_s_l_client_parameters.js b/class_s_s_l_client_parameters.js new file mode 100644 index 0000000..a9a7560 --- /dev/null +++ b/class_s_s_l_client_parameters.js @@ -0,0 +1,8 @@ +var class_s_s_l_client_parameters = +[ + [ "SSLClientParameters", "class_s_s_l_client_parameters.html#a97213b5554e90908fbf284669b5f22f3", null ], + [ "getCertChain", "class_s_s_l_client_parameters.html#ab00a35434fb94451b78b6dd502f53921", null ], + [ "getCertType", "class_s_s_l_client_parameters.html#ab48cdb94c7dedcc922b8b4fa84ca03b5", null ], + [ "getECKey", "class_s_s_l_client_parameters.html#a8d0294703c37b7f46eddc7914d6eb7c5", null ], + [ "getRSAKey", "class_s_s_l_client_parameters.html#a92e6fcaf9a4d001cb3df91f3e7b8b5e2", null ] +]; \ No newline at end of file diff --git a/class_s_s_l_session-members.html b/class_s_s_l_session-members.html new file mode 100644 index 0000000..b2a20de --- /dev/null +++ b/class_s_s_l_session-members.html @@ -0,0 +1,131 @@ + + + + + + +SSLClient: Member List + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
SSLSession Member List
+
+
+ +

This is the complete list of members for SSLSession, including all inherited members.

+ + + + +
get_hostname() const SSLSessioninline
SSLSession(const char *hostname)SSLSessioninline
to_br_session()SSLSessioninline
+
+ + + + diff --git a/class_s_s_l_session.html b/class_s_s_l_session.html new file mode 100644 index 0000000..d76d170 --- /dev/null +++ b/class_s_s_l_session.html @@ -0,0 +1,244 @@ + + + + + + +SSLClient: SSLSession Class Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
SSLSession Class Reference
+
+
+ +

This class stores values which allow SSLClient to save and resume SSL sessions. + More...

+ +

#include <SSLSession.h>

+
+Inheritance diagram for SSLSession:
+
+
+ + + +
+ + + + + + + + + + + +

+Public Member Functions

 SSLSession (const char *hostname)
 SSLSession constructor. More...
 
const String & get_hostname () const
 Get the hostname string associated with this session. More...
 
br_ssl_session_parameters * to_br_session ()
 Returns a pointer to the ::br_ssl_session_parameters component of this class. More...
 
+

Detailed Description

+

This class stores values which allow SSLClient to save and resume SSL sessions.

+

SSLSession.h

+

This file contains a simple utility class to store parameters about an SSL Session for reuse later. This class was created to extend the values stored in br_ssl_session_parameters, which allow BearSSL to resume an SSL session. When testing BearSSL's session resumption feature, it was observed that BearSSL can only resume a session that was was started with the same server. This becomes an issue when using repeated requests to a domain name which can resolve to multiple IP addresses ("api.github.com"), as the device will switch between two or three servers. Since BearSSL only stores one session at a time, this results in session resumption being few and far between.

+

To remedy this problem, an SSLSession stores the IPAddress and hostname, along with the parameters in br_ssl_session_parameters struct. Using this data, SSLClient is able to remember which IPAddress is associated with which session, allowing it to reconnect to the last IPAddress, as opposed to any associated with the domain.

+

Constructor & Destructor Documentation

+ +
+
+ + + + + +
+ + + + + + + + +
SSLSession::SSLSession (const char * hostname)
+
+inline
+
+ +

SSLSession constructor.

+

Sets all parameters to zero, and invalidates the session

+ +
+
+

Member Function Documentation

+ +
+
+ + + + + +
+ + + + + + + +
const String& SSLSession::get_hostname () const
+
+inline
+
+ +

Get the hostname string associated with this session.

+
Returns
A String object or "" if there is no hostname
+
Precondition
must check isValidSession before getting this value, as if this session in invalid this value is not guarenteed to be reset to "".
+ +
+
+ +
+
+ + + + + +
+ + + + + + + +
br_ssl_session_parameters* SSLSession::to_br_session ()
+
+inline
+
+ +

Returns a pointer to the ::br_ssl_session_parameters component of this class.

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/class_s_s_l_session.js b/class_s_s_l_session.js new file mode 100644 index 0000000..26c49ac --- /dev/null +++ b/class_s_s_l_session.js @@ -0,0 +1,6 @@ +var class_s_s_l_session = +[ + [ "SSLSession", "class_s_s_l_session.html#a0c8e01b0944c1f4b0ec6d4c423c95b74", null ], + [ "get_hostname", "class_s_s_l_session.html#a42aa22e9b6ef3a6d859cdbc21fef90e0", null ], + [ "to_br_session", "class_s_s_l_session.html#acbe6549b55d50541d09a16f770e65afc", null ] +]; \ No newline at end of file diff --git a/class_s_s_l_session.png b/class_s_s_l_session.png new file mode 100644 index 0000000..fc6de7e Binary files /dev/null and b/class_s_s_l_session.png differ diff --git a/classes.html b/classes.html new file mode 100644 index 0000000..d487ec5 --- /dev/null +++ b/classes.html @@ -0,0 +1,135 @@ + + + + + + +SSLClient: Class Index + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Class Index
+
+
+ + + + + + +
  S  
+
SSLClientParameters   
  s  
+
SSLSession   
SSLClient   ssl_pem_decode_state   
+ +
+
+ + + + diff --git a/closed.png b/closed.png new file mode 100644 index 0000000..98cc2c9 Binary files /dev/null and b/closed.png differ diff --git a/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/dir_68267d1309a1af8e8297ef4c3efbcdba.html new file mode 100644 index 0000000..58705cc --- /dev/null +++ b/dir_68267d1309a1af8e8297ef4c3efbcdba.html @@ -0,0 +1,140 @@ + + + + + + +SSLClient: src Directory Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
src Directory Reference
+
+
+ + + + + + + + + + + + + + +

+Files

file  SSLClient.cpp
 
file  SSLClient.h [code]
 
file  SSLClientParameters.cpp
 
file  SSLClientParameters.h [code]
 
file  SSLSession.h [code]
 
file  time_macros.h [code]
 
+
+
+ + + + diff --git a/dir_68267d1309a1af8e8297ef4c3efbcdba.js b/dir_68267d1309a1af8e8297ef4c3efbcdba.js new file mode 100644 index 0000000..791963d --- /dev/null +++ b/dir_68267d1309a1af8e8297ef4c3efbcdba.js @@ -0,0 +1,15 @@ +var dir_68267d1309a1af8e8297ef4c3efbcdba = +[ + [ "SSLClient.cpp", "_s_s_l_client_8cpp.html", null ], + [ "SSLClient.h", "_s_s_l_client_8h.html", [ + [ "SSLClient", "class_s_s_l_client.html", "class_s_s_l_client" ] + ] ], + [ "SSLClientParameters.cpp", "_s_s_l_client_parameters_8cpp.html", "_s_s_l_client_parameters_8cpp" ], + [ "SSLClientParameters.h", "_s_s_l_client_parameters_8h.html", [ + [ "SSLClientParameters", "class_s_s_l_client_parameters.html", "class_s_s_l_client_parameters" ] + ] ], + [ "SSLSession.h", "_s_s_l_session_8h.html", [ + [ "SSLSession", "class_s_s_l_session.html", "class_s_s_l_session" ] + ] ], + [ "time_macros.h", "time__macros_8h.html", "time__macros_8h" ] +]; \ No newline at end of file diff --git a/doc.png b/doc.png new file mode 100644 index 0000000..17edabf Binary files /dev/null and b/doc.png differ diff --git a/doxygen.css b/doxygen.css new file mode 100644 index 0000000..1425ec5 --- /dev/null +++ b/doxygen.css @@ -0,0 +1,1475 @@ +/* The standard CSS for doxygen 1.8.11 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + diff --git a/doxygen.png b/doxygen.png new file mode 100644 index 0000000..3ff17d8 Binary files /dev/null and b/doxygen.png differ diff --git a/dynsections.js b/dynsections.js new file mode 100644 index 0000000..85e1836 --- /dev/null +++ b/dynsections.js @@ -0,0 +1,97 @@ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + +SSLClient: File List + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all files with brief descriptions:
+
+
+ + + + diff --git a/files.js b/files.js new file mode 100644 index 0000000..04b0a8e --- /dev/null +++ b/files.js @@ -0,0 +1,4 @@ +var files = +[ + [ "src", "dir_68267d1309a1af8e8297ef4c3efbcdba.html", "dir_68267d1309a1af8e8297ef4c3efbcdba" ] +]; \ No newline at end of file diff --git a/folderclosed.png b/folderclosed.png new file mode 100644 index 0000000..bb8ab35 Binary files /dev/null and b/folderclosed.png differ diff --git a/folderopen.png b/folderopen.png new file mode 100644 index 0000000..d6c7f67 Binary files /dev/null and b/folderopen.png differ diff --git a/functions.html b/functions.html new file mode 100644 index 0000000..38f935d --- /dev/null +++ b/functions.html @@ -0,0 +1,336 @@ + + + + + + +SSLClient: Class Members + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- i -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- v -

+ + +

- w -

+
+
+ + + + diff --git a/functions_enum.html b/functions_enum.html new file mode 100644 index 0000000..8679055 --- /dev/null +++ b/functions_enum.html @@ -0,0 +1,138 @@ + + + + + + +SSLClient: Class Members - Enumerations + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
+ + + + diff --git a/functions_eval.html b/functions_eval.html new file mode 100644 index 0000000..1bc1215 --- /dev/null +++ b/functions_eval.html @@ -0,0 +1,168 @@ + + + + + + +SSLClient: Class Members - Enumerator + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
+ + + + diff --git a/functions_func.html b/functions_func.html new file mode 100644 index 0000000..80a32a0 --- /dev/null +++ b/functions_func.html @@ -0,0 +1,268 @@ + + + + + + +SSLClient: Class Members - Functions + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+ + +

- c -

+ + +

- f -

+ + +

- g -

+ + +

- o -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- w -

+
+
+ + + + diff --git a/functions_vars.html b/functions_vars.html new file mode 100644 index 0000000..859231d --- /dev/null +++ b/functions_vars.html @@ -0,0 +1,138 @@ + + + + + + +SSLClient: Class Members - Variables + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
+ + + + diff --git a/globals.html b/globals.html new file mode 100644 index 0000000..ec931ff --- /dev/null +++ b/globals.html @@ -0,0 +1,190 @@ + + + + + + +SSLClient: File Members + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+
+
+ + + + diff --git a/globals_defs.html b/globals_defs.html new file mode 100644 index 0000000..f86bf0f --- /dev/null +++ b/globals_defs.html @@ -0,0 +1,190 @@ + + + + + + +SSLClient: File Members + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
+ + + + diff --git a/hierarchy.html b/hierarchy.html new file mode 100644 index 0000000..b44cb46 --- /dev/null +++ b/hierarchy.html @@ -0,0 +1,135 @@ + + + + + + +SSLClient: Class Hierarchy + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+
This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 12]
+ + + + + + +
 Cbr_ssl_session_parameters
 CSSLSessionThis class stores values which allow SSLClient to save and resume SSL sessions
 CClient
 CSSLClientThe main SSLClient class. Check out README.md for more info
 Cssl_pem_decode_state
 CSSLClientParametersThis class stores data required for SSLClient to use mutual authentication
+
+
+
+ + + + diff --git a/hierarchy.js b/hierarchy.js new file mode 100644 index 0000000..20eae65 --- /dev/null +++ b/hierarchy.js @@ -0,0 +1,11 @@ +var hierarchy = +[ + [ "br_ssl_session_parameters", null, [ + [ "SSLSession", "class_s_s_l_session.html", null ] + ] ], + [ "Client", null, [ + [ "SSLClient", "class_s_s_l_client.html", null ] + ] ], + [ "ssl_pem_decode_state", "structssl__pem__decode__state.html", null ], + [ "SSLClientParameters", "class_s_s_l_client_parameters.html", null ] +]; \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..4b3a6ad --- /dev/null +++ b/index.html @@ -0,0 +1,200 @@ + + + + + + +SSLClient: SSLClient + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
+

+

SSLClient adds TLS 1.2 functionality to any network library implementing the Arduino Client interface, including the Arduino EthernetClient and WiFiClient classes. SSLClient was created to integrate TLS seamlessly with the Arduino infrastructure using BearSSL as an underlying TLS engine. Unlike ArduinoBearSSL, SSLClient is completly self-contained, and does not require any additional hardware (other than a network connection).

+

SSLClient officially supports SAMD21, SAM3X, ESP32, TIVA C, STM32, and Teensy 4.x; but it should work on any board with at least 110kb flash and 7kb RAM. SSClient does not currently support ESP8266 (see this issue) or AVR due to memory constraints on both platforms.

+

You can also view this README in doxygen.

+

Overview

+

Using SSLClient is similar to using any other Arduino-based Client class, as this library was developed around compatibility with EthernetClient. There are a few extra things, however, that you will need to get started:

+
    +
  1. Board and Network Peripheral - Your board should have a lot of resources (>110kb flash and >7kb RAM), and your network peripheral should have a large internal buffer (>7kb). This library was tested with the Adafruit Feather M0 (256K flash, 32K RAM) and the Adafruit Ethernet Featherwing (16kb Buffer), and we still had to modify the Arduino Ethernet library to support larger internal buffers per socket (see the Implementation Gotchas).
  2. +
  3. Trust Anchors - You will need a header containing array of trust anchors (example), which are used to verify the SSL connection later on. This file must generated for every project. Check out TrustAnchors.md on how to generate this file for your project, and for more information about what a trust anchor is.
  4. +
  5. Network Peripheral Driver Implementing Client - Examples include EthernetClient, WiFiClient, and so on—SSLClient will run on top of any network driver exposing the Client interface.
  6. +
  7. Analog Pin - Used for generating random data at the start of the connection (see the Implementation Gotchas).
  8. +
+

Once all those are ready, you can create an SSLClient object like this:

1 {C++}
2 BaseClientType baseClientInstance;
3 SSLClient client(baseClientInstance, TAs, (size_t)TAs_NUM, AnalogPin);

Where:

    +
  • BaseClientType - The type of baseClientInstance
  • +
  • BaseClientInstance - An instance of the class you are using for SSLClient (the class associated with the network interface, from step 3). It is important that this instance be stored outside the SSLClient declaration (for instance, SSLClient(BaseClientType() ...) wouldn't work).
  • +
  • TAs - The name of the trust anchor array created in step 2. If you generated a header using the tutorial this will probably be TAs.
  • +
  • TAs_NUM - The number of trust anchors in TAs. If you generated a header using the tutorial this will probably be TAs_NUM.
  • +
  • AnalogPin - The analog pin to pull random data from (step 4).

    +

    For example, if I am using EthernetClient, a generated array of 2 trust anchors, and the analog pin A7, I would declare an SSLClient instance using:

    1 {C++}
    2 EthernetClient baseClient;
    3 SSLClient client(baseClient, TAs, 2, A7);

    Given this client, simply use SSLClient as you would the base client class:

    1 {C++}
    2 // connect to ardiuino.cc over ssl (port 443 for websites)
    3 client.connect("www.arduino.cc", 443);
    4 // Make a HTTP request
    5 client.println("GET /asciilogo.txt HTTP/1.1");
    6 client.println("User-Agent: AdafruitFeatherM0WiFi");
    7 client.print("Host: ");
    8 client.println(server);
    9 client.println("Connection: close");
    10 client.println();
    11 client.flush();
    12 // read and print the data
    13 ...

    Note: client.connect("www.arduino.cc", 443) can take 5-15 seconds to finish on some low-power devices. This an unavoidable consequence of the SSL protocol, and is detailed more in Implementation Gotchas.

    +
  • +
+

For more information on SSLClient, check out the examples, API documentation, or the rest of this README.

+

Other Features

+

Logging

+

SSLClient also allows for changing the debugging level by adding an additional parameter to the constructor:

1 {C++}
2 EthernetClient baseClient;
3 SSLClient client(baseClient, TAs, (size_t)2, A7, 1, SSLClient::SSL_INFO);

Logging is always outputted through the Arduino Serial interface, so you'll need to setup Serial before you can view the SSL logs. Log levels are enumerated in ::DebugLevel. The log level is set to SSL_WARN by default.

+

Errors

+

When SSLClient encounters an error, it will attempt to terminate the SSL session gracefully if possible, and then close the socket. Simple error information can be found from SSLClient::getWriteError, which will return a value from the ::Error enum. For more detailed diagnostics, you can look at the serial logs, which will be displayed if the log level is at SSL_ERROR or lower.

+

Write Buffering

+

As you may have noticed in the documentation for SSLClient::write, calling this function does not actually write to the network. Instead, you must call SSLClient::available or SSLClient::flush, which will detect that the buffer is ready and write to the network (see SSLClient::write for details).

+

This was implemented as a buffered function because examples in Arduino libraries will often write to the network like so:

1 {C++}
2 EthernetClient client;
3 // ...
4 // connect to ardiuino.cc over ssl (port 443 for websites)
5 client.connect("www.arduino.cc", 443);
6 // ...
7 // write an http request to the network
8 client.write("GET /asciilogo.txt HTTP/1.1\r\n");
9 client.write("Host: arduino.cc\r\n");
10 client.write("Connection: close\r\n");
11 // wait for response
12 while (!client.available()) { /* ... */ }
13 // ...

Notice that every single write() call immediately writes to the network, which is fine with most network clients. With SSL, however, if we are encrypting and writing to the network every write() call, this will result in a lot of small encryption tasks. Encryption takes a lot of time and code, so to reduce the overhead of an SSL connection, SSLClient::write implicitly buffers until the developer states that they are waiting for data to be received with SSLClient::available. A simple example can be found below:

+
1 {C++}
2 EthernetClient baseClient;
3 SSLClient client(baseClient, TAs, (size_t)2, A7);
4 // ...
5 // connect to ardiuino.cc over ssl (port 443 for websites)
6 client.connect("www.arduino.cc", 443);
7 // ...
8 // add http request to the buffer
9 client.write("GET /asciilogo.txt HTTP/1.1\r\n");
10 client.write("Host: arduino.cc\r\n");
11 client.write("Connection: close\r\n");
12 // write the bytes to the network, then wait for response
13 while (!client.available()) { /* ... */ }
14 // ...

If you would like to trigger a network write manually without using the SSLClient::available, you can also call SSLClient::flush, which will write all data and return when finished.

+

Session Caching

+

As detailed in the resources section, SSL handshakes take an extended period (1-4sec) to negotiate. To remedy this problem, BearSSL is able to keep a SSL session cache of the clients it has connected to. If BearSSL successfully resumes an SSL session, it can reduce connection time to 100-500ms.

+

In order to use SSL session resumption:

    +
  • The website you are connecting to must support it. Support is widespread, but you can verify easily using the SSLLabs tool.
  • +
  • You must reuse the same SSLClient object (SSL Sessions are stored in the object itself).
  • +
  • You must reconnect to the exact same server.
  • +
+

SSLClient automatically stores an IP address and hostname in each session, ensuring that if you call connect("www.google.com") SSLClient will use the SSL session with that hostname. However, because some websites have multiple servers on a single IP address (github.com being an example), you may find that even if you are connecting to the same host the connection does not resume. This is a flaw in the SSL session protocol — though it has been resolved in TLS 1.3, the lack of widespread adoption of the new protocol prevents it from being used here. SSL sessions can also expire based on server criteria, which will result in a standard 4-10 second connection.

+

You can test whether or not a website can resume SSL Sessions using the Session Example included with this library. Because of all the confounding factors of SSL Sessions, it is generally prudent while programming to assume the session will always fail to resume.

+

SSL sessions take a lot of memory to store, so by default SSLClient will only store one at a time. You can change this behavior by adding the following to your SSLClient declaration:

1 {C++}
2 EthernetClient baseClient;
3 SSLClient client(baseClient, TAs, (size_t)2, A7, SomeNumber);

Where SomeNumber is the number of sessions you would like to store. For example this declaration can store 3 sessions:

1 {C++}
2 EthernetClient baseClient;
3 SSLClient client(baseClient, TAs, (size_t)2, A7, 3);

Sessions are managed internally using the SSLSession::getSession function. This function will cycle through sessions in a rotating order, allowing the session cache to continually overwrite old sessions. In general, it is a good idea to use a SessionCache size equal to the number of domains you plan on connecting to.

+

If you need to clear a session, you can do so using the SSLSession::removeSession function.

+

mTLS

+

As of v1.6.0, SSLClient supports mutual TLS authentication. mTLS is a varient of TLS that verifys both the server and device identities before a connection, and is commonly used in IoT protocols as a secure layer (MQTT over TLS, HTTPS over TLS, etc.).

+

To use mTLS with SSLClient you will need to a client certificate and client private key associated with the server you are attempting to connect to. Depending on your use case, you will either generate these yourself (ex. Mosquito MQTT setup), or have them generated for you (ex. AWS IoT Certificate Generation). Given this cryptographic information, you can modify the standard SSLClient connection sketch to enable mTLS authentication:

1 {C++}
2 ...
3 /* Somewhere above setup() */
4 
5 // The client certificate, can be PEM or DER format
6 // DER format will be an array of raw bytes, and PEM format will be a string
7 // PEM format is shown below
8 const char my_cert[] =
9 "-----BEGIN CERTIFICATE-----\n"
10 "MIIDpDCCAowCCQC7mCk5Iu3YmDANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMC\n"
11 ...
12 "-----END CERTIFICATE-----\n";
13 
14 // The client private key, must be the same format as the client certificate
15 // Both RSA and ECC are supported, ECC is shown below
16 const char my_key[] =
17 "-----BEGIN EC PRIVATE KEY-----\n"
18 ...
19 "-----END EC PRIVATE KEY-----\n";
20 
21 // This line will parse and store the above information so SSLClient can use it later
22 // Replace `fromPEM` with `fromDER` if you are using DER formatted certificates.
23 SSLClientParameters mTLS = SSLClientParameters::fromPEM(my_cert, sizeof(cert), my_key, sizeof(key));
24 SSLClient my_client(...);
25 ...
26 void setup() {
27  ...
28  /* Before SSLClient connects */
29 
30  my_client.setMutualAuthParams(mTLS);
31  ...
32 }
33 ...

The client certificate must be formatted correctly (according to BearSSL's specification) in order for mTLS to work. If the certificate is improperly formatted, SSLClient will attempt to make a regular TLS connection instead of an mTLS one, and fail to connect as a result. Because of this, if you are seeing errors similar to "peer did not send certificate chain" on your server, check that your certificate and key are formatted correctly (see https://github.com/OPEnSLab-OSU/SSLClient/issues/7#issuecomment-593704969). For more information on SSLClient's mTLS functionality, please see the SSLClientParameters documentation.

+

Note that both the above client certificate information as well as the correct trust anchors associated with the server are needed for the connection to succeed. Trust anchors will typically be generated from the CA used to generate the server certificate. More information on generating trust anchors can be found in ./TrustAnchors.md "TrustAnchors.md".

+

Implementation Gotchas

+

Some ideas that didn't quite fit in the API documentation.

+

SSLClient with Ethernet

+

If you are using the Arduino Ethernet library, you will need to modify the library to support the large buffer sizes required by SSL (detailed in resources). You can either modify the library yourself, or use this fork of the Ethernet library with the modification. To use the fork, simply install the library using the "add a .zip library" button in Arduino, and replace #include "Ethernet.h" with #include "EthernetLarge.h" in your sketch. Alternatively if for some reason this solution does not work, you can apply the modification using the instructions below.

+

Manual Modification

+

First find the location of the library in the directory where Arduino is installed (C:\Program Files (x86)\Arduino on Windows). Inside of this directory, navigate to libraries\Ethernet\src (C:\Program Files (x86)\Arduino\libraries\Ethernet\src on Windows). Modify Ethernet.h to replace these lines:

1 {C++}
2 ...
3 // Configure the maximum number of sockets to support. W5100 chips can have
4 // up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes
5 // of RAM are used for each socket. Reducing the maximum can save RAM, but
6 // you are limited to fewer simultaneous connections.
7 #if defined(RAMEND) && defined(RAMSTART) && ((RAMEND - RAMSTART) <= 2048)
8 #define MAX_SOCK_NUM 4
9 #else
10 #define MAX_SOCK_NUM 8
11 #endif
12 
13 // By default, each socket uses 2K buffers inside the Wiznet chip. If
14 // MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting
15 // this will use larger buffers within the Wiznet chip. Large buffers
16 // can really help with UDP protocols like Artnet. In theory larger
17 // buffers should allow faster TCP over high-latency links, but this
18 // does not always seem to work in practice (maybe Wiznet bugs?)
19 //#define ETHERNET_LARGE_BUFFERS
20 ...

With this:

1 {C++}
2 ...
3 // Configure the maximum number of sockets to support. W5100 chips can have
4 // up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes
5 // of RAM are used for each socket. Reducing the maximum can save RAM, but
6 // you are limited to fewer simultaneous connections.
7 #define MAX_SOCK_NUM 2
8 
9 // By default, each socket uses 2K buffers inside the Wiznet chip. If
10 // MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting
11 // this will use larger buffers within the Wiznet chip. Large buffers
12 // can really help with UDP protocols like Artnet. In theory larger
13 // buffers should allow faster TCP over high-latency links, but this
14 // does not always seem to work in practice (maybe Wiznet bugs?)
15 #define ETHERNET_LARGE_BUFFERS
16 ...

You may need to use sudo or administrator permissions to make this modification. We change MAX_SOCK_NUM and ETHERNET_LARGE_BUFFERS so the Ethernet hardware can allocate a larger space for SSLClient, however a downside of this modification is we are now only able to have two sockets concurrently. As most microprocessors barely have enough memory for one SSL connection, this limitation will rarely be encountered in practice.

+

Seeding Random Data

+

The SSL protocol requires that SSLClient generate some random bits before connecting with a server. BearSSL provides a random number generator but requires a some entropy for a seed. Normally this seed is generated by taking the microsecond time using the internal clock, however since most microcontrollers are not build with this feature another source must be found. As a simple solution, SSLClient uses a floating analog pin as an external source of random data, passed through to the constructor in the analog_pin argument. Before every connection, SSLClient will take the bottom byte from 16 analog reads on analog_pin, and combine these bytes into a 16 byte random number, which is used as a seed for BearSSL. To ensure the most random data, it is recommended that this analog pin be either floating or connected to a location not modifiable by the microcontroller (i.e. a battery voltage readout).

+

Certificate Verification

+

SSLClient uses BearSSL's minimal x509 verification engine to verify the certificate of an SSL connection. This engine requires the developer create a trust anchor array using values stored in trusted root certificates. Check out ./TrustAnchors.md "this document" for more details on this component of SSLClient.

+

BearSSL also features a known certificate validation engine, which only allows for a single domain in exchange for a significantly reduced resource usage (flash and CPU time). This functionality is planned to be implemented in the future.

+

Time

+

The minimal x509 verification engine requires an accurate source of time to properly verify the creation and expiration dates of a certificate. As most embedded devices do not have a reliable source of time, by default SSLClient opts to use the compilation timestamp (__DATE__ and __TIME__) as the "current time" during the verification process. While this approach reduces the complexity of using SSLClient, it is inherently insecure, and can cause errors if certificates are redeployed (see #27): to accommodate these edge cases, SSLClient::setVerificationTime can be used to update the timestamp before connecting, resolving the above issues.

+

Resources

+

The SSL protocol recommends a device support many different encryption algorithms, as well as protocols for SSL itself. The complexity of both of those components results in many medium sized components forming an extremely large whole. Additionally, most embedded processors lack the sophisticated math hardware commonly found in a modern CPU, and as a result require more instructions to create the encryption algorithms SSL requires. This not only increases size but makes the algorithms slow and memory intensive.

+

To illustrate this, I will run some tests on various domains below. I haven't yet, but I will.

+

If flash footprint is becoming a problem, there are numerous debugging strings (~3kb estimated) that can be removed from SSLClient.h, SSLClientImpl.h, and SSLClientImpl.cpp. I have not figured out a way to configure compilation of these strings, so you will need to modify the library to remove them yourself.

+

Read Buffer Overflow

+

SSL is a buffered protocol, and since most microcontrollers have limited resources (see Resources), SSLClient is limited in the size of its buffers. A common problem I encountered with SSL connections is buffer overflow, caused by the server sending too much data at once. This problem is caused by the microcontroller being unable to copy and decrypt data faster than it is being received, forcing some data to be discarded. This usually puts BearSSL in an unrecoverable state, forcing SSLClient to close the connection with a write error. If you are experiencing frequent timeout problems, this could be the reason why.

+

In order to remedy this problem, the device must be able to read the data faster than it is being received, or alternatively have a cache large enough to store the entire payload. Since SSL's encryption forces the device to read slowly, this means we must increase the cache size. Depending on your platform, there are a number of ways this can be done:

    +
  • Sometimes your communication shield will have an internal buffer, which can be expanded through the driver code. This is the case with the Arduino Ethernet library (in the form of the MAX_SOCK_NUM and ETHERNET_LARGE_BUFFERS macros), however the library must be modified for the change to take effect.
  • +
  • SSLClient has an internal buffer SSLClient::m_iobuf, which can be expanded. BearSSL limits the amount of data that can be processed based on the stage in the SSL handshake, and so this will change will have limited usefulness.
  • +
  • In some cases, a website will send so much data that even with the above solutions, SSLClient will be unable to keep up (a website with a lot of HTML is an example). In these cases you will have to find another method of retrieving the data you need.
  • +
  • If none of the above are viable, it is possible to implement your own Client class which has an internal buffer much larger than both the driver and BearSSL. This would require in-depth knowledge of programming and the communication shield you are working with, as well as a microcontroller with a significant amount of RAM.
  • +
+

Cipher Support

+

By default, SSLClient supports only TLS1.2 and the ciphers listed in this file under suites[], and the list is relatively small to keep the connection secure and the flash footprint down. These ciphers should work for most applications, however if for some reason you would like to use an older version of TLS or a different cipher, you can change the BearSSL profile being used by SSLClient to an alternate one with support for older protocols. To do this, edit SSLClientImpl::SSLClientImpl to change these lines:

1 {C++}
2 br_client_init_TLS12_only(&m_sslctx, &m_x509ctx, m_trust_anchors, m_trust_anchors_num);
3 // comment the above line and uncomment the line below if you're having trouble connecting over SSL
4 // br_ssl_client_init_full(&m_sslctx, &m_x509ctx, m_trust_anchors, m_trust_anchors_num);

to this:

1 {C++}
2 // br_client_init_TLS12_only(&m_sslctx, &m_x509ctx, m_trust_anchors, m_trust_anchors_num);
3 // comment the above line and uncomment the line below if you're having trouble connecting over SSL
4 br_ssl_client_init_full(&m_sslctx, &m_x509ctx, m_trust_anchors, m_trust_anchors_num);

If for some unfortunate reason you need SSL 3.0 or SSL 2.0, you will need to modify the BearSSL profile to enable support. Check out the BearSSL profiles documentation and I wish you the best of luck.

+

Security

+

Unlike BearSSL, SSLClient is not rigorously vetted to be secure. If your project has security requirements, I recommend you utilize BearSSL directly.

+

Known Issues

+
    +
  • In some drivers (Ethernet), calls to Client::flush will hang if internet is available but there is no route to the destination. Unfortunately SSLClient cannot correct for this without modifying the driver itself, and as a result the recommended solution is ensuring you choose a driver with built-in timeouts to prevent freezing. More information here.
  • +
  • When using PubSubClient on the ESP32, a stack overflow will occur if the user does not flush the buffer immediately after writing. The cause of this issue is under active investigation. More information in issue https://github.com/OPEnSLab-OSU/SSLClient/issues/9.
  • +
  • Previous to SSLClient v1.6.7, calls to SSLClient::stop would sometimes hang the device. More information in issue https://github.com/OPEnSLab-OSU/SSLClient/issues/13.
  • +
  • Previous to SSLClient v1.6.6, calls to SSLClient::connect would fail if the driver indicated that a socket was already opened (Client::connected returned true). This behavior created unintentional permanent failures when Client::stop would fail to close the socket, and as a result was downgraded to a warning in v1.6.6.
  • +
  • Previous to SSLClient v1.6.3, calling SSLClient::write with more than 2Kb of total data before flushing the write buffer would cause a buffer overflow.
  • +
+
+
+ + + + diff --git a/jquery.js b/jquery.js new file mode 100644 index 0000000..d52a1c7 --- /dev/null +++ b/jquery.js @@ -0,0 +1,68 @@ +/* + * jQuery JavaScript Library v1.7.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Nov 21 21:11:03 2011 -0500 + */ +(function(bb,L){var av=bb.document,bu=bb.navigator,bl=bb.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD)},bU=bb.jQuery,bH=bb.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
t
";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); +/* + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
","
"]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/* + * jQuery UI 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/* + * jQuery UI Widget 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/* + * jQuery UI Mouse 1.8.18 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/* + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$(' + + +
+
+
Contributor Covenant Code of Conduct
+
+
+

Our Pledge

+

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

+

Our Standards

+

Examples of behavior that contributes to creating a positive environment include:

+
    +
  • Using welcoming and inclusive language
  • +
  • Being respectful of differing viewpoints and experiences
  • +
  • Gracefully accepting constructive criticism
  • +
  • Focusing on what is best for the community
  • +
  • Showing empathy towards other community members
  • +
+

Examples of unacceptable behavior by participants include:

+
    +
  • The use of sexualized language or imagery and unwelcome sexual attention or advances
  • +
  • Trolling, insulting/derogatory comments, and personal or political attacks
  • +
  • Public or private harassment
  • +
  • Publishing others' private information, such as a physical or electronic address, without explicit permission
  • +
  • Other conduct which could reasonably be considered inappropriate in a professional setting
  • +
+

Our Responsibilities

+

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

+

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

+

Scope

+

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

+

Enforcement

+

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at open..nosp@m.sens.nosp@m.ing@o.nosp@m.rego.nosp@m.nstat.nosp@m.e.ed.nosp@m.u. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

+

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

+

Attribution

+

This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

+

For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq

+
+ + + + + diff --git a/md_CONTRIBUTING.html b/md_CONTRIBUTING.html new file mode 100644 index 0000000..7bbb036 --- /dev/null +++ b/md_CONTRIBUTING.html @@ -0,0 +1,140 @@ + + + + + + +SSLClient: Contributing + + + + + + + + + + + + + + + +
+
+
+ + + + + +
+
SSLClient +  v1.6.9 +
+
+ + + + + + +
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Contributing
+
+
+

Thank you for contributing to SSLClient! This library is a single-person effort, so help is always appreciated.

+

There is no formal style guide, however this project does attempt to provide detailed documentation through the README and Doxygen block comments which are highly encouraged. If you get stuck or have a question, please feel free to submit an issue. Below are some resources to get you started:

+
+
+ + + + diff --git a/md_TrustAnchors.html b/md_TrustAnchors.html new file mode 100644 index 0000000..f6e383a --- /dev/null +++ b/md_TrustAnchors.html @@ -0,0 +1,133 @@ + + + + + + +SSLClient: Trust Anchors + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Trust Anchors
+
+
+

Background

+

SSLClient uses BearSSL's minimal x509 verification engine to verify the certificate of an SSL connection. This engine requires the developer create a trust anchor array using values stored in trusted root certificates. In short, these trust anchor arrays allow BearSSL to verify that the server being connected to is who they say they are, and not someone malicious. You can read more about certificates and why they are important here.

+

SSLClient stores trust anchors in hardcoded constant variables, passed into SSLClient::SSLClient during setup. These constants are generally stored in their own header file as found in the BearSSL docs. This header file will look something like:

1 {C++}
2 #define TAs_NUM 1
3 
4 static const unsigned char TA_DN0[] = {
5  // lots of raw bytes here
6  // ...
7 };
8 
9 static const unsigned char TA_RSA_N0[] = {
10  // lots of raw bytes here
11  //...
12 };
13 
14 static const unsigned char TA_RSA_E0[] = {
15  // 1-3 bytes here
16 };
17 
18 static const br_x509_trust_anchor TAs[] = {
19  {
20  { (unsigned char *)TA_DN0, sizeof TA_DN0 },
21  BR_X509_TA_CA,
22  {
23  BR_KEYTYPE_RSA,
24  { .rsa = {
25  (unsigned char *)TA_RSA_N0, sizeof TA_RSA_N0,
26  (unsigned char *)TA_RSA_E0, sizeof TA_RSA_E0,
27  } }
28  }
29  },
30 };

A full example of a trust anchor header can be found in this file. Full documentation for the format of these variables can be found in the BearSSL documentation for br_x509_trust_anchor.

+

Generating Trust Anchors

+

Typically a trust anchor header file is generated using brssl, a command-line utility included in BearSSL. As it is a fairly involded process to get brssl working, SSLClient provides a number of alternative tools to make the generation process a bit easier.

+

Note: When working with certificates (particularly in complicated mTLS setups), it can easily become confusing which certificate does what. If you aren't sure what certificate to put into the Trust Anchor tool, remember that Trust Anchors only care about the verifying the server: in other words, the certificate that goes into a Trust Anchor generation tool should be the certificate used to generate the server's certificate (usually a CA). Trust Anchors will never contain any information about client certificates, which should be passed into SSLClientParams instead.

+

HTTPS

+

For HTTPS, there a couple of tools you can use. Ordered from easiest to hardest:

+

Other Connections

+

For other kinds of SSL connections, you will need to find the root certificate being used by your host. You can check out this StackExchange post for numerous methods of acquiring this certificate from a server. If these methods are not sufficient, you may need to request this certificate from your network administrator. Once you have the certificate, convert it to PEM format if needed (I use this website), and use the pycert_bearssl.py convert --no-search command to convert the certificate into a trust anchor header.

+

Using Trust Anchors

+

Once you've generated a trust anchor array, add it to your Arduino sketch using the Sketch->Add File button in the Arduino IDE, and link it to your SSLClient like so:

1 {C++}
2 #include "yourtrustanchorfile.h"
3 // ...
4 SSLClient client(SomeClient, TAs, (size_t)TAs_NUM, SomePin);
5 // ...

Where yourtrustanchorfile.h contains a generated trust anchor array names TAs, with length TAs_NUM. BearSSL will now automatically use these trust anchors when SSLClient::connect is called.

+
+
+ + + + diff --git a/namespacemembers.html b/namespacemembers.html new file mode 100644 index 0000000..6782b58 --- /dev/null +++ b/namespacemembers.html @@ -0,0 +1,130 @@ + + + + + + +SSLClient: Namespace Members + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all namespace members with links to the namespace documentation for each member:
    +
  • __attribute__() +: std +
  • +
+
+
+ + + + diff --git a/namespacemembers_func.html b/namespacemembers_func.html new file mode 100644 index 0000000..2e41fa4 --- /dev/null +++ b/namespacemembers_func.html @@ -0,0 +1,130 @@ + + + + + + +SSLClient: Namespace Members + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
    +
  • __attribute__() +: std +
  • +
+
+
+ + + + diff --git a/namespaces.html b/namespaces.html new file mode 100644 index 0000000..542f054 --- /dev/null +++ b/namespaces.html @@ -0,0 +1,128 @@ + + + + + + +SSLClient: Namespace List + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Namespace List
+
+
+
Here is a list of all namespaces with brief descriptions:
+ + +
 Nstd
+
+
+
+ + + + diff --git a/namespaces.js b/namespaces.js new file mode 100644 index 0000000..b2a2ef0 --- /dev/null +++ b/namespaces.js @@ -0,0 +1,4 @@ +var namespaces = +[ + [ "std", "namespacestd.html", null ] +]; \ No newline at end of file diff --git a/namespacestd.html b/namespacestd.html new file mode 100644 index 0000000..a5ff040 --- /dev/null +++ b/namespacestd.html @@ -0,0 +1,149 @@ + + + + + + +SSLClient: std Namespace Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
std Namespace Reference
+
+
+ + + + +

+Functions

void __attribute__ ((weak)) __throw_length_error(char const *)
 
+

Function Documentation

+ +
+
+ + + + + + + + +
void std::__attribute__ ((weak) ) const
+
+ +
+
+
+
+ + + + diff --git a/nav_f.png b/nav_f.png new file mode 100644 index 0000000..72a58a5 Binary files /dev/null and b/nav_f.png differ diff --git a/nav_g.png b/nav_g.png new file mode 100644 index 0000000..2093a23 Binary files /dev/null and b/nav_g.png differ diff --git a/nav_h.png b/nav_h.png new file mode 100644 index 0000000..33389b1 Binary files /dev/null and b/nav_h.png differ diff --git a/navtree.css b/navtree.css new file mode 100644 index 0000000..1a868b3 --- /dev/null +++ b/navtree.css @@ -0,0 +1,143 @@ +#nav-tree .children_ul { + margin:0; + padding:4px; +} + +#nav-tree ul { + list-style:none outside none; + margin:0px; + padding:0px; +} + +#nav-tree li { + white-space:nowrap; + margin:0px; + padding:0px; +} + +#nav-tree .plus { + margin:0px; +} + +#nav-tree .selected { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +#nav-tree img { + margin:0px; + padding:0px; + border:0px; + vertical-align: middle; +} + +#nav-tree a { + text-decoration:none; + padding:0px; + margin:0px; + outline:none; +} + +#nav-tree .label { + margin:0px; + padding:0px; + font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +#nav-tree .label a { + padding:2px; +} + +#nav-tree .selected a { + text-decoration:none; + color:#fff; +} + +#nav-tree .children_ul { + margin:0px; + padding:0px; +} + +#nav-tree .item { + margin:0px; + padding:0px; +} + +#nav-tree { + padding: 0px 0px; + background-color: #FAFAFF; + font-size:14px; + overflow:auto; +} + +#doc-content { + overflow:auto; + display:block; + padding:0px; + margin:0px; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#side-nav { + padding:0 6px 0 0; + margin: 0px; + display:block; + position: absolute; + left: 0px; + width: 250px; +} + +.ui-resizable .ui-resizable-handle { + display:block; +} + +.ui-resizable-e { + background:url("splitbar.png") repeat scroll right center transparent; + cursor:e-resize; + height:100%; + right:0; + top:0; + width:6px; +} + +.ui-resizable-handle { + display:none; + font-size:0.1px; + position:absolute; + z-index:1; +} + +#nav-tree-contents { + margin: 6px 0px 0px 0px; +} + +#nav-tree { + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + -webkit-overflow-scrolling : touch; /* iOS 5+ */ +} + +#nav-sync { + position:absolute; + top:5px; + right:24px; + z-index:0; +} + +#nav-sync img { + opacity:0.3; +} + +#nav-sync img:hover { + opacity:0.9; +} + +@media print +{ + #nav-tree { display: none; } + div.ui-resizable-handle { display: none; position: relative; } +} + diff --git a/navtree.js b/navtree.js new file mode 100644 index 0000000..9df45a7 --- /dev/null +++ b/navtree.js @@ -0,0 +1,523 @@ +var navTreeSubIndices = new Array(); + +function getData(varName) +{ + var i = varName.lastIndexOf('/'); + var n = i>=0 ? varName.substring(i+1) : varName; + return eval(n.replace(/\-/g,'_')); +} + +function stripPath(uri) +{ + return uri.substring(uri.lastIndexOf('/')+1); +} + +function stripPath2(uri) +{ + var i = uri.lastIndexOf('/'); + var s = uri.substring(i+1); + var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/); + return m ? uri.substring(i-6) : s; +} + +function hashValue() +{ + return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,''); +} + +function hashUrl() +{ + return '#'+hashValue(); +} + +function pathName() +{ + return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, ''); +} + +function localStorageSupported() +{ + try { + return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem; + } + catch(e) { + return false; + } +} + + +function storeLink(link) +{ + if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) { + window.localStorage.setItem('navpath',link); + } +} + +function deleteLink() +{ + if (localStorageSupported()) { + window.localStorage.setItem('navpath',''); + } +} + +function cachedLink() +{ + if (localStorageSupported()) { + return window.localStorage.getItem('navpath'); + } else { + return ''; + } +} + +function getScript(scriptName,func,show) +{ + var head = document.getElementsByTagName("head")[0]; + var script = document.createElement('script'); + script.id = scriptName; + script.type = 'text/javascript'; + script.onload = func; + script.src = scriptName+'.js'; + if ($.browser.msie && $.browser.version<=8) { + // script.onload does not work with older versions of IE + script.onreadystatechange = function() { + if (script.readyState=='complete' || script.readyState=='loaded') { + func(); if (show) showRoot(); + } + } + } + head.appendChild(script); +} + +function createIndent(o,domNode,node,level) +{ + var level=-1; + var n = node; + while (n.parentNode) { level++; n=n.parentNode; } + if (node.childrenData) { + var imgNode = document.createElement("img"); + imgNode.style.paddingLeft=(16*level).toString()+'px'; + imgNode.width = 16; + imgNode.height = 22; + imgNode.border = 0; + node.plus_img = imgNode; + node.expandToggle = document.createElement("a"); + node.expandToggle.href = "javascript:void(0)"; + node.expandToggle.onclick = function() { + if (node.expanded) { + $(node.getChildrenUL()).slideUp("fast"); + node.plus_img.src = node.relpath+"arrowright.png"; + node.expanded = false; + } else { + expandNode(o, node, false, false); + } + } + node.expandToggle.appendChild(imgNode); + domNode.appendChild(node.expandToggle); + imgNode.src = node.relpath+"arrowright.png"; + } else { + var span = document.createElement("span"); + span.style.display = 'inline-block'; + span.style.width = 16*(level+1)+'px'; + span.style.height = '22px'; + span.innerHTML = ' '; + domNode.appendChild(span); + } +} + +var animationInProgress = false; + +function gotoAnchor(anchor,aname,updateLocation) +{ + var pos, docContent = $('#doc-content'); + var ancParent = $(anchor.parent()); + if (ancParent.hasClass('memItemLeft') || + ancParent.hasClass('fieldname') || + ancParent.hasClass('fieldtype') || + ancParent.is(':header')) + { + pos = ancParent.position().top; + } else if (anchor.position()) { + pos = anchor.position().top; + } + if (pos) { + var dist = Math.abs(Math.min( + pos-docContent.offset().top, + docContent[0].scrollHeight- + docContent.height()-docContent.scrollTop())); + animationInProgress=true; + docContent.animate({ + scrollTop: pos + docContent.scrollTop() - docContent.offset().top + },Math.max(50,Math.min(500,dist)),function(){ + if (updateLocation) window.location.href=aname; + animationInProgress=false; + }); + } +} + +function newNode(o, po, text, link, childrenData, lastNode) +{ + var node = new Object(); + node.children = Array(); + node.childrenData = childrenData; + node.depth = po.depth + 1; + node.relpath = po.relpath; + node.isLast = lastNode; + + node.li = document.createElement("li"); + po.getChildrenUL().appendChild(node.li); + node.parentNode = po; + + node.itemDiv = document.createElement("div"); + node.itemDiv.className = "item"; + + node.labelSpan = document.createElement("span"); + node.labelSpan.className = "label"; + + createIndent(o,node.itemDiv,node,0); + node.itemDiv.appendChild(node.labelSpan); + node.li.appendChild(node.itemDiv); + + var a = document.createElement("a"); + node.labelSpan.appendChild(a); + node.label = document.createTextNode(text); + node.expanded = false; + a.appendChild(node.label); + if (link) { + var url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + link = url; + } else { + url = node.relpath+link; + } + a.className = stripPath(link.replace('#',':')); + if (link.indexOf('#')!=-1) { + var aname = '#'+link.split('#')[1]; + var srcPage = stripPath(pathName()); + var targetPage = stripPath(link.split('#')[0]); + a.href = srcPage!=targetPage ? url : "javascript:void(0)"; + a.onclick = function(){ + storeLink(link); + if (!$(a).parent().parent().hasClass('selected')) + { + $('.item').removeClass('selected'); + $('.item').removeAttr('id'); + $(a).parent().parent().addClass('selected'); + $(a).parent().parent().attr('id','selected'); + } + var anchor = $(aname); + gotoAnchor(anchor,aname,true); + }; + } else { + a.href = url; + a.onclick = function() { storeLink(link); } + } + } else { + if (childrenData != null) + { + a.className = "nolink"; + a.href = "javascript:void(0)"; + a.onclick = node.expandToggle.onclick; + } + } + + node.childrenUL = null; + node.getChildrenUL = function() { + if (!node.childrenUL) { + node.childrenUL = document.createElement("ul"); + node.childrenUL.className = "children_ul"; + node.childrenUL.style.display = "none"; + node.li.appendChild(node.childrenUL); + } + return node.childrenUL; + }; + + return node; +} + +function showRoot() +{ + var headerHeight = $("#top").height(); + var footerHeight = $("#nav-path").height(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + (function (){ // retry until we can scroll to the selected item + try { + var navtree=$('#nav-tree'); + navtree.scrollTo('#selected',0,{offset:-windowHeight/2}); + } catch (err) { + setTimeout(arguments.callee, 0); + } + })(); +} + +function expandNode(o, node, imm, showRoot) +{ + if (node.childrenData && !node.expanded) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + expandNode(o, node, imm, showRoot); + }, showRoot); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } if (imm || ($.browser.msie && $.browser.version>8)) { + // somehow slideDown jumps to the start of tree for IE9 :-( + $(node.getChildrenUL()).show(); + } else { + $(node.getChildrenUL()).slideDown("fast"); + } + if (node.isLast) { + node.plus_img.src = node.relpath+"arrowdown.png"; + } else { + node.plus_img.src = node.relpath+"arrowdown.png"; + } + node.expanded = true; + } + } +} + +function glowEffect(n,duration) +{ + n.addClass('glow').delay(duration).queue(function(next){ + $(this).removeClass('glow');next(); + }); +} + +function highlightAnchor() +{ + var aname = hashUrl(); + var anchor = $(aname); + if (anchor.parent().attr('class')=='memItemLeft'){ + var rows = $('.memberdecls tr[class$="'+hashValue()+'"]'); + glowEffect(rows.children(),300); // member without details + } else if (anchor.parent().attr('class')=='fieldname'){ + glowEffect(anchor.parent().parent(),1000); // enum value + } else if (anchor.parent().attr('class')=='fieldtype'){ + glowEffect(anchor.parent().parent(),1000); // struct field + } else if (anchor.parent().is(":header")) { + glowEffect(anchor.parent(),1000); // section header + } else { + glowEffect(anchor.next(),1000); // normal member + } + gotoAnchor(anchor,aname,false); +} + +function selectAndHighlight(hash,n) +{ + var a; + if (hash) { + var link=stripPath(pathName())+':'+hash.substring(1); + a=$('.item a[class$="'+link+'"]'); + } + if (a && a.length) { + a.parent().parent().addClass('selected'); + a.parent().parent().attr('id','selected'); + highlightAnchor(); + } else if (n) { + $(n.itemDiv).addClass('selected'); + $(n.itemDiv).attr('id','selected'); + } + if ($('#nav-tree-contents .item:first').hasClass('selected')) { + $('#nav-sync').css('top','30px'); + } else { + $('#nav-sync').css('top','5px'); + } + showRoot(); +} + +function showNode(o, node, index, hash) +{ + if (node && node.childrenData) { + if (typeof(node.childrenData)==='string') { + var varName = node.childrenData; + getScript(node.relpath+varName,function(){ + node.childrenData = getData(varName); + showNode(o,node,index,hash); + },true); + } else { + if (!node.childrenVisited) { + getNode(o, node); + } + $(node.getChildrenUL()).css({'display':'block'}); + node.plus_img.src = node.relpath+"arrowdown.png"; + node.expanded = true; + var n = node.children[o.breadcrumbs[index]]; + if (index+11) hash = '#'+parts[1].replace(/[^\w\-]/g,''); + else hash=''; + } + if (hash.match(/^#l\d+$/)) { + var anchor=$('a[name='+hash.substring(1)+']'); + glowEffect(anchor.parent(),1000); // line number + hash=''; // strip line number anchors + } + var url=root+hash; + var i=-1; + while (NAVTREEINDEX[i+1]<=url) i++; + if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath) + } else { + getScript(relpath+'navtreeindex'+i,function(){ + navTreeSubIndices[i] = eval('NAVTREEINDEX'+i); + if (navTreeSubIndices[i]) { + gotoNode(o,i,root,hash,relpath); + } + },true); + } +} + +function showSyncOff(n,relpath) +{ + n.html(''); +} + +function showSyncOn(n,relpath) +{ + n.html(''); +} + +function toggleSyncButton(relpath) +{ + var navSync = $('#nav-sync'); + if (navSync.hasClass('sync')) { + navSync.removeClass('sync'); + showSyncOff(navSync,relpath); + storeLink(stripPath2(pathName())+hashUrl()); + } else { + navSync.addClass('sync'); + showSyncOn(navSync,relpath); + deleteLink(); + } +} + +function initNavTree(toroot,relpath) +{ + var o = new Object(); + o.toroot = toroot; + o.node = new Object(); + o.node.li = document.getElementById("nav-tree-contents"); + o.node.childrenData = NAVTREE; + o.node.children = new Array(); + o.node.childrenUL = document.createElement("ul"); + o.node.getChildrenUL = function() { return o.node.childrenUL; }; + o.node.li.appendChild(o.node.childrenUL); + o.node.depth = 0; + o.node.relpath = relpath; + o.node.expanded = false; + o.node.isLast = true; + o.node.plus_img = document.createElement("img"); + o.node.plus_img.src = relpath+"arrowright.png"; + o.node.plus_img.width = 16; + o.node.plus_img.height = 22; + + if (localStorageSupported()) { + var navSync = $('#nav-sync'); + if (cachedLink()) { + showSyncOff(navSync,relpath); + navSync.removeClass('sync'); + } else { + showSyncOn(navSync,relpath); + } + navSync.click(function(){ toggleSyncButton(relpath); }); + } + + $(window).load(function(){ + navTo(o,toroot,hashUrl(),relpath); + showRoot(); + }); + + $(window).bind('hashchange', function(){ + if (window.location.hash && window.location.hash.length>1){ + var a; + if ($(location).attr('hash')){ + var clslink=stripPath(pathName())+':'+hashValue(); + a=$('.item a[class$="'+clslink.replace(/ + + + + + +SSLClient: Related Pages + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Related Pages
+
+
+
Here is a list of all related documentation pages:
+
+
+ + + + diff --git a/resize.js b/resize.js new file mode 100644 index 0000000..2b86c36 --- /dev/null +++ b/resize.js @@ -0,0 +1,97 @@ +var cookie_namespace = 'doxygen'; +var sidenav,navtree,content,header; + +function readCookie(cookie) +{ + var myCookie = cookie_namespace+"_"+cookie+"="; + if (document.cookie) + { + var index = document.cookie.indexOf(myCookie); + if (index != -1) + { + var valStart = index + myCookie.length; + var valEnd = document.cookie.indexOf(";", valStart); + if (valEnd == -1) + { + valEnd = document.cookie.length; + } + var val = document.cookie.substring(valStart, valEnd); + return val; + } + } + return 0; +} + +function writeCookie(cookie, val, expiration) +{ + if (val==undefined) return; + if (expiration == null) + { + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week + expiration = date.toGMTString(); + } + document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; expires=" + expiration+"; path=/"; +} + +function resizeWidth() +{ + var windowWidth = $(window).width() + "px"; + var sidenavWidth = $(sidenav).outerWidth(); + content.css({marginLeft:parseInt(sidenavWidth)+"px"}); + writeCookie('width',sidenavWidth, null); +} + +function restoreWidth(navWidth) +{ + var windowWidth = $(window).width() + "px"; + content.css({marginLeft:parseInt(navWidth)+6+"px"}); + sidenav.css({width:navWidth + "px"}); +} + +function resizeHeight() +{ + var headerHeight = header.outerHeight(); + var footerHeight = footer.outerHeight(); + var windowHeight = $(window).height() - headerHeight - footerHeight; + content.css({height:windowHeight + "px"}); + navtree.css({height:windowHeight + "px"}); + sidenav.css({height:windowHeight + "px"}); +} + +function initResizable() +{ + header = $("#top"); + sidenav = $("#side-nav"); + content = $("#doc-content"); + navtree = $("#nav-tree"); + footer = $("#nav-path"); + $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } }); + $(window).resize(function() { resizeHeight(); }); + var width = readCookie('width'); + if (width) { restoreWidth(width); } else { resizeWidth(); } + resizeHeight(); + var url = location.href; + var i=url.indexOf("#"); + if (i>=0) window.location.hash=url.substr(i); + var _preventDefault = function(evt) { evt.preventDefault(); }; + $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault); + $(document).bind('touchmove',function(e){ + var device = navigator.userAgent.toLowerCase(); + var ios = device.match(/(iphone|ipod|ipad)/); + if (ios) { + try { + var target = e.target; + while (target) { + if ($(target).css('-webkit-overflow-scrolling')=='touch') return; + target = target.parentNode; + } + e.preventDefault(); + } catch(err) { + e.preventDefault(); + } + } + }); +} + + diff --git a/search/all_0.html b/search/all_0.html new file mode 100644 index 0000000..d54e0bd --- /dev/null +++ b/search/all_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_0.js b/search/all_0.js new file mode 100644 index 0000000..98a0b4b --- /dev/null +++ b/search/all_0.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['_5f_5fattribute_5f_5f',['__attribute__',['../namespacestd.html#a39074ff6e8f24ae9df1cabe6767f8a4d',1,'std']]], + ['_5f_5ftime_5fdays_5f_5f',['__TIME_DAYS__',['../time__macros_8h.html#a7f2cdee2eebbccd45c179a50a0bbabcf',1,'time_macros.h']]], + ['_5f_5ftime_5fhours_5f_5f',['__TIME_HOURS__',['../time__macros_8h.html#a2488d1ddab7e5fa119da3421462231c4',1,'time_macros.h']]], + ['_5f_5ftime_5fminutes_5f_5f',['__TIME_MINUTES__',['../time__macros_8h.html#ab3592442029a102b388fafeadc4a6ab8',1,'time_macros.h']]], + ['_5f_5ftime_5fmonth_5f_5f',['__TIME_MONTH__',['../time__macros_8h.html#ac8f6b75d9e04634818984ba400d0dee1',1,'time_macros.h']]], + ['_5f_5ftime_5fseconds_5f_5f',['__TIME_SECONDS__',['../time__macros_8h.html#a38ac93dd8bfe385ff915a82c92bbfc97',1,'time_macros.h']]], + ['_5f_5ftime_5fyears_5f_5f',['__TIME_YEARS__',['../time__macros_8h.html#a56482fcc86a55713dee595c2092ed376',1,'time_macros.h']]], + ['_5funix_5ftimestamp',['_UNIX_TIMESTAMP',['../time__macros_8h.html#a868143e0521daf07b25a2f3947cf54a3',1,'time_macros.h']]], + ['_5funix_5ftimestamp_5ffday',['_UNIX_TIMESTAMP_FDAY',['../time__macros_8h.html#ab6c76862964ff7e543fd9d5807b2fa79',1,'time_macros.h']]], + ['_5funix_5ftimestamp_5fyday',['_UNIX_TIMESTAMP_YDAY',['../time__macros_8h.html#a5ab60a7e3e1b6e0a919b3a37bc0d4b97',1,'time_macros.h']]] +]; diff --git a/search/all_1.html b/search/all_1.html new file mode 100644 index 0000000..8cc6a1d --- /dev/null +++ b/search/all_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_1.js b/search/all_1.js new file mode 100644 index 0000000..0728bc1 --- /dev/null +++ b/search/all_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['available',['available',['../class_s_s_l_client.html#a0e775669b4a040fbd3f281dcbcd2de78',1,'SSLClient']]] +]; diff --git a/search/all_2.html b/search/all_2.html new file mode 100644 index 0000000..d15ac65 --- /dev/null +++ b/search/all_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_2.js b/search/all_2.js new file mode 100644 index 0000000..156f7c5 --- /dev/null +++ b/search/all_2.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['code_5fof_5fconduct_2emd',['CODE_OF_CONDUCT.md',['../_c_o_d_e___o_f___c_o_n_d_u_c_t_8md.html',1,'']]], + ['connect',['connect',['../class_s_s_l_client.html#ab97c0745f65a6c6009ac938b3b9912c3',1,'SSLClient::connect(IPAddress ip, uint16_t port) override'],['../class_s_s_l_client.html#a248a5152cc3c3e7666bf5443bfd57c90',1,'SSLClient::connect(const char *host, uint16_t port) override']]], + ['connected',['connected',['../class_s_s_l_client.html#a5488f01ccfddfd9e41f54dfbda48bcae',1,'SSLClient']]], + ['contributing_2emd',['CONTRIBUTING.md',['../_c_o_n_t_r_i_b_u_t_i_n_g_8md.html',1,'']]], + ['conv_5fstr2dec_5f1',['CONV_STR2DEC_1',['../time__macros_8h.html#ae0574ced3f997b97d357c1cb68000e3a',1,'time_macros.h']]], + ['conv_5fstr2dec_5f2',['CONV_STR2DEC_2',['../time__macros_8h.html#ae90924c33a05839b3eb1426472f40eb3',1,'time_macros.h']]], + ['conv_5fstr2dec_5f3',['CONV_STR2DEC_3',['../time__macros_8h.html#aad01b5fb233c0091aff2a837a8de32f4',1,'time_macros.h']]], + ['conv_5fstr2dec_5f4',['CONV_STR2DEC_4',['../time__macros_8h.html#a9da779a8ca64782ea49babce14122d34',1,'time_macros.h']]], + ['contributor_20covenant_20code_20of_20conduct',['Contributor Covenant Code of Conduct',['../md_CODE_OF_CONDUCT.html',1,'']]], + ['contributing',['Contributing',['../md_CONTRIBUTING.html',1,'']]] +]; diff --git a/search/all_3.html b/search/all_3.html new file mode 100644 index 0000000..9f526c6 --- /dev/null +++ b/search/all_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_3.js b/search/all_3.js new file mode 100644 index 0000000..1630eb3 --- /dev/null +++ b/search/all_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['debuglevel',['DebugLevel',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1',1,'SSLClient']]] +]; diff --git a/search/all_4.html b/search/all_4.html new file mode 100644 index 0000000..7b814aa --- /dev/null +++ b/search/all_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_4.js b/search/all_4.js new file mode 100644 index 0000000..2f4b1da --- /dev/null +++ b/search/all_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['error',['Error',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6cea',1,'SSLClient']]] +]; diff --git a/search/all_5.html b/search/all_5.html new file mode 100644 index 0000000..d8de556 --- /dev/null +++ b/search/all_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_5.js b/search/all_5.js new file mode 100644 index 0000000..af098e6 --- /dev/null +++ b/search/all_5.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['flush',['flush',['../class_s_s_l_client.html#aaf2192a6621fdf2f89cc26a9a1584f8c',1,'SSLClient']]], + ['fromder',['fromDER',['../class_s_s_l_client_parameters.html#a12e44f4b8340ef7f1dcbbed7649e4bef',1,'SSLClientParameters']]], + ['frompem',['fromPEM',['../class_s_s_l_client_parameters.html#ac5ddf993f7d560581297471593051ea6',1,'SSLClientParameters']]] +]; diff --git a/search/all_6.html b/search/all_6.html new file mode 100644 index 0000000..9ba0cc2 --- /dev/null +++ b/search/all_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_6.js b/search/all_6.js new file mode 100644 index 0000000..63b1e4a --- /dev/null +++ b/search/all_6.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['get_5fhostname',['get_hostname',['../class_s_s_l_session.html#a42aa22e9b6ef3a6d859cdbc21fef90e0',1,'SSLSession']]], + ['get_5fmonth',['GET_MONTH',['../time__macros_8h.html#a4dbe4cf7c879a2cdac386ce72c5e5994',1,'time_macros.h']]], + ['getcertchain',['getCertChain',['../class_s_s_l_client_parameters.html#ab00a35434fb94451b78b6dd502f53921',1,'SSLClientParameters']]], + ['getcerttype',['getCertType',['../class_s_s_l_client_parameters.html#ab48cdb94c7dedcc922b8b4fa84ca03b5',1,'SSLClientParameters']]], + ['getclient',['getClient',['../class_s_s_l_client.html#a9a4e9c9877ab73cf7e82d6942cc7db21',1,'SSLClient']]], + ['geteckey',['getECKey',['../class_s_s_l_client_parameters.html#a8d0294703c37b7f46eddc7914d6eb7c5',1,'SSLClientParameters']]], + ['getrsakey',['getRSAKey',['../class_s_s_l_client_parameters.html#a92e6fcaf9a4d001cb3df91f3e7b8b5e2',1,'SSLClientParameters']]], + ['getsession',['getSession',['../class_s_s_l_client.html#a2bd012ef6f01df9694ba9fd0a3c227c3',1,'SSLClient']]], + ['getsessioncount',['getSessionCount',['../class_s_s_l_client.html#a51dd3097cf5a3a8bf7644517026954b5',1,'SSLClient']]], + ['gettimeout',['getTimeout',['../class_s_s_l_client.html#a08f05da0fca82c3470be4c1da8cf80a3',1,'SSLClient']]] +]; diff --git a/search/all_7.html b/search/all_7.html new file mode 100644 index 0000000..9384ec9 --- /dev/null +++ b/search/all_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_7.js b/search/all_7.js new file mode 100644 index 0000000..2d07945 --- /dev/null +++ b/search/all_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['index',['index',['../structssl__pem__decode__state.html#a8abbaad636bfcf50ef38f529e3cfd5f3',1,'ssl_pem_decode_state']]] +]; diff --git a/search/all_8.html b/search/all_8.html new file mode 100644 index 0000000..37566c5 --- /dev/null +++ b/search/all_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_8.js b/search/all_8.js new file mode 100644 index 0000000..0aecf24 --- /dev/null +++ b/search/all_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['operator_20bool',['operator bool',['../class_s_s_l_client.html#a4192ee3562c4806d4a6829356ca2636b',1,'SSLClient']]] +]; diff --git a/search/all_9.html b/search/all_9.html new file mode 100644 index 0000000..c8c5102 --- /dev/null +++ b/search/all_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_9.js b/search/all_9.js new file mode 100644 index 0000000..95f21a7 --- /dev/null +++ b/search/all_9.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['peek',['peek',['../class_s_s_l_client.html#a0c0b6f2ad25701d1e45adb613d072d86',1,'SSLClient']]], + ['pst_5foffset',['PST_OFFSET',['../time__macros_8h.html#a243cf438274412bbecf4b8d5eeb02ccb',1,'time_macros.h']]] +]; diff --git a/search/all_a.html b/search/all_a.html new file mode 100644 index 0000000..4cb31f0 --- /dev/null +++ b/search/all_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_a.js b/search/all_a.js new file mode 100644 index 0000000..3e07012 --- /dev/null +++ b/search/all_a.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['read',['read',['../class_s_s_l_client.html#a4c5420541a06213133ae308a3bca1c95',1,'SSLClient::read(uint8_t *buf, size_t size) override'],['../class_s_s_l_client.html#aef1b52f4ad9633126cb68739175920eb',1,'SSLClient::read() override']]], + ['readme_2emd',['README.md',['../_r_e_a_d_m_e_8md.html',1,'']]], + ['removesession',['removeSession',['../class_s_s_l_client.html#ad5d9d8a4187a3f8918bf66af83e733c4',1,'SSLClient']]] +]; diff --git a/search/all_b.html b/search/all_b.html new file mode 100644 index 0000000..d34a612 --- /dev/null +++ b/search/all_b.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_b.js b/search/all_b.js new file mode 100644 index 0000000..5c21ba8 --- /dev/null +++ b/search/all_b.js @@ -0,0 +1,34 @@ +var searchData= +[ + ['sslclient',['SSLClient',['../index.html',1,'']]], + ['sec_5fper_5fday',['SEC_PER_DAY',['../time__macros_8h.html#a3aaee30ddedb3f6675aac341a66e39e2',1,'time_macros.h']]], + ['sec_5fper_5fhour',['SEC_PER_HOUR',['../time__macros_8h.html#a2d540510d5860d7f190d13124956bc57',1,'time_macros.h']]], + ['sec_5fper_5fmin',['SEC_PER_MIN',['../time__macros_8h.html#ac47b302f1b8d2a7a9c035c417247be76',1,'time_macros.h']]], + ['sec_5fper_5fyear',['SEC_PER_YEAR',['../time__macros_8h.html#a8cd8e04105fec7cd442d078c303e46b9',1,'time_macros.h']]], + ['setmutualauthparams',['setMutualAuthParams',['../class_s_s_l_client.html#aeee217b5558dfb0724f2319888a77256',1,'SSLClient']]], + ['settimeout',['setTimeout',['../class_s_s_l_client.html#a8da354f30537c1064d554921937a73ae',1,'SSLClient']]], + ['setverificationtime',['setVerificationTime',['../class_s_s_l_client.html#ab285c2f5a03124558ef7f74b9f3d12ad',1,'SSLClient']]], + ['ssl_5fbr_5fconnect_5ffail',['SSL_BR_CONNECT_FAIL',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa6a9cc2412a53b5981e937a41523eece5',1,'SSLClient']]], + ['ssl_5fbr_5fwrite_5ferror',['SSL_BR_WRITE_ERROR',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa37bef298be71b84a57e59fadbfbd9016',1,'SSLClient']]], + ['ssl_5fclient_5fconnect_5ffail',['SSL_CLIENT_CONNECT_FAIL',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa7510402478ffbecd6e1aa3811b175cfd',1,'SSLClient']]], + ['ssl_5fclient_5fwrtie_5ferror',['SSL_CLIENT_WRTIE_ERROR',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaab8581e1172fbf15067d435706d3a03a8',1,'SSLClient']]], + ['ssl_5fdump',['SSL_DUMP',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1ad1cf0d4d876daa655edb8331bfe2ce39',1,'SSLClient']]], + ['ssl_5ferror',['SSL_ERROR',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a199742ec5c99c72d9cede1fda0f125c5',1,'SSLClient']]], + ['ssl_5finfo',['SSL_INFO',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a8d5f7561f9cc0a2f3e5f362b02f4a5b2',1,'SSLClient']]], + ['ssl_5finternal_5ferror',['SSL_INTERNAL_ERROR',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaaf66f8d5f6601f9e7607b78bf7a07fc84',1,'SSLClient']]], + ['ssl_5fnone',['SSL_NONE',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a24122d1e1bb724237f305a0b4a21ff75',1,'SSLClient']]], + ['ssl_5fok',['SSL_OK',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa18dbddc0a3d4a94ee0f298fe55a06a94',1,'SSLClient']]], + ['ssl_5fout_5fof_5fmemory',['SSL_OUT_OF_MEMORY',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa0a4f8af0226cf29ede8f6fe4a9047b08',1,'SSLClient']]], + ['ssl_5fpem_5fdecode_5fstate',['ssl_pem_decode_state',['../structssl__pem__decode__state.html',1,'']]], + ['ssl_5fwarn',['SSL_WARN',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a26f3e5f1481f3ea22ea4ab5370b0fa97',1,'SSLClient']]], + ['sslclient',['SSLClient',['../class_s_s_l_client.html',1,'SSLClient'],['../class_s_s_l_client.html#a68f026a625ca1ccd1aba87bb6e670376',1,'SSLClient::SSLClient()']]], + ['sslclient_2ecpp',['SSLClient.cpp',['../_s_s_l_client_8cpp.html',1,'']]], + ['sslclient_2eh',['SSLClient.h',['../_s_s_l_client_8h.html',1,'']]], + ['sslclientparameters',['SSLClientParameters',['../class_s_s_l_client_parameters.html',1,'SSLClientParameters'],['../class_s_s_l_client_parameters.html#a97213b5554e90908fbf284669b5f22f3',1,'SSLClientParameters::SSLClientParameters()']]], + ['sslclientparameters_2ecpp',['SSLClientParameters.cpp',['../_s_s_l_client_parameters_8cpp.html',1,'']]], + ['sslclientparameters_2eh',['SSLClientParameters.h',['../_s_s_l_client_parameters_8h.html',1,'']]], + ['sslsession',['SSLSession',['../class_s_s_l_session.html',1,'SSLSession'],['../class_s_s_l_session.html#a0c8e01b0944c1f4b0ec6d4c423c95b74',1,'SSLSession::SSLSession()']]], + ['sslsession_2eh',['SSLSession.h',['../_s_s_l_session_8h.html',1,'']]], + ['std',['std',['../namespacestd.html',1,'']]], + ['stop',['stop',['../class_s_s_l_client.html#ad8ed697371748e31e01c3f697bc36cbe',1,'SSLClient']]] +]; diff --git a/search/all_c.html b/search/all_c.html new file mode 100644 index 0000000..c1ae2ca --- /dev/null +++ b/search/all_c.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_c.js b/search/all_c.js new file mode 100644 index 0000000..e203d5d --- /dev/null +++ b/search/all_c.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['trust_20anchors',['Trust Anchors',['../md_TrustAnchors.html',1,'']]], + ['time_5fmacros_2eh',['time_macros.h',['../time__macros_8h.html',1,'']]], + ['to_5fbr_5fsession',['to_br_session',['../class_s_s_l_session.html#acbe6549b55d50541d09a16f770e65afc',1,'SSLSession']]], + ['trustanchors_2emd',['TrustAnchors.md',['../_trust_anchors_8md.html',1,'']]] +]; diff --git a/search/all_d.html b/search/all_d.html new file mode 100644 index 0000000..712223c --- /dev/null +++ b/search/all_d.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_d.js b/search/all_d.js new file mode 100644 index 0000000..a658122 --- /dev/null +++ b/search/all_d.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['unix_5ftimestamp',['UNIX_TIMESTAMP',['../time__macros_8h.html#a04e76e262f0920441e5f0c5552e83487',1,'time_macros.h']]], + ['unix_5ftimestamp_5futc',['UNIX_TIMESTAMP_UTC',['../time__macros_8h.html#a2af3d1d741ae2b49627adf56bbc95dc3',1,'time_macros.h']]] +]; diff --git a/search/all_e.html b/search/all_e.html new file mode 100644 index 0000000..d553ffa --- /dev/null +++ b/search/all_e.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_e.js b/search/all_e.js new file mode 100644 index 0000000..5a20807 --- /dev/null +++ b/search/all_e.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['vect',['vect',['../structssl__pem__decode__state.html#aa004af7ee6bfb65161dc47558e3a2ac2',1,'ssl_pem_decode_state']]] +]; diff --git a/search/all_f.html b/search/all_f.html new file mode 100644 index 0000000..c77391a --- /dev/null +++ b/search/all_f.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/all_f.js b/search/all_f.js new file mode 100644 index 0000000..451bfc6 --- /dev/null +++ b/search/all_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['write',['write',['../class_s_s_l_client.html#a03c7926938acd57cfc3b982edf725a86',1,'SSLClient::write(const uint8_t *buf, size_t size) override'],['../class_s_s_l_client.html#a7343a58457b4659f83b61cac1f442c3d',1,'SSLClient::write(uint8_t b) override']]] +]; diff --git a/search/classes_0.html b/search/classes_0.html new file mode 100644 index 0000000..025587a --- /dev/null +++ b/search/classes_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/classes_0.js b/search/classes_0.js new file mode 100644 index 0000000..30a6271 --- /dev/null +++ b/search/classes_0.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['ssl_5fpem_5fdecode_5fstate',['ssl_pem_decode_state',['../structssl__pem__decode__state.html',1,'']]], + ['sslclient',['SSLClient',['../class_s_s_l_client.html',1,'']]], + ['sslclientparameters',['SSLClientParameters',['../class_s_s_l_client_parameters.html',1,'']]], + ['sslsession',['SSLSession',['../class_s_s_l_session.html',1,'']]] +]; diff --git a/search/close.png b/search/close.png new file mode 100644 index 0000000..9342d3d Binary files /dev/null and b/search/close.png differ diff --git a/search/defines_0.html b/search/defines_0.html new file mode 100644 index 0000000..17cfaa2 --- /dev/null +++ b/search/defines_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/defines_0.js b/search/defines_0.js new file mode 100644 index 0000000..7708a75 --- /dev/null +++ b/search/defines_0.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['_5f_5ftime_5fdays_5f_5f',['__TIME_DAYS__',['../time__macros_8h.html#a7f2cdee2eebbccd45c179a50a0bbabcf',1,'time_macros.h']]], + ['_5f_5ftime_5fhours_5f_5f',['__TIME_HOURS__',['../time__macros_8h.html#a2488d1ddab7e5fa119da3421462231c4',1,'time_macros.h']]], + ['_5f_5ftime_5fminutes_5f_5f',['__TIME_MINUTES__',['../time__macros_8h.html#ab3592442029a102b388fafeadc4a6ab8',1,'time_macros.h']]], + ['_5f_5ftime_5fmonth_5f_5f',['__TIME_MONTH__',['../time__macros_8h.html#ac8f6b75d9e04634818984ba400d0dee1',1,'time_macros.h']]], + ['_5f_5ftime_5fseconds_5f_5f',['__TIME_SECONDS__',['../time__macros_8h.html#a38ac93dd8bfe385ff915a82c92bbfc97',1,'time_macros.h']]], + ['_5f_5ftime_5fyears_5f_5f',['__TIME_YEARS__',['../time__macros_8h.html#a56482fcc86a55713dee595c2092ed376',1,'time_macros.h']]], + ['_5funix_5ftimestamp',['_UNIX_TIMESTAMP',['../time__macros_8h.html#a868143e0521daf07b25a2f3947cf54a3',1,'time_macros.h']]], + ['_5funix_5ftimestamp_5ffday',['_UNIX_TIMESTAMP_FDAY',['../time__macros_8h.html#ab6c76862964ff7e543fd9d5807b2fa79',1,'time_macros.h']]], + ['_5funix_5ftimestamp_5fyday',['_UNIX_TIMESTAMP_YDAY',['../time__macros_8h.html#a5ab60a7e3e1b6e0a919b3a37bc0d4b97',1,'time_macros.h']]] +]; diff --git a/search/defines_1.html b/search/defines_1.html new file mode 100644 index 0000000..5c0025e --- /dev/null +++ b/search/defines_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/defines_1.js b/search/defines_1.js new file mode 100644 index 0000000..d96070b --- /dev/null +++ b/search/defines_1.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['conv_5fstr2dec_5f1',['CONV_STR2DEC_1',['../time__macros_8h.html#ae0574ced3f997b97d357c1cb68000e3a',1,'time_macros.h']]], + ['conv_5fstr2dec_5f2',['CONV_STR2DEC_2',['../time__macros_8h.html#ae90924c33a05839b3eb1426472f40eb3',1,'time_macros.h']]], + ['conv_5fstr2dec_5f3',['CONV_STR2DEC_3',['../time__macros_8h.html#aad01b5fb233c0091aff2a837a8de32f4',1,'time_macros.h']]], + ['conv_5fstr2dec_5f4',['CONV_STR2DEC_4',['../time__macros_8h.html#a9da779a8ca64782ea49babce14122d34',1,'time_macros.h']]] +]; diff --git a/search/defines_2.html b/search/defines_2.html new file mode 100644 index 0000000..a206bfc --- /dev/null +++ b/search/defines_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/defines_2.js b/search/defines_2.js new file mode 100644 index 0000000..3b6b52c --- /dev/null +++ b/search/defines_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['get_5fmonth',['GET_MONTH',['../time__macros_8h.html#a4dbe4cf7c879a2cdac386ce72c5e5994',1,'time_macros.h']]] +]; diff --git a/search/defines_3.html b/search/defines_3.html new file mode 100644 index 0000000..3826e1f --- /dev/null +++ b/search/defines_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/defines_3.js b/search/defines_3.js new file mode 100644 index 0000000..437b39a --- /dev/null +++ b/search/defines_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['pst_5foffset',['PST_OFFSET',['../time__macros_8h.html#a243cf438274412bbecf4b8d5eeb02ccb',1,'time_macros.h']]] +]; diff --git a/search/defines_4.html b/search/defines_4.html new file mode 100644 index 0000000..c6864f7 --- /dev/null +++ b/search/defines_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/defines_4.js b/search/defines_4.js new file mode 100644 index 0000000..1c7ae85 --- /dev/null +++ b/search/defines_4.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['sec_5fper_5fday',['SEC_PER_DAY',['../time__macros_8h.html#a3aaee30ddedb3f6675aac341a66e39e2',1,'time_macros.h']]], + ['sec_5fper_5fhour',['SEC_PER_HOUR',['../time__macros_8h.html#a2d540510d5860d7f190d13124956bc57',1,'time_macros.h']]], + ['sec_5fper_5fmin',['SEC_PER_MIN',['../time__macros_8h.html#ac47b302f1b8d2a7a9c035c417247be76',1,'time_macros.h']]], + ['sec_5fper_5fyear',['SEC_PER_YEAR',['../time__macros_8h.html#a8cd8e04105fec7cd442d078c303e46b9',1,'time_macros.h']]] +]; diff --git a/search/defines_5.html b/search/defines_5.html new file mode 100644 index 0000000..eff6551 --- /dev/null +++ b/search/defines_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/defines_5.js b/search/defines_5.js new file mode 100644 index 0000000..a658122 --- /dev/null +++ b/search/defines_5.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['unix_5ftimestamp',['UNIX_TIMESTAMP',['../time__macros_8h.html#a04e76e262f0920441e5f0c5552e83487',1,'time_macros.h']]], + ['unix_5ftimestamp_5futc',['UNIX_TIMESTAMP_UTC',['../time__macros_8h.html#a2af3d1d741ae2b49627adf56bbc95dc3',1,'time_macros.h']]] +]; diff --git a/search/enums_0.html b/search/enums_0.html new file mode 100644 index 0000000..aba8d79 --- /dev/null +++ b/search/enums_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/enums_0.js b/search/enums_0.js new file mode 100644 index 0000000..1630eb3 --- /dev/null +++ b/search/enums_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['debuglevel',['DebugLevel',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1',1,'SSLClient']]] +]; diff --git a/search/enums_1.html b/search/enums_1.html new file mode 100644 index 0000000..a8d3843 --- /dev/null +++ b/search/enums_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/enums_1.js b/search/enums_1.js new file mode 100644 index 0000000..2f4b1da --- /dev/null +++ b/search/enums_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['error',['Error',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6cea',1,'SSLClient']]] +]; diff --git a/search/enumvalues_0.html b/search/enumvalues_0.html new file mode 100644 index 0000000..83192d3 --- /dev/null +++ b/search/enumvalues_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/enumvalues_0.js b/search/enumvalues_0.js new file mode 100644 index 0000000..c128b29 --- /dev/null +++ b/search/enumvalues_0.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['ssl_5fbr_5fconnect_5ffail',['SSL_BR_CONNECT_FAIL',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa6a9cc2412a53b5981e937a41523eece5',1,'SSLClient']]], + ['ssl_5fbr_5fwrite_5ferror',['SSL_BR_WRITE_ERROR',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa37bef298be71b84a57e59fadbfbd9016',1,'SSLClient']]], + ['ssl_5fclient_5fconnect_5ffail',['SSL_CLIENT_CONNECT_FAIL',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa7510402478ffbecd6e1aa3811b175cfd',1,'SSLClient']]], + ['ssl_5fclient_5fwrtie_5ferror',['SSL_CLIENT_WRTIE_ERROR',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaab8581e1172fbf15067d435706d3a03a8',1,'SSLClient']]], + ['ssl_5fdump',['SSL_DUMP',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1ad1cf0d4d876daa655edb8331bfe2ce39',1,'SSLClient']]], + ['ssl_5ferror',['SSL_ERROR',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a199742ec5c99c72d9cede1fda0f125c5',1,'SSLClient']]], + ['ssl_5finfo',['SSL_INFO',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a8d5f7561f9cc0a2f3e5f362b02f4a5b2',1,'SSLClient']]], + ['ssl_5finternal_5ferror',['SSL_INTERNAL_ERROR',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaaf66f8d5f6601f9e7607b78bf7a07fc84',1,'SSLClient']]], + ['ssl_5fnone',['SSL_NONE',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a24122d1e1bb724237f305a0b4a21ff75',1,'SSLClient']]], + ['ssl_5fok',['SSL_OK',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa18dbddc0a3d4a94ee0f298fe55a06a94',1,'SSLClient']]], + ['ssl_5fout_5fof_5fmemory',['SSL_OUT_OF_MEMORY',['../class_s_s_l_client.html#a48239f60f1b4318cc112706fc40c6ceaa0a4f8af0226cf29ede8f6fe4a9047b08',1,'SSLClient']]], + ['ssl_5fwarn',['SSL_WARN',['../class_s_s_l_client.html#af632625f8d247f3885c81e1f05043ad1a26f3e5f1481f3ea22ea4ab5370b0fa97',1,'SSLClient']]] +]; diff --git a/search/files_0.html b/search/files_0.html new file mode 100644 index 0000000..0b637cf --- /dev/null +++ b/search/files_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_0.js b/search/files_0.js new file mode 100644 index 0000000..3f94f60 --- /dev/null +++ b/search/files_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['code_5fof_5fconduct_2emd',['CODE_OF_CONDUCT.md',['../_c_o_d_e___o_f___c_o_n_d_u_c_t_8md.html',1,'']]], + ['contributing_2emd',['CONTRIBUTING.md',['../_c_o_n_t_r_i_b_u_t_i_n_g_8md.html',1,'']]] +]; diff --git a/search/files_1.html b/search/files_1.html new file mode 100644 index 0000000..1094e74 --- /dev/null +++ b/search/files_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_1.js b/search/files_1.js new file mode 100644 index 0000000..66a27ec --- /dev/null +++ b/search/files_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['readme_2emd',['README.md',['../_r_e_a_d_m_e_8md.html',1,'']]] +]; diff --git a/search/files_2.html b/search/files_2.html new file mode 100644 index 0000000..a08dbd3 --- /dev/null +++ b/search/files_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_2.js b/search/files_2.js new file mode 100644 index 0000000..2f119fd --- /dev/null +++ b/search/files_2.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['sslclient_2ecpp',['SSLClient.cpp',['../_s_s_l_client_8cpp.html',1,'']]], + ['sslclient_2eh',['SSLClient.h',['../_s_s_l_client_8h.html',1,'']]], + ['sslclientparameters_2ecpp',['SSLClientParameters.cpp',['../_s_s_l_client_parameters_8cpp.html',1,'']]], + ['sslclientparameters_2eh',['SSLClientParameters.h',['../_s_s_l_client_parameters_8h.html',1,'']]], + ['sslsession_2eh',['SSLSession.h',['../_s_s_l_session_8h.html',1,'']]] +]; diff --git a/search/files_3.html b/search/files_3.html new file mode 100644 index 0000000..647fc8d --- /dev/null +++ b/search/files_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/files_3.js b/search/files_3.js new file mode 100644 index 0000000..a77b038 --- /dev/null +++ b/search/files_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['time_5fmacros_2eh',['time_macros.h',['../time__macros_8h.html',1,'']]], + ['trustanchors_2emd',['TrustAnchors.md',['../_trust_anchors_8md.html',1,'']]] +]; diff --git a/search/functions_0.html b/search/functions_0.html new file mode 100644 index 0000000..6bc52b6 --- /dev/null +++ b/search/functions_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_0.js b/search/functions_0.js new file mode 100644 index 0000000..ab50b3a --- /dev/null +++ b/search/functions_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['_5f_5fattribute_5f_5f',['__attribute__',['../namespacestd.html#a39074ff6e8f24ae9df1cabe6767f8a4d',1,'std']]] +]; diff --git a/search/functions_1.html b/search/functions_1.html new file mode 100644 index 0000000..648831f --- /dev/null +++ b/search/functions_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_1.js b/search/functions_1.js new file mode 100644 index 0000000..0728bc1 --- /dev/null +++ b/search/functions_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['available',['available',['../class_s_s_l_client.html#a0e775669b4a040fbd3f281dcbcd2de78',1,'SSLClient']]] +]; diff --git a/search/functions_2.html b/search/functions_2.html new file mode 100644 index 0000000..c93d089 --- /dev/null +++ b/search/functions_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_2.js b/search/functions_2.js new file mode 100644 index 0000000..171bc1c --- /dev/null +++ b/search/functions_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['connect',['connect',['../class_s_s_l_client.html#ab97c0745f65a6c6009ac938b3b9912c3',1,'SSLClient::connect(IPAddress ip, uint16_t port) override'],['../class_s_s_l_client.html#a248a5152cc3c3e7666bf5443bfd57c90',1,'SSLClient::connect(const char *host, uint16_t port) override']]], + ['connected',['connected',['../class_s_s_l_client.html#a5488f01ccfddfd9e41f54dfbda48bcae',1,'SSLClient']]] +]; diff --git a/search/functions_3.html b/search/functions_3.html new file mode 100644 index 0000000..caa48ea --- /dev/null +++ b/search/functions_3.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_3.js b/search/functions_3.js new file mode 100644 index 0000000..af098e6 --- /dev/null +++ b/search/functions_3.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['flush',['flush',['../class_s_s_l_client.html#aaf2192a6621fdf2f89cc26a9a1584f8c',1,'SSLClient']]], + ['fromder',['fromDER',['../class_s_s_l_client_parameters.html#a12e44f4b8340ef7f1dcbbed7649e4bef',1,'SSLClientParameters']]], + ['frompem',['fromPEM',['../class_s_s_l_client_parameters.html#ac5ddf993f7d560581297471593051ea6',1,'SSLClientParameters']]] +]; diff --git a/search/functions_4.html b/search/functions_4.html new file mode 100644 index 0000000..a9c64ad --- /dev/null +++ b/search/functions_4.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_4.js b/search/functions_4.js new file mode 100644 index 0000000..84443e3 --- /dev/null +++ b/search/functions_4.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['get_5fhostname',['get_hostname',['../class_s_s_l_session.html#a42aa22e9b6ef3a6d859cdbc21fef90e0',1,'SSLSession']]], + ['getcertchain',['getCertChain',['../class_s_s_l_client_parameters.html#ab00a35434fb94451b78b6dd502f53921',1,'SSLClientParameters']]], + ['getcerttype',['getCertType',['../class_s_s_l_client_parameters.html#ab48cdb94c7dedcc922b8b4fa84ca03b5',1,'SSLClientParameters']]], + ['getclient',['getClient',['../class_s_s_l_client.html#a9a4e9c9877ab73cf7e82d6942cc7db21',1,'SSLClient']]], + ['geteckey',['getECKey',['../class_s_s_l_client_parameters.html#a8d0294703c37b7f46eddc7914d6eb7c5',1,'SSLClientParameters']]], + ['getrsakey',['getRSAKey',['../class_s_s_l_client_parameters.html#a92e6fcaf9a4d001cb3df91f3e7b8b5e2',1,'SSLClientParameters']]], + ['getsession',['getSession',['../class_s_s_l_client.html#a2bd012ef6f01df9694ba9fd0a3c227c3',1,'SSLClient']]], + ['getsessioncount',['getSessionCount',['../class_s_s_l_client.html#a51dd3097cf5a3a8bf7644517026954b5',1,'SSLClient']]], + ['gettimeout',['getTimeout',['../class_s_s_l_client.html#a08f05da0fca82c3470be4c1da8cf80a3',1,'SSLClient']]] +]; diff --git a/search/functions_5.html b/search/functions_5.html new file mode 100644 index 0000000..9d135fa --- /dev/null +++ b/search/functions_5.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_5.js b/search/functions_5.js new file mode 100644 index 0000000..0aecf24 --- /dev/null +++ b/search/functions_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['operator_20bool',['operator bool',['../class_s_s_l_client.html#a4192ee3562c4806d4a6829356ca2636b',1,'SSLClient']]] +]; diff --git a/search/functions_6.html b/search/functions_6.html new file mode 100644 index 0000000..5fca897 --- /dev/null +++ b/search/functions_6.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_6.js b/search/functions_6.js new file mode 100644 index 0000000..53b8b47 --- /dev/null +++ b/search/functions_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['peek',['peek',['../class_s_s_l_client.html#a0c0b6f2ad25701d1e45adb613d072d86',1,'SSLClient']]] +]; diff --git a/search/functions_7.html b/search/functions_7.html new file mode 100644 index 0000000..02631a3 --- /dev/null +++ b/search/functions_7.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_7.js b/search/functions_7.js new file mode 100644 index 0000000..c66bc46 --- /dev/null +++ b/search/functions_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['read',['read',['../class_s_s_l_client.html#a4c5420541a06213133ae308a3bca1c95',1,'SSLClient::read(uint8_t *buf, size_t size) override'],['../class_s_s_l_client.html#aef1b52f4ad9633126cb68739175920eb',1,'SSLClient::read() override']]], + ['removesession',['removeSession',['../class_s_s_l_client.html#ad5d9d8a4187a3f8918bf66af83e733c4',1,'SSLClient']]] +]; diff --git a/search/functions_8.html b/search/functions_8.html new file mode 100644 index 0000000..ff37095 --- /dev/null +++ b/search/functions_8.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_8.js b/search/functions_8.js new file mode 100644 index 0000000..2ae87ae --- /dev/null +++ b/search/functions_8.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['setmutualauthparams',['setMutualAuthParams',['../class_s_s_l_client.html#aeee217b5558dfb0724f2319888a77256',1,'SSLClient']]], + ['settimeout',['setTimeout',['../class_s_s_l_client.html#a8da354f30537c1064d554921937a73ae',1,'SSLClient']]], + ['setverificationtime',['setVerificationTime',['../class_s_s_l_client.html#ab285c2f5a03124558ef7f74b9f3d12ad',1,'SSLClient']]], + ['sslclient',['SSLClient',['../class_s_s_l_client.html#a68f026a625ca1ccd1aba87bb6e670376',1,'SSLClient']]], + ['sslclientparameters',['SSLClientParameters',['../class_s_s_l_client_parameters.html#a97213b5554e90908fbf284669b5f22f3',1,'SSLClientParameters']]], + ['sslsession',['SSLSession',['../class_s_s_l_session.html#a0c8e01b0944c1f4b0ec6d4c423c95b74',1,'SSLSession']]], + ['stop',['stop',['../class_s_s_l_client.html#ad8ed697371748e31e01c3f697bc36cbe',1,'SSLClient']]] +]; diff --git a/search/functions_9.html b/search/functions_9.html new file mode 100644 index 0000000..1d34583 --- /dev/null +++ b/search/functions_9.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_9.js b/search/functions_9.js new file mode 100644 index 0000000..96d95c1 --- /dev/null +++ b/search/functions_9.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['to_5fbr_5fsession',['to_br_session',['../class_s_s_l_session.html#acbe6549b55d50541d09a16f770e65afc',1,'SSLSession']]] +]; diff --git a/search/functions_a.html b/search/functions_a.html new file mode 100644 index 0000000..8eb5e56 --- /dev/null +++ b/search/functions_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/functions_a.js b/search/functions_a.js new file mode 100644 index 0000000..451bfc6 --- /dev/null +++ b/search/functions_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['write',['write',['../class_s_s_l_client.html#a03c7926938acd57cfc3b982edf725a86',1,'SSLClient::write(const uint8_t *buf, size_t size) override'],['../class_s_s_l_client.html#a7343a58457b4659f83b61cac1f442c3d',1,'SSLClient::write(uint8_t b) override']]] +]; diff --git a/search/mag_sel.png b/search/mag_sel.png new file mode 100644 index 0000000..81f6040 Binary files /dev/null and b/search/mag_sel.png differ diff --git a/search/namespaces_0.html b/search/namespaces_0.html new file mode 100644 index 0000000..f1b59ec --- /dev/null +++ b/search/namespaces_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/namespaces_0.js b/search/namespaces_0.js new file mode 100644 index 0000000..5ab0907 --- /dev/null +++ b/search/namespaces_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['std',['std',['../namespacestd.html',1,'']]] +]; diff --git a/search/nomatches.html b/search/nomatches.html new file mode 100644 index 0000000..b1ded27 --- /dev/null +++ b/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
+
No Matches
+
+ + diff --git a/search/pages_0.html b/search/pages_0.html new file mode 100644 index 0000000..0db7267 --- /dev/null +++ b/search/pages_0.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_0.js b/search/pages_0.js new file mode 100644 index 0000000..a297609 --- /dev/null +++ b/search/pages_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['contributor_20covenant_20code_20of_20conduct',['Contributor Covenant Code of Conduct',['../md_CODE_OF_CONDUCT.html',1,'']]], + ['contributing',['Contributing',['../md_CONTRIBUTING.html',1,'']]] +]; diff --git a/search/pages_1.html b/search/pages_1.html new file mode 100644 index 0000000..2c67a8e --- /dev/null +++ b/search/pages_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_1.js b/search/pages_1.js new file mode 100644 index 0000000..11688e5 --- /dev/null +++ b/search/pages_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['sslclient',['SSLClient',['../index.html',1,'']]] +]; diff --git a/search/pages_2.html b/search/pages_2.html new file mode 100644 index 0000000..9cb4325 --- /dev/null +++ b/search/pages_2.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/pages_2.js b/search/pages_2.js new file mode 100644 index 0000000..d49c30a --- /dev/null +++ b/search/pages_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['trust_20anchors',['Trust Anchors',['../md_TrustAnchors.html',1,'']]] +]; diff --git a/search/search.css b/search/search.css new file mode 100644 index 0000000..4d7612f --- /dev/null +++ b/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + position: absolute; + float: none; + display: inline; + margin-top: 8px; + right: 0px; + width: 170px; + z-index: 102; + background-color: white; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:111px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:0px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/search/search.js b/search/search.js new file mode 100644 index 0000000..dedce3b --- /dev/null +++ b/search/search.js @@ -0,0 +1,791 @@ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/variables_0.js b/search/variables_0.js new file mode 100644 index 0000000..2d07945 --- /dev/null +++ b/search/variables_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['index',['index',['../structssl__pem__decode__state.html#a8abbaad636bfcf50ef38f529e3cfd5f3',1,'ssl_pem_decode_state']]] +]; diff --git a/search/variables_1.html b/search/variables_1.html new file mode 100644 index 0000000..3c65cf2 --- /dev/null +++ b/search/variables_1.html @@ -0,0 +1,26 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/search/variables_1.js b/search/variables_1.js new file mode 100644 index 0000000..5a20807 --- /dev/null +++ b/search/variables_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['vect',['vect',['../structssl__pem__decode__state.html#aa004af7ee6bfb65161dc47558e3a2ac2',1,'ssl_pem_decode_state']]] +]; diff --git a/splitbar.png b/splitbar.png new file mode 100644 index 0000000..fe895f2 Binary files /dev/null and b/splitbar.png differ diff --git a/structssl__pem__decode__state-members.html b/structssl__pem__decode__state-members.html new file mode 100644 index 0000000..4cd3f32 --- /dev/null +++ b/structssl__pem__decode__state-members.html @@ -0,0 +1,130 @@ + + + + + + +SSLClient: Member List + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
ssl_pem_decode_state Member List
+
+
+ +

This is the complete list of members for ssl_pem_decode_state, including all inherited members.

+ + + +
indexssl_pem_decode_state
vectssl_pem_decode_state
+
+ + + + diff --git a/structssl__pem__decode__state.html b/structssl__pem__decode__state.html new file mode 100644 index 0000000..14796f4 --- /dev/null +++ b/structssl__pem__decode__state.html @@ -0,0 +1,165 @@ + + + + + + +SSLClient: ssl_pem_decode_state Struct Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
ssl_pem_decode_state Struct Reference
+
+
+ + + + + + +

+Public Attributes

std::vector< char > * vect
 
size_t index = 0
 
+

Member Data Documentation

+ +
+
+ + + + +
size_t ssl_pem_decode_state::index = 0
+
+ +
+
+ +
+
+ + + + +
std::vector<char>* ssl_pem_decode_state::vect
+
+ +
+
+
The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/structssl__pem__decode__state.js b/structssl__pem__decode__state.js new file mode 100644 index 0000000..613852e --- /dev/null +++ b/structssl__pem__decode__state.js @@ -0,0 +1,5 @@ +var structssl__pem__decode__state = +[ + [ "index", "structssl__pem__decode__state.html#a8abbaad636bfcf50ef38f529e3cfd5f3", null ], + [ "vect", "structssl__pem__decode__state.html#aa004af7ee6bfb65161dc47558e3a2ac2", null ] +]; \ No newline at end of file diff --git a/sync_off.png b/sync_off.png new file mode 100644 index 0000000..3b443fc Binary files /dev/null and b/sync_off.png differ diff --git a/sync_on.png b/sync_on.png new file mode 100644 index 0000000..e08320f Binary files /dev/null and b/sync_on.png differ diff --git a/tab_a.png b/tab_a.png new file mode 100644 index 0000000..3b725c4 Binary files /dev/null and b/tab_a.png differ diff --git a/tab_b.png b/tab_b.png new file mode 100644 index 0000000..e2b4a86 Binary files /dev/null and b/tab_b.png differ diff --git a/tab_h.png b/tab_h.png new file mode 100644 index 0000000..fd5cb70 Binary files /dev/null and b/tab_h.png differ diff --git a/tab_s.png b/tab_s.png new file mode 100644 index 0000000..ab478c9 Binary files /dev/null and b/tab_s.png differ diff --git a/tabs.css b/tabs.css new file mode 100644 index 0000000..9cf578f --- /dev/null +++ b/tabs.css @@ -0,0 +1,60 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/time__macros_8h.html b/time__macros_8h.html new file mode 100644 index 0000000..0354431 --- /dev/null +++ b/time__macros_8h.html @@ -0,0 +1,565 @@ + + + + + + +SSLClient: src/time_macros.h File Reference + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
time_macros.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Macros

#define PST_OFFSET   (8UL)
 
#define SEC_PER_MIN   (60UL)
 
#define SEC_PER_HOUR   (3600UL)
 
#define SEC_PER_DAY   (86400UL)
 
#define SEC_PER_YEAR   (SEC_PER_DAY*365)
 
#define CONV_STR2DEC_1(str, i)   (str[i]>'0'?str[i]-'0':0)
 
#define CONV_STR2DEC_2(str, i)   (CONV_STR2DEC_1(str, i)*10 + str[i+1]-'0')
 
#define CONV_STR2DEC_3(str, i)   (CONV_STR2DEC_2(str, i)*10 + str[i+2]-'0')
 
#define CONV_STR2DEC_4(str, i)   (CONV_STR2DEC_3(str, i)*10 + str[i+3]-'0')
 
#define GET_MONTH(str, i)
 
#define __TIME_SECONDS__   CONV_STR2DEC_2(__TIME__, 6)
 
#define __TIME_MINUTES__   CONV_STR2DEC_2(__TIME__, 3)
 
#define __TIME_HOURS__   CONV_STR2DEC_2(__TIME__, 0)
 
#define __TIME_DAYS__   CONV_STR2DEC_2(__DATE__, 4)
 
#define __TIME_MONTH__   GET_MONTH(__DATE__, 0)
 
#define __TIME_YEARS__   CONV_STR2DEC_4(__DATE__, 7)
 
#define _UNIX_TIMESTAMP_FDAY(year)
 
#define _UNIX_TIMESTAMP_YDAY(year, month, day)
 
#define _UNIX_TIMESTAMP(year, month, day, hour, minute, second)
 
#define UNIX_TIMESTAMP   _UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, __TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__)
 
#define UNIX_TIMESTAMP_UTC   (UNIX_TIMESTAMP + (PST_OFFSET*SEC_PER_HOUR))
 
+

Macro Definition Documentation

+ +
+
+ + + + +
#define __TIME_DAYS__   CONV_STR2DEC_2(__DATE__, 4)
+
+ +
+
+ +
+
+ + + + +
#define __TIME_HOURS__   CONV_STR2DEC_2(__TIME__, 0)
+
+ +
+
+ +
+
+ + + + +
#define __TIME_MINUTES__   CONV_STR2DEC_2(__TIME__, 3)
+
+ +
+
+ +
+
+ + + + +
#define __TIME_MONTH__   GET_MONTH(__DATE__, 0)
+
+ +
+
+ +
+
+ + + + +
#define __TIME_SECONDS__   CONV_STR2DEC_2(__TIME__, 6)
+
+ +
+
+ +
+
+ + + + +
#define __TIME_YEARS__   CONV_STR2DEC_4(__DATE__, 7)
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#define _UNIX_TIMESTAMP( year,
 month,
 day,
 hour,
 minute,
 second 
)
+
+Value:
( /* time */ second \
+ minute * SEC_PER_MIN \
+ hour * SEC_PER_HOUR \
+ /* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * SEC_PER_DAY \
+ /* year */ (year - 1970UL) * SEC_PER_YEAR \
+ ((year - 1969UL) / 4UL) * SEC_PER_DAY \
- ((year - 1901UL) / 100UL) * SEC_PER_DAY \
+ ((year - 1601UL) / 400UL) * SEC_PER_DAY \
)
#define SEC_PER_MIN
Definition: time_macros.h:28
+
#define _UNIX_TIMESTAMP_YDAY(year, month, day)
Definition: time_macros.h:69
+
#define SEC_PER_HOUR
Definition: time_macros.h:29
+
#define SEC_PER_DAY
Definition: time_macros.h:30
+
#define SEC_PER_YEAR
Definition: time_macros.h:31
+
+
+
+ +
+
+ + + + + + + + +
#define _UNIX_TIMESTAMP_FDAY( year)
+
+Value:
(((year) % 400) == 0UL ? 29UL : \
(((year) % 100) == 0UL ? 28UL : \
(((year) % 4) == 0UL ? 29UL : \
28UL)))
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
#define _UNIX_TIMESTAMP_YDAY( year,
 month,
 day 
)
+
+Value:
( \
/* January */ day \
/* February */ + (month >= 2 ? 31UL : 0UL) \
/* March */ + (month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) \
/* April */ + (month >= 4 ? 31UL : 0UL) \
/* May */ + (month >= 5 ? 30UL : 0UL) \
/* June */ + (month >= 6 ? 31UL : 0UL) \
/* July */ + (month >= 7 ? 30UL : 0UL) \
/* August */ + (month >= 8 ? 31UL : 0UL) \
/* September */+ (month >= 9 ? 31UL : 0UL) \
/* October */ + (month >= 10 ? 30UL : 0UL) \
/* November */ + (month >= 11 ? 31UL : 0UL) \
/* December */ + (month >= 12 ? 30UL : 0UL) \
)
#define _UNIX_TIMESTAMP_FDAY(year)
Definition: time_macros.h:62
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
#define CONV_STR2DEC_1( str,
 
)   (str[i]>'0'?str[i]-'0':0)
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
#define CONV_STR2DEC_2( str,
 
)   (CONV_STR2DEC_1(str, i)*10 + str[i+1]-'0')
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
#define CONV_STR2DEC_3( str,
 
)   (CONV_STR2DEC_2(str, i)*10 + str[i+2]-'0')
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
#define CONV_STR2DEC_4( str,
 
)   (CONV_STR2DEC_3(str, i)*10 + str[i+3]-'0')
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
#define GET_MONTH( str,
 
)
+
+Value:
(str[i]=='J' && str[i+1]=='a' && str[i+2]=='n' ? 1 : \
str[i]=='F' && str[i+1]=='e' && str[i+2]=='b' ? 2 : \
str[i]=='M' && str[i+1]=='a' && str[i+2]=='r' ? 3 : \
str[i]=='A' && str[i+1]=='p' && str[i+2]=='r' ? 4 : \
str[i]=='M' && str[i+1]=='a' && str[i+2]=='y' ? 5 : \
str[i]=='J' && str[i+1]=='u' && str[i+2]=='n' ? 6 : \
str[i]=='J' && str[i+1]=='u' && str[i+2]=='l' ? 7 : \
str[i]=='A' && str[i+1]=='u' && str[i+2]=='g' ? 8 : \
str[i]=='S' && str[i+1]=='e' && str[i+2]=='p' ? 9 : \
str[i]=='O' && str[i+1]=='c' && str[i+2]=='t' ? 10 : \
str[i]=='N' && str[i+1]=='o' && str[i+2]=='v' ? 11 : \
str[i]=='D' && str[i+1]=='e' && str[i+2]=='c' ? 12 : 0)
+
+
+ +
+
+ + + + +
#define PST_OFFSET   (8UL)
+
+ +
+
+ +
+
+ + + + +
#define SEC_PER_DAY   (86400UL)
+
+ +
+
+ +
+
+ + + + +
#define SEC_PER_HOUR   (3600UL)
+
+ +
+
+ +
+
+ + + + +
#define SEC_PER_MIN   (60UL)
+
+ +
+
+ +
+
+ + + + +
#define SEC_PER_YEAR   (SEC_PER_DAY*365)
+
+ +
+
+ + + +
+
+ + + + +
#define UNIX_TIMESTAMP_UTC   (UNIX_TIMESTAMP + (PST_OFFSET*SEC_PER_HOUR))
+
+ +
+
+
+
+ + + + diff --git a/time__macros_8h.js b/time__macros_8h.js new file mode 100644 index 0000000..e03251c --- /dev/null +++ b/time__macros_8h.js @@ -0,0 +1,24 @@ +var time__macros_8h = +[ + [ "__TIME_DAYS__", "time__macros_8h.html#a7f2cdee2eebbccd45c179a50a0bbabcf", null ], + [ "__TIME_HOURS__", "time__macros_8h.html#a2488d1ddab7e5fa119da3421462231c4", null ], + [ "__TIME_MINUTES__", "time__macros_8h.html#ab3592442029a102b388fafeadc4a6ab8", null ], + [ "__TIME_MONTH__", "time__macros_8h.html#ac8f6b75d9e04634818984ba400d0dee1", null ], + [ "__TIME_SECONDS__", "time__macros_8h.html#a38ac93dd8bfe385ff915a82c92bbfc97", null ], + [ "__TIME_YEARS__", "time__macros_8h.html#a56482fcc86a55713dee595c2092ed376", null ], + [ "_UNIX_TIMESTAMP", "time__macros_8h.html#a868143e0521daf07b25a2f3947cf54a3", null ], + [ "_UNIX_TIMESTAMP_FDAY", "time__macros_8h.html#ab6c76862964ff7e543fd9d5807b2fa79", null ], + [ "_UNIX_TIMESTAMP_YDAY", "time__macros_8h.html#a5ab60a7e3e1b6e0a919b3a37bc0d4b97", null ], + [ "CONV_STR2DEC_1", "time__macros_8h.html#ae0574ced3f997b97d357c1cb68000e3a", null ], + [ "CONV_STR2DEC_2", "time__macros_8h.html#ae90924c33a05839b3eb1426472f40eb3", null ], + [ "CONV_STR2DEC_3", "time__macros_8h.html#aad01b5fb233c0091aff2a837a8de32f4", null ], + [ "CONV_STR2DEC_4", "time__macros_8h.html#a9da779a8ca64782ea49babce14122d34", null ], + [ "GET_MONTH", "time__macros_8h.html#a4dbe4cf7c879a2cdac386ce72c5e5994", null ], + [ "PST_OFFSET", "time__macros_8h.html#a243cf438274412bbecf4b8d5eeb02ccb", null ], + [ "SEC_PER_DAY", "time__macros_8h.html#a3aaee30ddedb3f6675aac341a66e39e2", null ], + [ "SEC_PER_HOUR", "time__macros_8h.html#a2d540510d5860d7f190d13124956bc57", null ], + [ "SEC_PER_MIN", "time__macros_8h.html#ac47b302f1b8d2a7a9c035c417247be76", null ], + [ "SEC_PER_YEAR", "time__macros_8h.html#a8cd8e04105fec7cd442d078c303e46b9", null ], + [ "UNIX_TIMESTAMP", "time__macros_8h.html#a04e76e262f0920441e5f0c5552e83487", null ], + [ "UNIX_TIMESTAMP_UTC", "time__macros_8h.html#a2af3d1d741ae2b49627adf56bbc95dc3", null ] +]; \ No newline at end of file diff --git a/time__macros_8h_source.html b/time__macros_8h_source.html new file mode 100644 index 0000000..a6d998f --- /dev/null +++ b/time__macros_8h_source.html @@ -0,0 +1,124 @@ + + + + + + +SSLClient: src/time_macros.h Source File + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
SSLClient +  v1.6.9 +
+
+
+ + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
time_macros.h
+
+
+Go to the documentation of this file.
1 /*
2  *
3  * Created: 29.03.2018
4  *
5  * Authors:
6  *
7  * Assembled from the code released on Stackoverflow by:
8  * Dennis (instructable.com/member/nqtronix) | https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string
9  * and
10  * Alexis Wilke | https://stackoverflow.com/questions/10538444/do-you-know-of-a-c-macro-to-compute-unix-time-and-date
11  *
12  * Assembled by Jean Rabault
13  *
14  * UNIX_TIMESTAMP gives the UNIX timestamp (unsigned long integer of seconds since 1st Jan 1970) of compilation from macros using the compiler defined __TIME__ macro.
15  * This should include Gregorian calendar leap days, in particular the 29ths of February, 100 and 400 years modulo leaps.
16  *
17  * Careful: __TIME__ is the local time of the computer, NOT the UTC time in general!
18  *
19  */
20 
21 #ifndef COMPILE_TIME_H_
22 #define COMPILE_TIME_H_
23 
24 // add offset for pacific standard time
25 #define PST_OFFSET (8UL)
26 
27 // Some definitions for calculation
28 #define SEC_PER_MIN (60UL)
29 #define SEC_PER_HOUR (3600UL)
30 #define SEC_PER_DAY (86400UL)
31 #define SEC_PER_YEAR (SEC_PER_DAY*365)
32 
33 // extracts 1..4 characters from a string and interprets it as a decimal value
34 #define CONV_STR2DEC_1(str, i) (str[i]>'0'?str[i]-'0':0)
35 #define CONV_STR2DEC_2(str, i) (CONV_STR2DEC_1(str, i)*10 + str[i+1]-'0')
36 #define CONV_STR2DEC_3(str, i) (CONV_STR2DEC_2(str, i)*10 + str[i+2]-'0')
37 #define CONV_STR2DEC_4(str, i) (CONV_STR2DEC_3(str, i)*10 + str[i+3]-'0')
38 
39 // Custom "glue logic" to convert the month name to a usable number
40 #define GET_MONTH(str, i) (str[i]=='J' && str[i+1]=='a' && str[i+2]=='n' ? 1 : \
41  str[i]=='F' && str[i+1]=='e' && str[i+2]=='b' ? 2 : \
42  str[i]=='M' && str[i+1]=='a' && str[i+2]=='r' ? 3 : \
43  str[i]=='A' && str[i+1]=='p' && str[i+2]=='r' ? 4 : \
44  str[i]=='M' && str[i+1]=='a' && str[i+2]=='y' ? 5 : \
45  str[i]=='J' && str[i+1]=='u' && str[i+2]=='n' ? 6 : \
46  str[i]=='J' && str[i+1]=='u' && str[i+2]=='l' ? 7 : \
47  str[i]=='A' && str[i+1]=='u' && str[i+2]=='g' ? 8 : \
48  str[i]=='S' && str[i+1]=='e' && str[i+2]=='p' ? 9 : \
49  str[i]=='O' && str[i+1]=='c' && str[i+2]=='t' ? 10 : \
50  str[i]=='N' && str[i+1]=='o' && str[i+2]=='v' ? 11 : \
51  str[i]=='D' && str[i+1]=='e' && str[i+2]=='c' ? 12 : 0)
52 
53 // extract the information from the time string given by __TIME__ and __DATE__
54 #define __TIME_SECONDS__ CONV_STR2DEC_2(__TIME__, 6)
55 #define __TIME_MINUTES__ CONV_STR2DEC_2(__TIME__, 3)
56 #define __TIME_HOURS__ CONV_STR2DEC_2(__TIME__, 0)
57 #define __TIME_DAYS__ CONV_STR2DEC_2(__DATE__, 4)
58 #define __TIME_MONTH__ GET_MONTH(__DATE__, 0)
59 #define __TIME_YEARS__ CONV_STR2DEC_4(__DATE__, 7)
60 
61 // Days in February
62 #define _UNIX_TIMESTAMP_FDAY(year) \
63  (((year) % 400) == 0UL ? 29UL : \
64  (((year) % 100) == 0UL ? 28UL : \
65  (((year) % 4) == 0UL ? 29UL : \
66  28UL)))
67 
68 // Days in the year
69 #define _UNIX_TIMESTAMP_YDAY(year, month, day) \
70  ( \
71  /* January */ day \
72  /* February */ + (month >= 2 ? 31UL : 0UL) \
73  /* March */ + (month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) \
74  /* April */ + (month >= 4 ? 31UL : 0UL) \
75  /* May */ + (month >= 5 ? 30UL : 0UL) \
76  /* June */ + (month >= 6 ? 31UL : 0UL) \
77  /* July */ + (month >= 7 ? 30UL : 0UL) \
78  /* August */ + (month >= 8 ? 31UL : 0UL) \
79  /* September */+ (month >= 9 ? 31UL : 0UL) \
80  /* October */ + (month >= 10 ? 30UL : 0UL) \
81  /* November */ + (month >= 11 ? 31UL : 0UL) \
82  /* December */ + (month >= 12 ? 30UL : 0UL) \
83  )
84 
85 // get the UNIX timestamp from a digits representation
86 #define _UNIX_TIMESTAMP(year, month, day, hour, minute, second) \
87  ( /* time */ second \
88  + minute * SEC_PER_MIN \
89  + hour * SEC_PER_HOUR \
90  + /* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * SEC_PER_DAY \
91  + /* year */ (year - 1970UL) * SEC_PER_YEAR \
92  + ((year - 1969UL) / 4UL) * SEC_PER_DAY \
93  - ((year - 1901UL) / 100UL) * SEC_PER_DAY \
94  + ((year - 1601UL) / 400UL) * SEC_PER_DAY \
95  )
96 
97 // the UNIX timestamp
98 #define UNIX_TIMESTAMP _UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, __TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__)
99 #define UNIX_TIMESTAMP_UTC (UNIX_TIMESTAMP + (PST_OFFSET*SEC_PER_HOUR))
100 
101 #endif
+
+ + + +